├── sdk ├── tools ├── nvme_sensor.dat ├── nvme_sensor.data ├── crc8write └── crc8write.c ├── .gitignore ├── crc8.h ├── dht.h ├── radio.h ├── bh1750.h ├── ds18b20.h ├── README.md ├── tiny-AES128 ├── include │ └── aes.h ├── unlicense.txt ├── README.md ├── Makefile ├── src │ └── aes.c ├── obj │ └── aes.sym └── lib │ └── aes.lib ├── bme280.h ├── bh1750.c ├── crc8.c ├── dht.c ├── Makefile ├── main.h ├── radio.c ├── ds18b20.c ├── bme280_defs.h ├── main.c └── bme280.c /sdk: -------------------------------------------------------------------------------- 1 | ../../nRF24LE1/nRF24LE1_SDK -------------------------------------------------------------------------------- /tools/nvme_sensor.dat: -------------------------------------------------------------------------------- 1 | P 2 | w -------------------------------------------------------------------------------- /tools/nvme_sensor.data: -------------------------------------------------------------------------------- 1 | P 2 |  -------------------------------------------------------------------------------- /tools/crc8write: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AndruPol/nRF24LE1-sensor/HEAD/tools/crc8write -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | build 3 | aes/dep 4 | aes/lib 5 | aes/obj 6 | .project 7 | .cproject 8 | !build/nrf24le1-sensor.bin 9 | -------------------------------------------------------------------------------- /crc8.h: -------------------------------------------------------------------------------- 1 | /* 2 | * crc8.h 3 | * 4 | * Created on: 20/09/2016 5 | * Author: andru 6 | */ 7 | 8 | #ifndef CRC8_H_ 9 | #define CRC8_H_ 10 | 11 | // use CRC8 source table (increase program size ~100bytes) 12 | #define USECRC8TBL 0 13 | 14 | #include 15 | 16 | uint8_t CRC8(uint8_t *addr, uint8_t len); 17 | 18 | #endif /* CRC8_H_ */ 19 | -------------------------------------------------------------------------------- /dht.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dht.h 3 | * 4 | * Created on: 20/09/2016 5 | * Author: andru 6 | */ 7 | 8 | #ifndef DHT_H_ 9 | #define DHT_H_ 10 | 11 | typedef enum { 12 | DHT_OK, 13 | DHT_NO_RESPONSE, 14 | DHT_TIMEOUT_ERROR, 15 | DHT_CHECKSUM_ERROR, 16 | DHT_NO_VALUE, 17 | } dhterror_t; 18 | 19 | void dht_init(void); 20 | dhterror_t dht_read(int16_t *temp, uint16_t *hum); 21 | 22 | #endif /* DHT_H_ */ 23 | -------------------------------------------------------------------------------- /radio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * radio.h 3 | * 4 | * Created on: 10/07/2016 5 | * Author: andru 6 | */ 7 | 8 | #ifndef RADIO_H_ 9 | #define RADIO_H_ 10 | 11 | #include "main.h" 12 | 13 | #if EN_RF 14 | void rfinit(); 15 | void rfsend(const MESSAGE_T *msg); 16 | uint8_t rfread(MESSAGE_T *msg, uint16_t timeout); 17 | void rfdown(void); 18 | #else 19 | #define rfinit() {}; 20 | #define rfsend(msg) {}; 21 | #define rfread(msg, timeout) (0) 22 | #define rfdown() {}; 23 | #endif 24 | 25 | #endif /* RADIO_H_ */ 26 | -------------------------------------------------------------------------------- /bh1750.h: -------------------------------------------------------------------------------- 1 | /* 2 | * bh1750.h 3 | * 4 | * Created on: 21/09/2016 5 | * Author: andru 6 | */ 7 | 8 | #ifndef BH1750_H_ 9 | #define BH1750_H_ 10 | 11 | #define BH1750_WAIT 200 // wait results (datasheet says max. 180ms) 12 | 13 | typedef enum { 14 | BH1750_OK, 15 | BH1750_ERROR, 16 | BH1750_TIMEOUT, 17 | } bh1750error_t; 18 | 19 | void bh1750_init(void); 20 | bh1750error_t bh1750_read(uint16_t *light); 21 | bh1750error_t bh1750_ask(void); 22 | bh1750error_t bh1750_read_nowait(uint16_t *light); 23 | 24 | #endif /* BH1750_H_ */ 25 | -------------------------------------------------------------------------------- /ds18b20.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ds18b20.h 3 | * 4 | * Created on: 20/09/2016 5 | * Author: andru 6 | */ 7 | 8 | #ifndef DS18B20_H_ 9 | #define DS18B20_H_ 10 | 11 | #define SKIP_ROM_CMD 0xcc 12 | #define START_CONV_CMD 0x44 13 | #define READ_SCR_CMD 0xbe 14 | #define WRITE_SCR_CMD 0x4e 15 | #define REG_TH 0x00 16 | #define REG_TL 0xff 17 | #define REG_CONFIG 0x3f // precision 10bit 18 | 19 | #define DS18B20_WAIT 200 // wait results (datasheet says max. 187.5ms on 10bit prec) 20 | 21 | typedef enum { 22 | DS_OK, 23 | DS_NOT_FOUND, 24 | DS_TIMEOUT, 25 | DS_CRC_ERROR, 26 | } dserror_t; 27 | 28 | dserror_t ds18b20_read(int16_t *temp); 29 | dserror_t ds18b20_ask(void); 30 | dserror_t ds18b20_read_nowait(int16_t *temp); 31 | 32 | #endif /* DS18B20_H_ */ 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nRF24LE1-sensor 2 | ============== 3 | 4 | 5 | ##nRF24LE1 remote sensor 6 | 7 | - support DHT21/22, DS18B20, BME280, BH1750, photo resistor as light sensor, AES encryption 8 | 9 | - works with my custom nRF24 - MODBUS gateway 10 | 11 | - settings stored in nRF24LE1 NVM memory 12 | 13 | based on great project [SDK for the Nordic nRF24LE1](https://github.com/DeanCording/nRF24LE1_SDK) 14 | 15 | #####WARNING: BME280 with AES encryption cause linker error: Insufficient ROM/EPROM/FLASH memory 16 | 17 | === PINOUT === 18 | 19 | P0.1 - LED 20 | 21 | P0.3 - Battery voltage ADC value 22 | 23 | P0.0 - Photo resistor ADC value 24 | 25 | P0.4 - BH1750/BME280 I2C SCL 26 | 27 | P0.5 - BH1750/BME280 I2C SDA 28 | 29 | P1.4 - DHT21/22 30 | 31 | P1.3 - DS18B20 32 | -------------------------------------------------------------------------------- /tiny-AES128/include/aes.h: -------------------------------------------------------------------------------- 1 | #ifndef _AES_H_ 2 | #define _AES_H_ 3 | 4 | #include 5 | 6 | 7 | // #define the macros below to 1/0 to enable/disable the mode of operation. 8 | // 9 | // CBC enables AES128 encryption in CBC-mode of operation and handles 0-padding. 10 | // ECB enables the basic ECB 16-byte block algorithm. Both can be enabled simultaneously. 11 | 12 | // The #ifndef-guard allows it to be configured before #include'ing or at compile time. 13 | #ifndef CBC 14 | #define CBC 0 15 | #endif 16 | 17 | #ifndef ECB 18 | #define ECB 1 19 | #endif 20 | 21 | 22 | 23 | #if defined(ECB) && ECB 24 | 25 | void AES128_ECB_encrypt(const uint8_t* input, const uint8_t* key, uint8_t *output); 26 | void AES128_ECB_decrypt(const uint8_t* input, const uint8_t* key, uint8_t *output); 27 | 28 | #endif // #if defined(ECB) && ECB 29 | 30 | 31 | #if defined(CBC) && CBC 32 | 33 | void AES128_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv); 34 | void AES128_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv); 35 | 36 | #endif // #if defined(CBC) && CBC 37 | 38 | 39 | 40 | #endif //_AES_H_ 41 | -------------------------------------------------------------------------------- /tiny-AES128/unlicense.txt: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /bme280.h: -------------------------------------------------------------------------------- 1 | /* 2 | * nrf24le1_bme280.h 3 | * 4 | * Created on: 30/07/2018 5 | * Author: andru 6 | */ 7 | 8 | #ifndef NRF24LE1_BME280_H_ 9 | #define NRF24LE1_BME280_H_ 10 | 11 | #define BME280_PRESSURE 1 12 | #define BME280_HUMIDITY 1 13 | 14 | /*! CPP guard */ 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | #include 20 | #include "bme280_defs.h" 21 | 22 | bme280_error_t bme280_get_regs(uint8_t reg_addr, uint8_t *reg_data, uint16_t len); 23 | bme280_error_t bme280_set_regs(uint8_t reg_addr, uint8_t *reg_data, uint8_t len); 24 | bme280_error_t bme280_soft_reset(void); 25 | bme280_error_t bme280_init(void); 26 | bme280_error_t write_power_mode(uint8_t sensor_mode); 27 | bme280_error_t bme280_get_sensor_mode(uint8_t *sensor_mode); 28 | bme280_error_t bme280_set_sensor_mode(uint8_t sensor_mode); 29 | bme280_error_t set_osr_settings(uint8_t osr_t, uint8_t osr_p, uint8_t osr_h); 30 | bme280_error_t set_filter_settings(uint8_t filter); 31 | bme280_error_t set_standby_settings(uint8_t standby_time); 32 | bme280_error_t bme280_get_temperature(int32_t *temperature); 33 | #if BME280_PRESSURE 34 | uint32_t bme280_Pa_to_mmHg(uint32_t pressure); 35 | bme280_error_t bme280_get_pressure(uint32_t *pressure); 36 | #endif 37 | #if BME280_HUMIDITY 38 | bme280_error_t bme280_get_humidity(uint32_t *humidity); 39 | #endif 40 | #if DEBUG 41 | bme280_error_t stream_sensor_data_forced_mode(void); 42 | #endif 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif /* End of CPP guard */ 47 | 48 | #endif /* NRF24LE1_BME280_H_ */ 49 | -------------------------------------------------------------------------------- /bh1750.c: -------------------------------------------------------------------------------- 1 | /* 2 | * bh1750.c 3 | * 4 | * Created on: 21/09/2016 5 | * Author: andru 6 | * 7 | * BH1750 - nRF24LE1 light sensor driver 8 | * 9 | */ 10 | 11 | #define BH1750_ADDR 0x23 // device address 12 | #define BH1750_PWR_DOWN 0x0 // No active state. 13 | #define BH1750_CONT_HMODE 0x10 // Continuously H-Resolution Mode 14 | 15 | #include "delay.h" 16 | #include "w2.h" 17 | 18 | #include "bh1750.h" 19 | 20 | void bh1750_init(void) { 21 | w2_configure(W2_CONFIG_OPTION_ENABLE | 22 | W2_CONFIG_OPTION_MODE_MASTER | 23 | W2_CONFIG_OPTION_CLOCK_FREQ_100_KHZ | 24 | W2_CONFIG_OPTION_ALL_INTERRUPTS_ENABLE, 25 | 0 26 | ); 27 | } 28 | 29 | bh1750error_t bh1750_read(uint16_t *light) { 30 | uint8_t addr, txbuf=0, rxbuf[2]; 31 | 32 | addr = BH1750_CONT_HMODE; 33 | if (w2_master_write_to(BH1750_ADDR, &addr, 1, &txbuf, 0) == W2_NACK_VAL) 34 | return BH1750_TIMEOUT; 35 | 36 | delay_ms(BH1750_WAIT); 37 | 38 | if (w2_master_cur_address_read(BH1750_ADDR, rxbuf, 2) == W2_NACK_VAL) 39 | return BH1750_ERROR; 40 | 41 | addr = BH1750_PWR_DOWN; 42 | w2_master_write_to(BH1750_ADDR, &addr, 1, &txbuf, 0); 43 | 44 | *light = (uint32_t) ((rxbuf[0] << 8) + rxbuf[1]) * 10 / 12; 45 | 46 | return BH1750_OK; 47 | } 48 | 49 | bh1750error_t bh1750_ask(void) { 50 | uint8_t addr, txbuf=0; 51 | 52 | addr = BH1750_CONT_HMODE; 53 | if (w2_master_write_to(BH1750_ADDR, &addr, 1, &txbuf, 0) == W2_NACK_VAL) 54 | return BH1750_TIMEOUT; 55 | 56 | return BH1750_OK; 57 | } 58 | 59 | bh1750error_t bh1750_read_nowait(uint16_t *light) { 60 | uint8_t addr, txbuf=0, rxbuf[2]; 61 | 62 | if (w2_master_cur_address_read(BH1750_ADDR, rxbuf, 2) == W2_NACK_VAL) 63 | return BH1750_ERROR; 64 | 65 | addr = BH1750_PWR_DOWN; 66 | w2_master_write_to(BH1750_ADDR, &addr, 1, &txbuf, 0); 67 | 68 | *light = (uint32_t) ((rxbuf[0] << 8) + rxbuf[1]) * 10 / 12; 69 | 70 | return BH1750_OK; 71 | } 72 | -------------------------------------------------------------------------------- /crc8.c: -------------------------------------------------------------------------------- 1 | /* 2 | * crc8.c 3 | * 4 | * Created on: 20/09/2016 5 | * Author: andru 6 | */ 7 | 8 | #include 9 | 10 | #include "crc8.h" 11 | 12 | #if defined(USECRC8TBL) && USECRC8TBL 13 | 14 | // CRC8 data source table 15 | static const uint8_t dscrc_table[] = { 16 | 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, 17 | 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, 18 | 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, 19 | 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, 20 | 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, 21 | 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, 22 | 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, 23 | 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, 24 | 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, 25 | 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, 26 | 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, 27 | 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, 28 | 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, 29 | 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, 30 | 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, 31 | 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53 32 | }; 33 | 34 | uint8_t CRC8(uint8_t *addr, uint8_t len) 35 | { 36 | uint8_t crc = 0; 37 | 38 | while (len--) { 39 | crc = dscrc_table[crc ^ *addr++]; 40 | } 41 | return crc; 42 | } 43 | 44 | #else 45 | 46 | static uint8_t crcDS(uint8_t inp, uint8_t crc) 47 | { 48 | inp ^= crc; 49 | crc = 0; 50 | if(inp & 0x1) crc ^= 0x5e; 51 | if(inp & 0x2) crc ^= 0xbc; 52 | if(inp & 0x4) crc ^= 0x61; 53 | if(inp & 0x8) crc ^= 0xc2; 54 | if(inp & 0x10) crc ^= 0x9d; 55 | if(inp & 0x20) crc ^= 0x23; 56 | if(inp & 0x40) crc ^= 0x46; 57 | if(inp & 0x80) crc ^= 0x8c; 58 | return crc; 59 | } 60 | 61 | uint8_t CRC8(uint8_t *addr, uint8_t len) 62 | { 63 | uint8_t crc = 0; 64 | while (len--) { 65 | crc = crcDS(*addr++, crc); 66 | } 67 | return crc; 68 | } 69 | 70 | #endif 71 | 72 | -------------------------------------------------------------------------------- /tools/crc8write.c: -------------------------------------------------------------------------------- 1 | /* 2 | * CRC8 file calculator 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define MAXSIZE 512 11 | 12 | // CRC8 data source table 13 | static const uint8_t dscrc_table[] = { 14 | 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, 15 | 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, 16 | 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, 17 | 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, 18 | 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, 19 | 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, 20 | 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, 21 | 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, 22 | 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, 23 | 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, 24 | 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, 25 | 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, 26 | 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, 27 | 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, 28 | 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, 29 | 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53}; 30 | 31 | static uint8_t CRC8( uint8_t *addr, uint16_t len) 32 | { 33 | uint8_t crc = 0; 34 | 35 | while (len--) { 36 | crc = dscrc_table[crc ^ *addr++]; 37 | } 38 | return crc; 39 | } 40 | 41 | 42 | int main(int argc, char *argv[]) { 43 | uint8_t data[MAXSIZE]; 44 | FILE * pFile; 45 | 46 | if (argc < 3) { 47 | printf("\nCRC8 to file writer:\nUsage: %s input_file output_file\n", argv[0]); 48 | return 1; 49 | } 50 | 51 | pFile = fopen(argv[1] , "rb"); 52 | if (pFile == NULL) { 53 | printf("File open error: %s\n", argv[1]); 54 | return 1; 55 | } 56 | 57 | uint16_t bytes = 0; 58 | int ch; 59 | while ((ch = fgetc(pFile)) != EOF) { 60 | if (bytes > MAXSIZE) { 61 | printf("File size error: filesize > %d\n", MAXSIZE); 62 | fclose(pFile); 63 | return 1; 64 | } 65 | data[bytes++] = (uint8_t) ch; 66 | } 67 | fclose(pFile); 68 | 69 | uint16_t filesize = bytes--; 70 | uint8_t crc = CRC8(data, filesize); 71 | 72 | pFile = fopen(argv[2] , "wb"); 73 | if (pFile == NULL) { 74 | printf("File open error: %s\n", argv[2]); 75 | return 1; 76 | } 77 | 78 | bytes = 0; 79 | while (bytes < filesize) { 80 | if (fputc(data[bytes++], pFile) == EOF) { 81 | printf("Write to file error: %d\n", bytes--); 82 | fclose(pFile); 83 | return 1; 84 | } 85 | } 86 | 87 | if (fputc(crc, pFile) == EOF) { 88 | printf("Write CRC to file error\n"); 89 | } 90 | fclose(pFile); 91 | 92 | printf("File: %s, size %d, CRC8: 0x%02X\n", argv[1], filesize, crc); 93 | 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /tiny-AES128/README.md: -------------------------------------------------------------------------------- 1 | ### Tiny AES128 in C 2 | 3 | This is a small and portable implementation of the AES128 ECB and CBC encryption algorithms written in C. 4 | 5 | The API is very simple and looks like this (I am using C99 ``-style annotated types): 6 | 7 | ```C 8 | void AES128_ECB_encrypt(uint8_t* input, const uint8_t* key, uint8_t* output); 9 | void AES128_ECB_decrypt(uint8_t* input, const uint8_t* key, uint8_t* output); 10 | void AES128_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv); 11 | void AES128_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv); 12 | ``` 13 | 14 | You can choose to use one or both of the modes-of-operation, by defining the symbols CBC and ECB. See the header file for clarification. 15 | 16 | There is no built-in error checking or protection from out-of-bounds memory access errors as a result of malicious input. The two functions AES128_ECB_xxcrypt() do most of the work, and they expect inputs of 128 bit length. 17 | 18 | The module uses around 200 bytes of RAM and 2.5K ROM when compiled for ARM (~2K for Thumb but YMMV). 19 | 20 | It is one of the smallest implementation in C I've seen yet, but do contact me if you know of something smaller (or have improvements to the code here). 21 | 22 | I've successfully used the code on 64bit x86, 32bit ARM and 8 bit AVR platforms. 23 | 24 | 25 | GCC size output when ECB mode is compiled for ARM: 26 | 27 | 28 | 29 | $ arm-none-eabi-gcc -Os -c aes.c -DCBC=0 30 | $ size aes.o 31 | text data bss dec hex filename 32 | 2323 0 184 2507 9cb aes.o 33 | 34 | 35 | 36 | 37 | .. and when compiling for the THUMB instruction set, we end up around 2K in code size. 38 | 39 | $ arm-none-eabi-gcc -mthumb -Os -c aes.c -DCBC=0 40 | $ size aes.o 41 | text data bss dec hex filename 42 | 1775 0 184 1959 7a7 aes.o 43 | 44 | 45 | 46 | I am using Mentor Graphics free ARM toolchain: 47 | 48 | 49 | $ arm-none-eabi-gcc --version 50 | arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.8.4 20140526 (release) [ARM/embedded-4_8-branch revision 211358] 51 | Copyright (C) 2013 Free Software Foundation, Inc. 52 | This is free software; see the source for copying conditions. There is NO 53 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 54 | 55 | 56 | 57 | 58 | This implementation is verified against the data in: 59 | 60 | [National Institute of Standards and Technology Special Publication 800-38A 2001 ED](http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf) Appendix F: Example Vectors for Modes of Operation of the AES. 61 | 62 | 63 | All material in this repository is in the public domain. 64 | 65 | I am a bit slow to react to pull requests and issues, but I have an ambition to go through all issues sometime in the future and release a stable version. 66 | -------------------------------------------------------------------------------- /dht.c: -------------------------------------------------------------------------------- 1 | /* 2 | * dht.c 3 | * 4 | * Created on: 20/09/2016 5 | * Author: andru 6 | * 7 | * DHT21/22 nRF24LE1 driver 8 | */ 9 | 10 | #include 11 | 12 | #include "gpio.h" 13 | #include "delay.h" 14 | 15 | #include "dht.h" 16 | 17 | #define DHTUSEP0 0 // P0.X 18 | #define DHTUSEP1 1 // P1.X 19 | 20 | #define PIN0XVAL(p) ((P0 & (1 << (p % 8))) > 0 ? 1 : 0) // read P0.X 21 | #define PIN1XVAL(p) ((P1 & (1 << (p % 8))) > 0 ? 1 : 0) // read P1.X 22 | 23 | // P1.4 - номер пина DHT21/22 24 | #define DHTPIN GPIO_PIN_ID_P1_4 25 | 26 | static uint8_t waitpin(uint8_t val) 27 | { 28 | uint8_t readtm = 80; 29 | #if DHTUSEP0 30 | while ((PIN0XVAL(DHTPIN) != val) && (--readtm > 0)); // for P0.X only 31 | #endif 32 | #if DHTUSEP1 33 | while ((PIN1XVAL(DHTPIN) != val) && (--readtm > 0)); // for P1.X only 34 | #endif 35 | if (readtm == 0) { 36 | return 0; 37 | } 38 | return 1; 39 | } 40 | 41 | void dht_init(void) { 42 | gpio_pin_configure(DHTPIN, 43 | GPIO_PIN_CONFIG_OPTION_DIR_INPUT 44 | | GPIO_PIN_CONFIG_OPTION_PIN_MODE_INPUT_BUFFER_ON_NO_RESISTORS 45 | ); 46 | } 47 | 48 | /* temperature in 1/10 deg C, humidity in 1/10 % */ 49 | dhterror_t dht_read(int16_t *temp, uint16_t *hum) { 50 | uint8_t j, i; 51 | uint8_t datadht[5] = {0,0,0,0,0}; 52 | uint8_t crcdata = 0; 53 | 54 | //pin as output and set 0 55 | gpio_pin_configure(DHTPIN, 56 | GPIO_PIN_CONFIG_OPTION_DIR_OUTPUT 57 | | GPIO_PIN_CONFIG_OPTION_OUTPUT_VAL_CLEAR 58 | | GPIO_PIN_CONFIG_OPTION_PIN_MODE_OUTPUT_BUFFER_NORMAL_DRIVE_STRENGTH 59 | ); 60 | 61 | delay_ms(1); // reset 1-20ms 62 | 63 | //pin as input 64 | gpio_pin_configure(DHTPIN, 65 | GPIO_PIN_CONFIG_OPTION_DIR_INPUT 66 | | GPIO_PIN_CONFIG_OPTION_PIN_MODE_INPUT_BUFFER_ON_NO_RESISTORS 67 | ); 68 | 69 | //=============check DHT response 70 | if (!waitpin(0)) { 71 | return DHT_NO_RESPONSE; 72 | } 73 | if (!waitpin(1)) { 74 | return DHT_NO_RESPONSE; 75 | } 76 | //===============receive 40 data bits 77 | if (!waitpin(0)) { 78 | return DHT_NO_RESPONSE; 79 | } 80 | 81 | for (j = 0; j < 5; j++) { 82 | for(i = 0; i < 8; i++) { 83 | if (!waitpin(1)) { 84 | return DHT_TIMEOUT_ERROR; 85 | } 86 | delay_us(30); 87 | if (gpio_pin_val_read(DHTPIN)) 88 | datadht[j] |= 1 << (7-i); 89 | if (!waitpin(0)) { 90 | return DHT_TIMEOUT_ERROR; 91 | } 92 | } 93 | } 94 | 95 | if (datadht[0] == 0 && datadht[1] == 0 && datadht[2] == 0 && datadht[3] == 0) { 96 | return DHT_NO_VALUE; 97 | } 98 | 99 | for(i = 0; i < 4; i++) { 100 | crcdata += datadht[i]; 101 | } 102 | if ((crcdata & 0xff) != datadht[4]) { // CRC check 103 | return DHT_CHECKSUM_ERROR; 104 | } 105 | 106 | if ((datadht[1] == 0) && (datadht[3] == 0)) { 107 | // dht11 108 | *hum = datadht[2]*10; 109 | *temp = datadht[0]*10; 110 | } 111 | else { 112 | // dht22 113 | *hum = ((uint16_t) datadht[0] << 8) | (uint16_t) datadht[1]; 114 | *temp = (((uint16_t) datadht[2] & 0x7F) << 8) | (uint16_t) datadht[3]; 115 | if (datadht[2] & 0x80) *temp *= -1; 116 | } 117 | 118 | return DHT_OK; 119 | } 120 | -------------------------------------------------------------------------------- /tiny-AES128/Makefile: -------------------------------------------------------------------------------- 1 | # Functions needed by this makefile and the one that builds the source libraries (MakefileSrc) 2 | export ECHO = @echo 3 | export RM = rm 4 | export SED = sed 5 | export MKDIR = mkdir -p 6 | export RMDIR = rmdir 7 | export TR = tr 8 | export BLACKHOLE = /dev/null 9 | export PWD = pwd 10 | export CD = cd 11 | export LS = ls 12 | 13 | # Programs to use for creating dependencies, compiling source files, and creating the library file, respectively 14 | DEP = sdcc 15 | CC = sdcc 16 | LIB = sdcclib 17 | 18 | # Flags for above programs when calling them from the command line 19 | DFLAGS = -MM $(INCDIRS) $< 20 | CFLAGS = --model-large --std-c99 $(INCDIRS) -c $< -o "obj/" 21 | LFLAGS = 22 | 23 | # File extensions for dependency files, source files, object files, and library files, respectively 24 | DEPEXT = d 25 | SRCEXT = c 26 | OBJEXT = rel 27 | LIBEXT = lib 28 | 29 | # Compiler version 30 | ifneq ($(MINCOMPILERBUILD),) 31 | CCVERSION := $(subst \#,,$(filter \#%,$(strip $(shell $(CC) -v)))) 32 | CCVERSIONOK := $(shell [ $(CCVERSION) -ge $(MINCOMPILERBUILD) ] && echo "YES" || echo "NO") 33 | ifeq ($(CCVERSIONOK),NO) 34 | $(error "The build has detected an SDCC build of #$(CCVERSION). This library must be built by an SDCC build of at least #$(MINCOMPILERBUILD). Please update your SDCC installation.") 35 | endif 36 | endif 37 | 38 | # Source dir name, include directories, and sub source dir 39 | TARGET := aes 40 | INCDIRS = -Iinclude 41 | SRCDIR = src 42 | 43 | # Directories for objects, dependencies, and library files 44 | OBJDIR = obj 45 | DEPDIR = dep 46 | LIBDIR = lib 47 | 48 | # Name of library file, list of source files, object files, and dependency files 49 | LIBFILE = $(LIBDIR)/$(TARGET).$(LIBEXT) 50 | LIBFILES = $(subst .$(OBJEXT),.$(LIBEXT),$(subst $(OBJDIR),$(LIBDIR),$(OBJFILES))) 51 | SRCFILES := $(shell $(LS) $(SRCDIR)/*.$(SRCEXT)) 52 | OBJFILES = $(subst .$(SRCEXT),.$(OBJEXT),$(subst $(SRCDIR),$(OBJDIR),$(SRCFILES))) 53 | DEPFILES = $(subst .$(SRCEXT),.$(DEPEXT),$(subst $(SRCDIR),$(DEPDIR),$(SRCFILES))) 54 | 55 | # Used to makes sure source files get built if their dependency files are modified 56 | #-include $(DEPFILES) 57 | 58 | all: $(LIBFILE) 59 | 60 | $(LIBDIR)/%.$(LIBEXT): $(OBJFILES) 61 | $(ECHO) 62 | $(ECHO) "Building library file '$@'" 63 | [ -d $(LIBDIR) ] || $(MKDIR) $(LIBDIR) > $(BLACKHOLE) 64 | $(LIB) $(LFLAGS) $@ $(OBJFILES) 65 | $(ECHO) "Finished building library file '$@'" 66 | $(ECHO) 67 | 68 | $(OBJDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT) $(DEPDIR)/%.$(DEPEXT) 69 | $(ECHO) 70 | $(ECHO) "Building object file '$@'" 71 | [ -d $(OBJDIR) ] || $(MKDIR) $(OBJDIR) > $(BLACKHOLE) 72 | $(CC) $(CFLAGS) 73 | $(ECHO) "Finished building object file '$@'" 74 | 75 | clean: 76 | $(RM) -rf $(OBJDIR)/* $(DEPDIR)/* $(LIBDIR)/* > $(BLACKHOLE) 77 | [ -d $(DEPDIR) ] && $(RMDIR) $(DEPDIR) > $(BLACKHOLE) 78 | [ -d $(OBJDIR) ] && $(RMDIR) $(OBJDIR) > $(BLACKHOLE) 79 | [ -d $(LIBDIR) ] && $(RMDIR) $(LIBDIR) > $(BLACKHOLE) 80 | 81 | $(DEPDIR)/%.$(DEPEXT): $(SRCDIR)/%.$(SRCEXT) 82 | $(ECHO) 83 | $(ECHO) "Building dependency file '$@'" 84 | [ -d $(DEPDIR) ] || $(MKDIR) $(DEPDIR) > $(BLACKHOLE) 85 | $(ECHO) "$(OBJDIR)/" | $(TR) -d '\n' | $(TR) -d '\r' > $@.tmp 86 | $(DEP) $(DFLAGS) >> $@.tmp 87 | $(SED) 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.tmp > $@ 88 | $(RM) -f $@.tmp 89 | $(ECHO) "Finished building dependency file '$@'" 90 | 91 | #.SECONDARY: $(OBJFILES) $(DEPFILES) 92 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Functions needed by this makefile and the one that builds the source libraries (MakefileSrc) 2 | export ECHO = @echo 3 | export RM = rm 4 | export SED = sed 5 | export MKDIR = mkdir -p 6 | export RMDIR = rmdir 7 | export TR = tr 8 | export BLACKHOLE = /dev/null 9 | export PWD = pwd 10 | export CD = cd 11 | export LS = ls 12 | 13 | PROJECT = nrf24le1-sensor 14 | 15 | TARGET = _target_sdcc_nrf24le1_32 16 | MEMORYMODEL = --model-large 17 | 18 | # Programs to use for creating dependencies, compiling source files, and creating the library file, respectively 19 | DEP = sdcc 20 | CC = sdcc 21 | LD = sdld 22 | LIB = sdcclib 23 | HEX2BIN = ../hex2bin/hex2bin 24 | 25 | BUILD := build 26 | OBJDIR := $(BUILD)/obj 27 | DEPDIR := $(BUILD)/dep 28 | LIBDIR := $(BUILD)/lib 29 | 30 | SRCFILES = crc8.c \ 31 | bme280.c \ 32 | ds18b20.c \ 33 | bh1750.c \ 34 | radio.c \ 35 | dht.c \ 36 | main.c 37 | 38 | DEPFILES := $(subst .c,.d,$(addprefix $(DEPDIR)/,$(SRCFILES))) 39 | OBJFILES := $(SRCFILES:.c=.rel) 40 | OBJFILES := $(addprefix $(OBJDIR)/,$(OBJFILES)) 41 | LIBFILES := $(SRCFILES:.c=.lib) 42 | LIBFILES := $(addprefix $(LIBDIR)/,$(LIBFILES)) 43 | LDFILES := $(SRCFILES:.c=) 44 | LDFILES := $(addprefix -l,$(LDFILES)) 45 | 46 | LDSDCC = -L/usr/local/share/sdcc/lib/large -lmcs51 -llibsdcc 47 | LDNRF = -Lsdk/$(TARGET)/lib -lnrf24le1 48 | LDtinyAES = -Ltiny-AES128/lib -laes 49 | 50 | LIBNRF = sdk/$(TARGET)/lib/nrf24le1.lib 51 | LIBtinyAES = tiny-AES128/lib/aes.lib 52 | 53 | DFLAGS=-MM -Isdk/include -Isdk/$(TARGET)/include/ -Itiny-AES128/include/ 54 | CCFLAGS=$(MEMORYMODEL) --std-c99 --opt-code-size -Isdk/include -Isdk/$(TARGET)/include/ -Itiny-AES128/include/ 55 | LDFLAGS=--code-loc 0x0000 --code-size 0x4000 --xram-loc 0x0000 --xram-size 0x400 $(LDSDCC) $(LDNRF) $(LDtinyAES) -L$(LIBDIR) $(LDFILES) 56 | LFLAGS = 57 | 58 | PROJECTBIN = $(BUILD)/$(PROJECT).bin 59 | CRC8CALC = tools/crc8calc 60 | 61 | all: $(LIBNRF) $(LIBtinyAES) $(PROJECTBIN) 62 | 63 | -include $(DEPFILES) 64 | 65 | $(DEPDIR)/%.d: %.c %.h 66 | $(ECHO) 67 | $(ECHO) "Building dependency file '$@'" 68 | [ -d $(DEPDIR) ] || $(MKDIR) $(DEPDIR) > $(BLACKHOLE) 69 | $(CC) $(DFLAGS) $< >> $@.tmp 70 | $(SED) 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.tmp > $@ 71 | $(RM) -f $@.tmp 72 | $(ECHO) "Finished building dependency file '$@'" 73 | 74 | $(LIBDIR)/%.lib: %.rel $(OBJFILES) 75 | $(ECHO) 76 | $(ECHO) "Building library file '$@'" 77 | [ -d $(LIBDIR) ] || $(MKDIR) $(LIBDIR) > $(BLACKHOLE) 78 | $(LIB) $(LFLAGS) $@ $(OBJDIR)/$< 79 | $(ECHO) "Finished building library file '$@'" 80 | $(ECHO) 81 | 82 | $(OBJDIR)/%.rel : %.c $(DEPFILES) 83 | $(ECHO) 84 | $(ECHO) "Building object file '$@'" 85 | [ -d $(OBJDIR) ] || $(MKDIR) $(OBJDIR) > $(BLACKHOLE) 86 | $(DEP) -c $(CCFLAGS) $< -o $(OBJDIR)/ 87 | $(ECHO) "Finished building object file '$@'" 88 | 89 | $(BUILD)/$(PROJECT).ihx : $(LIBFILES) 90 | $(ECHO) 91 | $(ECHO) "Building hex file '$@'" 92 | $(CC) $(MEMORYMODEL) $(OBJDIR)/main.rel -o $@ $(LDFLAGS) 93 | $(ECHO) "Finished building hex file '$@'" 94 | 95 | $(BUILD)/%.bin: $(BUILD)/%.ihx 96 | $(ECHO) 97 | $(ECHO) "Building binary file '$@'" 98 | $(HEX2BIN) -p 00 $@ $^ 99 | $(ECHO) "Finished building binary file '$@'" 100 | # copy to home 101 | cp -vf $(PROJECTBIN) ~/ 102 | 103 | $(LIBNRF): 104 | make -C sdk all 105 | 106 | $(LIBtinyAES): 107 | make -C tiny-AES128 all 108 | 109 | tools: tools/crc8calc 110 | 111 | tools/crc8calc : tools/crc8calc.c 112 | $(ECHO) 113 | $(ECHO) "Building '$@'" 114 | gcc $< -o $@ 115 | $(ECHO) "Finished building '$@'" 116 | 117 | clean: 118 | $(RM) -rf $(BUILD)/* && $(RMDIR) $(BUILD) 119 | 120 | cleanall: 121 | $(RM) -rf $(BUILD)/* && $(RMDIR) $(BUILD) 122 | make -C sdk clean 123 | make -C tiny-AES128 clean 124 | 125 | .PHONY: all clean cleanall tools 126 | -------------------------------------------------------------------------------- /main.h: -------------------------------------------------------------------------------- 1 | /* 2 | * main.h 3 | * 4 | * Created on: 20/09/2016 5 | * Author: andru 6 | */ 7 | 8 | #ifndef MAIN_H_ 9 | #define MAIN_H_ 10 | 11 | #include 12 | 13 | #define FIRMWARE 131 // firmware revision 14 | #define BATTERY 1 // battery power 15 | #define DEBUG 0 // debug output via UART 16 | //#define printf printf_tiny 17 | 18 | #define EN_LED 0 // LED enable 19 | #define EN_RF 1 // radio enable 20 | #define EN_DHT 1 // DHT21/22 enable 21 | #define EN_DS18B20 1 // DS18B20 enable 22 | #define EN_VBAT 1 // ADC battery voltage 23 | #define EN_BH1750 0 // BH1750 light sensor enable 24 | #define EN_LIGHT 1 // ADC light sensor enable 25 | #define EN_SLEEP 1 // power save mode enable 26 | #define EN_AES 1 // AES encryption enable 27 | #define EN_BME280 0 // BME280 sensor enable 28 | #define EN_CRC 0 // use CRC8 in radio packets 29 | 30 | // NVM configuration data for nRF24LE1 31 | typedef struct CONFIG CONFIG_T; 32 | struct CONFIG { 33 | uint8_t version; // configuration version 34 | uint8_t deviceid; // device ID 35 | uint8_t channel; // radio channel: 0-199 36 | uint8_t sndaddr[5]; // gateway address to send 37 | uint8_t rcvaddr[5]; // device address to receive command 38 | uint8_t maxsend; // max message send retries 39 | uint16_t sleeptm; // wakeup by watchdog timer, S (LSB first) 40 | uint16_t vbatlow; // battery low ADC value 41 | #if EN_AES 42 | uint8_t aeskey[16]; // aes encryption key 43 | #endif 44 | uint8_t crcbyte; // CRC8 sizeof(config) - 1 45 | }; 46 | 47 | // internal address map 48 | #define ADDR_NUM 8 49 | typedef enum { 50 | #if EN_LIGHT 51 | ADDR_LIGHT = 0, // ADC light 52 | #endif 53 | #if EN_BH1750 54 | ADDR_BH1750 = 0, // BH1750 light 55 | #endif 56 | #if EN_DS18B20 57 | ADDR_DS18B20 = 1, // DS18B20 temperature 58 | #endif 59 | #if EN_DHT 60 | ADDR_DHT_TEMP = 2, // DHT temperature 61 | ADDR_DHT_HUM = 3, // DHT humidity 62 | #endif 63 | #if EN_BME280 64 | ADDR_BME280_TEMP = 2, // BME280 temperature 65 | ADDR_BME280_HUM = 3, // BME280 humidity 66 | ADDR_BME280_PRES = 8, // BME280 pressure 67 | #endif 68 | #if EN_VBAT 69 | ADDR_VBAT = 4, // BATTERY voltage (ADC) 70 | CFG_VBATLOW = 5, // uint16_t vbatlow; 71 | #endif 72 | CFG_CHANNEL = 6, // uint8_t channel; 73 | CFG_SLEEP = 7, // uint16_t sleeptm; 74 | } address_t; 75 | 76 | // типы передаваемых сообщений 77 | typedef enum { 78 | MSG_INFO = 0, 79 | MSG_DATA, 80 | MSG_ERROR, 81 | MSG_CMD, 82 | } msgtype_t; 83 | 84 | // типы передаваемых данных 85 | typedef enum { 86 | VAL_ch, 87 | VAL_i16, 88 | VAL_i32, 89 | VAL_fl, 90 | } msgvalue_t; 91 | 92 | // команды устройству 93 | typedef enum { 94 | CMD_CFGREAD = 1, // read configuration value 95 | CMD_CFGWRITE, // write configuration value 96 | CMD_RESET, // reset device 97 | CMD_MSGWAIT, //remote waiting messages 98 | CMD_SENSOREAD = 10, // read sensor value 99 | CMD_ON = 20, // ON 100 | CMD_OFF, // OFF 101 | CMD_ONTM, // ON timeout (S) 102 | CMD_OFFTM, // OFF timeout (S) 103 | CMD_GETREG = 40, // GET register value 104 | CMD_SETREG, // SET register value 105 | } command_t; 106 | 107 | // тип отправки сообщения: записывается в cmdparam 108 | typedef enum { 109 | CMD_NONE, // command none 110 | CMD_SEND, // command send immediately 111 | CMD_WAIT, // wait message from device & send command 112 | } devicecmd_t; 113 | 114 | // message length 115 | #define MSGLEN sizeof(MESSAGE_T) 116 | 117 | // NRF receive/send message format 118 | typedef struct MESSAGE MESSAGE_T; 119 | struct MESSAGE { 120 | msgtype_t msgtype; // (in/out): message type 121 | uint8_t deviceid; // (in/out): remote device id 122 | uint8_t firmware; // (in/out): remote firmware 123 | uint8_t addrnum; // (out): remote device internal address number 124 | uint8_t address; // (in/out): on remote device internal address 125 | command_t command; // (in): command 126 | uint8_t error; // (in): remote error code 127 | msgvalue_t datatype; // (in/out): type of data 128 | uint8_t datapower; // (in/out): ^10 data power; 129 | uint8_t datalength; // (out): data array length 130 | int16_t cmdparam; // (in): command parameter 131 | union { // (in): value depend of message type 132 | uint8_t c4[4]; // char value in c4[0] 133 | int16_t i16[2]; // int16 value in i16[0] 134 | int32_t i32; // int32 value 135 | float f; // float value 136 | } data; 137 | }; 138 | 139 | // error codes 140 | typedef enum { 141 | ERR_VBATLOW = 1, 142 | ERR_CFGWRITE, 143 | ERR_CMDPARAM, 144 | } msgerr_t; 145 | 146 | extern CONFIG_T config; 147 | 148 | #endif /* MAIN_H_ */ 149 | -------------------------------------------------------------------------------- /radio.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "rf.h" 5 | #include "interrupt.h" 6 | #include "main.h" 7 | #include "crc8.h" 8 | 9 | #if EN_AES 10 | #include "tiny-AES128/include/aes.h" 11 | #endif 12 | 13 | /////////////////////////////////////////// 14 | // Inline function definitions 15 | /////////////////////////////////////////// 16 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | // 18 | // static __INLINE uint8_t enc_dec_accel_galois_multiply(uint8_t a, uint8_t b) __reentrant 19 | // 20 | // Description: 21 | // Performs a GF(2^8) mutliplication in hardware and returns the result 22 | // 23 | // Parameters: 24 | // uint8_t a - multiplier in the operation 25 | // uint8_t b - multiplicand in the operation 26 | // 27 | // Return value: 28 | // Result of the GF(2^8) multiplication 29 | // 30 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 31 | //See enc_dec_accel_galois_multiply.c for function details (function body is the same) 32 | unsigned char enc_dec_accel_galois_multiply(unsigned char a, unsigned char b) 33 | { 34 | //Load the hardware registers for the operators 35 | CCPDATIA = a; 36 | CCPDATIB = b; 37 | 38 | //Return the result of the hardware GF(2^8) multiplication 39 | return CCPDATO; 40 | } 41 | 42 | void rfinit() { 43 | uint8_t setup; 44 | 45 | rf_spi_configure_enable(); 46 | 47 | setup = RF_CONFIG_EN_CRC; // power up here, CRC 1 bytes 48 | rf_power_up_param(false, setup); 49 | 50 | setup = RF_SETUP_RETR_ARD_750 | RF_SETUP_RETR_ARC_3; // 750us, 3 retry 51 | rf_write_register(RF_SETUP_RETR, &setup, 1); 52 | 53 | setup = RF_SETUP_AW_5BYTES; // 5 bytes address 54 | rf_write_register(RF_SETUP_AW, &setup, 1); 55 | 56 | setup = RF_EN_RXADDR_ERX_P0 | RF_EN_RXADDR_ERX_P1; // enable pipe0 & pipe1 57 | rf_write_register(RF_EN_RXADDR, &setup, 1); 58 | 59 | rf_write_register(RF_RX_ADDR_P0, config.sndaddr, 5); 60 | rf_write_register(RF_TX_ADDR, config.sndaddr, 5); 61 | 62 | config.rcvaddr[4] = config.deviceid; 63 | rf_write_register(RF_RX_ADDR_P1, config.rcvaddr, 5); 64 | 65 | setup = MSGLEN; /* Number of bytes in RX payload */ 66 | rf_write_register(RF_RX_PW_P0, &setup, 1); 67 | rf_write_register(RF_RX_PW_P1, &setup, 1); 68 | 69 | setup = RF_EN_AA_ENAA_P0 | RF_EN_AA_ENAA_P1; // set autoask 70 | rf_write_register(RF_EN_AA, &setup, 1); 71 | 72 | rf_set_rf_channel(config.channel); 73 | 74 | rf_set_output_power(RF_RF_SETUP_RF_PWR_0_DBM); 75 | 76 | setup &= ~(RF_RF_SETUP_RF_DR_LOW | RF_RF_SETUP_RF_DR_HIGH); // default datarate 1Mhz 77 | rf_write_register(RF_RF_SETUP, &setup, 1); 78 | 79 | interrupt_control_rfirq_enable(); 80 | } 81 | 82 | void rfdown(void) { 83 | rf_irq_clear_all(); 84 | rf_power_down(); 85 | } 86 | 87 | void rfsend(const MESSAGE_T *msg) { 88 | uint16_t timeout; 89 | uint8_t retry = config.maxsend; 90 | uint8_t buf[MSGLEN], out[MSGLEN]; 91 | 92 | if (!(rf_read_register_1_byte(RF_CONFIG) & RF_CONFIG_PWR_UP)) 93 | rfinit(); 94 | 95 | memcpy(&buf, msg, MSGLEN); 96 | #if EN_CRC 97 | buf[MSGLEN-1] = CRC8((uint8_t *) msg, MSGLEN-1); 98 | #endif 99 | 100 | #if EN_AES 101 | AES128_ECB_encrypt((uint8_t*) buf, config.aeskey, out); 102 | #else 103 | memcpy(&out, &buf, MSGLEN); 104 | #endif 105 | 106 | start: 107 | if (rf_tx_fifo_is_full()) 108 | rf_flush_tx(); 109 | 110 | rf_irq_clear_all(); //clear all interrupts in the 24L01 111 | rf_set_as_tx(); //resume normal operation as a TX 112 | 113 | rf_write_tx_payload(out, MSGLEN, true); //transmit received char over RF 114 | 115 | //wait until the packet has been sent or the maximum number of retries has been reached 116 | timeout = 90; // 90*26us = 2.3ms > 750uS * 3 117 | while(! rf_irq_pin_active()) { 118 | if (timeout-- == 0) { // checking timeout if nothing 119 | if (retry-- > 0) goto start; 120 | break; 121 | } 122 | delay_us(10); // 10us 123 | } 124 | if (rf_irq_pin_active() && rf_irq_max_rt_active()) { // checking max_rt bit 125 | if (retry-- > 0) goto start; 126 | } 127 | 128 | rf_irq_clear_all(); 129 | } 130 | 131 | // blocking read NRF24LE1, timeout in 10us intervals 132 | uint8_t rfread(MESSAGE_T *msg, uint16_t timeout) { 133 | uint8_t status, state = 0; 134 | uint8_t buf[MSGLEN], in[MSGLEN]; 135 | 136 | if (!(rf_read_register_1_byte(RF_CONFIG) & RF_CONFIG_PWR_UP)) 137 | rfinit(); 138 | 139 | rf_set_as_rx(true); //change the device to an RX to get the character back from the other 24L01 140 | rf_irq_clear_all(); //clear interrupts again 141 | 142 | while (timeout-- > 0) { 143 | //wait a while to see if we get the data back (change the loop maximum and the lower if 144 | // argument (should be loop maximum - 1) to lengthen or shorten this time frame 145 | if(rf_irq_pin_active() && rf_irq_rx_dr_active()) { 146 | status = rf_read_rx_payload(buf, MSGLEN); //get the payload into data 147 | if (rf_is_rxed_payload_on_pipe_1_in_status_val(status)) { 148 | state = 1; 149 | break; 150 | } 151 | } 152 | delay_us(10); // 10us 153 | } 154 | 155 | rf_irq_clear_all(); 156 | 157 | if (!state) 158 | return state; 159 | 160 | #if EN_AES 161 | AES128_ECB_decrypt(buf, config.aeskey, in); 162 | #else 163 | memcpy(&in, &buf, MSGLEN); 164 | #endif 165 | #if EN_CRC 166 | if (in[MSGLEN-1] != CRC8(in, MSGLEN-1)) { 167 | return 0; 168 | } 169 | #endif 170 | memcpy(msg, &in, MSGLEN); 171 | 172 | return state; 173 | } 174 | -------------------------------------------------------------------------------- /ds18b20.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ds18b20.c 3 | * 4 | * Created on: 20/09/2016 5 | * Author: andru 6 | * 7 | * DS18B20 nRF24LE1 driver 8 | * 9 | */ 10 | 11 | // P1.3 - DS18B20 pin 12 | #define DSPIN GPIO_PIN_ID_P1_3 13 | 14 | #include 15 | 16 | #include "gpio.h" 17 | #include "delay.h" 18 | #include "interrupt.h" 19 | 20 | #include "crc8.h" 21 | #include "ds18b20.h" 22 | 23 | // DS18B20 temperature convertation to int16_t 24 | #define BIT2_1 (1<<3) 25 | #define BIT2_2 (1<<2) 26 | #define BIT2_3 (1<<1) 27 | #define BIT2_4 (1<<0) 28 | 29 | #define POWER2_1 (5000) 30 | #define POWER2_2 (2500) 31 | #define POWER2_3 (1250) 32 | #define POWER2_4 (0650) 33 | 34 | // return DS18B20 temperature * 10 35 | static int16_t tconv(int16_t raw) { 36 | int16_t frac = ((raw & BIT2_1) ? POWER2_1 : 0) + 37 | ((raw & BIT2_2) ? POWER2_2 : 0) + 38 | ((raw & BIT2_3) ? POWER2_3 : 0) + 39 | ((raw & BIT2_4) ? POWER2_4 : 0); 40 | frac = (frac - frac / 1000) >= 500 ? frac + 500 : frac - 500; 41 | frac = (raw & (1<<15)) ? (-1 * frac / 1000) : (frac / 1000); 42 | return (10 * (raw >> 4) + frac); 43 | } 44 | 45 | static uint8_t OneWireReset(void) 46 | { 47 | uint8_t r = 1; 48 | gpio_pin_configure(DSPIN, 49 | GPIO_PIN_CONFIG_OPTION_DIR_OUTPUT 50 | | GPIO_PIN_CONFIG_OPTION_OUTPUT_VAL_CLEAR 51 | | GPIO_PIN_CONFIG_OPTION_PIN_MODE_OUTPUT_BUFFER_NORMAL_DRIVE_STRENGTH 52 | ); 53 | delay_us(480); 54 | gpio_pin_configure(DSPIN, 55 | GPIO_PIN_CONFIG_OPTION_DIR_INPUT 56 | | GPIO_PIN_CONFIG_OPTION_PIN_MODE_INPUT_BUFFER_ON_NO_RESISTORS 57 | ); 58 | delay_us(70); 59 | r = !gpio_pin_val_read(DSPIN); 60 | delay_us(410); 61 | return r; 62 | } 63 | 64 | static void OneWireOutByte(uint8_t d) 65 | { 66 | uint8_t n; 67 | 68 | for(n = 8; n > 0; n--) { 69 | if (d & 0x01) { 70 | gpio_pin_configure(DSPIN, 71 | GPIO_PIN_CONFIG_OPTION_DIR_OUTPUT 72 | | GPIO_PIN_CONFIG_OPTION_OUTPUT_VAL_CLEAR 73 | | GPIO_PIN_CONFIG_OPTION_PIN_MODE_OUTPUT_BUFFER_NORMAL_DRIVE_STRENGTH 74 | ); 75 | delay_us(1); 76 | gpio_pin_configure(DSPIN, 77 | GPIO_PIN_CONFIG_OPTION_DIR_INPUT 78 | | GPIO_PIN_CONFIG_OPTION_PIN_MODE_INPUT_BUFFER_ON_NO_RESISTORS 79 | ); 80 | delay_us(50); 81 | } 82 | else { 83 | gpio_pin_configure(DSPIN, 84 | GPIO_PIN_CONFIG_OPTION_DIR_OUTPUT 85 | | GPIO_PIN_CONFIG_OPTION_OUTPUT_VAL_CLEAR 86 | | GPIO_PIN_CONFIG_OPTION_PIN_MODE_OUTPUT_BUFFER_NORMAL_DRIVE_STRENGTH 87 | ); 88 | delay_us(50); 89 | gpio_pin_configure(DSPIN, 90 | GPIO_PIN_CONFIG_OPTION_DIR_INPUT 91 | | GPIO_PIN_CONFIG_OPTION_PIN_MODE_INPUT_BUFFER_ON_NO_RESISTORS 92 | ); 93 | delay_us(1); 94 | } 95 | d = d >> 1; 96 | } 97 | } 98 | 99 | static uint8_t OneWireInByte(void) 100 | { 101 | uint8_t d = 0, n, b = 0; 102 | 103 | for (n = 0; n < 8; n++) { 104 | gpio_pin_configure(DSPIN, 105 | GPIO_PIN_CONFIG_OPTION_DIR_OUTPUT 106 | | GPIO_PIN_CONFIG_OPTION_OUTPUT_VAL_CLEAR 107 | | GPIO_PIN_CONFIG_OPTION_PIN_MODE_OUTPUT_BUFFER_NORMAL_DRIVE_STRENGTH 108 | ); 109 | delay_us(1); 110 | gpio_pin_configure(DSPIN, 111 | GPIO_PIN_CONFIG_OPTION_DIR_INPUT 112 | | GPIO_PIN_CONFIG_OPTION_PIN_MODE_INPUT_BUFFER_ON_NO_RESISTORS 113 | ); 114 | delay_us(2); 115 | b = gpio_pin_val_read(DSPIN); 116 | delay_us(50); 117 | d = (d >> 1) | (b << 7); 118 | } 119 | return d; 120 | } 121 | 122 | // read DS18B20 tempearature in 1/10 C 123 | dserror_t ds18b20_read(int16_t *temp) 124 | { 125 | uint8_t i, data[9], crc = 0; 126 | 127 | if (!OneWireReset()) { 128 | return DS_NOT_FOUND; 129 | } 130 | // 0xCC skip ROM 131 | OneWireOutByte(SKIP_ROM_CMD); 132 | 133 | // setting precision 10bit 134 | OneWireOutByte(WRITE_SCR_CMD); 135 | OneWireOutByte(REG_TH); 136 | OneWireOutByte(REG_TL); 137 | OneWireOutByte(REG_CONFIG); 138 | 139 | if (!OneWireReset()) { 140 | return DS_NOT_FOUND; 141 | } 142 | // 0xCC skip ROM 143 | OneWireOutByte(SKIP_ROM_CMD); 144 | // 0x44 start conversion 145 | OneWireOutByte(START_CONV_CMD); 146 | 147 | // wait while temperature value not ready 148 | delay_ms(DS18B20_WAIT); 149 | 150 | if (!OneWireReset()) { 151 | return DS_NOT_FOUND; 152 | } 153 | 154 | OneWireOutByte(SKIP_ROM_CMD); 155 | // 0xbe get temperature from ram 156 | OneWireOutByte(READ_SCR_CMD); 157 | 158 | for (i = 0; i < 9; i++) { 159 | /* Read byte by byte */ 160 | data[i] = OneWireInByte(); 161 | } 162 | 163 | if (CRC8(data, 8) != data[8]) { 164 | return DS_CRC_ERROR; 165 | } 166 | 167 | /* First two bytes of scratchpad are temperature values */ 168 | *temp = tconv((int16_t)(data[1] << 8) | data[0]); 169 | 170 | return DS_OK; 171 | } 172 | 173 | // ask DS18B20 temperature 174 | dserror_t ds18b20_ask(void) 175 | { 176 | if (!OneWireReset()) { 177 | return DS_NOT_FOUND; 178 | } 179 | // 0xCC skip ROM 180 | OneWireOutByte(SKIP_ROM_CMD); 181 | 182 | // setting precision 10bit 183 | OneWireOutByte(WRITE_SCR_CMD); 184 | OneWireOutByte(REG_TH); 185 | OneWireOutByte(REG_TL); 186 | OneWireOutByte(REG_CONFIG); 187 | 188 | if (!OneWireReset()) { 189 | return DS_NOT_FOUND; 190 | } 191 | // 0xCC skip ROM 192 | OneWireOutByte(SKIP_ROM_CMD); 193 | // 0x44 start conversion 194 | OneWireOutByte(START_CONV_CMD); 195 | return DS_OK; 196 | } 197 | 198 | // read DS18B20 tempearature in 1/10 C 199 | dserror_t ds18b20_read_nowait(int16_t *temp) 200 | { 201 | uint8_t i, data[9], crc = 0; 202 | 203 | if (!OneWireReset()) { 204 | return DS_NOT_FOUND; 205 | } 206 | 207 | OneWireOutByte(SKIP_ROM_CMD); 208 | // 0xbe get temperature from ram 209 | OneWireOutByte(READ_SCR_CMD); 210 | 211 | for (i = 0; i < 9; i++) { 212 | /* Read byte by byte */ 213 | data[i] = OneWireInByte(); 214 | } 215 | 216 | if (CRC8(data, 8) != data[8]) { 217 | return DS_CRC_ERROR; 218 | } 219 | 220 | /* First two bytes of scratchpad are temperature values */ 221 | *temp = tconv((int16_t)(data[1] << 8) | data[0]); 222 | 223 | return DS_OK; 224 | } 225 | -------------------------------------------------------------------------------- /bme280_defs.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016 - 2017 Bosch Sensortec GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 10 | * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * Neither the name of the copyright holder nor the names of the 15 | * contributors may be used to endorse or promote products derived from 16 | * this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 19 | * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 20 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER 23 | * OR CONTRIBUTORS BE LIABLE FOR ANY 24 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 25 | * OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, 26 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | * ANY WAY OUT OF THE USE OF THIS 32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 33 | * 34 | * The information provided is believed to be accurate and reliable. 35 | * The copyright holder assumes no responsibility 36 | * for the consequences of use 37 | * of such information nor for any infringement of patents or 38 | * other rights of third parties which may result from its use. 39 | * No license is granted by implication or otherwise under any patent or 40 | * patent rights of the copyright holder. 41 | * 42 | * @file bme280_defs.h 43 | * @date 14 Feb 2018 44 | * @version 3.3.4 45 | * @brief 46 | * 47 | */ 48 | 49 | /*! @file bme280_defs.h 50 | @brief Sensor driver for BME280 sensor */ 51 | /*! 52 | * @defgroup BME280 SENSOR API 53 | * @brief 54 | * @{*/ 55 | #ifndef BME280_DEFS_H_ 56 | #define BME280_DEFS_H_ 57 | 58 | #include 59 | #include 60 | 61 | /********************************************************/ 62 | /*! @name Common macros */ 63 | /********************************************************/ 64 | 65 | #if !defined(UINT8_C) && !defined(INT8_C) 66 | #define INT8_C(x) S8_C(x) 67 | #define UINT8_C(x) U8_C(x) 68 | #endif 69 | 70 | #if !defined(UINT16_C) && !defined(INT16_C) 71 | #define INT16_C(x) S16_C(x) 72 | #define UINT16_C(x) U16_C(x) 73 | #endif 74 | 75 | #if !defined(INT32_C) && !defined(UINT32_C) 76 | #define INT32_C(x) S32_C(x) 77 | #define UINT32_C(x) U32_C(x) 78 | #endif 79 | 80 | #if !defined(INT64_C) && !defined(UINT64_C) 81 | #define INT64_C(x) S64_C(x) 82 | #define UINT64_C(x) U64_C(x) 83 | #endif 84 | 85 | /**@}*/ 86 | 87 | /**\name C standard macros */ 88 | #ifndef NULL 89 | #ifdef __cplusplus 90 | #define NULL 0 91 | #else 92 | #define NULL ((void *) 0) 93 | #endif 94 | #endif 95 | /********************************************************/ 96 | 97 | #ifndef TRUE 98 | #define TRUE UINT8_C(1) 99 | #endif 100 | #ifndef FALSE 101 | #define FALSE UINT8_C(0) 102 | #endif 103 | 104 | /**\name I2C addresses */ 105 | #define BME280_I2C_ADDR_PRIM UINT8_C(0x76) 106 | #define BME280_I2C_ADDR_SEC UINT8_C(0x77) 107 | 108 | /**\name BME280 chip identifier */ 109 | #define BME280_CHIP_ID UINT8_C(0x60) 110 | 111 | /**\name Register Address */ 112 | #define BME280_CHIP_ID_ADDR UINT8_C(0xD0) 113 | #define BME280_RESET_ADDR UINT8_C(0xE0) 114 | #define BME280_CTRL_HUM_ADDR UINT8_C(0xF2) 115 | #define BME280_STATUS_ADDR UINT8_C(0xF3) 116 | #define BME280_PWR_CTRL_ADDR UINT8_C(0xF4) 117 | #define BME280_CTRL_MEAS_ADDR UINT8_C(0xF4) 118 | #define BME280_CONFIG_ADDR UINT8_C(0xF5) 119 | #define BME280_P_DATA_ADDR UINT8_C(0xF7) 120 | #define BME280_T_DATA_ADDR UINT8_C(0xFA) 121 | #define BME280_H_DATA_ADDR UINT8_C(0xFD) 122 | #define BME280_T_CALIB_DATA_ADDR UINT8_C(0x88) 123 | #define BME280_P_CALIB_DATA_ADDR UINT8_C(0x8E) 124 | #define BME280_H_CALIB_DATA_ADDR1 UINT8_C(0xA1) 125 | #define BME280_H_CALIB_DATA_ADDR2 UINT8_C(0xE1) 126 | 127 | #define TEMPERATURE_MIN INT32_C( -4000 ) 128 | #define TEMPERATURE_MAX INT32_C( 8500 ) 129 | #define PRESSURE_MIN UINT32_C( 30000 ) 130 | #define PRESSURE_MAX UINT32_C( 110000 ) 131 | #define HUMIDITY_MAX UINT32_C( 102400 ) 132 | 133 | /**\name API error codes */ 134 | typedef enum { 135 | BME280_OK, 136 | BME280_E_NULL_PTR, 137 | BME280_E_DEV_NOT_FOUND, 138 | BME280_E_INVALID_LEN, 139 | BME280_E_COMM_FAIL, 140 | BME280_E_SLEEP_MODE_FAIL, 141 | BME280_E_CONV, 142 | } bme280_error_t; 143 | 144 | /**\name API warning codes */ 145 | #define BME280_W_INVALID_OSR_MACRO INT8_C(1) 146 | 147 | /**\name Macros related to size */ 148 | #define BME280_T_CALIB_DATA_LEN UINT8_C(6) 149 | #define BME280_P_CALIB_DATA_LEN UINT8_C(18) 150 | #define BME280_H_CALIB_DATA_LEN1 UINT8_C(1) 151 | #define BME280_H_CALIB_DATA_LEN2 UINT8_C(8) 152 | #define BME280_T_DATA_LEN UINT8_C(3) 153 | #define BME280_P_DATA_LEN UINT8_C(3) 154 | #define BME280_H_DATA_LEN UINT8_C(2) 155 | 156 | /**\name Sensor power modes */ 157 | #define BME280_SLEEP_MODE UINT8_C(0x00) 158 | #define BME280_FORCED_MODE UINT8_C(0x01) 159 | #define BME280_NORMAL_MODE UINT8_C(0x03) 160 | 161 | /**\name Macro to combine two 8 bit data's to form a 16 bit data */ 162 | #define BME280_CONCAT_BYTES(msb, lsb) (((uint16_t)msb << 8) | (uint16_t)lsb) 163 | 164 | #define BME280_SET_BITS(reg_data, bitname, data) \ 165 | ((reg_data & ~(bitname##_MSK)) | \ 166 | ((data << bitname##_POS) & bitname##_MSK)) 167 | #define BME280_SET_BITS_POS_0(reg_data, bitname, data) \ 168 | ((reg_data & ~(bitname##_MSK)) | \ 169 | (data & bitname##_MSK)) 170 | 171 | #define BME280_GET_BITS(reg_data, bitname) ((reg_data & (bitname##_MSK)) >> \ 172 | (bitname##_POS)) 173 | #define BME280_GET_BITS_POS_0(reg_data, bitname) (reg_data & (bitname##_MSK)) 174 | 175 | /**\name Macros for bit masking */ 176 | #define BME280_SENSOR_MODE_MSK UINT8_C(0x03) 177 | #define BME280_SENSOR_MODE_POS UINT8_C(0x00) 178 | 179 | #define BME280_CTRL_HUM_MSK UINT8_C(0x07) 180 | #define BME280_CTRL_HUM_POS UINT8_C(0x00) 181 | 182 | #define BME280_CTRL_PRESS_MSK UINT8_C(0x1C) 183 | #define BME280_CTRL_PRESS_POS UINT8_C(0x02) 184 | 185 | #define BME280_CTRL_TEMP_MSK UINT8_C(0xE0) 186 | #define BME280_CTRL_TEMP_POS UINT8_C(0x05) 187 | 188 | #define BME280_FILTER_MSK UINT8_C(0x1C) 189 | #define BME280_FILTER_POS UINT8_C(0x02) 190 | 191 | #define BME280_STANDBY_MSK UINT8_C(0xE0) 192 | #define BME280_STANDBY_POS UINT8_C(0x05) 193 | 194 | /**\name Oversampling macros */ 195 | #define BME280_NO_OVERSAMPLING UINT8_C(0x00) 196 | #define BME280_OVERSAMPLING_1X UINT8_C(0x01) 197 | #define BME280_OVERSAMPLING_2X UINT8_C(0x02) 198 | #define BME280_OVERSAMPLING_4X UINT8_C(0x03) 199 | #define BME280_OVERSAMPLING_8X UINT8_C(0x04) 200 | #define BME280_OVERSAMPLING_16X UINT8_C(0x05) 201 | 202 | /**\name Standby duration selection macros */ 203 | #define BME280_STANDBY_TIME_1_MS (0x00) 204 | #define BME280_STANDBY_TIME_62_5_MS (0x01) 205 | #define BME280_STANDBY_TIME_125_MS (0x02) 206 | #define BME280_STANDBY_TIME_250_MS (0x03) 207 | #define BME280_STANDBY_TIME_500_MS (0x04) 208 | #define BME280_STANDBY_TIME_1000_MS (0x05) 209 | #define BME280_STANDBY_TIME_10_MS (0x06) 210 | #define BME280_STANDBY_TIME_20_MS (0x07) 211 | 212 | /**\name Filter coefficient selection macros */ 213 | #define BME280_FILTER_COEFF_OFF (0x00) 214 | #define BME280_FILTER_COEFF_2 (0x01) 215 | #define BME280_FILTER_COEFF_4 (0x02) 216 | #define BME280_FILTER_COEFF_8 (0x03) 217 | #define BME280_FILTER_COEFF_16 (0x04) 218 | 219 | #endif /* BME280_DEFS_H_ */ 220 | /** @}*/ 221 | /** @}*/ 222 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on: 20/09/2016 3 | * Author: andru 4 | * 5 | * nRF24LE1 remote sensors unit 6 | * support DHT21/22, DS18B20, BH1750, ADC sensors, AES encryption 7 | * 8 | * based on great nRF24LE1 SDK https://github.com/DeanCording/nRF24LE1_SDK 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include "gpio.h" 16 | #include "delay.h" 17 | #include "memory.h" 18 | #include "adc.h" 19 | #include "rtc2.h" 20 | #include "pwr_clk_mgmt.h" 21 | #include "watchdog.h" 22 | #include "interrupt.h" 23 | 24 | #include "main.h" 25 | #include "crc8.h" 26 | #include "radio.h" 27 | #if EN_DHT 28 | #include "dht.h" 29 | #endif 30 | #if EN_DS18B20 31 | #include "ds18b20.h" 32 | #endif 33 | #if EN_BH1750 34 | #include "bh1750.h" 35 | #endif 36 | #if EN_BME280 37 | #include "bme280.h" 38 | #endif 39 | 40 | #define CMDWAIT 4000 // command wait time in ~20us intervals 41 | #define WDGTIMEOUT 2 // watchdog timeout, sec 42 | #define PWRUPWAIT 19800 // power up DHT sensor ~ 600mS 43 | #define SENSWAIT 6560 // sensors max wait ~200mS 44 | 45 | #if DEBUG 46 | #define EN_UART 1 // use UART for debugging 47 | #define UARTTXPIN GPIO_PIN_ID_P0_3 // P0.3 - UART TX 48 | #define UARTRXPIN GPIO_PIN_ID_P0_4 // P0.4 - UART RX 49 | #else 50 | #define EN_UART 0 // use UART for debugging 51 | #endif 52 | 53 | #define LEDPIN GPIO_PIN_ID_P0_0 // P0.0 - LED 54 | //#define DHTPIN GPIO_PIN_ID_P1_4 // P1.4 - DHT21/22 55 | //#define DSPIN GPIO_PIN_ID_P1_3 // P1.3 - DS18B20 56 | #define VBATCH ADC_CHANNEL_AIN5 // P0.5 - VBAT 57 | #define LIGHTCH ADC_CHANNEL_AIN1 // P0.1 - ADC LIGHT 58 | //#define W2SCL GPIO_PIN_ID_P0_4 // P0.4 - BH1750 2-wire SCL 59 | //#define W2SDA GPIO_PIN_ID_P0_5 // P0.5 - BH1750 2-wire SDA 60 | #define VENPIN GPIO_PIN_ID_P0_7 // P0.7 - sensors power enable 61 | 62 | #define LEDOFF gpio_pin_configure(LEDPIN, \ 63 | GPIO_PIN_CONFIG_OPTION_DIR_OUTPUT \ 64 | | GPIO_PIN_CONFIG_OPTION_OUTPUT_VAL_CLEAR \ 65 | | GPIO_PIN_CONFIG_OPTION_PIN_MODE_OUTPUT_BUFFER_NORMAL_DRIVE_STRENGTH \ 66 | ); 67 | 68 | #define LEDON gpio_pin_configure(LEDPIN, \ 69 | GPIO_PIN_CONFIG_OPTION_DIR_OUTPUT \ 70 | | GPIO_PIN_CONFIG_OPTION_OUTPUT_VAL_SET \ 71 | | GPIO_PIN_CONFIG_OPTION_PIN_MODE_OUTPUT_BUFFER_NORMAL_DRIVE_STRENGTH \ 72 | ); 73 | 74 | #define VENOFF gpio_pin_configure(VENPIN, \ 75 | GPIO_PIN_CONFIG_OPTION_DIR_OUTPUT \ 76 | | GPIO_PIN_CONFIG_OPTION_OUTPUT_VAL_CLEAR \ 77 | | GPIO_PIN_CONFIG_OPTION_PIN_MODE_OUTPUT_BUFFER_NORMAL_DRIVE_STRENGTH \ 78 | ); 79 | 80 | #define VENON gpio_pin_configure(VENPIN, \ 81 | GPIO_PIN_CONFIG_OPTION_DIR_OUTPUT \ 82 | | GPIO_PIN_CONFIG_OPTION_OUTPUT_VAL_SET \ 83 | | GPIO_PIN_CONFIG_OPTION_PIN_MODE_OUTPUT_BUFFER_NORMAL_DRIVE_STRENGTH \ 84 | ); 85 | 86 | #define NVM_START_ADDRESS MEMORY_FLASH_NV_STD_END_START_ADDRESS 87 | #define ENVM_START_ADDRESS MEMORY_FLASH_NV_EXT_END_START_ADDRESS 88 | #define ENVM_PAGE_NUM MEMORY_FLASH_NV_EXT_END_FIRST_PAGE_NUM 89 | 90 | #if EN_UART 91 | #include "uart.h" 92 | #endif 93 | 94 | CONFIG_T config; 95 | MESSAGE_T message; 96 | 97 | // halt 98 | static void halt(void) { 99 | while (1) { 100 | #if EN_LED && ! BATTERY 101 | gpio_pin_val_complement(LEDPIN); 102 | #endif 103 | delay_ms(250); 104 | } 105 | } 106 | 107 | #define SAMPLES_NUM 16 108 | #define SAMPLES_GOOD 2 109 | #define SAMPLES_SUM 12 110 | static uint16_t samples[SAMPLES_NUM]; 111 | 112 | static void samples_sort(void) { 113 | uint8_t i, j; 114 | for(i = 0 ; i < SAMPLES_NUM - 1; i++) { 115 | for(j = 0 ; j < SAMPLES_NUM - i - 1 ; j++) { 116 | if(samples[j] > samples[j+1]) { 117 | uint16_t tmp = samples[j]; 118 | samples[j] = samples[j+1] ; 119 | samples[j+1] = tmp; 120 | } 121 | } 122 | } 123 | } 124 | 125 | #if EN_VBAT || EN_LIGHT 126 | static uint16_t adc_get(adc_channel_t channel) { 127 | uint8_t i; 128 | uint32_t sum = 0; 129 | 130 | for (i = 0; i < SAMPLES_NUM; i++) { 131 | samples[i] = adc_start_single_conversion_get_value(channel); 132 | } 133 | samples_sort(); 134 | for (i = SAMPLES_GOOD; i < SAMPLES_GOOD + SAMPLES_SUM; i++) { 135 | sum += samples[i]; 136 | } 137 | 138 | return (uint16_t) sum / SAMPLES_SUM; 139 | } 140 | #else 141 | static uint16_t adc_get(adc_channel_t channel) { 142 | (void) channel; 143 | return 0; 144 | } 145 | #endif 146 | 147 | static void uart_init(void) { 148 | #if EN_UART 149 | // Setup UART pins 150 | gpio_pin_configure(GPIO_PIN_ID_FUNC_RXD, 151 | GPIO_PIN_CONFIG_OPTION_DIR_INPUT | 152 | GPIO_PIN_CONFIG_OPTION_PIN_MODE_INPUT_BUFFER_ON_NO_RESISTORS 153 | ); 154 | 155 | gpio_pin_configure(GPIO_PIN_ID_FUNC_TXD, 156 | GPIO_PIN_CONFIG_OPTION_DIR_OUTPUT | 157 | GPIO_PIN_CONFIG_OPTION_OUTPUT_VAL_SET | 158 | GPIO_PIN_CONFIG_OPTION_PIN_MODE_OUTPUT_BUFFER_NORMAL_DRIVE_STRENGTH 159 | ); 160 | 161 | uart_configure_8_n_1_38400(); 162 | #endif 163 | } 164 | 165 | static void rtc_init(void) { 166 | // RTC2 init on 1s interval 167 | pwr_clk_mgmt_clklf_configure(PWR_CLK_MGMT_CLKLF_CONFIG_OPTION_CLK_SRC_RCOSC32K); 168 | pwr_clk_mgmt_wait_until_clklf_is_ready(); 169 | 170 | watchdog_setup(); 171 | watchdog_set_wdsv_count(watchdog_calc_timeout_from_sec(WDGTIMEOUT)); 172 | 173 | pwr_clk_mgmt_op_mode_configure( 174 | PWR_CLK_MGMT_OP_MODE_CONFIG_OPTION_RUN_WD_NORMALLY | 175 | PWR_CLK_MGMT_WAKEUP_CONFIG_OPTION_WAKEUP_ON_RTC2_TICK_ALWAYS 176 | ); 177 | 178 | rtc2_configure( 179 | RTC2_CONFIG_OPTION_COMPARE_MODE_0_RESET_AT_IRQ, 180 | 32767); // 1s 181 | } 182 | 183 | static void adc_init(void) { 184 | #if EN_VBAT || EN_LIGHT 185 | adc_configure((uint16_t) 186 | ADC_CONFIG_OPTION_RESOLUTION_10_BITS 187 | | ADC_CONFIG_OPTION_REF_SELECT_VDD 188 | | ADC_CONFIG_OPTION_RESULT_JUSTIFICATION_RIGHT 189 | | ADC_CONFIG_OPTION_ACQ_TIME_12_US 190 | ); 191 | adc_power_up(); 192 | #endif 193 | } 194 | 195 | // write NVM config to eNVM 196 | static uint8_t write_config(void) { 197 | uint8_t ret = CRC8((uint8_t *) &config, sizeof(CONFIG_T) - 1); 198 | config.crcbyte = ret; 199 | if (memory_flash_erase_page(ENVM_PAGE_NUM) != MEMORY_FLASH_OK) 200 | return 0; 201 | if (memory_flash_write_bytes(ENVM_START_ADDRESS, sizeof(CONFIG_T), (uint8_t *) &config) != MEMORY_FLASH_OK) 202 | return 0; 203 | return 1; 204 | } 205 | 206 | static void read_config(uint16_t addr) { 207 | uint16_t i; 208 | memory_movx_accesses_data_memory(); 209 | for (i = 0; i < sizeof(CONFIG_T); i++) { 210 | *((uint8_t*) &config + i) = *((__xdata uint8_t*) addr + i); 211 | } 212 | } 213 | 214 | static void message_fill(uint8_t addr) { 215 | memset(&message, 0, MSGLEN); 216 | message.firmware = FIRMWARE; 217 | message.addrnum = ADDR_NUM; 218 | message.cmdparam = CMD_WAIT; 219 | message.deviceid = config.deviceid; 220 | message.address = addr; 221 | } 222 | 223 | static void send_config(uint8_t addr, uint16_t value) { 224 | #if 0 225 | printf("cfg: addr=%d, val=%d\r\n", addr, (uint16_t) value); 226 | #endif 227 | message_fill(addr); 228 | message.msgtype = MSG_INFO; 229 | message.datatype = VAL_i32; 230 | message.datapower = 0; 231 | message.data.i32 = value; 232 | rfsend(&message); 233 | } 234 | 235 | static void send_config_err(uint8_t addr, uint8_t errcode) { 236 | #if 0 237 | printf("cfg: addr=%d, error=%d\r\n", addr, errcode); 238 | #endif 239 | message_fill(addr); 240 | message.msgtype = MSG_ERROR; 241 | message.error = errcode; 242 | message.datapower = 0; 243 | message.data.i32 = errcode; 244 | rfsend(&message); 245 | } 246 | 247 | #if EN_SLEEP 248 | // register retension sleep 30.51uS * time 249 | void dosleep(uint16_t tm) { 250 | if (tm == 0) return; 251 | 252 | rtc2_configure( 253 | RTC2_CONFIG_OPTION_COMPARE_MODE_0_RESET_AT_IRQ, 254 | tm); 255 | 256 | watchdog_set_wdsv_count(watchdog_calc_timeout_from_sec(WDGTIMEOUT)); 257 | 258 | rtc2_run(); 259 | pwr_clk_mgmt_enter_pwr_mode_register_ret(); 260 | rtc2_stop(); 261 | #if DEBUG 262 | printf("sleep: time=%d\r\n", tm); 263 | #endif 264 | } 265 | #endif 266 | 267 | 268 | // main 269 | void main(void) { 270 | // variable definition 271 | uint8_t ret, cmd; 272 | 273 | #if EN_VBAT 274 | uint16_t vbat; 275 | #endif 276 | 277 | #if EN_LIGHT || EN_BH1750 278 | uint16_t light; 279 | #endif 280 | 281 | #if EN_DS18B20 282 | int16_t DSTemp; 283 | #endif 284 | 285 | #if EN_DHT 286 | int16_t DHTTemp, DHTHum; 287 | #endif 288 | 289 | #if EN_BME280 290 | int32_t val32; 291 | #endif 292 | 293 | #if EN_LED 294 | LEDOFF; 295 | #endif 296 | 297 | read_config(NVM_START_ADDRESS); 298 | ret = CRC8((uint8_t *) &config, sizeof(CONFIG_T)-1); 299 | if (config.crcbyte != ret) { 300 | // NVM config wrong stop work 301 | halt(); 302 | } 303 | 304 | cmd = config.version; 305 | read_config(ENVM_START_ADDRESS); 306 | ret = CRC8((uint8_t *) &config, sizeof(CONFIG_T)-1); 307 | if (config.crcbyte != ret || config.version != cmd) { 308 | read_config(NVM_START_ADDRESS); 309 | if (!write_config()) { 310 | // config write error stop work 311 | halt(); 312 | } 313 | } 314 | 315 | uart_init(); 316 | 317 | #if 0 318 | printf("\r\nid=%d\r\ncfgver=%d\r\nchannel=%d\r\n", config.deviceid, config.version, config.channel); 319 | printf("maxsend=%d\r\nsleep=%d\r\nvbatlow=%d\r\n", config.maxsend, config.sleeptm, config.vbatlow); 320 | printf("sndaddr=%02X%02X%02X%02X%02X, ", config.sndaddr[0],config.sndaddr[1],config.sndaddr[2],config.sndaddr[3],config.sndaddr[4]); 321 | printf("rcvaddr=%02X%02X%02X%02X%02X\r\n", config.rcvaddr[0],config.rcvaddr[1],config.rcvaddr[2],config.rcvaddr[3],config.deviceid); 322 | #endif 323 | 324 | rtc_init(); 325 | 326 | // main loop 327 | while (1) { 328 | #if EN_LED 329 | LEDON 330 | #endif 331 | 332 | adc_init(); 333 | 334 | #if EN_VBAT 335 | vbat = adc_get(VBATCH); 336 | if (config.vbatlow > 0 && vbat < config.vbatlow) 337 | goto VBATLOW; 338 | #endif 339 | 340 | VENON // sensors power on 341 | 342 | #if EN_LIGHT 343 | light = adc_get(LIGHTCH); 344 | #endif 345 | 346 | #if EN_VBAT || EN_LIGHT 347 | adc_power_down(); 348 | #endif 349 | 350 | #if EN_DHT 351 | dosleep(PWRUPWAIT); // DHT power up time ~600mS 352 | #endif 353 | 354 | #if EN_BH1750 355 | bh1750_init(); 356 | light = bh1750_ask(); 357 | #endif 358 | 359 | #if EN_DS18B20 360 | DSTemp = ds18b20_ask(); 361 | #endif //DS18B20 362 | 363 | #if EN_BME280 364 | bme280_init(); 365 | set_osr_settings(BME280_OVERSAMPLING_1X, BME280_OVERSAMPLING_16X, BME280_OVERSAMPLING_2X); 366 | set_filter_settings(BME280_FILTER_COEFF_16); 367 | set_standby_settings(BME280_STANDBY_TIME_1_MS); 368 | bme280_set_sensor_mode(BME280_FORCED_MODE); 369 | #endif 370 | 371 | dosleep(SENSWAIT); // max sensors wait time, ~200mS 372 | 373 | #if EN_LIGHT 374 | message_fill(ADDR_LIGHT); 375 | message.msgtype = MSG_DATA; 376 | message.datatype = VAL_i32; 377 | message.datapower = 0; 378 | message.data.i32 = 1023 - light; 379 | rfsend(&message); 380 | #if DEBUG 381 | printf("adc light=%d\r\n", 1023 - light); 382 | #endif 383 | #endif 384 | 385 | #if EN_BH1750 386 | message_fill(ADDR_BH1750); 387 | message.datatype = VAL_i32; 388 | message.datapower = 0; 389 | if (light == BH1750_OK && (ret = bh1750_read_nowait((uint16_t *) &light)) == BH1750_OK) { 390 | message.msgtype = MSG_DATA; 391 | message.data.i32 = light; 392 | #if DEBUG 393 | printf("bh1750 light=%d\r\n", light); 394 | #endif 395 | } else { 396 | message.msgtype = MSG_ERROR; 397 | message.error = ret; 398 | message.data.i32 = ret; 399 | #if DEBUG 400 | printf("bh1750 err=%d\r\n", ret); 401 | #endif 402 | } 403 | rfsend(&message); 404 | #endif 405 | 406 | #if EN_DS18B20 407 | message_fill(ADDR_DS18B20); 408 | message.datatype = VAL_i32; 409 | message.datapower = 1; 410 | if (DSTemp == DS_OK && (ret = ds18b20_read_nowait((int16_t *) &DSTemp)) == DS_OK) { 411 | // DS18B20 temperature send 412 | message.msgtype = MSG_DATA; 413 | message.data.i32 = DSTemp; 414 | #if DEBUG 415 | printf("ds18b280 temp=%d\r\n", DSTemp); 416 | #endif 417 | } else { 418 | message.msgtype = MSG_ERROR; 419 | message.error = ret; 420 | message.data.i32 = ret; 421 | #if DEBUG 422 | printf("ds18b20 err=%d\r\n", ret); 423 | #endif 424 | } 425 | rfsend(&message); 426 | #endif //DS18B20 427 | 428 | #if EN_BME280 429 | message_fill(ADDR_BME280_TEMP); 430 | message.msgtype = MSG_DATA; 431 | message.datatype = VAL_i32; 432 | message.datapower = 2; 433 | ret = bme280_get_temperature(&val32); 434 | if (ret == BME280_OK) { 435 | message.data.i32 = val32; 436 | #if DEBUG 437 | printf("bme280 temp=%ld\r\n", val32); 438 | #endif 439 | } else { 440 | message.msgtype = MSG_ERROR; 441 | message.error = ret; 442 | #if DEBUG 443 | printf("bme280 temp err=%d\r\n", ret); 444 | #endif 445 | } 446 | rfsend(&message); 447 | 448 | #if BME280_PRESSURE 449 | message_fill(ADDR_BME280_PRES); 450 | message.msgtype = MSG_DATA; 451 | message.datatype = VAL_i32; 452 | message.datapower = 3; 453 | ret = bme280_get_pressure((uint32_t *)&val32); 454 | if (ret == BME280_OK) { 455 | message.data.i32 = bme280_Pa_to_mmHg((uint32_t)val32); 456 | #if DEBUG 457 | printf("bme280 pres=%ld\r\n", bme280_Pa_to_mmHg((uint32_t)val32)); 458 | #endif 459 | } else { 460 | message.msgtype = MSG_ERROR; 461 | message.error = ret; 462 | #if DEBUG 463 | printf("bme280 pres err=%d\r\n", ret); 464 | #endif 465 | } 466 | rfsend(&message); 467 | #endif 468 | 469 | #if BME280_HUMIDITY 470 | message_fill(ADDR_BME280_HUM); 471 | message.msgtype = MSG_DATA; 472 | message.datatype = VAL_i32; 473 | message.datapower = 3; 474 | ret = bme280_get_humidity(&val32); 475 | if (ret == BME280_OK) { 476 | message.data.i32 = val32; 477 | #if DEBUG 478 | printf("bme280 hum=%ld\r\n", val32); 479 | #endif 480 | } else { 481 | message.msgtype = MSG_ERROR; 482 | message.error = ret; 483 | #if DEBUG 484 | printf("bme280 hum err=%d\r\n", ret); 485 | #endif 486 | } 487 | rfsend(&message); 488 | #endif 489 | #endif 490 | 491 | #if EN_DHT 492 | // delay after startup & reset need to be > 500ms :( 493 | ret = dht_read(&DHTTemp, &DHTHum); 494 | if (ret != DHT_OK) { 495 | message_fill(ADDR_DHT_TEMP); 496 | message.msgtype = MSG_ERROR; 497 | message.error = ret; 498 | message.data.i32 = ret; 499 | rfsend(&message); 500 | message_fill(ADDR_DHT_HUM); 501 | message.msgtype = MSG_ERROR; 502 | message.error = ret; 503 | message.data.i32 = ret; 504 | rfsend(&message); 505 | #if DEBUG 506 | printf("dht error=%d\r\n", ret); 507 | #endif 508 | } 509 | else { 510 | // DHT temperature, humidity send 511 | message_fill(ADDR_DHT_TEMP); 512 | message.msgtype = MSG_DATA; 513 | message.datatype = VAL_i32; 514 | message.datapower = 1; 515 | message.data.i32 = DHTTemp; 516 | rfsend(&message); 517 | #if DEBUG 518 | printf("dht temp=%d\r\n", DHTTemp); 519 | #endif 520 | message_fill(ADDR_DHT_HUM); 521 | message.msgtype = MSG_DATA; 522 | message.datatype = VAL_i32; 523 | message.datapower = 1; 524 | message.data.i32 = DHTHum; 525 | rfsend(&message); 526 | #if DEBUG 527 | printf("dht hum=%d\r\n", DHTHum); 528 | #endif 529 | } 530 | #endif //DHT 531 | 532 | VBATLOW: 533 | VENOFF 534 | 535 | #if EN_VBAT 536 | #if DEBUG 537 | printf("vbat=%d, vbatlow=%d\r\n", vbat, config.vbatlow); 538 | #endif 539 | message_fill(ADDR_VBAT); 540 | if (config.vbatlow > 0 && vbat < config.vbatlow) { 541 | message.msgtype = MSG_ERROR; 542 | message.error = ERR_VBATLOW; 543 | message.data.i32 = ERR_VBATLOW; 544 | #if DEBUG 545 | printf("vbat low fired\r\n"); 546 | #endif 547 | } else { 548 | message.msgtype = MSG_DATA; 549 | message.datatype = VAL_i32; 550 | message.datapower = 0; 551 | message.data.i32 = vbat; 552 | } 553 | rfsend(&message); 554 | #endif 555 | 556 | WAITCMD: 557 | message_fill(0); 558 | message.msgtype = MSG_CMD; 559 | message.command = CMD_MSGWAIT; 560 | rfsend(&message); 561 | 562 | // wait command from smarthome gateway 563 | memset(&message, 0, MSGLEN); 564 | cmd = rfread(&message, CMDWAIT); 565 | 566 | if (cmd && message.deviceid == config.deviceid && message.msgtype == MSG_CMD) { 567 | #if DEBUG 568 | printf("\r\ncommand: %d\r\n", message.command); 569 | printf("address: %d\r\n", message.address); 570 | printf("param: %d\r\n\r\n", (uint16_t) message.data.i32); 571 | #endif 572 | // команда чтения/записи конфигурации 573 | if ((message.command == CMD_CFGREAD || message.command == CMD_CFGWRITE)) { 574 | switch (message.address) { 575 | case CFG_CHANNEL: 576 | if (message.command == CMD_CFGWRITE) { 577 | if (message.data.i32 < 0 || message.data.i32 >= 100) { 578 | send_config_err(CFG_CHANNEL, ERR_CMDPARAM); 579 | break; 580 | } 581 | config.channel = (uint8_t) message.data.i32; 582 | if (!write_config()) { 583 | send_config_err(CFG_CHANNEL, ERR_CFGWRITE); 584 | break; 585 | } 586 | } 587 | send_config(CFG_CHANNEL, config.channel); 588 | break; 589 | case CFG_SLEEP: 590 | if (message.command == CMD_CFGWRITE) { 591 | if (message.data.i32 < 0 || message.data.i32 > 512) { 592 | send_config_err(CFG_SLEEP, ERR_CMDPARAM); 593 | break; 594 | } 595 | config.sleeptm = (uint16_t) message.data.i32; 596 | if (!write_config()) { 597 | send_config_err(CFG_SLEEP, ERR_CFGWRITE); 598 | break; 599 | } 600 | } 601 | send_config(CFG_SLEEP, config.sleeptm); 602 | break; 603 | #if EN_VBAT 604 | case CFG_VBATLOW: 605 | if (message.command == CMD_CFGWRITE) { 606 | if (message.data.i32 < 0 || message.data.i32 > 1023) { 607 | send_config_err(CFG_VBATLOW, ERR_CMDPARAM); 608 | break; 609 | } 610 | config.vbatlow = (uint16_t) message.data.i32; 611 | if (!write_config()) { 612 | send_config_err(CFG_VBATLOW, ERR_CFGWRITE); 613 | break; 614 | } 615 | } 616 | send_config(CFG_VBATLOW, config.vbatlow); 617 | break; 618 | #endif 619 | default: 620 | break; 621 | } 622 | } 623 | goto WAITCMD; 624 | } 625 | 626 | rfdown(); 627 | 628 | #if EN_LED 629 | LEDOFF 630 | #endif 631 | 632 | #if EN_SLEEP 633 | if (config.sleeptm > 0) { 634 | watchdog_set_wdsv_count(watchdog_calc_timeout_from_sec(config.sleeptm)); 635 | pwr_clk_mgmt_enter_pwr_mode_memory_ret_tmr_on(); // 1mkA 636 | } 637 | #else 638 | if (config.sleeptm > 0) { 639 | watchdog_set_wdsv_count(watchdog_calc_timeout_from_sec(config.sleeptm+1)); 640 | delay_s(config.sleeptm); 641 | } 642 | #endif 643 | } // main loop 644 | } 645 | -------------------------------------------------------------------------------- /bme280.c: -------------------------------------------------------------------------------- 1 | /* 2 | * nrf24le1_bme280.h 3 | * 4 | * Created on: 30/07/2018 5 | * Author: andru 6 | */ 7 | 8 | #include "bme280.h" 9 | #include "bme280_defs.h" 10 | 11 | #include "main.h" 12 | 13 | #if DEBUG 14 | #include 15 | #include 16 | #include 17 | #endif 18 | 19 | #include "delay.h" 20 | #include "w2.h" 21 | 22 | #define BME280_ADDR BME280_I2C_ADDR_PRIM 23 | 24 | // Constant for Pascals to millimeters of mercury conversion 25 | #define BME_MMHG_Q0_20 (uint32_t)7865; // 0.00750061683 in Q0.20 format 26 | 27 | static int32_t t_fine = 0; 28 | 29 | static void i2c_init(void) { 30 | w2_configure(W2_CONFIG_OPTION_ENABLE | 31 | W2_CONFIG_OPTION_MODE_MASTER | 32 | W2_CONFIG_OPTION_CLOCK_FREQ_100_KHZ | 33 | W2_CONFIG_OPTION_ALL_INTERRUPTS_ENABLE, 34 | 0 35 | ); 36 | } 37 | 38 | static bme280_error_t i2c_read(uint8_t reg_addr, uint8_t *data, uint16_t len) 39 | { 40 | uint8_t buf; 41 | 42 | if (w2_master_write_to(BME280_ADDR, ®_addr, 1, &buf, 0) == W2_NACK_VAL) 43 | return BME280_E_COMM_FAIL; 44 | 45 | if (w2_master_cur_address_read(BME280_ADDR, data, len) == W2_NACK_VAL) 46 | return BME280_E_COMM_FAIL; 47 | 48 | return BME280_OK; 49 | } 50 | 51 | static bme280_error_t i2c_write(uint8_t reg_addr, uint8_t *data, uint16_t len) 52 | { 53 | if (w2_master_write_to(BME280_ADDR, ®_addr, 1, data, len) == W2_NACK_VAL) 54 | return BME280_E_COMM_FAIL; 55 | 56 | return BME280_OK; 57 | } 58 | 59 | /*! 60 | * @brief This API reads the data from the given register address of the sensor. 61 | */ 62 | bme280_error_t bme280_get_regs(uint8_t reg_addr, uint8_t *reg_data, uint16_t len) 63 | { 64 | /* Read the data */ 65 | if (i2c_read(reg_addr, reg_data, len) != BME280_OK) 66 | return BME280_E_COMM_FAIL; 67 | 68 | return BME280_OK; 69 | } 70 | 71 | /*! 72 | * @brief This API writes the given data to the register address 73 | * of the sensor. 74 | */ 75 | bme280_error_t bme280_set_regs(uint8_t reg_addr, uint8_t *reg_data, uint8_t len) 76 | { 77 | /* Check for arguments validity */ 78 | if (reg_data == NULL) 79 | return BME280_E_NULL_PTR; 80 | if (len == 0) 81 | return BME280_E_INVALID_LEN; 82 | if (i2c_write(reg_addr, reg_data, len) == BME280_OK) 83 | return BME280_OK; 84 | 85 | return BME280_E_COMM_FAIL; 86 | } 87 | 88 | /*! 89 | * @brief This API performs the soft reset of the sensor. 90 | */ 91 | bme280_error_t bme280_soft_reset(void) 92 | { 93 | /* 0xB6 is the soft reset command */ 94 | uint8_t soft_rst_cmd = 0xB6; 95 | 96 | /* Write the soft reset command in the sensor */ 97 | if (bme280_set_regs(BME280_RESET_ADDR, &soft_rst_cmd, 1) == BME280_OK) { 98 | /* As per data sheet, startup time is 2 ms. */ 99 | delay_ms(2); 100 | return BME280_OK; 101 | } 102 | return BME280_E_COMM_FAIL; 103 | } 104 | 105 | /*! 106 | * @brief This API is the entry point. 107 | * It reads the chip-id and calibration data from the sensor. 108 | */ 109 | bme280_error_t bme280_init(void) 110 | { 111 | bme280_error_t rslt; 112 | /* chip id read try count */ 113 | uint8_t try_count = 5; 114 | uint8_t chip_id = 0; 115 | 116 | rslt = BME280_OK; 117 | i2c_init(); 118 | while (try_count) { 119 | /* Read the chip-id of bme280 sensor */ 120 | rslt = bme280_get_regs(BME280_CHIP_ID_ADDR, &chip_id, 1); 121 | /* Check for chip id validity */ 122 | if ((rslt == BME280_OK) && (chip_id == BME280_CHIP_ID)) { 123 | /* Reset the sensor */ 124 | if (bme280_soft_reset() == BME280_OK) { 125 | return BME280_OK; 126 | } 127 | } 128 | /* Wait for 1 ms */ 129 | delay_ms(1); 130 | --try_count; 131 | } 132 | /* Chip id check failed */ 133 | if (!try_count) 134 | rslt = BME280_E_DEV_NOT_FOUND; 135 | 136 | return rslt; 137 | } 138 | 139 | /*! 140 | * @brief This internal API writes the power mode in the sensor. 141 | */ 142 | bme280_error_t write_power_mode(uint8_t sensor_mode) 143 | { 144 | bme280_error_t rslt; 145 | /* Variable to store the value read from power mode register */ 146 | uint8_t sensor_mode_reg_val; 147 | 148 | /* Read the power mode register */ 149 | rslt = bme280_get_regs(BME280_PWR_CTRL_ADDR, &sensor_mode_reg_val, 1); 150 | /* Set the power mode */ 151 | if (rslt == BME280_OK) { 152 | sensor_mode_reg_val = BME280_SET_BITS_POS_0(sensor_mode_reg_val, BME280_SENSOR_MODE, sensor_mode); 153 | /* Write the power mode in the register */ 154 | rslt = bme280_set_regs(BME280_PWR_CTRL_ADDR, &sensor_mode_reg_val, 1); 155 | } 156 | 157 | return rslt; 158 | } 159 | 160 | /*! 161 | * @brief This API gets the power mode of the sensor. 162 | */ 163 | bme280_error_t bme280_get_sensor_mode(uint8_t *sensor_mode) 164 | { 165 | bme280_error_t rslt; 166 | 167 | /* Read the power mode register */ 168 | rslt = bme280_get_regs(BME280_PWR_CTRL_ADDR, sensor_mode, 1); 169 | /* Assign the power mode in the device structure */ 170 | *sensor_mode = BME280_GET_BITS_POS_0(*sensor_mode, BME280_SENSOR_MODE); 171 | 172 | return rslt; 173 | } 174 | 175 | /*! 176 | * @brief This API sets the power mode of the sensor. 177 | */ 178 | bme280_error_t bme280_set_sensor_mode(uint8_t sensor_mode) 179 | { 180 | bme280_error_t rslt; 181 | uint8_t last_set_mode; 182 | 183 | rslt = bme280_get_sensor_mode(&last_set_mode); 184 | /* If the sensor is not in sleep mode put the device to sleep 185 | mode */ 186 | if ((rslt == BME280_OK) && (last_set_mode != BME280_SLEEP_MODE)) 187 | rslt = write_power_mode(BME280_SLEEP_MODE); 188 | /* Set the power mode */ 189 | if (rslt == BME280_OK) 190 | rslt = write_power_mode(sensor_mode); 191 | 192 | return rslt; 193 | } 194 | 195 | /*! 196 | * @brief This API sets the temperature, pressure and humidity oversampling settings 197 | * in the sensor according to the settings selected by the user. 198 | */ 199 | bme280_error_t set_osr_settings(uint8_t osr_t, uint8_t osr_p, uint8_t osr_h) 200 | { 201 | bme280_error_t rslt; 202 | uint8_t reg_data; 203 | 204 | reg_data = osr_h & BME280_CTRL_HUM_MSK; 205 | 206 | /* Write the humidity control value in the register */ 207 | rslt = bme280_set_regs(BME280_CTRL_HUM_ADDR, ®_data, 1); 208 | if (rslt != BME280_OK) 209 | return rslt; 210 | 211 | rslt = bme280_get_regs(BME280_CTRL_MEAS_ADDR, ®_data, 1); 212 | if (rslt != BME280_OK) 213 | return rslt; 214 | 215 | reg_data = BME280_SET_BITS(reg_data, BME280_CTRL_TEMP, osr_t); 216 | reg_data = BME280_SET_BITS(reg_data, BME280_CTRL_PRESS, osr_p); 217 | 218 | /* Write the oversampling settings in the register */ 219 | rslt = bme280_set_regs(BME280_CTRL_MEAS_ADDR, ®_data, 1); 220 | 221 | return rslt; 222 | } 223 | 224 | /*! 225 | * @brief This internal API sets the filter settings 226 | * in the sensor according to the settings selected by the user. 227 | */ 228 | bme280_error_t set_filter_settings(uint8_t filter) 229 | { 230 | bme280_error_t rslt; 231 | uint8_t reg_data; 232 | 233 | rslt = bme280_get_regs(BME280_CONFIG_ADDR, ®_data, 1); 234 | 235 | if (rslt == BME280_OK) { 236 | reg_data = BME280_SET_BITS(reg_data, BME280_FILTER, filter); 237 | /* Write the oversampling settings in the register */ 238 | rslt = bme280_set_regs(BME280_CONFIG_ADDR, ®_data, 1); 239 | } 240 | 241 | return rslt; 242 | } 243 | 244 | /*! 245 | * @brief This internal API sets the standby duration settings 246 | * in the sensor according to the settings selected by the user. 247 | */ 248 | bme280_error_t set_standby_settings(uint8_t standby_time) 249 | { 250 | bme280_error_t rslt; 251 | uint8_t reg_data; 252 | 253 | rslt = bme280_get_regs(BME280_CONFIG_ADDR, ®_data, 1); 254 | 255 | if (rslt == BME280_OK) { 256 | reg_data = BME280_SET_BITS(reg_data, BME280_STANDBY, standby_time); 257 | /* Write the oversampling settings in the register */ 258 | rslt = bme280_set_regs(BME280_CONFIG_ADDR, ®_data, 1); 259 | } 260 | 261 | return rslt; 262 | } 263 | 264 | /*! 265 | * @brief This internal API is used to compensate the raw temperature data and 266 | * return the compensated temperature data in integer data type. 267 | * 268 | * Returns temperature in DegC, resolution is 0.01 DegC. Output value of “5123” equals 51.23 DegC. 269 | * t_fine carries fine temperature as global value 270 | */ 271 | static bme280_error_t compensate_temperature(int32_t uncomp_t, int32_t *temperature) 272 | { 273 | bme280_error_t rslt; 274 | uint16_t dig_T1; 275 | int16_t dig_T2, dig_T3; 276 | 277 | uint8_t calib_data[BME280_T_CALIB_DATA_LEN] = {0}; 278 | 279 | /* Read the calibration data from the sensor */ 280 | rslt = bme280_get_regs(BME280_T_CALIB_DATA_ADDR, calib_data, BME280_T_CALIB_DATA_LEN); 281 | 282 | if (rslt != BME280_OK) 283 | return rslt; 284 | 285 | dig_T1 = BME280_CONCAT_BYTES(calib_data[1], calib_data[0]); 286 | dig_T2 = (int16_t) BME280_CONCAT_BYTES(calib_data[3], calib_data[2]); 287 | dig_T3 = (int16_t) BME280_CONCAT_BYTES(calib_data[5], calib_data[4]); 288 | 289 | // (!) t_fine assigned here 290 | t_fine = ((((uncomp_t>>3) - ((int32_t)dig_T1<<1))) * ((int32_t)dig_T2)) >> 11; 291 | t_fine += (((((uncomp_t>>4) - ((int32_t)dig_T1)) * ((uncomp_t>>4) - ((int32_t)dig_T1))) >> 12) * ((int32_t)dig_T3)) >> 14; 292 | 293 | *temperature = (t_fine * 5 + 128) >> 8; 294 | 295 | if (*temperature < TEMPERATURE_MIN) 296 | *temperature = TEMPERATURE_MIN; 297 | if (*temperature > TEMPERATURE_MAX) 298 | *temperature = TEMPERATURE_MAX; 299 | 300 | return rslt; 301 | } 302 | 303 | /*! 304 | * @brief This API reads the temperature data from the 305 | * sensor, compensates the data and store it in the temperature parameter. 306 | */ 307 | bme280_error_t bme280_get_temperature(int32_t *temperature) 308 | { 309 | bme280_error_t rslt; 310 | uint8_t reg_data[BME280_T_DATA_LEN] = {0}; 311 | int32_t uncomp_t; 312 | 313 | /* Read the temperature data from the sensor */ 314 | rslt = bme280_get_regs(BME280_T_DATA_ADDR, reg_data, BME280_T_DATA_LEN); 315 | if (rslt == BME280_OK) { 316 | uncomp_t = (uint32_t) reg_data[0] << 12 | (uint32_t) reg_data[1] << 4 | (uint32_t) reg_data[2] >> 4; 317 | /* Compensate the temperature data from the sensor */ 318 | rslt = compensate_temperature(uncomp_t, temperature); 319 | } 320 | 321 | return rslt; 322 | } 323 | 324 | #if BME280_PRESSURE 325 | // Fixed point Pa to mmHg conversion (Pascals to millimeters of mercury) 326 | // 1 Pa = 0.00750061683 mmHg 327 | // input: 328 | // PQ24_8 - pressure in pascals (Q24.8 format, result of BME280_CalcP function) 329 | // return: 330 | // pressure in millimeter of mercury 331 | // note: return value of '746225' represents 746.225 mmHg 332 | // note: maximum input value is 131071 Pa 333 | // source: https://github.com/LonelyWolf/stm32/blob/master/bme280/bme280.c 334 | uint32_t bme280_Pa_to_mmHg(uint32_t pressure) 335 | { 336 | // Truncate the pressure value to Q24.2 format and multiply by Q0.20 constant (~0.00750061683) 337 | // The multiply product will be Q10.22 pressure value in mmHg 338 | uint32_t p_mmHg = ((pressure << 8) >> 6) * BME_MMHG_Q0_20; 339 | 340 | // (p_mmHg >> 22) -> integer part from Q10.22 value 341 | // ((uint32_t)p_mmHg << 10) >> 18 -> fractional part truncated down to 14 bits 342 | // (XXX * 61039) / 1000000 is rough integer equivalent of float (XXX / 16383.0) * 1000 343 | return ((p_mmHg >> 22) * 1000) + ((((p_mmHg << 10) >> 18) * 61039) / 1000000); 344 | } 345 | 346 | /*! 347 | * @brief This internal API is used to compensate the raw pressure data and 348 | * return the compensated pressure data in integer data type. 349 | * 350 | * Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24 integer bits and 8 fractional bits). 351 | * Output value of “24674867” represents 24674867/256 = 96386.2 Pa = 963.862 hPa 352 | */ 353 | static bme280_error_t compensate_pressure(uint32_t uncomp_p, uint32_t *pressure) 354 | { 355 | bme280_error_t rslt; 356 | uint16_t dig_P1; 357 | int16_t dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9; 358 | int32_t var1, var2; 359 | 360 | uint8_t calib_data[BME280_P_CALIB_DATA_LEN] = {0}; 361 | 362 | if (t_fine == 0) 363 | return BME280_E_CONV; 364 | 365 | /* Read the calibration data from the sensor */ 366 | rslt = bme280_get_regs(BME280_P_CALIB_DATA_ADDR, calib_data, BME280_P_CALIB_DATA_LEN); 367 | 368 | if (rslt != BME280_OK) 369 | return rslt; 370 | 371 | dig_P1 = BME280_CONCAT_BYTES(calib_data[1], calib_data[0]); 372 | dig_P2 = (int16_t) BME280_CONCAT_BYTES(calib_data[3], calib_data[2]); 373 | dig_P3 = (int16_t) BME280_CONCAT_BYTES(calib_data[5], calib_data[4]); 374 | dig_P4 = (int16_t) BME280_CONCAT_BYTES(calib_data[7], calib_data[6]); 375 | dig_P5 = (int16_t) BME280_CONCAT_BYTES(calib_data[9], calib_data[8]); 376 | dig_P6 = (int16_t) BME280_CONCAT_BYTES(calib_data[11], calib_data[10]); 377 | dig_P7 = (int16_t) BME280_CONCAT_BYTES(calib_data[13], calib_data[12]); 378 | dig_P8 = (int16_t) BME280_CONCAT_BYTES(calib_data[15], calib_data[14]); 379 | dig_P9 = (int16_t) BME280_CONCAT_BYTES(calib_data[17], calib_data[16]); 380 | 381 | var1 = (((int32_t)t_fine)>>1) - (int32_t)64000; 382 | var2 = (((var1>>2) * (var1>>2)) >> 11 ) * ((int32_t)dig_P6); 383 | var2 = var2 + ((var1*((int32_t)dig_P5))<<1); 384 | var2 = (var2>>2)+(((int32_t)dig_P4)<<16); 385 | var1 = (((dig_P3 * (((var1>>2) * (var1>>2)) >> 13 )) >> 3) + ((((int32_t)dig_P2) * var1)>>1))>>18; 386 | var1 =((((32768+var1))*((int32_t)dig_P1))>>15); 387 | if (var1 == 0) { 388 | return BME280_E_CONV; // avoid exception caused by division by zero 389 | } 390 | *pressure = (((uint32_t)(((int32_t)1048576)-uncomp_p)-(var2>>12)))*3125; 391 | if (*pressure < 0x80000000) { 392 | *pressure = (*pressure << 1) / ((uint32_t)var1); 393 | } else { 394 | *pressure = (*pressure / (uint32_t)var1) * 2; 395 | } 396 | var1 = (((int32_t)dig_P9) * ((int32_t)(((*pressure>>3) * (*pressure>>3))>>13)))>>12; 397 | var2 = (((int32_t)(*pressure>>2)) * ((int32_t)dig_P8))>>13; 398 | *pressure = (uint32_t)((int32_t)*pressure + ((var1 + var2 + dig_P7) >> 4)); 399 | 400 | if (*pressure < PRESSURE_MIN) 401 | *pressure = PRESSURE_MIN; 402 | if (*pressure > PRESSURE_MAX) 403 | *pressure = PRESSURE_MAX; 404 | 405 | return rslt; 406 | } 407 | 408 | /*! 409 | * @brief This API reads the pressure data from the 410 | * sensor, compensates the data and store it in the pressure parameter. 411 | */ 412 | bme280_error_t bme280_get_pressure(uint32_t *pressure) 413 | { 414 | bme280_error_t rslt; 415 | uint8_t reg_data[BME280_P_DATA_LEN] = {0}; 416 | int32_t uncomp_p; 417 | 418 | /* Read the pressure data from the sensor */ 419 | rslt = bme280_get_regs(BME280_P_DATA_ADDR, reg_data, BME280_P_DATA_LEN); 420 | if (rslt == BME280_OK) { 421 | uncomp_p = (uint32_t) reg_data[0] << 12 | (uint32_t) reg_data[1] << 4 | (uint32_t) reg_data[2] >> 4; 422 | /* Compensate the pressure data from the sensor */ 423 | rslt = compensate_pressure(uncomp_p, pressure); 424 | } 425 | 426 | return rslt; 427 | } 428 | #endif 429 | 430 | #if BME280_HUMIDITY 431 | /*! 432 | * @brief This internal API is used to compensate the raw temperature data and 433 | * return the compensated temperature data in integer data type. 434 | * 435 | * Returns humidity in %RH as unsigned 32 bit integer in Q22.10 format (22 integer and 10 fractional bits). 436 | * Output value of “47445” represents 47445/1024 = 46.333 %RH 437 | */ 438 | static bme280_error_t compensate_humidity(int32_t uncomp_h, int32_t *humidity) 439 | { 440 | bme280_error_t rslt; 441 | uint8_t dig_H1, dig_H3; 442 | int16_t dig_H2, dig_H4, dig_H5; 443 | int8_t dig_H6; 444 | int32_t v_x1_u32r; 445 | 446 | /* Array to store calibration data */ 447 | uint8_t calib_data[BME280_H_CALIB_DATA_LEN2] = {0}; 448 | 449 | if (t_fine == 0) 450 | return BME280_E_CONV; 451 | 452 | /* Read the calibration data from the sensor */ 453 | rslt = bme280_get_regs(BME280_H_CALIB_DATA_ADDR1, calib_data, BME280_H_CALIB_DATA_LEN1); 454 | 455 | if (rslt != BME280_OK) 456 | return rslt; 457 | 458 | dig_H1 = (uint8_t) calib_data[0]; 459 | 460 | /* Read the calibration data from the sensor */ 461 | rslt = bme280_get_regs(BME280_H_CALIB_DATA_ADDR2, calib_data, BME280_H_CALIB_DATA_LEN2); 462 | 463 | if (rslt != BME280_OK) 464 | return rslt; 465 | 466 | dig_H2 = (int16_t) BME280_CONCAT_BYTES(calib_data[1], calib_data[0]); 467 | dig_H3 = (uint8_t) calib_data[2]; 468 | dig_H4 = (int16_t) calib_data[3] << 4 | (int16_t) calib_data[4] & 0x0F; 469 | dig_H5 = (int16_t) calib_data[5] << 4 | (int16_t) calib_data[4] >> 4; 470 | dig_H6 = (int8_t) calib_data[6]; 471 | 472 | v_x1_u32r = (t_fine - ((int32_t)76800)); 473 | v_x1_u32r = (((((uncomp_h << 14) - (((int32_t)dig_H4) << 20) - (((int32_t)dig_H5) * v_x1_u32r)) + 474 | ((int32_t)16384)) >> 15) * (((((((v_x1_u32r * ((int32_t)dig_H6)) >> 10) * (((v_x1_u32r * 475 | ((int32_t)dig_H3)) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) * ((int32_t)dig_H2) + 8192) >> 14)); 476 | v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int32_t)dig_H1)) >> 4)); 477 | v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r); 478 | v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r); 479 | *humidity = (uint32_t)(v_x1_u32r>>12); 480 | 481 | if (*humidity > HUMIDITY_MAX) 482 | *humidity = HUMIDITY_MAX; 483 | 484 | return rslt; 485 | } 486 | 487 | /*! 488 | * @brief This API reads the humidity data from the 489 | * sensor, compensates the data and store it in the humidity parameter. 490 | */ 491 | bme280_error_t bme280_get_humidity(uint32_t *humidity) 492 | { 493 | bme280_error_t rslt; 494 | uint8_t reg_data[BME280_H_DATA_LEN] = {0}; 495 | int32_t uncomp_h; 496 | 497 | /* Read the humidity data from the sensor */ 498 | rslt = bme280_get_regs(BME280_H_DATA_ADDR, reg_data, BME280_H_DATA_LEN); 499 | if (rslt == BME280_OK) { 500 | uncomp_h = (uint32_t) reg_data[0] << 8 | (uint32_t) reg_data[1]; 501 | /* Compensate the humidity data from the sensor */ 502 | rslt = compensate_humidity(uncomp_h, humidity); 503 | } 504 | 505 | return rslt; 506 | } 507 | #endif 508 | 509 | #if DEBUG 510 | bme280_error_t stream_sensor_data_forced_mode(void) { 511 | bme280_error_t rslt; 512 | int32_t temperature = 0; 513 | uint32_t pressure = 0; 514 | uint32_t humidity = 0; 515 | 516 | /* Recommended mode of operation: Indoor navigation */ 517 | set_osr_settings(BME280_OVERSAMPLING_1X, BME280_OVERSAMPLING_16X, BME280_OVERSAMPLING_2X); 518 | set_filter_settings(BME280_FILTER_COEFF_16); 519 | set_standby_settings(BME280_STANDBY_TIME_1_MS); 520 | 521 | #if DEBUG 522 | printf("Temperature, Pressure, Humidity\r\n"); 523 | #endif 524 | /* Continuously stream sensor data */ 525 | rslt = bme280_set_sensor_mode(BME280_FORCED_MODE); 526 | 527 | /* Wait for the measurement to complete and print data @25Hz */ 528 | delay_ms(40); 529 | 530 | if (bme280_get_temperature(&temperature) == BME280_OK) { 531 | #if DEBUG 532 | printf("temp=%ld\r\n", temperature); 533 | #endif 534 | } 535 | 536 | #if BME280_PRESSURE 537 | if (bme280_get_pressure(&pressure) == BME280_OK) { 538 | #if DEBUG 539 | printf("pres=%ld\r\n", bme280_Pa_to_mmHg(pressure)); 540 | #endif 541 | } 542 | #endif 543 | 544 | #if BME280_HUMIDITY 545 | if (bme280_get_humidity(&humidity) == BME280_OK) { 546 | #if DEBUG 547 | printf("hum=%ld\r\n", humidity); 548 | #endif 549 | } 550 | #endif 551 | 552 | return rslt; 553 | } 554 | #endif 555 | -------------------------------------------------------------------------------- /tiny-AES128/src/aes.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This is an implementation of the AES128 algorithm, specifically ECB and CBC mode. 4 | 5 | The implementation is verified against the test vectors in: 6 | National Institute of Standards and Technology Special Publication 800-38A 2001 ED 7 | 8 | ECB-AES128 9 | ---------- 10 | 11 | plain-text: 12 | 6bc1bee22e409f96e93d7e117393172a 13 | ae2d8a571e03ac9c9eb76fac45af8e51 14 | 30c81c46a35ce411e5fbc1191a0a52ef 15 | f69f2445df4f9b17ad2b417be66c3710 16 | 17 | key: 18 | 2b7e151628aed2a6abf7158809cf4f3c 19 | 20 | resulting cipher 21 | 3ad77bb40d7a3660a89ecaf32466ef97 22 | f5d3d58503b9699de785895a96fdbaaf 23 | 43b1cd7f598ece23881b00e3ed030688 24 | 7b0c785e27e8ad3f8223207104725dd4 25 | 26 | 27 | NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0) 28 | You should pad the end of the string with zeros if this is not the case. 29 | 30 | */ 31 | 32 | 33 | /*****************************************************************************/ 34 | /* Includes: */ 35 | /*****************************************************************************/ 36 | #include 37 | #include // CBC mode, for memset 38 | #include "aes.h" 39 | 40 | 41 | /*****************************************************************************/ 42 | /* Defines: */ 43 | /*****************************************************************************/ 44 | // The number of columns comprising a state in AES. This is a constant in AES. Value=4 45 | #define Nb 4 46 | // The number of 32 bit words in a key. 47 | #define Nk 4 48 | // Key length in bytes [128 bit] 49 | #define KEYLEN 16 50 | // The number of rounds in AES Cipher. 51 | #define Nr 10 52 | 53 | // jcallan@github points out that declaring Multiply as a function 54 | // reduces code size considerably with the Keil ARM compiler. 55 | // See this link for more information: https://github.com/kokke/tiny-AES128-C/pull/3 56 | #ifndef MULTIPLY_AS_A_FUNCTION 57 | #define MULTIPLY_AS_A_FUNCTION 1 58 | extern inline uint8_t enc_dec_accel_galois_multiply(unsigned char a, unsigned char b); //Extern function or include the header file for the function here 59 | #define Multiply(a, b) enc_dec_accel_galois_multiply(a, b) //Change the name of the second function to your own 60 | #endif 61 | 62 | 63 | /*****************************************************************************/ 64 | /* Private variables: */ 65 | /*****************************************************************************/ 66 | // state - array holding the intermediate results during decryption. 67 | typedef uint8_t state_t[4][4]; 68 | state_t* state; 69 | 70 | // The array that stores the round keys. 71 | uint8_t RoundKey[176]; 72 | 73 | // The Key input to the AES Program 74 | const uint8_t* Key; 75 | 76 | #if defined(CBC) && CBC 77 | // Initial Vector used only for CBC mode 78 | static uint8_t* Iv; 79 | #endif 80 | 81 | // The lookup-tables are marked const so they can be placed in read-only storage instead of RAM 82 | // The numbers below can be computed dynamically trading ROM for RAM - 83 | // This can be useful in (embedded) bootloader applications, where ROM is often limited. 84 | static const uint8_t sbox[256] = { 85 | //0 1 2 3 4 5 6 7 8 9 A B C D E F 86 | 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 87 | 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 88 | 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 89 | 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 90 | 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 91 | 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 92 | 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 93 | 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 94 | 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 95 | 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 96 | 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 97 | 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 98 | 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 99 | 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 100 | 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 101 | 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; 102 | 103 | static const uint8_t rsbox[256] = 104 | { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 105 | 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 106 | 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 107 | 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 108 | 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 109 | 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 110 | 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 111 | 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 112 | 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 113 | 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 114 | 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 115 | 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 116 | 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 117 | 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 118 | 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 119 | 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }; 120 | 121 | 122 | // The round constant word array, Rcon[i], contains the values given by 123 | // x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8) 124 | // Note that i starts at 1, not 0). 125 | static const uint8_t Rcon[255] = { 126 | 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 127 | 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 128 | 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 129 | 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 130 | 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 131 | 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 132 | 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 133 | 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 134 | 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 135 | 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 136 | 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 137 | 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 138 | 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 139 | 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 140 | 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 141 | 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb }; 142 | 143 | 144 | /*****************************************************************************/ 145 | /* Private functions: */ 146 | /*****************************************************************************/ 147 | static uint8_t getSBoxValue(uint8_t num) 148 | { 149 | return sbox[num]; 150 | } 151 | 152 | static uint8_t getSBoxInvert(uint8_t num) 153 | { 154 | return rsbox[num]; 155 | } 156 | 157 | // This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states. 158 | static void KeyExpansion(void) 159 | { 160 | uint32_t i, j, k; 161 | uint8_t tempa[4]; // Used for the column/row operations 162 | 163 | // The first round key is the key itself. 164 | for(i = 0; i < Nk; ++i) 165 | { 166 | RoundKey[(i * 4) + 0] = Key[(i * 4) + 0]; 167 | RoundKey[(i * 4) + 1] = Key[(i * 4) + 1]; 168 | RoundKey[(i * 4) + 2] = Key[(i * 4) + 2]; 169 | RoundKey[(i * 4) + 3] = Key[(i * 4) + 3]; 170 | } 171 | 172 | // All other round keys are found from the previous round keys. 173 | for(; (i < (Nb * (Nr + 1))); ++i) 174 | { 175 | for(j = 0; j < 4; ++j) 176 | { 177 | tempa[j]=RoundKey[(i-1) * 4 + j]; 178 | } 179 | if (i % Nk == 0) 180 | { 181 | // This function rotates the 4 bytes in a word to the left once. 182 | // [a0,a1,a2,a3] becomes [a1,a2,a3,a0] 183 | 184 | // Function RotWord() 185 | { 186 | k = tempa[0]; 187 | tempa[0] = tempa[1]; 188 | tempa[1] = tempa[2]; 189 | tempa[2] = tempa[3]; 190 | tempa[3] = k; 191 | } 192 | 193 | // SubWord() is a function that takes a four-byte input word and 194 | // applies the S-box to each of the four bytes to produce an output word. 195 | 196 | // Function Subword() 197 | { 198 | tempa[0] = getSBoxValue(tempa[0]); 199 | tempa[1] = getSBoxValue(tempa[1]); 200 | tempa[2] = getSBoxValue(tempa[2]); 201 | tempa[3] = getSBoxValue(tempa[3]); 202 | } 203 | 204 | tempa[0] = tempa[0] ^ Rcon[i/Nk]; 205 | } 206 | else if (Nk > 6 && i % Nk == 4) 207 | { 208 | // Function Subword() 209 | { 210 | tempa[0] = getSBoxValue(tempa[0]); 211 | tempa[1] = getSBoxValue(tempa[1]); 212 | tempa[2] = getSBoxValue(tempa[2]); 213 | tempa[3] = getSBoxValue(tempa[3]); 214 | } 215 | } 216 | RoundKey[i * 4 + 0] = RoundKey[(i - Nk) * 4 + 0] ^ tempa[0]; 217 | RoundKey[i * 4 + 1] = RoundKey[(i - Nk) * 4 + 1] ^ tempa[1]; 218 | RoundKey[i * 4 + 2] = RoundKey[(i - Nk) * 4 + 2] ^ tempa[2]; 219 | RoundKey[i * 4 + 3] = RoundKey[(i - Nk) * 4 + 3] ^ tempa[3]; 220 | } 221 | } 222 | 223 | // This function adds the round key to state. 224 | // The round key is added to the state by an XOR function. 225 | static void AddRoundKey(uint8_t round) 226 | { 227 | uint8_t i,j; 228 | for(i=0;i<4;++i) 229 | { 230 | for(j = 0; j < 4; ++j) 231 | { 232 | (*state)[i][j] ^= RoundKey[round * Nb * 4 + i * Nb + j]; 233 | } 234 | } 235 | } 236 | 237 | // The SubBytes Function Substitutes the values in the 238 | // state matrix with values in an S-box. 239 | static void SubBytes(void) 240 | { 241 | uint8_t i, j; 242 | for(i = 0; i < 4; ++i) 243 | { 244 | for(j = 0; j < 4; ++j) 245 | { 246 | (*state)[j][i] = getSBoxValue((*state)[j][i]); 247 | } 248 | } 249 | } 250 | 251 | // The ShiftRows() function shifts the rows in the state to the left. 252 | // Each row is shifted with different offset. 253 | // Offset = Row number. So the first row is not shifted. 254 | static void ShiftRows(void) 255 | { 256 | uint8_t temp; 257 | 258 | // Rotate first row 1 columns to left 259 | temp = (*state)[0][1]; 260 | (*state)[0][1] = (*state)[1][1]; 261 | (*state)[1][1] = (*state)[2][1]; 262 | (*state)[2][1] = (*state)[3][1]; 263 | (*state)[3][1] = temp; 264 | 265 | // Rotate second row 2 columns to left 266 | temp = (*state)[0][2]; 267 | (*state)[0][2] = (*state)[2][2]; 268 | (*state)[2][2] = temp; 269 | 270 | temp = (*state)[1][2]; 271 | (*state)[1][2] = (*state)[3][2]; 272 | (*state)[3][2] = temp; 273 | 274 | // Rotate third row 3 columns to left 275 | temp = (*state)[0][3]; 276 | (*state)[0][3] = (*state)[3][3]; 277 | (*state)[3][3] = (*state)[2][3]; 278 | (*state)[2][3] = (*state)[1][3]; 279 | (*state)[1][3] = temp; 280 | } 281 | 282 | static uint8_t xtime(uint8_t x) 283 | { 284 | return ((x<<1) ^ (((x>>7) & 1) * 0x1b)); 285 | } 286 | 287 | // MixColumns function mixes the columns of the state matrix 288 | static void MixColumns(void) 289 | { 290 | uint8_t i; 291 | uint8_t Tmp,Tm,t; 292 | for(i = 0; i < 4; ++i) 293 | { 294 | t = (*state)[i][0]; 295 | Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ; 296 | Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ; 297 | Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ; 298 | Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ; 299 | Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ; 300 | } 301 | } 302 | 303 | // Multiply is used to multiply numbers in the field GF(2^8) 304 | #if MULTIPLY_AS_A_FUNCTION 305 | #if 0 306 | static uint8_t Multiply(uint8_t x, uint8_t y) 307 | { 308 | return (((y & 1) * x) ^ 309 | ((y>>1 & 1) * xtime(x)) ^ 310 | ((y>>2 & 1) * xtime(xtime(x))) ^ 311 | ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ 312 | ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))); 313 | } 314 | #endif 315 | #else 316 | #define Multiply(x, y) \ 317 | ( ((y & 1) * x) ^ \ 318 | ((y>>1 & 1) * xtime(x)) ^ \ 319 | ((y>>2 & 1) * xtime(xtime(x))) ^ \ 320 | ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \ 321 | ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \ 322 | 323 | #endif 324 | 325 | // MixColumns function mixes the columns of the state matrix. 326 | // The method used to multiply may be difficult to understand for the inexperienced. 327 | // Please use the references to gain more information. 328 | static void InvMixColumns(void) 329 | { 330 | int i; 331 | uint8_t a,b,c,d; 332 | for(i=0;i<4;++i) 333 | { 334 | a = (*state)[i][0]; 335 | b = (*state)[i][1]; 336 | c = (*state)[i][2]; 337 | d = (*state)[i][3]; 338 | 339 | (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09); 340 | (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d); 341 | (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b); 342 | (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e); 343 | } 344 | } 345 | 346 | 347 | // The SubBytes Function Substitutes the values in the 348 | // state matrix with values in an S-box. 349 | static void InvSubBytes(void) 350 | { 351 | uint8_t i,j; 352 | for(i=0;i<4;++i) 353 | { 354 | for(j=0;j<4;++j) 355 | { 356 | (*state)[j][i] = getSBoxInvert((*state)[j][i]); 357 | } 358 | } 359 | } 360 | 361 | static void InvShiftRows(void) 362 | { 363 | uint8_t temp; 364 | 365 | // Rotate first row 1 columns to right 366 | temp=(*state)[3][1]; 367 | (*state)[3][1]=(*state)[2][1]; 368 | (*state)[2][1]=(*state)[1][1]; 369 | (*state)[1][1]=(*state)[0][1]; 370 | (*state)[0][1]=temp; 371 | 372 | // Rotate second row 2 columns to right 373 | temp=(*state)[0][2]; 374 | (*state)[0][2]=(*state)[2][2]; 375 | (*state)[2][2]=temp; 376 | 377 | temp=(*state)[1][2]; 378 | (*state)[1][2]=(*state)[3][2]; 379 | (*state)[3][2]=temp; 380 | 381 | // Rotate third row 3 columns to right 382 | temp=(*state)[0][3]; 383 | (*state)[0][3]=(*state)[1][3]; 384 | (*state)[1][3]=(*state)[2][3]; 385 | (*state)[2][3]=(*state)[3][3]; 386 | (*state)[3][3]=temp; 387 | } 388 | 389 | 390 | // Cipher is the main function that encrypts the PlainText. 391 | static void Cipher(void) 392 | { 393 | uint8_t round = 0; 394 | 395 | // Add the First round key to the state before starting the rounds. 396 | AddRoundKey(0); 397 | 398 | // There will be Nr rounds. 399 | // The first Nr-1 rounds are identical. 400 | // These Nr-1 rounds are executed in the loop below. 401 | for(round = 1; round < Nr; ++round) 402 | { 403 | SubBytes(); 404 | ShiftRows(); 405 | MixColumns(); 406 | AddRoundKey(round); 407 | } 408 | 409 | // The last round is given below. 410 | // The MixColumns function is not here in the last round. 411 | SubBytes(); 412 | ShiftRows(); 413 | AddRoundKey(Nr); 414 | } 415 | 416 | static void InvCipher(void) 417 | { 418 | uint8_t round=0; 419 | 420 | // Add the First round key to the state before starting the rounds. 421 | AddRoundKey(Nr); 422 | 423 | // There will be Nr rounds. 424 | // The first Nr-1 rounds are identical. 425 | // These Nr-1 rounds are executed in the loop below. 426 | for(round=Nr-1;round>0;round--) 427 | { 428 | InvShiftRows(); 429 | InvSubBytes(); 430 | AddRoundKey(round); 431 | InvMixColumns(); 432 | } 433 | 434 | // The last round is given below. 435 | // The MixColumns function is not here in the last round. 436 | InvShiftRows(); 437 | InvSubBytes(); 438 | AddRoundKey(0); 439 | } 440 | 441 | static void BlockCopy(uint8_t* output, const uint8_t* input) 442 | { 443 | uint8_t i; 444 | for (i=0;i 2 | 3 | 4 | 245 5 | 6 | aes 9 7 | .__.ABS. 8 | _state 9 | _AES128_ECB_encrypt_PARM_2 10 | _AES128_ECB_encrypt_PARM_3 11 | _Key 12 | _RoundKey 13 | _AES128_ECB_decrypt_PARM_2 14 | _AES128_ECB_decrypt_PARM_3 15 | _AES128_ECB_decrypt 16 | _AES128_ECB_encrypt 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | aes 25 | 26 | XH3 27 | H 1B areas E global symbols 28 | M aes 29 | O -mmcs51 --model-large 30 | S _enc_dec_accel_galois_multiply_PARM_2 Ref000000 31 | S __gptrput Ref000000 32 | S .__.ABS. Def000000 33 | S _enc_dec_accel_galois_multiply Ref000000 34 | S __gptrget Ref000000 35 | A _CODE size 0 flags 0 addr 0 36 | A RSEG size 0 flags 8 addr 0 37 | A RSEG0 size 0 flags 8 addr 0 38 | A RSEG1 size 0 flags 8 addr 0 39 | A REG_BANK_0 size 8 flags 4 addr 0 40 | A DSEG size 1C flags 0 addr 0 41 | A OSEG size 3 flags 4 addr 0 42 | A ISEG size 0 flags 0 addr 0 43 | A IABS size 0 flags 8 addr 0 44 | A BSEG size 0 flags 80 addr 0 45 | A PSEG size 0 flags 50 addr 0 46 | A XSEG size DE flags 40 addr 0 47 | S _state Def000000 48 | S _AES128_ECB_encrypt_PARM_2 Def0000CC 49 | S _AES128_ECB_encrypt_PARM_3 Def0000CF 50 | S _Key Def0000B3 51 | S _RoundKey Def000003 52 | S _AES128_ECB_decrypt_PARM_2 Def0000D5 53 | S _AES128_ECB_decrypt_PARM_3 Def0000D8 54 | A XABS size 0 flags 48 addr 0 55 | A XISEG size 0 flags 40 addr 0 56 | A HOME size 0 flags 20 addr 0 57 | A GSINIT0 size 0 flags 20 addr 0 58 | A GSINIT1 size 0 flags 20 addr 0 59 | A GSINIT2 size 0 flags 20 addr 0 60 | A GSINIT3 size 0 flags 20 addr 0 61 | A GSINIT4 size 0 flags 20 addr 0 62 | A GSINIT5 size 0 flags 20 addr 0 63 | A GSINIT size 0 flags 20 addr 0 64 | A GSFINAL size 0 flags 20 addr 0 65 | A CSEG size FB9 flags 20 addr 0 66 | S _AES128_ECB_decrypt Def000F4D 67 | S _AES128_ECB_encrypt Def000EE1 68 | A CONST size 2FF flags 20 addr 0 69 | A XINIT size 0 flags 20 addr 0 70 | A CABS size 0 flags 28 addr 0 71 | T 00 00 00 72 | R 00 00 00 02 73 | T 00 00 00 74 | R 00 00 00 03 75 | T 00 00 00 76 | R 00 00 00 04 77 | T 00 00 00 78 | R 00 00 00 05 79 | T 00 00 00 80 | R 00 00 00 05 81 | T 00 00 02 82 | R 00 00 00 05 83 | T 00 00 02 84 | R 00 00 00 05 85 | T 00 00 03 86 | R 00 00 00 05 87 | T 00 00 03 88 | R 00 00 00 05 89 | T 00 00 07 90 | R 00 00 00 05 91 | T 00 00 07 92 | R 00 00 00 05 93 | T 00 00 0B 94 | R 00 00 00 05 95 | T 00 00 0B 96 | R 00 00 00 05 97 | T 00 00 0F 98 | R 00 00 00 05 99 | T 00 00 0F 100 | R 00 00 00 05 101 | T 00 00 10 102 | R 00 00 00 05 103 | T 00 00 10 104 | R 00 00 00 05 105 | T 00 00 13 106 | R 00 00 00 05 107 | T 00 00 13 108 | R 00 00 00 05 109 | T 00 00 16 110 | R 00 00 00 05 111 | T 00 00 16 112 | R 00 00 00 05 113 | T 00 00 17 114 | R 00 00 00 05 115 | T 00 00 17 116 | R 00 00 00 05 117 | T 00 00 19 118 | R 00 00 00 05 119 | T 00 00 19 120 | R 00 00 00 05 121 | T 00 00 00 122 | R 00 00 00 06 123 | T 00 00 00 124 | R 00 00 00 06 125 | T 00 00 01 126 | R 00 00 00 06 127 | T 00 00 01 128 | R 00 00 00 06 129 | T 00 00 00 130 | R 00 00 00 06 131 | T 00 00 00 132 | R 00 00 00 06 133 | T 00 00 00 134 | R 00 00 00 0B 135 | T 00 00 00 136 | R 00 00 00 0B 137 | T 00 00 03 138 | R 00 00 00 0B 139 | T 00 00 03 140 | R 00 00 00 0B 141 | T 00 00 B3 142 | R 00 00 00 0B 143 | T 00 00 B3 144 | R 00 00 00 0B 145 | T 00 00 B6 146 | R 00 00 00 0B 147 | T 00 00 B6 148 | R 00 00 00 0B 149 | T 00 00 B7 150 | R 00 00 00 0B 151 | T 00 00 B7 152 | R 00 00 00 0B 153 | T 00 00 B8 154 | R 00 00 00 0B 155 | T 00 00 B8 156 | R 00 00 00 0B 157 | T 00 00 BC 158 | R 00 00 00 0B 159 | T 00 00 BC 160 | R 00 00 00 0B 161 | T 00 00 BD 162 | R 00 00 00 0B 163 | T 00 00 BD 164 | R 00 00 00 0B 165 | T 00 00 BE 166 | R 00 00 00 0B 167 | T 00 00 BE 168 | R 00 00 00 0B 169 | T 00 00 BF 170 | R 00 00 00 0B 171 | T 00 00 BF 172 | R 00 00 00 0B 173 | T 00 00 C0 174 | R 00 00 00 0B 175 | T 00 00 C0 176 | R 00 00 00 0B 177 | T 00 00 C1 178 | R 00 00 00 0B 179 | T 00 00 C1 180 | R 00 00 00 0B 181 | T 00 00 C2 182 | R 00 00 00 0B 183 | T 00 00 C2 184 | R 00 00 00 0B 185 | T 00 00 C3 186 | R 00 00 00 0B 187 | T 00 00 C3 188 | R 00 00 00 0B 189 | T 00 00 C4 190 | R 00 00 00 0B 191 | T 00 00 C4 192 | R 00 00 00 0B 193 | T 00 00 C5 194 | R 00 00 00 0B 195 | T 00 00 C5 196 | R 00 00 00 0B 197 | T 00 00 C6 198 | R 00 00 00 0B 199 | T 00 00 C6 200 | R 00 00 00 0B 201 | T 00 00 C9 202 | R 00 00 00 0B 203 | T 00 00 C9 204 | R 00 00 00 0B 205 | T 00 00 CC 206 | R 00 00 00 0B 207 | T 00 00 CC 208 | R 00 00 00 0B 209 | T 00 00 CF 210 | R 00 00 00 0B 211 | T 00 00 CF 212 | R 00 00 00 0B 213 | T 00 00 D2 214 | R 00 00 00 0B 215 | T 00 00 D2 216 | R 00 00 00 0B 217 | T 00 00 D5 218 | R 00 00 00 0B 219 | T 00 00 D5 220 | R 00 00 00 0B 221 | T 00 00 D8 222 | R 00 00 00 0B 223 | T 00 00 D8 224 | R 00 00 00 0B 225 | T 00 00 DB 226 | R 00 00 00 0B 227 | T 00 00 DB 228 | R 00 00 00 0B 229 | T 00 00 00 230 | R 00 00 00 17 231 | T 00 00 00 E5 82 90 00 B6 F0 E0 90 00 00 93 F5 82 232 | R 00 00 00 17 00 06 00 0B 00 0B 00 18 233 | T 00 00 0D 22 234 | R 00 00 00 17 235 | T 00 00 0E 236 | R 00 00 00 17 237 | T 00 00 0E E5 82 90 00 B7 F0 E0 90 01 00 93 F5 82 238 | R 00 00 00 17 00 06 00 0B 00 0B 00 18 239 | T 00 00 1B 22 240 | R 00 00 00 17 241 | T 00 00 1C 242 | R 00 00 00 17 243 | T 00 00 1C 7C 00 7D 00 7E 00 7F 00 244 | R 00 00 00 17 245 | T 00 00 24 246 | R 00 00 00 17 247 | T 00 00 24 8C 03 EB 2B 25 E0 F5 00 00 02 24 248 | R 00 00 00 17 F1 21 0A 00 05 249 | T 00 00 2D 00 00 03 F5 00 00 00 E4 34 250 | R 00 00 00 17 F1 01 03 00 0B F1 21 07 00 05 251 | T 00 00 32 00 00 03 F5 00 00 01 EC 2C F5 252 | R 00 00 00 17 F1 81 03 00 0B F1 21 07 00 05 253 | T 00 00 38 00 00 03 ED 33 F5 00 00 04 EE 33 F5 254 | R 00 00 00 17 F1 21 03 00 05 F1 21 09 00 05 255 | T 00 00 40 00 00 05 EF 33 F5 00 00 06 E5 256 | R 00 00 00 17 F1 21 03 00 05 F1 21 09 00 05 257 | T 00 00 46 00 00 03 25 00 00 03 F5 258 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 259 | T 00 00 4A 00 00 03 E5 00 00 04 33 F5 260 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 261 | T 00 00 4F 00 00 04 E5 00 00 05 33 F5 262 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 263 | T 00 00 54 00 00 05 E5 00 00 06 33 F5 264 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 265 | T 00 00 59 00 00 06 90 00 B3 E0 F9 A3 E0 FA A3 E0 266 | R 00 00 00 17 F1 21 03 00 05 00 07 00 0B 267 | T 00 00 64 FB E5 00 00 03 29 F9 E5 00 00 04 3A FA 268 | R 00 00 00 17 F1 21 05 00 05 F1 21 0B 00 05 269 | T 00 00 6D 89 82 8A 83 8B F0 12 00 00 85 00 00 00 270 | R 00 00 00 17 02 0A 00 04 F1 21 0D 00 05 271 | T 00 00 78 82 85 00 00 01 83 F0 E5 00 00 02 04 24 272 | R 00 00 00 17 F1 21 05 00 05 F1 21 0B 00 05 273 | T 00 00 81 00 00 03 F5 00 00 00 E4 34 274 | R 00 00 00 17 F1 01 03 00 0B F1 21 07 00 05 275 | T 00 00 86 00 00 03 F5 00 00 01 74 01 25 276 | R 00 00 00 17 F1 81 03 00 0B F1 21 07 00 05 277 | T 00 00 8C 00 00 03 F5 00 00 07 E4 35 278 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 279 | T 00 00 91 00 00 04 F5 00 00 08 E4 35 280 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 281 | T 00 00 96 00 00 05 F5 00 00 09 E4 35 282 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 283 | T 00 00 9B 00 00 06 F5 00 00 0A 90 284 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 285 | T 00 00 9F 00 B3 E0 F9 A3 E0 FA A3 E0 FB E5 286 | R 00 00 00 17 00 03 00 0B 287 | T 00 00 AA 00 00 07 29 F9 E5 00 00 08 3A FA 89 82 288 | R 00 00 00 17 F1 21 03 00 05 F1 21 09 00 05 289 | T 00 00 B3 8A 83 8B F0 12 00 00 85 00 00 00 82 85 290 | R 00 00 00 17 02 08 00 04 F1 21 0B 00 05 291 | T 00 00 BE 00 00 01 83 F0 74 02 25 00 00 02 24 292 | R 00 00 00 17 F1 21 03 00 05 F1 21 0B 00 05 293 | T 00 00 C6 00 00 03 F5 00 00 07 E4 34 294 | R 00 00 00 17 F1 01 03 00 0B F1 21 07 00 05 295 | T 00 00 CB 00 00 03 F5 00 00 08 74 02 25 296 | R 00 00 00 17 F1 81 03 00 0B F1 21 07 00 05 297 | T 00 00 D1 00 00 03 F5 00 00 0B E4 35 298 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 299 | T 00 00 D6 00 00 04 F5 00 00 0C E4 35 300 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 301 | T 00 00 DB 00 00 05 F5 00 00 0D E4 35 302 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 303 | T 00 00 E0 00 00 06 F5 00 00 0E 90 304 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 305 | T 00 00 E4 00 B3 E0 F9 A3 E0 FA A3 E0 FB E5 306 | R 00 00 00 17 00 03 00 0B 307 | T 00 00 EF 00 00 0B 29 F9 E5 00 00 0C 3A FA 89 82 308 | R 00 00 00 17 F1 21 03 00 05 F1 21 09 00 05 309 | T 00 00 F8 8A 83 8B F0 12 00 00 85 00 00 07 82 85 310 | R 00 00 00 17 02 08 00 04 F1 21 0B 00 05 311 | T 00 01 03 00 00 08 83 F0 74 03 25 00 00 02 24 312 | R 00 00 00 17 F1 21 03 00 05 F1 21 0B 00 05 313 | T 00 01 0B 00 00 03 F5 00 00 0B E4 34 314 | R 00 00 00 17 F1 01 03 00 0B F1 21 07 00 05 315 | T 00 01 10 00 00 03 F5 00 00 0C 74 03 25 316 | R 00 00 00 17 F1 81 03 00 0B F1 21 07 00 05 317 | T 00 01 16 00 00 03 F5 00 00 07 E4 35 318 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 319 | T 00 01 1B 00 00 04 F5 00 00 08 E4 35 320 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 321 | T 00 01 20 00 00 05 F5 00 00 09 E4 35 322 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 323 | T 00 01 25 00 00 06 F5 00 00 0A 90 324 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 325 | T 00 01 29 00 B3 E0 F9 A3 E0 FA A3 E0 FB E5 326 | R 00 00 00 17 00 03 00 0B 327 | T 00 01 34 00 00 07 29 F9 E5 00 00 08 3A FA 89 82 328 | R 00 00 00 17 F1 21 03 00 05 F1 21 09 00 05 329 | T 00 01 3D 8A 83 8B F0 12 00 00 F9 85 00 00 0B 82 330 | R 00 00 00 17 02 08 00 04 F1 21 0C 00 05 331 | T 00 01 48 85 00 00 0C 83 F0 0C BC 00 09 0D BD 00 332 | R 00 00 00 17 F1 21 04 00 05 333 | T 00 01 53 05 0E BE 00 01 0F 334 | R 00 00 00 17 335 | T 00 01 59 336 | R 00 00 00 17 337 | T 00 01 59 C3 EC 94 04 ED 94 00 EE 94 00 EF 94 00 338 | R 00 00 00 17 339 | T 00 01 66 50 03 02 00 24 340 | R 00 00 00 17 00 06 00 17 341 | T 00 01 6B 342 | R 00 00 00 17 343 | T 00 01 6B 344 | R 00 00 00 17 345 | T 00 01 6B C3 EC 94 2C ED 94 00 EE 94 00 EF 94 00 346 | R 00 00 00 17 347 | T 00 01 78 40 01 22 348 | R 00 00 00 17 349 | T 00 01 7B 350 | R 00 00 00 17 351 | T 00 01 7B 8C 00 8D 01 8E 02 8F 03 E4 F5 00 00 0B 352 | R 00 00 00 17 F1 21 0D 00 05 353 | T 00 01 86 F5 00 00 0C F5 00 00 0D F5 354 | R 00 00 00 17 F1 21 04 00 05 F1 21 08 00 05 355 | T 00 01 8B 00 00 0E 356 | R 00 00 00 17 F1 21 03 00 05 357 | T 00 01 8C 358 | R 00 00 00 17 359 | T 00 01 8C C0 04 C0 05 C0 06 C0 07 E5 00 00 0B 24 360 | R 00 00 00 17 F1 21 0C 00 05 361 | T 00 01 97 00 00 B8 FE E5 00 00 0C 34 362 | R 00 00 00 17 F1 01 03 00 0B F1 21 08 00 05 363 | T 00 01 9C 00 00 B8 FF 88 05 1D ED 2D 25 E0 FD E5 364 | R 00 00 00 17 F1 81 03 00 0B 365 | T 00 01 A7 00 00 0B FC 2D 24 00 00 03 F5 82 E4 34 366 | R 00 00 00 17 F1 21 03 00 05 F1 01 09 00 0B 367 | T 00 01 B0 00 00 03 F5 83 E0 FD 8E 82 8F 83 F0 05 368 | R 00 00 00 17 F1 81 03 00 0B 369 | T 00 01 BB 00 00 0B E4 B5 00 00 0B 0C 05 370 | R 00 00 00 17 F1 21 03 00 05 F1 21 08 00 05 371 | T 00 01 C1 00 00 0C B5 00 00 0C 07 05 372 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 373 | T 00 01 C6 00 00 0D B5 00 00 0D 02 05 374 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 375 | T 00 01 CB 00 00 0E 376 | R 00 00 00 17 F1 21 03 00 05 377 | T 00 01 CC 378 | R 00 00 00 17 379 | T 00 01 CC C3 E5 00 00 0B 94 04 E5 00 00 0C 94 00 380 | R 00 00 00 17 F1 21 05 00 05 F1 21 0B 00 05 381 | T 00 01 D5 E5 00 00 0D 94 00 E5 00 00 0E 94 00 D0 382 | R 00 00 00 17 F1 21 04 00 05 F1 21 0A 00 05 383 | T 00 01 DE 07 D0 06 D0 05 D0 04 40 A5 E8 54 03 60 384 | R 00 00 00 17 385 | T 00 01 EB 03 02 02 B8 386 | R 00 00 00 17 00 05 00 17 387 | T 00 01 EF 388 | R 00 00 00 17 389 | T 00 01 EF C0 04 C0 05 C0 06 C0 07 90 00 B8 E0 FF 390 | R 00 00 00 17 00 0C 00 0B 391 | T 00 01 FC 8F 00 00 0B 75 00 00 0C 00 75 392 | R 00 00 00 17 F1 21 04 00 05 F1 21 08 00 05 393 | T 00 02 02 00 00 0D 00 75 00 00 0E 00 90 394 | R 00 00 00 17 F1 21 03 00 05 F1 21 08 00 05 395 | T 00 02 08 00 B9 E0 FF 90 00 B8 F0 90 396 | R 00 00 00 17 00 03 00 0B 00 08 00 0B 397 | T 00 02 11 00 BA E0 90 00 B9 F0 90 398 | R 00 00 00 17 00 03 00 0B 00 07 00 0B 399 | T 00 02 19 00 BB E0 90 00 BA F0 AE 400 | R 00 00 00 17 00 03 00 0B 00 07 00 0B 401 | T 00 02 21 00 00 0B 90 00 BB EE F0 8F 82 C0 06 C0 402 | R 00 00 00 17 F1 21 03 00 05 00 07 00 0B 403 | T 00 02 2C 05 C0 04 C0 03 C0 02 C0 01 C0 00 12 404 | R 00 00 00 17 405 | T 00 02 38 00 00 AF 82 90 00 B8 EF F0 90 406 | R 00 00 00 17 00 03 00 17 00 08 00 0B 407 | T 00 02 42 00 B9 E0 F5 82 12 00 00 AF 82 90 408 | R 00 00 00 17 00 03 00 0B 00 09 00 17 409 | T 00 02 4D 00 B9 EF F0 90 00 BA E0 F5 82 12 410 | R 00 00 00 17 00 03 00 0B 00 08 00 0B 411 | T 00 02 58 00 00 AF 82 90 00 BA EF F0 90 412 | R 00 00 00 17 00 03 00 17 00 08 00 0B 413 | T 00 02 62 00 BB E0 F5 82 12 00 00 AF 82 D0 00 D0 414 | R 00 00 00 17 00 03 00 0B 00 09 00 17 415 | T 00 02 6F 01 D0 02 D0 03 D0 04 D0 05 D0 06 90 416 | R 00 00 00 17 417 | T 00 02 7B 00 BB EF F0 90 00 B8 E0 FF EB C3 13 FB 418 | R 00 00 00 17 00 03 00 0B 00 08 00 0B 419 | T 00 02 88 EA 13 FA E9 13 F9 E8 13 F8 EB C3 13 FB 420 | R 00 00 00 17 421 | T 00 02 95 EA 13 FA E9 13 F9 E8 13 F8 24 00 02 00 422 | R 00 00 00 17 F1 01 0D 00 18 423 | T 00 02 A0 F5 82 E9 34 00 02 00 F5 83 E4 93 62 07 424 | R 00 00 00 17 F1 81 07 00 18 425 | T 00 02 AB 90 00 B8 EF F0 D0 07 D0 06 D0 05 D0 04 426 | R 00 00 00 17 00 04 00 0B 427 | T 00 02 B8 428 | R 00 00 00 17 429 | T 00 02 B8 8C 03 EB 2B 25 E0 FA 24 00 00 03 F5 430 | R 00 00 00 17 F1 01 0B 00 0B 431 | T 00 02 C2 00 00 0B E4 34 00 00 03 F5 432 | R 00 00 00 17 F1 21 03 00 05 F1 81 08 00 0B 433 | T 00 02 C7 00 00 0C 1B 1B 1B 1B EB 2B 25 E0 FB 24 434 | R 00 00 00 17 F1 21 03 00 05 435 | T 00 02 D2 00 00 03 F5 82 E4 34 00 00 03 F5 83 E0 436 | R 00 00 00 17 F1 01 03 00 0B F1 81 0A 00 0B 437 | T 00 02 DB F9 90 00 B8 E0 62 01 85 00 00 0B 82 85 438 | R 00 00 00 17 00 05 00 0B F1 21 0B 00 05 439 | T 00 02 E6 00 00 0C 83 E9 F0 EA 04 24 00 00 03 F5 440 | R 00 00 00 17 F1 21 03 00 05 F1 01 0C 00 0B 441 | T 00 02 EF 00 00 0B E4 34 00 00 03 F5 442 | R 00 00 00 17 F1 21 03 00 05 F1 81 08 00 0B 443 | T 00 02 F4 00 00 0C EB 04 24 00 00 03 F5 82 E4 34 444 | R 00 00 00 17 F1 21 03 00 05 F1 01 09 00 0B 445 | T 00 02 FD 00 00 03 F5 83 E0 F9 90 00 B9 E0 62 01 446 | R 00 00 00 17 F1 81 03 00 0B 00 0B 00 0B 447 | T 00 03 08 85 00 00 0B 82 85 00 00 0C 83 E9 F0 74 448 | R 00 00 00 17 F1 21 04 00 05 F1 21 09 00 05 449 | T 00 03 11 02 2A 24 00 00 03 F5 00 00 0B E4 34 450 | R 00 00 00 17 F1 01 06 00 0B F1 21 0A 00 05 451 | T 00 03 19 00 00 03 F5 00 00 0C 74 02 2B 24 452 | R 00 00 00 17 F1 81 03 00 0B F1 21 07 00 05 453 | T 00 03 20 00 00 03 F5 82 E4 34 00 00 03 F5 83 E0 454 | R 00 00 00 17 F1 01 03 00 0B F1 81 0A 00 0B 455 | T 00 03 29 F9 90 00 BA E0 62 01 85 00 00 0B 82 85 456 | R 00 00 00 17 00 05 00 0B F1 21 0B 00 05 457 | T 00 03 34 00 00 0C 83 E9 F0 74 03 2A 24 00 00 03 458 | R 00 00 00 17 F1 21 03 00 05 F1 01 0D 00 0B 459 | T 00 03 3D F9 E4 34 00 00 03 FA 74 03 2B 24 460 | R 00 00 00 17 F1 81 06 00 0B 461 | T 00 03 46 00 00 03 F5 82 E4 34 00 00 03 F5 83 E0 462 | R 00 00 00 17 F1 01 03 00 0B F1 81 0A 00 0B 463 | T 00 03 4F FB 90 00 BB E0 F8 62 03 89 82 8A 83 EB 464 | R 00 00 00 17 00 05 00 0B 465 | T 00 03 5C F0 0C BC 00 09 0D BD 00 05 0E BE 00 01 466 | R 00 00 00 17 467 | T 00 03 69 0F 468 | R 00 00 00 17 469 | T 00 03 6A 470 | R 00 00 00 17 471 | T 00 03 6A 02 01 6B 472 | R 00 00 00 17 00 04 00 17 473 | T 00 03 6D 474 | R 00 00 00 17 475 | T 00 03 6D E5 82 90 00 BC F0 E0 C4 54 F0 FF 7E 00 476 | R 00 00 00 17 00 06 00 0B 477 | T 00 03 7A 478 | R 00 00 00 17 479 | T 00 03 7A EE F5 00 00 00 25 E0 25 E0 FC 2F FB 7A 480 | R 00 00 00 17 F1 21 05 00 06 481 | T 00 03 85 00 482 | R 00 00 00 17 483 | T 00 03 86 484 | R 00 00 00 17 485 | T 00 03 86 C0 07 90 00 00 E0 F8 A3 E0 F9 A3 E0 FF 486 | R 00 00 00 17 00 06 00 0B 487 | T 00 03 93 EC 28 F8 E4 39 F9 EA 28 F8 E4 39 F9 EA 488 | R 00 00 00 17 489 | T 00 03 A0 2B 24 00 00 03 F5 82 E4 34 00 00 03 F5 490 | R 00 00 00 17 F1 01 05 00 0B F1 81 0C 00 0B 491 | T 00 03 A9 83 E0 F5 00 00 01 88 82 89 83 8F F0 12 492 | R 00 00 00 17 F1 21 06 00 06 493 | T 00 03 B4 00 00 FD E5 00 00 01 62 05 88 82 89 83 494 | R 00 00 00 17 02 03 00 04 F1 21 07 00 06 495 | T 00 03 BF 8F F0 ED 12 00 00 0A BA 04 00 496 | R 00 00 00 17 02 07 00 01 497 | T 00 03 C9 498 | R 00 00 00 17 499 | T 00 03 C9 D0 07 40 B9 E5 00 00 00 04 FE BE 04 00 500 | R 00 00 00 17 F1 21 08 00 06 501 | T 00 03 D4 502 | R 00 00 00 17 503 | T 00 03 D4 40 A4 22 504 | R 00 00 00 17 505 | T 00 03 D7 506 | R 00 00 00 17 507 | T 00 03 D7 7F 00 508 | R 00 00 00 17 509 | T 00 03 D9 510 | R 00 00 00 17 511 | T 00 03 D9 8F 06 7D 00 512 | R 00 00 00 17 513 | T 00 03 DD 514 | R 00 00 00 17 515 | T 00 03 DD 90 00 00 E0 FA A3 E0 FB A3 E0 FC ED 2D 516 | R 00 00 00 17 00 04 00 0B 517 | T 00 03 EA 25 E0 2A FA E4 3B FB EE 2A FA E4 3B FB 518 | R 00 00 00 17 519 | T 00 03 F7 8A 82 8B 83 8C F0 12 00 00 F5 82 C0 06 520 | R 00 00 00 17 02 0A 00 04 521 | T 00 04 04 C0 05 C0 04 C0 03 C0 02 12 00 00 A9 82 522 | R 00 00 00 17 00 0C 00 17 523 | T 00 04 11 D0 02 D0 03 D0 04 D0 05 D0 06 8A 82 8B 524 | R 00 00 00 17 525 | T 00 04 1E 83 8C F0 E9 12 00 00 0D BD 04 00 526 | R 00 00 00 17 02 08 00 01 527 | T 00 04 29 528 | R 00 00 00 17 529 | T 00 04 29 40 B2 EE 04 FF BF 04 00 530 | R 00 00 00 17 531 | T 00 04 31 532 | R 00 00 00 17 533 | T 00 04 31 40 A6 22 534 | R 00 00 00 17 535 | T 00 04 34 536 | R 00 00 00 17 537 | T 00 04 34 90 00 00 E0 FD A3 E0 FE A3 E0 FF 74 01 538 | R 00 00 00 17 00 04 00 0B 539 | T 00 04 41 2D FA E4 3E FB 8F 04 8A 82 8B 83 8C F0 540 | R 00 00 00 17 541 | T 00 04 4E 12 00 00 90 00 BD F0 74 05 2D FD E4 3E 542 | R 00 00 00 17 02 04 00 04 00 07 00 0B 543 | T 00 04 5B FE 8D 82 8E 83 8F F0 12 00 00 8A 82 8B 544 | R 00 00 00 17 02 0B 00 04 545 | T 00 04 68 83 8C F0 12 00 00 90 00 00 E0 FD A3 E0 546 | R 00 00 00 17 02 07 00 01 00 0A 00 0B 547 | T 00 04 75 FE A3 E0 FF 74 05 2D FA E4 3E FB 8F 04 548 | R 00 00 00 17 549 | T 00 04 82 74 09 2D FD E4 3E FE 8D 82 8E 83 8F F0 550 | R 00 00 00 17 551 | T 00 04 8F 12 00 00 8A 82 8B 83 8C F0 12 00 00 90 552 | R 00 00 00 17 02 04 00 04 02 0D 00 01 553 | T 00 04 9C 00 00 E0 FD A3 E0 FE A3 E0 FF 74 09 2D 554 | R 00 00 00 17 00 03 00 0B 555 | T 00 04 A9 FA E4 3E FB 8F 04 74 0D 2D FD E4 3E FE 556 | R 00 00 00 17 557 | T 00 04 B6 8D 82 8E 83 8F F0 12 00 00 8A 82 8B 83 558 | R 00 00 00 17 02 0A 00 04 559 | T 00 04 C3 8C F0 12 00 00 90 00 00 E0 FD A3 E0 FE 560 | R 00 00 00 17 02 06 00 01 00 09 00 0B 561 | T 00 04 D0 A3 E0 FF 74 0D 2D FD E4 3E FE 90 00 BD 562 | R 00 00 00 17 00 0E 00 0B 563 | T 00 04 DD E0 8D 82 8E 83 8F F0 12 00 00 90 00 00 564 | R 00 00 00 17 02 0B 00 01 00 0E 00 0B 565 | T 00 04 EA E0 FD A3 E0 FE A3 E0 FF 74 02 2D FA E4 566 | R 00 00 00 17 567 | T 00 04 F7 3E FB 8F 04 8A 82 8B 83 8C F0 12 00 00 568 | R 00 00 00 17 02 0E 00 04 569 | T 00 05 04 90 00 BD F0 74 0A 2D FD E4 3E FE 8D 82 570 | R 00 00 00 17 00 04 00 0B 571 | T 00 05 11 8E 83 8F F0 12 00 00 8A 82 8B 83 8C F0 572 | R 00 00 00 17 02 08 00 04 573 | T 00 05 1E 12 00 00 90 00 00 E0 FD A3 E0 FE A3 E0 574 | R 00 00 00 17 02 04 00 01 00 07 00 0B 575 | T 00 05 2B FF 74 0A 2D FD E4 3E FE 90 00 BD E0 8D 576 | R 00 00 00 17 00 0C 00 0B 577 | T 00 05 38 82 8E 83 8F F0 12 00 00 90 00 00 E0 FD 578 | R 00 00 00 17 02 09 00 01 00 0C 00 0B 579 | T 00 05 45 A3 E0 FE A3 E0 FF 74 06 2D FA E4 3E FB 580 | R 00 00 00 17 581 | T 00 05 52 8F 04 8A 82 8B 83 8C F0 12 00 00 90 582 | R 00 00 00 17 02 0C 00 04 583 | T 00 05 5E 00 BD F0 74 0E 2D FD E4 3E FE 8D 82 8E 584 | R 00 00 00 17 00 03 00 0B 585 | T 00 05 6B 83 8F F0 12 00 00 8A 82 8B 83 8C F0 12 586 | R 00 00 00 17 02 07 00 04 587 | T 00 05 78 00 00 90 00 00 E0 FD A3 E0 FE A3 E0 FF 588 | R 00 00 00 17 02 03 00 01 00 06 00 0B 589 | T 00 05 85 74 0E 2D FD E4 3E FE 90 00 BD E0 8D 82 590 | R 00 00 00 17 00 0B 00 0B 591 | T 00 05 92 8E 83 8F F0 12 00 00 90 00 00 E0 FD A3 592 | R 00 00 00 17 02 08 00 01 00 0B 00 0B 593 | T 00 05 9F E0 FE A3 E0 FF 74 03 2D FA E4 3E FB 8F 594 | R 00 00 00 17 595 | T 00 05 AC 04 8A 82 8B 83 8C F0 12 00 00 90 00 BD 596 | R 00 00 00 17 02 0B 00 04 00 0E 00 0B 597 | T 00 05 B9 F0 74 0F 2D FD E4 3E FE 8D 82 8E 83 8F 598 | R 00 00 00 17 599 | T 00 05 C6 F0 12 00 00 8A 82 8B 83 8C F0 12 00 00 600 | R 00 00 00 17 02 05 00 04 02 0E 00 01 601 | T 00 05 D3 90 00 00 E0 FD A3 E0 FE A3 E0 FF 74 0F 602 | R 00 00 00 17 00 04 00 0B 603 | T 00 05 E0 2D FA E4 3E FB 8F 04 74 0B 2D FD E4 3E 604 | R 00 00 00 17 605 | T 00 05 ED FE 8D 82 8E 83 8F F0 12 00 00 8A 82 8B 606 | R 00 00 00 17 02 0B 00 04 607 | T 00 05 FA 83 8C F0 12 00 00 90 00 00 E0 FD A3 E0 608 | R 00 00 00 17 02 07 00 01 00 0A 00 0B 609 | T 00 06 07 FE A3 E0 FF 74 0B 2D FA E4 3E FB 8F 04 610 | R 00 00 00 17 611 | T 00 06 14 74 07 2D FD E4 3E FE 8D 82 8E 83 8F F0 612 | R 00 00 00 17 613 | T 00 06 21 12 00 00 8A 82 8B 83 8C F0 12 00 00 90 614 | R 00 00 00 17 02 04 00 04 02 0D 00 01 615 | T 00 06 2E 00 00 E0 FD A3 E0 FE A3 E0 FF 74 07 2D 616 | R 00 00 00 17 00 03 00 0B 617 | T 00 06 3B FD E4 3E FE 90 00 BD E0 8D 82 8E 83 8F 618 | R 00 00 00 17 00 08 00 0B 619 | T 00 06 48 F0 02 00 00 620 | R 00 00 00 17 02 05 00 01 621 | T 00 06 4C 622 | R 00 00 00 17 623 | T 00 06 4C E5 82 90 00 BE F0 E0 FF 25 E0 FE EF 23 624 | R 00 00 00 17 00 06 00 0B 625 | T 00 06 59 54 01 75 F0 1B A4 FF EE 62 07 8F 82 22 626 | R 00 00 00 17 627 | T 00 06 66 628 | R 00 00 00 17 629 | T 00 06 66 7F 00 630 | R 00 00 00 17 631 | T 00 06 68 632 | R 00 00 00 17 633 | T 00 06 68 90 00 00 E0 FC A3 E0 FD A3 E0 FE EF 2F 634 | R 00 00 00 17 00 04 00 0B 635 | T 00 06 75 25 E0 FB 2C FC E4 3D FD 8C 82 8D 83 8E 636 | R 00 00 00 17 637 | T 00 06 82 F0 12 00 00 F5 00 00 0F 90 638 | R 00 00 00 17 02 05 00 04 F1 21 08 00 05 639 | T 00 06 89 00 C0 F0 74 01 2C F8 E4 3D F9 8E 02 88 640 | R 00 00 00 17 00 03 00 0B 641 | T 00 06 96 82 89 83 8A F0 12 00 00 62 00 00 0F 74 642 | R 00 00 00 17 02 09 00 04 F1 21 0C 00 05 643 | T 00 06 A1 02 2C F8 E4 3D F9 8E 02 88 82 89 83 8A 644 | R 00 00 00 17 645 | T 00 06 AE F0 12 00 00 F8 E5 00 00 0F 62 00 74 03 646 | R 00 00 00 17 02 05 00 04 F1 21 09 00 05 647 | T 00 06 B9 2C FC E4 3D FD 8C 82 8D 83 8E F0 12 648 | R 00 00 00 17 649 | T 00 06 C5 00 00 90 00 BF 68 F0 85 650 | R 00 00 00 17 02 03 00 04 00 06 00 0B 651 | T 00 06 CD 00 00 0F 82 C0 07 C0 03 12 06 4C AE 82 652 | R 00 00 00 17 F1 21 03 00 05 00 0C 00 17 653 | T 00 06 D8 D0 03 90 00 00 E0 FA A3 E0 FC A3 E0 FD 654 | R 00 00 00 17 00 06 00 0B 655 | T 00 06 E5 EB 2A FA E4 3C FC 90 00 BF E0 F9 62 06 656 | R 00 00 00 17 00 0A 00 0B 657 | T 00 06 F2 8A 82 8C 83 8D F0 12 00 00 62 06 8A 82 658 | R 00 00 00 17 02 0A 00 04 659 | T 00 06 FF 8C 83 8D F0 EE 12 00 00 90 00 00 E0 FC 660 | R 00 00 00 17 02 09 00 01 00 0C 00 0B 661 | T 00 07 0C A3 E0 FD A3 E0 FE EB 2C F5 00 00 10 E4 662 | R 00 00 00 17 F1 21 0C 00 05 663 | T 00 07 17 3D F5 00 00 11 8E 00 00 12 74 01 25 664 | R 00 00 00 17 F1 21 05 00 05 F1 21 09 00 05 665 | T 00 07 1F 00 00 10 F5 00 00 13 E4 35 666 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 667 | T 00 07 24 00 00 11 F5 00 00 14 85 668 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 669 | T 00 07 28 00 00 12 00 00 15 74 02 25 670 | R 00 00 00 17 F1 21 03 00 05 F1 21 06 00 05 671 | T 00 07 2D 00 00 10 FC E4 35 00 00 11 FD AE 672 | R 00 00 00 17 F1 21 03 00 05 F1 21 09 00 05 673 | T 00 07 34 00 00 12 8C 82 8D 83 8E F0 12 00 00 FC 674 | R 00 00 00 17 F1 21 03 00 05 02 0D 00 04 675 | T 00 07 3F 85 00 00 13 82 85 00 00 14 83 85 676 | R 00 00 00 17 F1 21 04 00 05 F1 21 09 00 05 677 | T 00 07 46 00 00 15 F0 12 00 00 62 04 8C 82 C0 03 678 | R 00 00 00 17 F1 21 03 00 05 02 08 00 04 679 | T 00 07 51 C0 01 12 06 4C AE 82 D0 01 D0 03 D0 07 680 | R 00 00 00 17 00 06 00 17 681 | T 00 07 5E 90 00 00 E0 FA A3 E0 FC A3 E0 FD EB 2A 682 | R 00 00 00 17 00 04 00 0B 683 | T 00 07 6B FA E4 3C FC 0A BA 00 01 0C 684 | R 00 00 00 17 685 | T 00 07 74 686 | R 00 00 00 17 687 | T 00 07 74 E9 62 06 8A 82 8C 83 8D F0 12 00 00 62 688 | R 00 00 00 17 02 0D 00 04 689 | T 00 07 81 06 8A 82 8C 83 8D F0 EE 12 00 00 90 690 | R 00 00 00 17 02 0C 00 01 691 | T 00 07 8D 00 00 E0 FC A3 E0 FD A3 E0 FE EB 2C F5 692 | R 00 00 00 17 00 03 00 0B 693 | T 00 07 9A 00 00 13 E4 3D F5 00 00 14 8E 694 | R 00 00 00 17 F1 21 03 00 05 F1 21 09 00 05 695 | T 00 07 A0 00 00 15 74 02 25 00 00 13 F5 696 | R 00 00 00 17 F1 21 03 00 05 F1 21 09 00 05 697 | T 00 07 A6 00 00 10 E4 35 00 00 14 F5 698 | R 00 00 00 17 F1 21 03 00 05 F1 21 08 00 05 699 | T 00 07 AB 00 00 11 85 00 00 15 700 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 701 | T 00 07 AE 00 00 12 74 03 25 00 00 13 FC E4 35 702 | R 00 00 00 17 F1 21 03 00 05 F1 21 09 00 05 703 | T 00 07 B6 00 00 14 FD AE 00 00 15 8C 82 8D 83 8E 704 | R 00 00 00 17 F1 21 03 00 05 F1 21 08 00 05 705 | T 00 07 BF F0 12 00 00 FC 85 00 00 10 82 85 706 | R 00 00 00 17 02 05 00 04 F1 21 09 00 05 707 | T 00 07 C8 00 00 11 83 85 00 00 12 F0 12 708 | R 00 00 00 17 F1 21 03 00 05 F1 21 08 00 05 709 | T 00 07 CE 00 00 62 04 8C 82 C0 07 C0 03 C0 01 12 710 | R 00 00 00 17 02 03 00 04 711 | T 00 07 DB 06 4C AE 82 D0 01 D0 03 90 00 00 E0 FA 712 | R 00 00 00 17 00 03 00 17 00 0C 00 0B 713 | T 00 07 E8 A3 E0 FC A3 E0 FD EB 2A FA E4 3C FC 74 714 | R 00 00 00 17 715 | T 00 07 F5 02 2A FA E4 3C FC E9 62 06 8A 82 8C 83 716 | R 00 00 00 17 717 | T 00 08 02 8D F0 12 00 00 62 06 8A 82 8C 83 8D F0 718 | R 00 00 00 17 02 06 00 04 719 | T 00 08 0F EE 12 00 00 90 00 00 E0 FC A3 E0 FD A3 720 | R 00 00 00 17 02 05 00 01 00 08 00 0B 721 | T 00 08 1C E0 FE EB 2C FC E4 3D FD 74 03 2C FC E4 722 | R 00 00 00 17 723 | T 00 08 29 3D FD 90 00 C0 E0 FA 8C 82 8D 83 8E F0 724 | R 00 00 00 17 00 06 00 0B 725 | T 00 08 36 12 00 00 62 02 8A 82 C0 03 C0 01 12 726 | R 00 00 00 17 02 04 00 04 727 | T 00 08 42 06 4C AE 82 D0 01 D0 03 D0 07 90 00 00 728 | R 00 00 00 17 00 03 00 17 00 0E 00 0B 729 | T 00 08 4F E0 FA A3 E0 FC A3 E0 FD EB 2A FA E4 3C 730 | R 00 00 00 17 731 | T 00 08 5C FC 74 03 2A FA E4 3C FC EE 62 01 8A 82 732 | R 00 00 00 17 733 | T 00 08 69 8C 83 8D F0 12 00 00 FE 62 01 8A 82 8C 734 | R 00 00 00 17 02 08 00 04 735 | T 00 08 76 83 8D F0 E9 12 00 00 0F BF 04 00 736 | R 00 00 00 17 02 08 00 01 737 | T 00 08 81 738 | R 00 00 00 17 739 | T 00 08 81 50 03 02 06 68 740 | R 00 00 00 17 00 06 00 17 741 | T 00 08 86 742 | R 00 00 00 17 743 | T 00 08 86 22 744 | R 00 00 00 17 745 | T 00 08 87 746 | R 00 00 00 17 747 | T 00 08 87 E4 F5 00 00 17 F5 00 00 18 748 | R 00 00 00 17 F1 21 05 00 05 F1 21 09 00 05 749 | T 00 08 8C 750 | R 00 00 00 17 751 | T 00 08 8C 90 00 00 E0 FB A3 E0 FC A3 E0 FD A9 752 | R 00 00 00 17 00 04 00 0B 753 | T 00 08 98 00 00 17 E5 00 00 18 C9 25 E0 C9 33 C9 754 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 755 | T 00 08 A1 25 E0 C9 33 FA E9 2B FB EA 3C FC 8B 82 756 | R 00 00 00 17 757 | T 00 08 AE 8C 83 8D F0 12 00 00 F5 00 00 16 90 758 | R 00 00 00 17 02 08 00 04 F1 21 0B 00 05 759 | T 00 08 B8 00 C1 F0 74 01 2B F8 E4 3C FE 8D 07 88 760 | R 00 00 00 17 00 03 00 0B 761 | T 00 08 C5 82 8E 83 8F F0 12 00 00 90 00 C2 F0 74 762 | R 00 00 00 17 02 09 00 04 00 0C 00 0B 763 | T 00 08 D2 02 2B F8 E4 3C FE 8D 07 88 82 8E 83 8F 764 | R 00 00 00 17 765 | T 00 08 DF F0 12 00 00 90 00 C3 F0 74 03 2B F8 E4 766 | R 00 00 00 17 02 05 00 04 00 08 00 0B 767 | T 00 08 EC 3C FE 8D 07 88 82 8E 83 8F F0 12 00 00 768 | R 00 00 00 17 02 0E 00 04 769 | T 00 08 F9 90 00 C4 F0 8B 00 00 19 8C 770 | R 00 00 00 17 00 04 00 0B F1 21 08 00 05 771 | T 00 09 00 00 00 1A 8D 00 00 1B 90 772 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 773 | T 00 09 04 00 00 74 0E F0 85 00 00 16 82 C0 02 C0 774 | R 00 00 00 17 02 03 00 00 F1 21 09 00 05 775 | T 00 09 0F 01 12 00 00 AF 82 D0 01 D0 02 90 00 C2 776 | R 00 00 00 17 02 05 00 03 00 0E 00 0B 777 | T 00 09 1C E0 FE 90 00 00 74 0B F0 8E 82 C0 07 C0 778 | R 00 00 00 17 02 06 00 00 779 | T 00 09 29 06 C0 02 C0 01 12 00 00 A8 82 D0 01 D0 780 | R 00 00 00 17 02 09 00 03 781 | T 00 09 36 02 D0 06 D0 07 E8 6F F5 00 00 16 90 782 | R 00 00 00 17 F1 21 0B 00 05 783 | T 00 09 40 00 C3 E0 F8 90 00 00 74 0D F0 88 82 C0 784 | R 00 00 00 17 00 03 00 0B 02 08 00 00 785 | T 00 09 4D 06 C0 02 C0 01 C0 00 12 00 00 AF 82 D0 786 | R 00 00 00 17 02 0B 00 03 787 | T 00 09 5A 00 D0 01 D0 02 D0 06 EF 62 00 00 16 90 788 | R 00 00 00 17 F1 21 0C 00 05 789 | T 00 09 65 00 C4 E0 FF 90 00 00 74 09 F0 8F 82 C0 790 | R 00 00 00 17 00 03 00 0B 02 08 00 00 791 | T 00 09 72 07 C0 06 C0 02 C0 01 C0 00 12 00 00 AD 792 | R 00 00 00 17 02 0D 00 03 793 | T 00 09 7F 82 D0 00 D0 01 D0 02 E5 00 00 16 62 05 794 | R 00 00 00 17 F1 21 0B 00 05 795 | T 00 09 8A 85 00 00 19 82 85 00 00 1A 83 85 796 | R 00 00 00 17 F1 21 04 00 05 F1 21 09 00 05 797 | T 00 09 91 00 00 1B F0 ED 12 00 00 90 798 | R 00 00 00 17 F1 21 03 00 05 02 09 00 01 799 | T 00 09 98 00 00 E0 FB A3 E0 FC A3 E0 FD E9 2B FB 800 | R 00 00 00 17 00 03 00 0B 801 | T 00 09 A5 EA 3C FC 74 01 2B F5 00 00 19 E4 3C F5 802 | R 00 00 00 17 F1 21 0A 00 05 803 | T 00 09 B0 00 00 1A 8D 00 00 1B 90 804 | R 00 00 00 17 F1 21 03 00 05 F1 21 07 00 05 805 | T 00 09 B4 00 C1 E0 F5 00 00 16 90 806 | R 00 00 00 17 00 03 00 0B F1 21 07 00 05 807 | T 00 09 BA 00 00 74 09 F0 85 00 00 16 82 C0 02 C0 808 | R 00 00 00 17 02 03 00 00 F1 21 09 00 05 809 | T 00 09 C5 01 C0 00 12 00 00 AC 82 D0 00 D0 01 D0 810 | R 00 00 00 17 02 07 00 03 811 | T 00 09 D2 02 D0 06 90 00 00 74 0E F0 8E 82 C0 06 812 | R 00 00 00 17 02 07 00 00 813 | T 00 09 DF C0 04 C0 02 C0 01 C0 00 12 00 00 AB 82 814 | R 00 00 00 17 02 0C 00 03 815 | T 00 09 EC D0 00 D0 01 D0 02 D0 04 EB 62 04 90 816 | R 00 00 00 17 817 | T 00 09 F8 00 00 74 0B F0 88 82 C0 04 C0 02 C0 01 818 | R 00 00 00 17 02 03 00 00 819 | T 00 0A 05 C0 00 12 00 00 AB 82 D0 00 D0 01 D0 02 820 | R 00 00 00 17 02 06 00 03 821 | T 00 0A 12 D0 04 D0 06 D0 07 EB 62 04 90 00 00 74 822 | R 00 00 00 17 02 0D 00 00 823 | T 00 0A 1F 0D F0 8F 82 C0 07 C0 06 C0 04 C0 02 C0 824 | R 00 00 00 17 825 | T 00 0A 2C 01 C0 00 12 00 00 AB 82 D0 00 D0 01 D0 826 | R 00 00 00 17 02 07 00 03 827 | T 00 0A 39 02 D0 04 EB 62 04 85 00 00 19 82 85 828 | R 00 00 00 17 F1 21 0A 00 05 829 | T 00 0A 43 00 00 1A 83 85 00 00 1B F0 EC 12 830 | R 00 00 00 17 F1 21 03 00 05 F1 21 08 00 05 831 | T 00 0A 4A 00 00 90 00 00 E0 FB A3 E0 FC A3 E0 FD 832 | R 00 00 00 17 02 03 00 01 00 06 00 0B 833 | T 00 0A 57 E9 2B FB EA 3C FC 74 02 2B F5 00 00 19 834 | R 00 00 00 17 F1 21 0D 00 05 835 | T 00 0A 62 E4 3C F5 00 00 1A 8D 00 00 1B 90 836 | R 00 00 00 17 F1 21 06 00 05 F1 21 0A 00 05 837 | T 00 0A 69 00 00 74 0D F0 85 00 00 16 82 C0 02 C0 838 | R 00 00 00 17 02 03 00 00 F1 21 09 00 05 839 | T 00 0A 74 01 C0 00 12 00 00 AD 82 D0 00 D0 01 D0 840 | R 00 00 00 17 02 07 00 03 841 | T 00 0A 81 02 D0 06 90 00 00 74 09 F0 8E 82 C0 06 842 | R 00 00 00 17 02 07 00 00 843 | T 00 0A 8E C0 05 C0 02 C0 01 C0 00 12 00 00 AC 82 844 | R 00 00 00 17 02 0C 00 03 845 | T 00 0A 9B D0 00 D0 01 D0 02 D0 05 EC 62 05 90 846 | R 00 00 00 17 847 | T 00 0A A7 00 00 74 0E F0 88 82 C0 05 C0 02 C0 01 848 | R 00 00 00 17 02 03 00 00 849 | T 00 0A B4 C0 00 12 00 00 AC 82 D0 00 D0 01 D0 02 850 | R 00 00 00 17 02 06 00 03 851 | T 00 0A C1 D0 05 D0 06 D0 07 EC 62 05 90 00 00 74 852 | R 00 00 00 17 02 0D 00 00 853 | T 00 0A CE 0B F0 8F 82 C0 07 C0 06 C0 05 C0 02 C0 854 | R 00 00 00 17 855 | T 00 0A DB 01 C0 00 12 00 00 AC 82 D0 00 D0 01 D0 856 | R 00 00 00 17 02 07 00 03 857 | T 00 0A E8 02 D0 05 EC 62 05 85 00 00 19 82 85 858 | R 00 00 00 17 F1 21 0A 00 05 859 | T 00 0A F2 00 00 1A 83 85 00 00 1B F0 ED 12 860 | R 00 00 00 17 F1 21 03 00 05 F1 21 08 00 05 861 | T 00 0A F9 00 00 90 00 00 E0 FB A3 E0 FC A3 E0 FD 862 | R 00 00 00 17 02 03 00 01 00 06 00 0B 863 | T 00 0B 06 E9 2B FB EA 3C FC 74 03 2B FB E4 3C FC 864 | R 00 00 00 17 865 | T 00 0B 13 90 00 00 74 0B F0 85 00 00 16 82 C0 05 866 | R 00 00 00 17 02 04 00 00 F1 21 0A 00 05 867 | T 00 0B 1E C0 04 C0 03 C0 00 12 00 00 AA 82 D0 00 868 | R 00 00 00 17 02 0A 00 03 869 | T 00 0B 2B D0 03 D0 04 D0 05 D0 06 90 00 00 74 0D 870 | R 00 00 00 17 02 0C 00 00 871 | T 00 0B 38 F0 8E 82 C0 05 C0 04 C0 03 C0 02 C0 00 872 | R 00 00 00 17 873 | T 00 0B 45 12 00 00 AE 82 D0 00 D0 02 EE 62 02 90 874 | R 00 00 00 17 02 04 00 03 875 | T 00 0B 52 00 00 74 09 F0 88 82 C0 02 12 00 00 AE 876 | R 00 00 00 17 02 03 00 00 02 0D 00 03 877 | T 00 0B 5F 82 D0 02 D0 03 D0 04 D0 05 D0 07 EE 62 878 | R 00 00 00 17 879 | T 00 0B 6C 02 90 00 00 74 0E F0 8F 82 C0 05 C0 04 880 | R 00 00 00 17 02 05 00 00 881 | T 00 0B 79 C0 03 C0 02 12 00 00 AF 82 D0 02 D0 03 882 | R 00 00 00 17 02 08 00 03 883 | T 00 0B 86 D0 04 D0 05 EF 62 02 8B 82 8C 83 8D F0 884 | R 00 00 00 17 885 | T 00 0B 93 EA 12 00 00 05 00 00 17 E4 B5 886 | R 00 00 00 17 02 05 00 01 F1 21 08 00 05 887 | T 00 0B 9B 00 00 17 02 05 00 00 18 888 | R 00 00 00 17 F1 21 03 00 05 F1 21 08 00 05 889 | T 00 0B 9F 890 | R 00 00 00 17 891 | T 00 0B 9F C3 E5 00 00 17 94 04 E5 00 00 18 64 80 892 | R 00 00 00 17 F1 21 05 00 05 F1 21 0B 00 05 893 | T 00 0B A8 94 80 50 03 02 08 8C 894 | R 00 00 00 17 00 08 00 17 895 | T 00 0B AF 896 | R 00 00 00 17 897 | T 00 0B AF 22 898 | R 00 00 00 17 899 | T 00 0B B0 900 | R 00 00 00 17 901 | T 00 0B B0 7F 00 902 | R 00 00 00 17 903 | T 00 0B B2 904 | R 00 00 00 17 905 | T 00 0B B2 8F 06 7D 00 906 | R 00 00 00 17 907 | T 00 0B B6 908 | R 00 00 00 17 909 | T 00 0B B6 90 00 00 E0 FA A3 E0 FB A3 E0 FC ED 2D 910 | R 00 00 00 17 00 04 00 0B 911 | T 00 0B C3 25 E0 2A FA E4 3B FB EE 2A FA E4 3B FB 912 | R 00 00 00 17 913 | T 00 0B D0 8A 82 8B 83 8C F0 12 00 00 F5 82 C0 06 914 | R 00 00 00 17 02 0A 00 04 915 | T 00 0B DD C0 05 C0 04 C0 03 C0 02 12 00 0E A9 82 916 | R 00 00 00 17 00 0C 00 17 917 | T 00 0B EA D0 02 D0 03 D0 04 D0 05 D0 06 8A 82 8B 918 | R 00 00 00 17 919 | T 00 0B F7 83 8C F0 E9 12 00 00 0D BD 04 00 920 | R 00 00 00 17 02 08 00 01 921 | T 00 0C 02 922 | R 00 00 00 17 923 | T 00 0C 02 40 B2 EE 04 FF BF 04 00 924 | R 00 00 00 17 925 | T 00 0C 0A 926 | R 00 00 00 17 927 | T 00 0C 0A 40 A6 22 928 | R 00 00 00 17 929 | T 00 0C 0D 930 | R 00 00 00 17 931 | T 00 0C 0D 90 00 00 E0 FD A3 E0 FE A3 E0 FF 74 0D 932 | R 00 00 00 17 00 04 00 0B 933 | T 00 0C 1A 2D FA E4 3E FB 8F 04 8A 82 8B 83 8C F0 934 | R 00 00 00 17 935 | T 00 0C 27 12 00 00 F9 90 00 C5 F0 74 09 2D FD E4 936 | R 00 00 00 17 02 04 00 04 00 08 00 0B 937 | T 00 0C 34 3E FE 8D 82 8E 83 8F F0 12 00 00 8A 82 938 | R 00 00 00 17 02 0C 00 04 939 | T 00 0C 41 8B 83 8C F0 12 00 00 90 00 00 E0 FD A3 940 | R 00 00 00 17 02 08 00 01 00 0B 00 0B 941 | T 00 0C 4E E0 FE A3 E0 FF 74 09 2D FA E4 3E FB 8F 942 | R 00 00 00 17 943 | T 00 0C 5B 04 74 05 2D FD E4 3E FE 8D 82 8E 83 8F 944 | R 00 00 00 17 945 | T 00 0C 68 F0 12 00 00 8A 82 8B 83 8C F0 12 00 00 946 | R 00 00 00 17 02 05 00 04 02 0E 00 01 947 | T 00 0C 75 90 00 00 E0 FD A3 E0 FE A3 E0 FF 74 05 948 | R 00 00 00 17 00 04 00 0B 949 | T 00 0C 82 2D FA E4 3E FB 8F 04 0D BD 00 01 0E 950 | R 00 00 00 17 951 | T 00 0C 8E 952 | R 00 00 00 17 953 | T 00 0C 8E 8D 82 8E 83 8F F0 12 00 00 8A 82 8B 83 954 | R 00 00 00 17 02 0A 00 04 955 | T 00 0C 9B 8C F0 12 00 00 90 00 00 E0 FD A3 E0 FE 956 | R 00 00 00 17 02 06 00 01 00 09 00 0B 957 | T 00 0C A8 A3 E0 FF 0D BD 00 01 0E 958 | R 00 00 00 17 959 | T 00 0C B0 960 | R 00 00 00 17 961 | T 00 0C B0 90 00 C5 E0 8D 82 8E 83 8F F0 12 00 00 962 | R 00 00 00 17 00 04 00 0B 02 0E 00 01 963 | T 00 0C BD 90 00 00 E0 FD A3 E0 FE A3 E0 FF 74 02 964 | R 00 00 00 17 00 04 00 0B 965 | T 00 0C CA 2D FA E4 3E FB 8F 04 8A 82 8B 83 8C F0 966 | R 00 00 00 17 967 | T 00 0C D7 12 00 00 90 00 C5 F0 74 0A 2D FD E4 3E 968 | R 00 00 00 17 02 04 00 04 00 07 00 0B 969 | T 00 0C E4 FE 8D 82 8E 83 8F F0 12 00 00 8A 82 8B 970 | R 00 00 00 17 02 0B 00 04 971 | T 00 0C F1 83 8C F0 12 00 00 90 00 00 E0 FD A3 E0 972 | R 00 00 00 17 02 07 00 01 00 0A 00 0B 973 | T 00 0C FE FE A3 E0 FF 74 0A 2D FD E4 3E FE 90 974 | R 00 00 00 17 975 | T 00 0D 0A 00 C5 E0 8D 82 8E 83 8F F0 12 00 00 90 976 | R 00 00 00 17 00 03 00 0B 02 0D 00 01 977 | T 00 0D 17 00 00 E0 FD A3 E0 FE A3 E0 FF 74 06 2D 978 | R 00 00 00 17 00 03 00 0B 979 | T 00 0D 24 FA E4 3E FB 8F 04 8A 82 8B 83 8C F0 12 980 | R 00 00 00 17 981 | T 00 0D 31 00 00 90 00 C5 F0 74 0E 2D FD E4 3E FE 982 | R 00 00 00 17 02 03 00 04 00 06 00 0B 983 | T 00 0D 3E 8D 82 8E 83 8F F0 12 00 00 8A 82 8B 83 984 | R 00 00 00 17 02 0A 00 04 985 | T 00 0D 4B 8C F0 12 00 00 90 00 00 E0 FD A3 E0 FE 986 | R 00 00 00 17 02 06 00 01 00 09 00 0B 987 | T 00 0D 58 A3 E0 FF 74 0E 2D FD E4 3E FE 90 00 C5 988 | R 00 00 00 17 00 0E 00 0B 989 | T 00 0D 65 E0 8D 82 8E 83 8F F0 12 00 00 90 00 00 990 | R 00 00 00 17 02 0B 00 01 00 0E 00 0B 991 | T 00 0D 72 E0 FD A3 E0 FE A3 E0 FF 74 03 2D FA E4 992 | R 00 00 00 17 993 | T 00 0D 7F 3E FB 8F 04 8A 82 8B 83 8C F0 12 00 00 994 | R 00 00 00 17 02 0E 00 04 995 | T 00 0D 8C 90 00 C5 F0 74 07 2D FD E4 3E FE 8D 82 996 | R 00 00 00 17 00 04 00 0B 997 | T 00 0D 99 8E 83 8F F0 12 00 00 8A 82 8B 83 8C F0 998 | R 00 00 00 17 02 08 00 04 999 | T 00 0D A6 12 00 00 90 00 00 E0 FD A3 E0 FE A3 E0 1000 | R 00 00 00 17 02 04 00 01 00 07 00 0B 1001 | T 00 0D B3 FF 74 07 2D FA E4 3E FB 8F 04 74 0B 2D 1002 | R 00 00 00 17 1003 | T 00 0D C0 FD E4 3E FE 8D 82 8E 83 8F F0 12 00 00 1004 | R 00 00 00 17 02 0E 00 04 1005 | T 00 0D CD 8A 82 8B 83 8C F0 12 00 00 90 00 00 E0 1006 | R 00 00 00 17 02 0A 00 01 00 0D 00 0B 1007 | T 00 0D DA FD A3 E0 FE A3 E0 FF 74 0B 2D FA E4 3E 1008 | R 00 00 00 17 1009 | T 00 0D E7 FB 8F 04 74 0F 2D FD E4 3E FE 8D 82 8E 1010 | R 00 00 00 17 1011 | T 00 0D F4 83 8F F0 12 00 00 8A 82 8B 83 8C F0 12 1012 | R 00 00 00 17 02 07 00 04 1013 | T 00 0E 01 00 00 90 00 00 E0 FD A3 E0 FE A3 E0 FF 1014 | R 00 00 00 17 02 03 00 01 00 06 00 0B 1015 | T 00 0E 0E 74 0F 2D FD E4 3E FE 90 00 C5 E0 8D 82 1016 | R 00 00 00 17 00 0B 00 0B 1017 | T 00 0E 1B 8E 83 8F F0 02 00 00 1018 | R 00 00 00 17 02 08 00 01 1019 | T 00 0E 22 1020 | R 00 00 00 17 1021 | T 00 0E 22 75 82 00 12 03 6D 7F 01 1022 | R 00 00 00 17 00 07 00 17 1023 | T 00 0E 2A 1024 | R 00 00 00 17 1025 | T 00 0E 2A C0 07 12 03 D7 12 04 34 12 1026 | R 00 00 00 17 00 06 00 17 00 09 00 17 1027 | T 00 0E 33 06 66 D0 07 8F 82 C0 07 12 03 6D D0 07 1028 | R 00 00 00 17 00 03 00 17 00 0C 00 17 1029 | T 00 0E 40 0F BF 0A 00 1030 | R 00 00 00 17 1031 | T 00 0E 44 1032 | R 00 00 00 17 1033 | T 00 0E 44 40 E4 12 03 D7 12 04 34 75 82 0A 02 1034 | R 00 00 00 17 00 06 00 17 00 09 00 17 1035 | T 00 0E 50 03 6D 1036 | R 00 00 00 17 00 03 00 17 1037 | T 00 0E 52 1038 | R 00 00 00 17 1039 | T 00 0E 52 75 82 0A 12 03 6D 7F 09 1040 | R 00 00 00 17 00 07 00 17 1041 | T 00 0E 5A 1042 | R 00 00 00 17 1043 | T 00 0E 5A C0 07 12 0C 0D 12 0B B0 D0 07 8F 82 C0 1044 | R 00 00 00 17 00 06 00 17 00 09 00 17 1045 | T 00 0E 67 07 12 03 6D 12 08 87 D0 07 DF E8 12 1046 | R 00 00 00 17 00 05 00 17 00 08 00 17 1047 | T 00 0E 73 0C 0D 12 0B B0 75 82 00 02 1048 | R 00 00 00 17 00 03 00 17 00 06 00 17 1049 | T 00 0E 7C 03 6D 1050 | R 00 00 00 17 00 03 00 17 1051 | T 00 0E 7E 1052 | R 00 00 00 17 1053 | T 00 0E 7E AF F0 AE 83 E5 82 90 00 C9 F0 EE A3 F0 1054 | R 00 00 00 17 00 0A 00 0B 1055 | T 00 0E 8B EF A3 F0 90 00 C9 E0 FD A3 E0 FE A3 E0 1056 | R 00 00 00 17 00 07 00 0B 1057 | T 00 0E 98 FF 90 00 C6 E0 F5 00 00 00 A3 E0 F5 1058 | R 00 00 00 17 00 05 00 0B F1 21 09 00 06 1059 | T 00 0E A2 00 00 01 A3 E0 F5 00 00 02 79 00 1060 | R 00 00 00 17 F1 21 03 00 06 F1 21 09 00 06 1061 | T 00 0E A9 1062 | R 00 00 00 17 1063 | T 00 0E A9 E9 2D F8 E4 3E FB 8F 04 C0 05 C0 06 C0 1064 | R 00 00 00 17 1065 | T 00 0E B6 07 E9 25 00 00 00 FA E4 35 00 00 01 FE 1066 | R 00 00 00 17 F1 21 06 00 06 F1 21 0C 00 06 1067 | T 00 0E BF AF 00 00 02 8A 82 8E 83 8F F0 12 00 00 1068 | R 00 00 00 17 F1 21 04 00 06 02 0E 00 04 1069 | T 00 0E CA FA 88 82 8B 83 8C F0 12 00 00 09 B9 10 1070 | R 00 00 00 17 02 0B 00 01 1071 | T 00 0E D7 00 1072 | R 00 00 00 17 1073 | T 00 0E D8 1074 | R 00 00 00 17 1075 | T 00 0E D8 D0 07 D0 06 D0 05 40 C9 22 1076 | R 00 00 00 17 1077 | T 00 0E E1 1078 | R 00 00 00 17 1079 | T 00 0E E1 AF F0 AE 83 E5 82 90 00 D2 F0 EE A3 F0 1080 | R 00 00 00 17 00 0A 00 0B 1081 | T 00 0E EE EF A3 F0 90 00 CF E0 FD A3 E0 FE A3 E0 1082 | R 00 00 00 17 00 07 00 0B 1083 | T 00 0E FB FF 90 00 D2 E0 FA A3 E0 FB A3 E0 FC 90 1084 | R 00 00 00 17 00 05 00 0B 1085 | T 00 0F 08 00 C6 EA F0 EB A3 F0 EC A3 F0 8D 82 8E 1086 | R 00 00 00 17 00 03 00 0B 1087 | T 00 0F 15 83 8F F0 12 0E 7E 90 00 CF E0 FD A3 E0 1088 | R 00 00 00 17 00 07 00 17 00 0A 00 0B 1089 | T 00 0F 22 FE A3 E0 FF 90 00 00 ED F0 EE A3 F0 EF 1090 | R 00 00 00 17 00 08 00 0B 1091 | T 00 0F 2F A3 F0 90 00 CC E0 FD A3 E0 FE A3 E0 FF 1092 | R 00 00 00 17 00 06 00 0B 1093 | T 00 0F 3C 90 00 B3 ED F0 EE A3 F0 EF A3 F0 12 1094 | R 00 00 00 17 00 04 00 0B 1095 | T 00 0F 48 00 1C 02 0E 22 1096 | R 00 00 00 17 00 03 00 17 00 06 00 17 1097 | T 00 0F 4D 1098 | R 00 00 00 17 1099 | T 00 0F 4D AF F0 AE 83 E5 82 90 00 DB F0 EE A3 F0 1100 | R 00 00 00 17 00 0A 00 0B 1101 | T 00 0F 5A EF A3 F0 90 00 D8 E0 FD A3 E0 FE A3 E0 1102 | R 00 00 00 17 00 07 00 0B 1103 | T 00 0F 67 FF 90 00 DB E0 FA A3 E0 FB A3 E0 FC 90 1104 | R 00 00 00 17 00 05 00 0B 1105 | T 00 0F 74 00 C6 EA F0 EB A3 F0 EC A3 F0 8D 82 8E 1106 | R 00 00 00 17 00 03 00 0B 1107 | T 00 0F 81 83 8F F0 12 0E 7E 90 00 D8 E0 FD A3 E0 1108 | R 00 00 00 17 00 07 00 17 00 0A 00 0B 1109 | T 00 0F 8E FE A3 E0 FF 90 00 00 ED F0 EE A3 F0 EF 1110 | R 00 00 00 17 00 08 00 0B 1111 | T 00 0F 9B A3 F0 90 00 D5 E0 FD A3 E0 FE A3 E0 FF 1112 | R 00 00 00 17 00 06 00 0B 1113 | T 00 0F A8 90 00 B3 ED F0 EE A3 F0 EF A3 F0 12 1114 | R 00 00 00 17 00 04 00 0B 1115 | T 00 0F B4 00 1C 02 0E 52 1116 | R 00 00 00 17 00 03 00 17 00 06 00 17 1117 | T 00 00 00 1118 | R 00 00 00 18 1119 | T 00 00 00 63 7C 77 7B F2 6B 6F C5 30 01 67 2B FE 1120 | R 00 00 00 18 1121 | T 00 00 0D D7 AB 76 CA 82 C9 7D FA 59 47 F0 AD D4 1122 | R 00 00 00 18 1123 | T 00 00 1A A2 AF 9C A4 72 C0 B7 FD 93 26 36 3F F7 1124 | R 00 00 00 18 1125 | T 00 00 27 CC 34 A5 E5 F1 71 D8 31 15 04 C7 23 C3 1126 | R 00 00 00 18 1127 | T 00 00 34 18 96 05 9A 07 12 80 E2 EB 27 B2 75 09 1128 | R 00 00 00 18 1129 | T 00 00 41 83 2C 1A 1B 6E 5A A0 52 3B D6 B3 29 E3 1130 | R 00 00 00 18 1131 | T 00 00 4E 2F 84 53 D1 00 ED 20 FC B1 5B 6A CB BE 1132 | R 00 00 00 18 1133 | T 00 00 5B 39 4A 4C 58 CF D0 EF AA FB 43 4D 33 85 1134 | R 00 00 00 18 1135 | T 00 00 68 45 F9 02 7F 50 3C 9F A8 51 A3 40 8F 92 1136 | R 00 00 00 18 1137 | T 00 00 75 9D 38 F5 BC B6 DA 21 10 FF F3 D2 CD 0C 1138 | R 00 00 00 18 1139 | T 00 00 82 13 EC 5F 97 44 17 C4 A7 7E 3D 64 5D 19 1140 | R 00 00 00 18 1141 | T 00 00 8F 73 60 81 4F DC 22 2A 90 88 46 EE B8 14 1142 | R 00 00 00 18 1143 | T 00 00 9C DE 5E 0B DB E0 32 3A 0A 49 06 24 5C C2 1144 | R 00 00 00 18 1145 | T 00 00 A9 D3 AC 62 91 95 E4 79 E7 C8 37 6D 8D D5 1146 | R 00 00 00 18 1147 | T 00 00 B6 4E A9 6C 56 F4 EA 65 7A AE 08 BA 78 25 1148 | R 00 00 00 18 1149 | T 00 00 C3 2E 1C A6 B4 C6 E8 DD 74 1F 4B BD 8B 8A 1150 | R 00 00 00 18 1151 | T 00 00 D0 70 3E B5 66 48 03 F6 0E 61 35 57 B9 86 1152 | R 00 00 00 18 1153 | T 00 00 DD C1 1D 9E E1 F8 98 11 69 D9 8E 94 9B 1E 1154 | R 00 00 00 18 1155 | T 00 00 EA 87 E9 CE 55 28 DF 8C A1 89 0D BF E6 42 1156 | R 00 00 00 18 1157 | T 00 00 F7 68 41 99 2D 0F B0 54 BB 16 1158 | R 00 00 00 18 1159 | T 00 01 00 1160 | R 00 00 00 18 1161 | T 00 01 00 52 09 6A D5 30 36 A5 38 BF 40 A3 9E 81 1162 | R 00 00 00 18 1163 | T 00 01 0D F3 D7 FB 7C E3 39 82 9B 2F FF 87 34 8E 1164 | R 00 00 00 18 1165 | T 00 01 1A 43 44 C4 DE E9 CB 54 7B 94 32 A6 C2 23 1166 | R 00 00 00 18 1167 | T 00 01 27 3D EE 4C 95 0B 42 FA C3 4E 08 2E A1 66 1168 | R 00 00 00 18 1169 | T 00 01 34 28 D9 24 B2 76 5B A2 49 6D 8B D1 25 72 1170 | R 00 00 00 18 1171 | T 00 01 41 F8 F6 64 86 68 98 16 D4 A4 5C CC 5D 65 1172 | R 00 00 00 18 1173 | T 00 01 4E B6 92 6C 70 48 50 FD ED B9 DA 5E 15 46 1174 | R 00 00 00 18 1175 | T 00 01 5B 57 A7 8D 9D 84 90 D8 AB 00 8C BC D3 0A 1176 | R 00 00 00 18 1177 | T 00 01 68 F7 E4 58 05 B8 B3 45 06 D0 2C 1E 8F CA 1178 | R 00 00 00 18 1179 | T 00 01 75 3F 0F 02 C1 AF BD 03 01 13 8A 6B 3A 91 1180 | R 00 00 00 18 1181 | T 00 01 82 11 41 4F 67 DC EA 97 F2 CF CE F0 B4 E6 1182 | R 00 00 00 18 1183 | T 00 01 8F 73 96 AC 74 22 E7 AD 35 85 E2 F9 37 E8 1184 | R 00 00 00 18 1185 | T 00 01 9C 1C 75 DF 6E 47 F1 1A 71 1D 29 C5 89 6F 1186 | R 00 00 00 18 1187 | T 00 01 A9 B7 62 0E AA 18 BE 1B FC 56 3E 4B C6 D2 1188 | R 00 00 00 18 1189 | T 00 01 B6 79 20 9A DB C0 FE 78 CD 5A F4 1F DD A8 1190 | R 00 00 00 18 1191 | T 00 01 C3 33 88 07 C7 31 B1 12 10 59 27 80 EC 5F 1192 | R 00 00 00 18 1193 | T 00 01 D0 60 51 7F A9 19 B5 4A 0D 2D E5 7A 9F 93 1194 | R 00 00 00 18 1195 | T 00 01 DD C9 9C EF A0 E0 3B 4D AE 2A F5 B0 C8 EB 1196 | R 00 00 00 18 1197 | T 00 01 EA BB 3C 83 53 99 61 17 2B 04 7E BA 77 D6 1198 | R 00 00 00 18 1199 | T 00 01 F7 26 E1 69 14 63 55 21 0C 7D 1200 | R 00 00 00 18 1201 | T 00 02 00 1202 | R 00 00 00 18 1203 | T 00 02 00 8D 01 02 04 08 10 20 40 80 1B 36 6C D8 1204 | R 00 00 00 18 1205 | T 00 02 0D AB 4D 9A 2F 5E BC 63 C6 97 35 6A D4 B3 1206 | R 00 00 00 18 1207 | T 00 02 1A 7D FA EF C5 91 39 72 E4 D3 BD 61 C2 9F 1208 | R 00 00 00 18 1209 | T 00 02 27 25 4A 94 33 66 CC 83 1D 3A 74 E8 CB 8D 1210 | R 00 00 00 18 1211 | T 00 02 34 01 02 04 08 10 20 40 80 1B 36 6C D8 AB 1212 | R 00 00 00 18 1213 | T 00 02 41 4D 9A 2F 5E BC 63 C6 97 35 6A D4 B3 7D 1214 | R 00 00 00 18 1215 | T 00 02 4E FA EF C5 91 39 72 E4 D3 BD 61 C2 9F 25 1216 | R 00 00 00 18 1217 | T 00 02 5B 4A 94 33 66 CC 83 1D 3A 74 E8 CB 8D 01 1218 | R 00 00 00 18 1219 | T 00 02 68 02 04 08 10 20 40 80 1B 36 6C D8 AB 4D 1220 | R 00 00 00 18 1221 | T 00 02 75 9A 2F 5E BC 63 C6 97 35 6A D4 B3 7D FA 1222 | R 00 00 00 18 1223 | T 00 02 82 EF C5 91 39 72 E4 D3 BD 61 C2 9F 25 4A 1224 | R 00 00 00 18 1225 | T 00 02 8F 94 33 66 CC 83 1D 3A 74 E8 CB 8D 01 02 1226 | R 00 00 00 18 1227 | T 00 02 9C 04 08 10 20 40 80 1B 36 6C D8 AB 4D 9A 1228 | R 00 00 00 18 1229 | T 00 02 A9 2F 5E BC 63 C6 97 35 6A D4 B3 7D FA EF 1230 | R 00 00 00 18 1231 | T 00 02 B6 C5 91 39 72 E4 D3 BD 61 C2 9F 25 4A 94 1232 | R 00 00 00 18 1233 | T 00 02 C3 33 66 CC 83 1D 3A 74 E8 CB 8D 01 02 04 1234 | R 00 00 00 18 1235 | T 00 02 D0 08 10 20 40 80 1B 36 6C D8 AB 4D 9A 2F 1236 | R 00 00 00 18 1237 | T 00 02 DD 5E BC 63 C6 97 35 6A D4 B3 7D FA EF C5 1238 | R 00 00 00 18 1239 | T 00 02 EA 91 39 72 E4 D3 BD 61 C2 9F 25 4A 94 33 1240 | R 00 00 00 18 1241 | T 00 02 F7 66 CC 83 1D 3A 74 E8 CB 1242 | R 00 00 00 18 1243 | 1244 | 1245 | 1246 | 1247 | 1248 | 1249 | 1250 | 1251 | --------------------------------------------------------------------------------