├── output ├── firmware40.elf ├── firmware41.elf └── firmware40.hex ├── measurements ├── test1a-0.png ├── test1b-0.png └── README.md ├── source ├── include │ ├── custom.h │ ├── clib.h │ ├── defs.h │ ├── cfg.h │ ├── types.h │ ├── utils.h │ ├── rpc.h │ ├── dcdc.h │ ├── debug.h │ ├── gpio.h │ ├── paddr.h │ ├── iomuxc.h │ ├── compile_time.h │ ├── glitch.h │ ├── uart.h │ ├── teensy.h │ ├── ccm.h │ └── teensy_pads.h ├── vector.s ├── custom.c ├── utils.c ├── boot.c ├── glitch.s ├── dcdc.c ├── main.c ├── boot_hdr.s ├── clib.c ├── boot.s ├── gpio.c ├── debug.c ├── iomux.c ├── uart.c ├── teensy.c ├── rp.c ├── ccm.c └── glitch.c ├── README.md ├── LICENSE ├── Makefile ├── linker.x └── teensy_rpc.py /output/firmware40.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKGleba/teensy4vfi/HEAD/output/firmware40.elf -------------------------------------------------------------------------------- /output/firmware41.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKGleba/teensy4vfi/HEAD/output/firmware41.elf -------------------------------------------------------------------------------- /measurements/test1a-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKGleba/teensy4vfi/HEAD/measurements/test1a-0.png -------------------------------------------------------------------------------- /measurements/test1b-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKGleba/teensy4vfi/HEAD/measurements/test1b-0.png -------------------------------------------------------------------------------- /source/include/custom.h: -------------------------------------------------------------------------------- 1 | #ifndef __CUSTOM_H__ 2 | #define __CUSTOM_H__ 3 | 4 | #include "types.h" 5 | 6 | int custom_main(int a0, int a1, int a2, void* ax); 7 | 8 | #endif -------------------------------------------------------------------------------- /source/vector.s: -------------------------------------------------------------------------------- 1 | # classic style exception vectors 2 | # TODO 3 | 4 | .syntax unified 5 | .thumb 6 | .cpu cortex-m7 7 | 8 | .section .text.vectors 9 | 10 | .global exv 11 | .global exha 12 | 13 | exv: 14 | ldr pc,reset_addr 15 | 16 | exha: 17 | reset_addr: 18 | .word init 19 | -------------------------------------------------------------------------------- /source/custom.c: -------------------------------------------------------------------------------- 1 | #include "include/types.h" 2 | #include "include/debug.h" 3 | #include "include/teensy.h" 4 | 5 | #include "include/custom.h" 6 | 7 | int custom_main(int a0, int a1, int a2, void* ax) { 8 | printf("custom func with args %X %X %X | %X\n", a0, a1, a2, ax); 9 | 10 | return 0; 11 | } -------------------------------------------------------------------------------- /source/utils.c: -------------------------------------------------------------------------------- 1 | #include "include/types.h" 2 | #include "include/compile_time.h" 3 | 4 | #include "include/utils.h" 5 | 6 | void delay(unsigned int n) { 7 | volatile unsigned int i, j; 8 | for (i = 0; i < n; i++) 9 | for (j = 0; j < 600; j++) 10 | ; 11 | } 12 | 13 | __attribute__((noinline)) 14 | uint32_t get_build_timestamp(void) { 15 | return (uint32_t)UNIX_TIMESTAMP; 16 | } -------------------------------------------------------------------------------- /source/include/clib.h: -------------------------------------------------------------------------------- 1 | #ifndef __CLIB_H__ 2 | #define __CLIB_H__ 3 | 4 | #include "types.h" 5 | 6 | void* memset(void* s, uint8_t c, uint32_t n); 7 | void* memset32(void* s, uint32_t c, uint32_t n); 8 | void* memset8(void* s, uint8_t c, uint32_t n); 9 | void* memcpy(void* dest, const void* src, uint32_t n); 10 | int memcmp(const void* s1, const void* s2, uint32_t n); 11 | uint32_t strlen(const char* str); 12 | 13 | #endif -------------------------------------------------------------------------------- /source/include/defs.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEFS_H__ 2 | #define __DEFS_H__ 3 | 4 | // hard definitions 5 | 6 | #include "types.h" 7 | #include "teensy.h" 8 | #include "ccm.h" 9 | 10 | //#define SILENT // suppress prints and uart init 11 | 12 | #ifndef SILENT 13 | #define DEBUG_UARTN 1 // default debug __teensy__ uartn 14 | #endif 15 | 16 | #define DEFAULT_CLOCKSPEED CCM_ARM_CLKF_FULL_SPEED 17 | 18 | #define RPC_WRITE_DELAY 0x100 // delay before replying to a RPC 19 | 20 | #endif -------------------------------------------------------------------------------- /source/include/cfg.h: -------------------------------------------------------------------------------- 1 | #ifndef __CFG_H__ 2 | #define __CFG_H__ 3 | 4 | #include "types.h" 5 | 6 | extern uint32_t cfg_prog_bss_start; 7 | extern uint32_t cfg_prog_bss_end; 8 | extern uint32_t cfg_prog_itcm_flash_start; 9 | extern uint32_t cfg_prog_itcm_flash_size; 10 | extern uint32_t cfg_prog_itcm_flash_end; 11 | extern uint32_t cfg_prog_dtcm_flash_start; 12 | extern uint32_t cfg_prog_dtcm_flash_size; 13 | extern uint32_t cfg_prog_dtcm_flash_end; 14 | extern uint32_t cfg_prog_sp_addr; 15 | 16 | 17 | #endif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # teensy4vfi 2 | Teensy 4.0 / 4.1 firmware for Voltage Fault Injection research 3 | 4 | ## note 5 | This project is in its very early stages, it also serves as a way for me to learn """white box""" SoC baremetal programming.
6 | Some code might make no sense and/or be overcomplicated, suggestions and non-C++ PRs are welcome. 7 | 8 | ## Known TODOs 9 | - Critical bug fixes 10 | - Docs, readme, measurements, etc 11 | - More glitch types 12 | 13 | ### Optional 14 | - Exceptions & Interrupts 15 | - Interrupt-based trigger (optional due to high jitter) 16 | - More RPC commands 17 | 18 | ## compiling & flashing 19 | This project does not have any external requirements, it can be compiled with the [Arm GNU Toolchain](https://developer.arm.com/Tools%20and%20Software/GNU%20Toolchain).
20 | The output *.hex* can be used with [teensy-loader](https://www.pjrc.com/teensy/loader_win10.html) to flash the flash (lul) 21 | -------------------------------------------------------------------------------- /source/include/types.h: -------------------------------------------------------------------------------- 1 | #ifndef __TYPES_H__ 2 | #define __TYPES_H__ 3 | 4 | typedef unsigned char uint8_t; ///< Unsigned 8-bit type 5 | typedef unsigned short int uint16_t; ///< Unsigned 16-bit type 6 | typedef unsigned int uint32_t; ///< Unsigned 32-bit type 7 | typedef unsigned long long uint64_t; ///< Unsigned 64-bit type 8 | 9 | typedef char int8_t; ///< signed 8-bit type 10 | typedef short int int16_t; ///< signed 16-bit type 11 | typedef int int32_t; ///< signed 32-bit type 12 | typedef long long int64_t; ///< signed 64-bit type 13 | 14 | // dont ask 15 | typedef int bool; 16 | #define true 1 17 | #define false 0 18 | 19 | #define NULL (void*)0 20 | 21 | typedef __builtin_va_list va_list; 22 | #define va_start(v,l) __builtin_va_start(v,l) 23 | #define va_end(v) __builtin_va_end(v) 24 | #define va_arg(v,l) __builtin_va_arg(v,l) 25 | #define va_copy(d,s) __builtin_va_copy(d,s) 26 | 27 | #endif -------------------------------------------------------------------------------- /source/boot.c: -------------------------------------------------------------------------------- 1 | #include "include/types.h" 2 | #include "include/paddr.h" 3 | #include "include/aips.h" 4 | #include "include/utils.h" 5 | #include "include/gpio.h" 6 | #include "include/teensy.h" 7 | 8 | /* 9 | maybe add some stage3/BS there? 10 | */ 11 | __attribute__((section(".boot.c"))) 12 | int c_BOOT(void) { // c extension for s_BOOT 13 | return 0; 14 | } 15 | 16 | /* 17 | As a bootfail indicator we will use the onboard orange led (PAD_GPIO_B0_03) 18 | if we failed soon enough, we will also get a blinking red bloader led as a bonus 19 | */ 20 | __attribute__((section(".boot.f"))) 21 | int c_BFAIL(void) { // c extension for s_BFAIL 22 | teensy_pad_logic_set_outdir_direct(TEENSY_PAD_ORANGE_LED); // GPIO2:GDIR set bit3 => set GPIO2::3 mode to output 23 | teensy_pad_logic_set_direct(TEENSY_PAD_ORANGE_LED); // GPIO2:DR_SET set bit3 => set GPIO2::3 24 | return -1; // no boot resuming 25 | } -------------------------------------------------------------------------------- /source/include/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTILS_H__ 2 | #define __UTILS_H__ 3 | 4 | // atrocious, but i love it 5 | #define p *(uint32_t*) 6 | #define vp *(volatile uint32_t*) 7 | 8 | // le typicals 9 | #define dmb() asm volatile("dmb\n\t" ::: "memory") 10 | #define dsb() asm volatile("dsb\n\t" ::: "memory") 11 | #define wfe() asm volatile("wfe\n\t") 12 | #define wfi() asm volatile("wfi\n\t") 13 | #define sev() asm volatile("sev\n\t") // not a multicore system so ig doesnt apply? 14 | 15 | #define BITF(n) (~(-1 << n)) 16 | #define BITN(n) (1 << (n)) 17 | #define BITNVAL(n, val) ((val) << (n)) 18 | #define BITNVALM(n, val, mask) (((val) & (mask)) << (n)) 19 | 20 | // funcs 21 | void delay(unsigned int n); 22 | 23 | // 3 instructions, 64bits total, consistent bp curve on real delay values, ignore the exp w 24 | #define delay_abs(delay_val_reg) asm("1:\nsubs %0, #1\nbne 1b\n" : : "r"(delay_val_reg)) 25 | 26 | // get compile timestamp 27 | __attribute__((noinline)) uint32_t get_build_timestamp(void); 28 | 29 | #endif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Sebastian Kubala 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /source/glitch.s: -------------------------------------------------------------------------------- 1 | # 2 | # glitch funcs 3 | # 4 | 5 | .syntax unified 6 | .thumb 7 | .cpu cortex-m7 8 | 9 | .text 10 | .section .text.glitch_funcs 11 | 12 | # 13 | # s_glitch 14 | # registers: 15 | # 16 | # r0-r2: gp 17 | # 18 | # r3: offset 19 | # r4: offset mult 20 | # r5: width 21 | # r6: driver mask 22 | # r7: driver SET reg 23 | # r8: driver CLR reg 24 | # 25 | # r9: trigger expected bitfield 26 | # r10: trigger reg mask 27 | # r11: trigger DATA reg 28 | # 29 | # r12: next glitch config 30 | # 31 | .global s_glitch 32 | .thumb_func 33 | s_glitch: 34 | push.w {r1-r12, lr} 35 | # preload vars & args 36 | 1: 37 | ldmia.w r0!, {r3-r12} 38 | 39 | # ready, wait for trigger 40 | 2: 41 | ldr.w r1,[r11] 42 | and.w r1,r1,r10 43 | cmp.w r1,r9 44 | bne.w 2b 45 | 46 | # wait [offset] * [offset_mult] 47 | 3: 48 | mov.w r2, r3 49 | 4: 50 | subs.w r2, #0x1 51 | bne.w 4b 52 | subs.w r4, #0x1 53 | bne.w 3b 54 | 55 | # drive 56 | str.w r6,[r7] 57 | 58 | # wait [width] 59 | 5: 60 | subs.w r5, #0x1 61 | bne.w 5b 62 | 63 | # stop 64 | str.w r6,[r8] 65 | 66 | # execute next if/in chain 67 | movs.w r0, r12 68 | bne.w 1b 69 | 70 | # bye 71 | pop.w {r1-r12, pc} 72 | -------------------------------------------------------------------------------- /source/dcdc.c: -------------------------------------------------------------------------------- 1 | #include "include/paddr.h" 2 | #include "include/aips.h" 3 | #include "include/utils.h" 4 | #include "include/debug.h" 5 | 6 | #include "include/dcdc.h" 7 | 8 | int dcdc_ctrl_vdd_soc(int mv, bool step, bool wait, bool onlyUp) { 9 | if (!mv) 10 | return DCDC_TRG_TO_VDD_SOC(dcdc.reg_3 & DCDC_REG3_BITMASK_TRG); 11 | 12 | int trg = DCDC_VDD_SOC_TO_TRG(mv); 13 | if (trg > DCDC_REG3_BITMASK_TRG) 14 | return -1; 15 | 16 | int dcdc_r3 = dcdc.reg_3; 17 | if ((dcdc_r3 & BITNVAL(DCDC_REG3_BITS_TRG, DCDC_REG3_BITMASK_TRG)) == BITNVAL(DCDC_REG3_BITS_TRG, trg)) 18 | return 0; 19 | 20 | if (onlyUp && ((dcdc_r3 & BITNVAL(DCDC_REG3_BITS_TRG, DCDC_REG3_BITMASK_TRG)) > BITNVAL(DCDC_REG3_BITS_TRG, trg))) 21 | return 0; 22 | 23 | dcdc_r3 &= ~(BITNVAL(DCDC_REG3_BITS_TRG, DCDC_REG3_BITMASK_TRG) | BITN(DCDC_REG3_BITS_DISABLE_STEP)); 24 | dcdc_r3 |= BITNVAL(DCDC_REG3_BITS_TRG, trg); 25 | if (!step) 26 | dcdc_r3 |= BITN(DCDC_REG3_BITS_DISABLE_STEP); 27 | 28 | printf("VDD_SOC %X => %X [%s]\n", dcdc_get_vdd_soc(), mv, (step) ? "STEP" : "JUMP"); 29 | dcdc.reg_3 = dcdc_r3; 30 | if (wait) 31 | while (!(dcdc.reg_0 & BITN(DCDC_REG0_BITS_STS_DC_OK))) {}; 32 | 33 | return DCDC_TRG_TO_VDD_SOC(dcdc.reg_3 & DCDC_REG3_BITMASK_TRG); 34 | } -------------------------------------------------------------------------------- /source/include/rpc.h: -------------------------------------------------------------------------------- 1 | #ifndef __RPC_H__ 2 | #define __RPC_H__ 3 | 4 | #include "types.h" 5 | 6 | #define RPC_MAGIC '@' 7 | #define RPC_WATERMARK "!PC_" 8 | 9 | enum RPC_COMMANDS { 10 | RPC_CMD_NOP, 11 | RPC_CMD_READ32, 12 | RPC_CMD_WRITE32, 13 | RPC_CMD_MEMSET, 14 | RPC_CMD_MEMCPY, 15 | RPC_CMD_SET_DELAY, 16 | RPC_CMD_STOP_RPC, 17 | RPC_CMD_HEXDUMP, 18 | RPC_CMD_MEMSET32, 19 | RPC_CMD_GLITCH_PREP_LL, 20 | RPC_CMD_GLITCH_ARM, 21 | RPC_CMD_GLITCH_PREP_CUSTOM, 22 | RPC_CMD_GLITCH_PREP_UART, 23 | RPC_CMD_SET_CLK, 24 | RPC_CMD_GLITCH_PREP_CUSTOM_CHAIN, 25 | RPC_CMD_GLITCH_PREP_NONE, 26 | RPC_CMD_CUSTOM, 27 | RPC_CMD_UART_INIT, 28 | RPC_CMD_PAD_CONFIGURE, 29 | RPC_CMD_PAD_CTRL_LOGIC, 30 | RPC_CMD_GLITCH_SET_CHAIN_MAX, 31 | RPC_CMD_GET_SP, 32 | RPC_CMD_GLITCH_LOOP 33 | }; 34 | 35 | enum RPC_CMD_PAD_CTRL_LOGIC_FUNCS { 36 | RPC_CMD_PAD_CTRL_LOGIC_CLEAR = 0, 37 | RPC_CMD_PAD_CTRL_LOGIC_SET, 38 | RPC_CMD_PAD_CTRL_LOGIC_TOGGLE, 39 | RPC_CMD_PAD_CTRL_LOGIC_MODE, 40 | RPC_CMD_PAD_CTRL_LOGIC_READ, 41 | RPC_CMD_PAD_CTRL_LOGIC_TIGHTNESS 42 | }; 43 | 44 | struct _rpc_cmd_s { 45 | uint8_t magic; 46 | uint8_t id; 47 | uint8_t data_size; 48 | uint8_t hash; 49 | } __attribute__((packed)); 50 | typedef struct _rpc_cmd_s rpc_cmd_s; 51 | 52 | void rpc_loop(void); 53 | 54 | #endif -------------------------------------------------------------------------------- /source/main.c: -------------------------------------------------------------------------------- 1 | #include "include/types.h" 2 | #include "include/utils.h" 3 | #include "include/teensy.h" 4 | #include "include/debug.h" 5 | #include "include/ccm.h" 6 | #include "include/rpc.h" 7 | 8 | int main() { 9 | // default 10 | rpc_loop(); 11 | 12 | // infiniblink 13 | teensy_set_pad_ctl(TEENSY_PAD_ORANGE_LED, -1, TEENSY_PAD_MODE_GPIO, true); 14 | teensy_pad_logic_mode(TEENSY_PAD_ORANGE_LED, true, true); 15 | while (true) { 16 | teensy_pad_logic_set(TEENSY_PAD_ORANGE_LED, true); 17 | delay(0x10000); 18 | teensy_pad_logic_clear(TEENSY_PAD_ORANGE_LED, true); 19 | delay(0x10000); 20 | } 21 | } 22 | 23 | void init() { 24 | #ifndef SILENT 25 | ccm_set_uart_clk(true, 0, true); // derive uart clock from 24mhz osc_clk, don't divide 26 | if (teensy_uart_init( 27 | DEBUG_UARTN, 28 | UART_BAUD_115200, 29 | BITN(UART_INIT_BITS_RX_EN) | BITN(UART_INIT_BITS_RX_FIFO_EN) | BITN(UART_INIT_BITS_TX_EN) | BITN(UART_INIT_BITS_TX_FIFO_EN), 30 | true 31 | ) >= 0) { // init default debug uart 32 | g_debug_uartn = DEBUG_UARTN; // print to default debug uart 33 | printf("\ninit teensy4vfi [%X], me @ %X\n", get_build_timestamp(), init); 34 | } 35 | #endif 36 | 37 | ccm_set_core_clkf(DEFAULT_CLOCKSPEED, 0); // ARM & TCstuff clocks 38 | 39 | main(); 40 | 41 | while (1) 42 | wfi(); 43 | } -------------------------------------------------------------------------------- /source/boot_hdr.s: -------------------------------------------------------------------------------- 1 | # 2 | # Based on info from IMXRT1060 ref man 3 | # and teensy4 flash image 4 | # 5 | 6 | .syntax unified 7 | .thumb 8 | .cpu cortex-m7 9 | 10 | .section .boot.header 11 | 12 | flashcfg: # size is 0x200, FlexSPI config block 13 | .word 0x42464346 14 | .word 0x56010000 15 | .word 0 16 | .byte 1 17 | .byte 3 18 | .byte 3 19 | .byte 0 20 | .rept 52 21 | .byte 0 22 | .endr 23 | .byte 1 24 | .byte 4 25 | .byte 8 26 | .byte 0 27 | .word 0, 0 28 | .word cfg_sflashA1Size, 0 29 | .word 0, 0 30 | .word 0, 0, 0, 0 31 | .word 0 32 | .word 0 33 | .word 0 34 | .word 0 35 | .word 0x0A1804EB, 0x26043206, 0, 0, 0x24040405, 0, 0, 0 36 | .word 0, 0, 0, 0, 0x00000406, 0, 0, 0 37 | .word 0, 0, 0, 0, 0x08180420, 0, 0, 0 38 | .word 0, 0, 0, 0, 0, 0, 0, 0 39 | .word 0x081804D8, 0, 0, 0, 0x08180402, 0x00002004, 0, 0 40 | .word 0, 0, 0, 0, 0x00000460, 0, 0, 0 41 | .rept 32 42 | .word 0 43 | .endr 44 | .word 256 45 | .word 4096 46 | .word 1 47 | .word 0 48 | .word 0x00010000 49 | .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 50 | 51 | prognfo: 52 | .word 0x60000000, cfg_prog_size, 0 53 | 54 | .section .boot.some_other_header 55 | .global some_other_header 56 | some_other_header: 57 | .word 0x402000D1 58 | .word s_BOOT+1 59 | .word 0, 0 60 | .word prognfo 61 | .word some_other_header 62 | .word 0, 0 63 | -------------------------------------------------------------------------------- /source/include/dcdc.h: -------------------------------------------------------------------------------- 1 | #ifndef __DCDC_H__ 2 | #define __DCDC_H__ 3 | 4 | #include "aips.h" 5 | 6 | #define dcdc ((aips_1_s*)AIPS_1_OFFSET)->dcdc 7 | 8 | #define DCDC_VDD_SOC_TO_TRG(mv) (((mv) - 800) / 25) // 25mV increments from 0.8v 9 | #define DCDC_TRG_TO_VDD_SOC(trg) (((trg) * 25) + 800) // 25mV increments from 0.8v 10 | 11 | enum DCDC_REG3_BITS { 12 | DCDC_REG3_BITS_TRG = 0, 13 | DCDC_REG3_BITS_TARGET_LP = 8, 14 | DCDC_REG3_BITS_MINPWR_DC_HALFCLK = 24, 15 | DCDC_REG3_BITS_DISABLE_STEP = 30 16 | }; 17 | 18 | #define DCDC_REG3_BITMASK_TRG 0b11111 19 | 20 | enum DCDC_REG0_BITS { 21 | DCDC_REG0_BITS_PWD_ZCD = 0, 22 | DCDC_REG0_BITS_DISABLE_AUTO_CLK_SWITCH, 23 | DCDC_REG0_BITS_SEL_CLK, 24 | DCDC_REG0_BITS_PWD_OSC_INT, 25 | DCDC_REG0_BITS_PWD_CUR_SNS_CMP, 26 | DCDC_REG0_BITS_CUR_SNS_THRSH, 27 | DCDC_REG0_BITS_PWD_OVERCUR_DET = 8, 28 | DCDC_REG0_BITS_OVERCUR_TRIG_ADJ, 29 | DCDC_REG0_BITS_PWD_CMP_BATT_DET = 11, 30 | DCDC_REG0_BITS_EN_LP_OVERLOAD_SNS = 16, 31 | DCDC_REG0_BITS_PWD_HI_VOLT_DET, 32 | DCDC_REG0_BITS_LP_OVERLOAD_THRSH, 33 | DCDC_REG0_BITS_LP_OVERLOAD_FREQ_SEL = 20, 34 | DCDC_REG0_BITS_LP_HIGH_HYS, 35 | DCDC_REG0_BITS_PWD_CMP_OFFSET = 26, 36 | DCDC_REG0_BITS_XTALOK_DISABLE, 37 | DCDC_REG0_BITS_CURRENT_ALERT_RESET, 38 | DCDC_REG0_BITS_XTAL_24M_OK, 39 | DCDC_REG0_BITS_STS_DC_OK = 31 40 | }; 41 | 42 | int dcdc_ctrl_vdd_soc(int mv, bool step, bool wait, bool onlyUp); 43 | #define dcdc_get_vdd_soc() (DCDC_TRG_TO_VDD_SOC((dcdc.reg_3 >> DCDC_REG3_BITS_TRG) & DCDC_REG3_BITMASK_TRG)) 44 | 45 | #endif -------------------------------------------------------------------------------- /source/include/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEBUG_H__ 2 | #define __DEBUG_H__ 3 | 4 | #include "types.h" 5 | #include "defs.h" 6 | #include "teensy.h" 7 | 8 | #ifdef SILENT 9 | 10 | #define print(str) 11 | #define printf 12 | #define printn(str, n) 13 | #define printx(x) 14 | #define printp(x) 15 | #define hexdump(addr, length, show_addr) 16 | 17 | #else 18 | 19 | #define print(str) teensy_uart_print(g_debug_uartn, (char *)(str)) 20 | #define printf debug_printFormat 21 | #define printn(str, n) teensy_uart_printn(g_debug_uartn, (char *)(str), n) 22 | #define printx(x) debug_printU32((uint32_t)(x), true) 23 | #define printp(x) printf("%X: %X\n", (uint32_t)(x), vp (x)) 24 | #define hexdump(addr, length, show_addr) debug_printRange(addr, length, (int)show_addr) 25 | 26 | // get a "\r\n" terminated string from debug uart 27 | #define scans(string_buf, max_len) teensy_uart_scanns(g_debug_uartn, (char*)string_buf, max_len, 0) 28 | #define scans_timeout(string_buf, max_len, timeout) teensy_uart_scanns(g_debug_uartn, (char*)string_buf, max_len, timeout) 29 | 30 | // get [count] bytes from debug uart 31 | #define scanb(bytes_buf, count) teensy_uart_scann(g_debug_uartn, (uint8_t*)bytes_buf, count, 0) 32 | #define scanb_timeout(bytes_buf, count, timeout) teensy_uart_scann(g_debug_uartn, (uint8_t*)bytes_buf, count, timeout) 33 | 34 | #define rxflush() teensy_uart_rxfifo_flush(g_debug_uartn) 35 | 36 | #endif 37 | 38 | extern volatile int g_debug_uartn; 39 | void debug_printU32(uint32_t value, int add_nl); 40 | void debug_printFormat(char* base, ...); 41 | void debug_printRange(uint32_t addr, uint32_t size, int show_addr); 42 | 43 | #endif -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SRCDIR = source 2 | SRCS = $(wildcard source/*.c) 3 | OBJS = $(SRCS:.c=.o) source/boot_hdr.ao source/boot.ao source/vector.ao source/glitch.ao 4 | OBJS41 = $(SRCS:.c=.o41) source/boot_hdr.ao41 source/boot.ao41 source/vector.ao41 source/glitch.ao41 5 | 6 | PREFIX = arm-none-eabi 7 | CC = $(PREFIX)-gcc 8 | OBJCOPY = $(PREFIX)-objcopy 9 | CFLAGS = -mcpu=cortex-m7 -mthumb -Os -Wall -fno-builtin 10 | LDFLAGS = -T linker.x -nostartfiles -nostdlib 11 | ASFLAGS = 12 | 13 | .PHONY: teensy4 teensy41 all clean 14 | 15 | all: output/firmware40.hex output/firmware41.hex 16 | teensy4: output/firmware40.hex 17 | teensy41: output/firmware41.hex 18 | 19 | output/firmware40.hex: fw40.hex 20 | -rm source/*.o source/*.ao 21 | -rm output/firmware40.hex output/firmware40.elf 22 | -mkdir output 23 | mv fw40.elf output/firmware40.elf 24 | mv fw40.hex output/firmware40.hex 25 | 26 | fw40.hex: fw40.elf 27 | $(OBJCOPY) -O ihex $^ $@ 28 | 29 | fw40.elf: $(OBJS) 30 | $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) -Xlinker --defsym=TARGET_TEENSY41=0 31 | 32 | %.o: %.c 33 | $(CC) $(CFLAGS) -c $< -o $@ 34 | 35 | %.ao: %.s 36 | $(CC) $(ASFLAGS) -c $< -o $@ 37 | 38 | output/firmware41.hex: fw41.hex output/firmware40.hex 39 | -rm source/*.o41 source/*.ao41 40 | -rm output/firmware41.hex output/firmware41.elf 41 | -mkdir output 42 | mv fw41.elf output/firmware41.elf 43 | mv fw41.hex output/firmware41.hex 44 | 45 | fw41.hex: fw41.elf 46 | $(OBJCOPY) -O ihex $^ $@ 47 | 48 | fw41.elf: $(OBJS41) 49 | $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) -Xlinker --defsym=TARGET_TEENSY41=1 50 | 51 | %.o41: %.c 52 | $(CC) $(CFLAGS) -DTARGET_TEENSY41 -c $< -o $@ 53 | 54 | %.ao41: %.s 55 | $(CC) $(ASFLAGS) -c $< -o $@ 56 | 57 | clean: 58 | -rm source/*.o 59 | -rm source/*.ao 60 | -rm source/*.o41 61 | -rm source/*.ao41 62 | -rm -rf output -------------------------------------------------------------------------------- /linker.x: -------------------------------------------------------------------------------- 1 | /* 2 | linker "inspired" by teensy4 core's linker 3 | https://github.com/PaulStoffregen/cores/blob/master/teensy4/imxrt1062.ld 4 | */ 5 | /* IN: TARGET_TEENSY41 (0/1) */ 6 | MEMORY 7 | { 8 | ITCM (rwx): ORIGIN = 0x00000000, LENGTH = 512K 9 | DTCM (rwx): ORIGIN = 0x20000000, LENGTH = 512K 10 | OCRAM (rwx): ORIGIN = 0x20200000, LENGTH = 512K 11 | FLASH (rwx): ORIGIN = 0x60000000, LENGTH = TARGET_TEENSY41 ? 7936K : 1984K 12 | } 13 | 14 | ENTRY(some_other_header) 15 | 16 | SECTIONS 17 | { 18 | .boot : { 19 | *(.boot.header) 20 | FILL(0xFF) 21 | . = ORIGIN(FLASH) + 0x1000; 22 | *(.boot.some_other_header) 23 | *(.boot*) 24 | . = ALIGN(1024); 25 | } > FLASH 26 | 27 | .itcm : { 28 | *(.text.vectors) 29 | *(.text.glitch_funcs) 30 | *(.text*) 31 | . = ALIGN(4); 32 | } > ITCM AT > FLASH 33 | 34 | .dtcm : { 35 | *(.rodata*) 36 | *(.data*) 37 | . = ALIGN(4); 38 | } > DTCM AT > FLASH 39 | 40 | .bss ALIGN(4) : { 41 | cfg_prog_bss_start = .; 42 | *(.bss*) 43 | *(COMMON) 44 | . = ALIGN(32); 45 | cfg_prog_bss_end = .; 46 | } > DTCM 47 | 48 | /* set ITCM, DTCM and OCRAM banks */ 49 | cfg_prog_itcm_block_count = (SIZEOF(.itcm) + 0x7FFF) >> 15; 50 | cfg_prog_flexram_bank_config = 0xAAAAAAAA | ((1 << (cfg_prog_itcm_block_count * 2)) - 1); 51 | 52 | /* for stage2's copy_sections */ 53 | cfg_prog_itcm_flash_start = LOADADDR(.itcm); 54 | cfg_prog_itcm_flash_size = SIZEOF(.itcm); 55 | cfg_prog_itcm_flash_end = cfg_prog_itcm_flash_start + cfg_prog_itcm_flash_size; 56 | cfg_prog_dtcm_flash_start = LOADADDR(.dtcm); 57 | cfg_prog_dtcm_flash_size = SIZEOF(.dtcm); 58 | cfg_prog_dtcm_flash_end = cfg_prog_dtcm_flash_start + cfg_prog_dtcm_flash_size; 59 | 60 | /* set SP to end of DTCM */ 61 | cfg_prog_sp_addr = ORIGIN(DTCM) + ((16 - cfg_prog_itcm_block_count) << 15); 62 | 63 | /* overall size for flashcfg */ 64 | cfg_prog_size = SIZEOF(.boot) + SIZEOF(.itcm) + SIZEOF(.dtcm); 65 | 66 | /* diff between teensy4 and teensy4.1 */ 67 | cfg_sflashA1Size = TARGET_TEENSY41 ? 0x00800000 : 0x00200000; 68 | } 69 | -------------------------------------------------------------------------------- /source/include/gpio.h: -------------------------------------------------------------------------------- 1 | #ifndef __GPIO_H__ 2 | #define __GPIO_H__ 3 | 4 | #include "aips.h" 5 | 6 | #define GPIO_1_OFFSET (&((aips_2_s *)AIPS_2_OFFSET)->gpio1) 7 | #define GPIO_2_OFFSET (&((aips_2_s *)AIPS_2_OFFSET)->gpio2) 8 | #define GPIO_3_OFFSET (&((aips_2_s *)AIPS_2_OFFSET)->gpio3) 9 | #define GPIO_4_OFFSET (&((aips_2_s *)AIPS_2_OFFSET)->gpio4) 10 | #define GPIO_5_OFFSET (&((aips_1_s *)AIPS_1_OFFSET)->gpio5) 11 | #define GPIO_6_OFFSET (&((aips_5_s *)AIPS_5_OFFSET)->gpio6) 12 | #define GPIO_7_OFFSET (&((aips_5_s *)AIPS_5_OFFSET)->gpio7) 13 | #define GPIO_8_OFFSET (&((aips_5_s *)AIPS_5_OFFSET)->gpio8) 14 | #define GPIO_9_OFFSET (&((aips_5_s *)AIPS_5_OFFSET)->gpio9) 15 | 16 | #define GPIO_TCGPIO_OFFSET 5 17 | #define gpio_get_bus_tightalt(bus) ((bus > 5) ? (bus - GPIO_TCGPIO_OFFSET) : ((bus == 0) ? 0 : ((bus < 5) ? (bus + GPIO_TCGPIO_OFFSET) : 5))) 18 | 19 | // use _direct funcs only with abs args 20 | #define gpio_get_bus_paddr_direct(bus) (GPIO_ ## bus ## _OFFSET) 21 | #define gpio_read_direct(bus, port) (!!(((aips_gpio*)(gpio_get_bus_paddr_direct(bus)))->dr & BITN(port))) 22 | #define gpio_set_direct(bus, port) (((aips_gpio*)(gpio_get_bus_paddr_direct(bus)))->dr_set = BITN(port)) 23 | #define gpio_clear_direct(bus, port) (((aips_gpio*)(gpio_get_bus_paddr_direct(bus)))->dr_clear = BITN(port)) 24 | #define gpio_toggle_direct(bus, port) (((aips_gpio*)(gpio_get_bus_paddr_direct(bus)))->dr_toggle = BITN(port)) 25 | #define gpio_set_indir_direct(bus, port) (((aips_gpio*)(gpio_get_bus_paddr_direct(bus)))->gdir &= ~(BITN(port))) 26 | #define gpio_set_outdir_direct(bus, port) (((aips_gpio*)(gpio_get_bus_paddr_direct(bus)))->gdir |= BITN(port)) 27 | 28 | #define gpio_get_bus_paddr(bus) gpio_regs[bus] 29 | 30 | extern aips_gpio* gpio_regs[10]; 31 | 32 | int gpio_port_mode(int bus, int port, bool output, bool wait); 33 | int gpio_port_set(int bus, int port, bool wait); 34 | int gpio_port_clear(int bus, int port, bool wait); 35 | int gpio_port_toggle(int bus, int port, bool wait); 36 | bool gpio_port_read(int bus, int port, bool wait, bool wait_target); 37 | 38 | #endif -------------------------------------------------------------------------------- /source/clib.c: -------------------------------------------------------------------------------- 1 | #include "include/types.h" 2 | #include "include/utils.h" 3 | #include "include/clib.h" 4 | 5 | void* memset8(void* s, uint8_t c, uint32_t n) { 6 | uint8_t* z = s; 7 | 8 | while (n) { 9 | *z++ = c; 10 | n--; 11 | } 12 | 13 | return z; 14 | } 15 | 16 | void* memset32(void* s, uint32_t c, uint32_t n) { 17 | uint32_t* z = s; 18 | 19 | while (n) { 20 | *z++ = c; 21 | n -= 4; 22 | } 23 | 24 | return z; 25 | } 26 | 27 | void* memset(void* s, uint8_t c, uint32_t n) { 28 | if (((uint32_t)s | (uint32_t)n) & 3) 29 | return memset8(s, c, n); 30 | else 31 | return memset32(s, c | (c << 8) | (c << 16) | (c << 24), n); 32 | } 33 | 34 | void* memcpy(void* dest, const void* src, uint32_t n) { 35 | if (((uint32_t)src | (uint32_t)dest | (uint32_t)n) & 3) { 36 | const uint8_t* s = src; 37 | uint8_t* d = dest; 38 | 39 | while (n) { 40 | *d++ = *s++; 41 | n--; 42 | } 43 | 44 | } else { 45 | const uint32_t* s = src; 46 | uint32_t* d = dest; 47 | 48 | while (n) { 49 | *d++ = *s++; 50 | n -= 4; 51 | } 52 | } 53 | 54 | return dest; 55 | } 56 | 57 | int memcmp(const void* s1, const void* s2, uint32_t n) { 58 | if (((uint32_t)s1 | (uint32_t)s2 | (uint32_t)n) & 3) { 59 | const uint8_t* c1 = s1, * c2 = s2; 60 | uint8_t u1, u2; 61 | 62 | for (; n--; c1++, c2++) { 63 | u1 = *c1; 64 | u2 = *c2; 65 | if (u1 != u2) 66 | return u1 - u2; 67 | } 68 | } else { 69 | const uint32_t* l1 = s1, * l2 = s2; 70 | uint32_t u1, u2; 71 | 72 | for (; n; l1++, l2++) { 73 | u1 = *l1; 74 | u2 = *l2; 75 | if (u1 != u2) 76 | return u1 - u2; 77 | n -= 4; 78 | } 79 | } 80 | 81 | return 0; 82 | } 83 | 84 | uint32_t strlen(const char* str) { 85 | const char* s = str; 86 | 87 | while (*s) 88 | s++; 89 | 90 | return s - str; 91 | } -------------------------------------------------------------------------------- /source/boot.s: -------------------------------------------------------------------------------- 1 | # 2 | # stage 2 : minimal setup, flash=>ram & jump to reset 3 | # 4 | 5 | .syntax unified 6 | .thumb 7 | .cpu cortex-m7 8 | 9 | .section .boot.s 10 | 11 | .global s_BOOT 12 | .thumb_func 13 | s_BOOT: 14 | ldr r0,=0x400AC000; # IOMUXC_GPR 15 | ldr r1,=cfg_prog_flexram_bank_config; # set RAM banks : ITCM, DTCM, OCRAM 16 | 1: # init mem stuff 17 | str r1,[r0, #0x44] 18 | movs r1, #0x7; # enable ITCM & DTCM, use FLEXRAM_BANK_CFG 19 | str r1,[r0, #0x40] 20 | mov r1,#0xaa0000; # ITCM and DTCM = 512KB, kinda stupid 21 | str r1,[r0, #0x38] 22 | 2: # prep args for cpy [isz] @ ccode => ITCM 23 | ldr r0,=(cfg_prog_itcm_flash_start - 4) 24 | ldr r1,=cfg_prog_itcm_flash_end 25 | mvn r2, #0x3 26 | 3: # memcpy 27 | ldr r3, [r0, #0x4]! 28 | str r3, [r2, #0x4]! 29 | cmp r0, r1 30 | bne 3b 31 | 4: # check if already copied data 32 | ldr r1,=cfg_prog_dtcm_flash_end 33 | cmp r0, r1 34 | beq 7f 35 | 5: # check if there even is data to copy 36 | ldr r0,=cfg_prog_dtcm_flash_size 37 | cmp r0,#0 38 | beq 7f 39 | 6: # prep args for cpy [dsz] @ data => DTCM 40 | ldr r0,=(cfg_prog_dtcm_flash_start - 4) 41 | mov r2, #0x20000000; # DTCM_START 42 | sub r2, r2, #0x4 43 | b 3b 44 | 7: # TODO: modes? 45 | ldr sp,=cfg_prog_sp_addr 46 | 8: # optional C extension 47 | bl c_BOOT 48 | cmp r0,#0 49 | bne s_BFAIL 50 | 51 | s_BITCM: # prep done, jump to ITCM (|1 cuz thumb) 52 | ldr pc,=0x1 53 | 54 | s_BFAIL: # boot failed 55 | mov r4, r0 56 | 1: # optional C extension 57 | mov r0, r4 58 | bl c_BFAIL 59 | 2: # maybe we have a magic c_BFAIL 60 | cmp r0,#0 61 | beq s_BITCM 62 | 3: # infiniloop 63 | wfi 64 | b 3b 65 | -------------------------------------------------------------------------------- /source/include/paddr.h: -------------------------------------------------------------------------------- 1 | #ifndef __PADDR_H__ 2 | #define __PADDR_H__ 3 | 4 | #define ITCM_OFFSET 0x00000000 5 | #define ITCM_SIZE 0x00080000 6 | #define DTCM_OFFSET 0x20000000 7 | #define DTCM_SIZE 0x00080000 8 | #define OCRAM2_OFFSET 0x20200000 9 | #define OCRAM2_SIZE 0x00080000 10 | #define OCRAM_FR_OFFSET 0x20280000 11 | #define OCRAM_FR_SIZE 0x00080000 12 | #define AIPS_1_OFFSET 0x40000000 13 | #define AIPS_1_SIZE 0x00100000 14 | #define AIPS_2_OFFSET 0x40100000 15 | #define AIPS_2_SIZE 0x00100000 16 | #define AIPS_3_OFFSET 0x40200000 17 | #define AIPS_3_SIZE 0x00100000 18 | #define AIPS_4_OFFSET 0x40300000 19 | #define AIPS_4_SIZE 0x00100000 20 | #define MAIN_CFG_PORT_OFFSET 0x41000000 21 | #define MAIN_CFG_PORT_SIZE 0x00100000 22 | #define M_CFG_PORT_OFFSET 0x41100000 23 | #define M_CFG_PORT_SIZE 0x00100000 24 | #define CPU_CFG_PORT_OFFSET 0x41400000 25 | #define CPU_CFG_PORT_SIZE 0x00100000 26 | #define AIPS_5_OFFSET 0x42000000 27 | #define AIPS_5_SIZE 0x00100000 28 | #define FLEXSPI_CT_OFFSET 0x60000000 29 | #define FLEXSPI_CT_SIZE 0x10000000 30 | #define FLEXSPI2_CT_OFFSET 0x70000000 31 | #define FLEXSPI2_CT_SIZE 0x0F000000 32 | #define FLEXSPI2_TXFIFO_OFFSET 0x7F000000 33 | #define FLEXSPI2_TXFIFO_SIZE 0x00400000 34 | #define FLEXSPI2_RXFIFO_OFFSET 0x7F400000 35 | #define FLEXSPI2_RXFIFO_SIZE 0x00400000 36 | #define FLEXSPI_TXFIFO_OFFSET 0x7F800000 37 | #define FLEXSPI_TXFIFO_SIZE 0x00400000 38 | #define FLEXSPI_RXFIFO_OFFSET 0x7FC00000 39 | #define FLEXSPI_RXFIFO_SIZE 0x00400000 40 | #define SEMC_SHARED_OFFSET 0x80000000 41 | #define SEMC_SHARED_SIZE 0x60000000 42 | #define CM7_PPB_OFFSET 0xE0000000 43 | #define CM7_PPB_SIZE 0x00100000 44 | 45 | #define PADDR_AFTER_ENTRY(entry) (entry ## _OFFSET + entry ## _SIZE) 46 | #define PADDR_ENTRY_SEPARATION(prev,next) (next ## _OFFSET - PADDR_AFTER_ENTRY(prev)) 47 | 48 | #endif -------------------------------------------------------------------------------- /source/gpio.c: -------------------------------------------------------------------------------- 1 | #include "include/paddr.h" 2 | #include "include/aips.h" 3 | #include "include/utils.h" 4 | 5 | #include "include/gpio.h" 6 | 7 | aips_gpio* gpio_regs[10] = { // legacy support 8 | NULL, // no gpio0 9 | gpio_get_bus_paddr_direct(1), 10 | gpio_get_bus_paddr_direct(2), 11 | gpio_get_bus_paddr_direct(3), 12 | gpio_get_bus_paddr_direct(4), 13 | gpio_get_bus_paddr_direct(5), 14 | gpio_get_bus_paddr_direct(6), 15 | gpio_get_bus_paddr_direct(7), 16 | gpio_get_bus_paddr_direct(8), 17 | gpio_get_bus_paddr_direct(9) 18 | }; 19 | 20 | int gpio_port_mode(int bus, int port, bool output, bool wait) { 21 | if (!gpio_regs[bus]) 22 | return -1; 23 | if (output) { 24 | gpio_regs[bus]->gdir |= 1 << port; 25 | while (wait && !(gpio_regs[bus]->gdir & (1 << port))) 26 | ; 27 | } else { 28 | gpio_regs[bus]->gdir &= ~(1 << port); 29 | while (wait && (gpio_regs[bus]->gdir & (1 << port))) 30 | ; 31 | } 32 | 33 | return 0; 34 | } 35 | 36 | int gpio_port_set(int bus, int port, bool wait) { 37 | if (!gpio_regs[bus]) 38 | return -1; 39 | 40 | if (gpio_regs[bus]->gdir & (1 << port)) { 41 | gpio_regs[bus]->dr_set = 1 << port; 42 | while (wait && !(gpio_regs[bus]->dr & (1 << port))) 43 | ; 44 | return 0; 45 | } 46 | 47 | return -2; 48 | } 49 | 50 | int gpio_port_clear(int bus, int port, bool wait) { 51 | if (!gpio_regs[bus]) 52 | return -1; 53 | 54 | if (gpio_regs[bus]->gdir & (1 << port)) { 55 | gpio_regs[bus]->dr_clear = 1 << port; 56 | while (wait && (gpio_regs[bus]->dr & (1 << port))) 57 | ; 58 | return 0; 59 | } 60 | 61 | return -2; 62 | } 63 | 64 | int gpio_port_toggle(int bus, int port, bool wait) { 65 | if (!gpio_regs[bus]) 66 | return -1; 67 | 68 | if (gpio_regs[bus]->gdir & (1 << port)) { 69 | bool prev = gpio_regs[bus]->dr & (1 << port); 70 | gpio_regs[bus]->dr_toggle = 1 << port; 71 | while (wait && (prev == (gpio_regs[bus]->dr & (1 << port)))) {}; 72 | return 0; 73 | } 74 | 75 | return -2; 76 | } 77 | 78 | bool gpio_port_read(int bus, int port, bool wait, bool wait_target) { 79 | if (!gpio_regs[bus]) 80 | return -1; 81 | 82 | if (!(gpio_regs[bus]->gdir & BITN(port))) { 83 | bool state = !!(gpio_regs[bus]->dr & BITN(port)); 84 | if (wait) { 85 | if (wait_target > 1) // dont use this unless you know what you are doing [timings] 86 | wait_target = !state; 87 | while (1) { 88 | state = !!(gpio_regs[bus]->dr & BITN(port)); 89 | if (state == wait_target) 90 | break; 91 | }; 92 | } 93 | return state; 94 | } 95 | 96 | return -2; 97 | } -------------------------------------------------------------------------------- /source/include/iomuxc.h: -------------------------------------------------------------------------------- 1 | #ifndef __IOMUXC_H__ 2 | #define __IOMUXC_H__ 3 | 4 | #include "aips.h" 5 | 6 | #define iomuxc_gpr ((aips_1_s*)AIPS_1_OFFSET)->iomuxc_gpr.gpr 7 | #define iomuxc ((aips_2_s*)AIPS_2_OFFSET)->iomuxc 8 | 9 | #define IOMUXC_GPR_GPIO_MUX1_GPIO_SEL 26 10 | #define IOMUXC_GPR_GPIO_MUX2_GPIO_SEL 27 11 | #define IOMUXC_GPR_GPIO_MUX3_GPIO_SEL 28 12 | #define IOMUXC_GPR_GPIO_MUX4_GPIO_SEL 29 13 | 14 | enum IOMUXC_PORT_MUX_CTL_BITS { 15 | IOMUXC_PORT_MUX_CTL_BITS_MUX_MODE = 0, 16 | IOMUXC_PORT_MUX_CTL_BITS_SION = 4, 17 | IOMUXC_PORT_MUX_CTL_BITS__END 18 | }; 19 | 20 | #define IOMUXC_PORT_MUX_CTL_BITMASK_MUX_MODE 0b1111 // sometimes 0b111 21 | 22 | enum IOMUXC_PORT_CTL_BITS { 23 | IOMUXC_PORT_CTL_BITS_SRE = 0, // Fast Slew Rate 24 | IOMUXC_PORT_CTL_BITS_DSE = 3, // Drive Strength 25 | IOMUXC_PORT_CTL_BITS_SPEED = 6, 26 | IOMUXC_PORT_CTL_BITS_ODE = 11, // Open Drain Enabled 27 | IOMUXC_PORT_CTL_BITS_PKE, // Pull/Keep Enable 28 | IOMUXC_PORT_CTL_BITS_PUE, // Pull ^ 29 | IOMUXC_PORT_CTL_BITS_PUS, 30 | IOMUXC_PORT_CTL_BITS_HYS = 16, // Hysteresis Enabled 31 | IOMUXC_PORT_CTL_BITS__END 32 | }; 33 | 34 | enum IOMUXC_PORT_CTL_PUS_MODES { // Pull Up/Down config 35 | IOMUXC_PORT_CTL_PUS_100K_PULL_DOWN = 0, 36 | IOMUXC_PORT_CTL_PUS_47K_PULL_UP, 37 | IOMUXC_PORT_CTL_PUS_100K_PULL_UP, 38 | IOMUXC_PORT_CTL_PUS_22K_PULL_UP 39 | }; 40 | 41 | #define IOMUXC_PORT_CTL_DSE_DISABLED 0 42 | #define IOMUXC_PORT_CTL_DSE_R0(div) (div) // R0(150 Ohm @ 3.3V, 260 Ohm@1.8V), max div 7 43 | #define IOMUXC_PORT_CTL_SPEED(mult) (mult - 1) // mult * 50Mhz 44 | 45 | #define IOMUXC_PORT_CTL_BITMASK_DSE 0b111 46 | #define IOMUXC_PORT_CTL_BITMASK_SPEED 0b11 47 | #define IOMUXC_PORT_CTL_BITMASK_PUS 0b11 48 | 49 | // ehh 50 | #define IOMUXC_PORT_CTL_FIELD(sre, dse, speed, ode, pke, pue, pus, hys) ( \ 51 | BITNVALM(IOMUXC_PORT_CTL_BITS_SRE, sre, 1) \ 52 | | BITNVALM(IOMUXC_PORT_CTL_BITS_DSE, dse, IOMUXC_PORT_CTL_BITMASK_DSE) \ 53 | | BITNVALM(IOMUXC_PORT_CTL_BITS_SPEED, speed, IOMUXC_PORT_CTL_BITMASK_SPEED) \ 54 | | BITNVALM(IOMUXC_PORT_CTL_BITS_ODE, ode, 1) \ 55 | | BITNVALM(IOMUXC_PORT_CTL_BITS_PKE, pke, 1) \ 56 | | BITNVALM(IOMUXC_PORT_CTL_BITS_PUE, pue, 1) \ 57 | | BITNVALM(IOMUXC_PORT_CTL_BITS_PUS, pus, IOMUXC_PORT_CTL_BITMASK_PUS) \ 58 | | BITNVALM(IOMUXC_PORT_CTL_BITS_HYS, hys, 1) \ 59 | ) 60 | 61 | /* 62 | enable tcgpio [bus] [port] 63 | to set tcgpio->gpio give the func a gpio [bus] 64 | if you want to set multiple ports, set the [mask] bitfield 65 | */ 66 | int iomuxc_set_tcgpio(int bus, int port, int mask, bool wait); 67 | 68 | volatile uint32_t* iomuxc_get_ctl_reg_for_port(bool mux_ctl, int port, int gpio_bus); 69 | // TODO: iomuxc_get_ctl_reg_for_port_direct ? 70 | #define iomuxc_port_ctl_mux(port, gpio_bus) vp(iomuxc_get_ctl_reg_for_port(true, port, gpio_bus)) 71 | #define iomuxc_port_ctl(port, gpio_bus) vp(iomuxc_get_ctl_reg_for_port(false, port, gpio_bus)) 72 | int iomuxc_set_port_ctl(int port, int gpio_bus, int ctl, int mux_ctl, bool wait); 73 | 74 | #endif -------------------------------------------------------------------------------- /source/debug.c: -------------------------------------------------------------------------------- 1 | #include "include/types.h" 2 | #include "include/uart.h" 3 | #include "include/clib.h" 4 | #include "include/utils.h" 5 | #include "include/defs.h" 6 | #include "include/gpio.h" 7 | #include "include/debug.h" 8 | 9 | static const char debug_hexbase[] = "0123456789ABCDEF"; 10 | volatile int g_debug_uartn = 1; // should have !0 checks everywhere but meh 11 | 12 | // equ printf(0x08X) 13 | void debug_printU32(uint32_t value, bool add_nl) { 14 | char i_buf[4]; 15 | char a_buf[12]; 16 | 17 | p i_buf = value; 18 | memset(a_buf, '0', 12); 19 | a_buf[1] = 'x'; 20 | a_buf[10] = add_nl ? '\n' : 0; 21 | a_buf[11] = 0; 22 | 23 | for (int i = 0; i < 4; i -= -1) { 24 | a_buf[9 - i * 2] = debug_hexbase[i_buf[i] & 0x0F]; 25 | a_buf[8 - i * 2] = debug_hexbase[(i_buf[i] & 0xF0) >> 4]; 26 | } 27 | 28 | print(a_buf); 29 | } 30 | 31 | // dumbed down printf 32 | void debug_printFormat(char* base, ...) { 33 | int base_len = strlen(base); 34 | if (!base_len) 35 | return; 36 | 37 | va_list args; 38 | va_start(args, base); 39 | 40 | int v_pos = 0, i = 0; 41 | for (i = 0; i < base_len; i++) { 42 | if (base[i] != '%') 43 | continue; 44 | 45 | printn(base + v_pos, i - v_pos); 46 | 47 | i++; 48 | 49 | switch (base[i]) { 50 | case 'X': 51 | case 'x': 52 | debug_printU32(va_arg(args, uint32_t), false); 53 | break; 54 | case 'S': 55 | case 's': 56 | print((char*)va_arg(args, uint32_t)); 57 | break; 58 | default: 59 | continue; 60 | } 61 | 62 | i++; 63 | v_pos = i; 64 | } 65 | 66 | va_end(args); 67 | 68 | printn(base + v_pos, i - v_pos); 69 | } 70 | 71 | static void printRange32(uint32_t* addr, uint32_t size, bool show_addr) { 72 | if (!size) 73 | return; 74 | 75 | if (show_addr) 76 | printf("%X: ", addr); 77 | 78 | uint32_t data = 0; 79 | char cwc[13]; 80 | cwc[12] = 0; 81 | for (uint32_t off = 0; off < size; off -= -4) { 82 | data = addr[(off >> 2)]; 83 | cwc[0] = debug_hexbase[(data & 0xF0) >> 4]; 84 | cwc[1] = debug_hexbase[data & 0x0F]; 85 | cwc[2] = ' '; 86 | cwc[3] = debug_hexbase[((data >> 8) & 0xF0) >> 4]; 87 | cwc[4] = debug_hexbase[(data >> 8) & 0x0F]; 88 | cwc[5] = ' '; 89 | cwc[6] = debug_hexbase[((data >> 16) & 0xF0) >> 4]; 90 | cwc[7] = debug_hexbase[(data >> 16) & 0x0F]; 91 | cwc[8] = ' '; 92 | cwc[9] = debug_hexbase[((data >> 24) & 0xF0) >> 4]; 93 | cwc[10] = debug_hexbase[(data >> 24) & 0x0F]; 94 | cwc[11] = ' '; 95 | print(cwc); 96 | if ((off & 0xc) == 0xc) { 97 | print(" \n"); 98 | if (show_addr && off + 4 < size) 99 | printf("%X: ", addr + (off >> 2) + 1); 100 | } 101 | } 102 | 103 | print(" \n"); 104 | } 105 | 106 | static void printRange8(char* addr, uint32_t size, bool show_addr) { 107 | if (!size) 108 | return; 109 | 110 | if (show_addr) 111 | printf("%X: ", addr); 112 | 113 | char cwc[4]; 114 | cwc[3] = 0; 115 | for (uint32_t off = 0; off < size; off -= -1) { 116 | cwc[0] = debug_hexbase[(addr[off] & 0xF0) >> 4]; 117 | cwc[1] = debug_hexbase[addr[off] & 0x0F]; 118 | cwc[2] = ' '; 119 | print(cwc); 120 | if ((off & 0xf) == 0xf) { 121 | print(" \n"); 122 | if (show_addr && off + 1 < size) 123 | printf("%X: ", addr + off + 1); 124 | } 125 | } 126 | 127 | print(" \n"); 128 | } 129 | 130 | void debug_printRange(uint32_t addr, uint32_t size, bool show_addr) { 131 | if (!size) 132 | return; 133 | 134 | if (((uint32_t)addr | (uint32_t)size) & 3) 135 | printRange8((char*)addr, size, show_addr); 136 | else 137 | printRange32((uint32_t*)addr, size, show_addr); 138 | } -------------------------------------------------------------------------------- /source/iomux.c: -------------------------------------------------------------------------------- 1 | #include "include/paddr.h" 2 | #include "include/aips.h" 3 | #include "include/utils.h" 4 | 5 | #include "include/iomuxc.h" 6 | 7 | int iomuxc_set_tcgpio(int bus, int port, int mask, bool wait) { 8 | bool clear = false; 9 | 10 | if (!bus || (bus == 5) || (bus > 9)) 11 | return -1; 12 | 13 | if (bus < 5) { 14 | bus -=- 5; 15 | clear = true; 16 | } 17 | 18 | if (!mask) 19 | mask = 1 << port; 20 | 21 | if (clear) { 22 | iomuxc_gpr[IOMUXC_GPR_GPIO_MUX1_GPIO_SEL + bus - 5 - 1] &= ~mask; 23 | dsb(); 24 | while (wait && (iomuxc_gpr[IOMUXC_GPR_GPIO_MUX1_GPIO_SEL + bus - 5 - 1] & mask)) 25 | ; 26 | } else { 27 | iomuxc_gpr[IOMUXC_GPR_GPIO_MUX1_GPIO_SEL + bus - 5 - 1] |= mask; 28 | dsb(); 29 | while (wait && !(iomuxc_gpr[IOMUXC_GPR_GPIO_MUX1_GPIO_SEL + bus - 5 - 1] & mask)) 30 | ; 31 | } 32 | 33 | return iomuxc_gpr[IOMUXC_GPR_GPIO_MUX1_GPIO_SEL + bus - 5 - 1]; 34 | } 35 | 36 | /* 37 | We can calculate default periph ctrls for pads based on their gpio ports & bus 38 | bus1 : 39 | - ports 0 - 15 -> ad_b0 [n] 40 | - ports 16 - 31 -> ad_b1 [n - 16] 41 | bus2 : 42 | - ports 0 - 15 -> b0 [n] 43 | - ports 16 - 31 -> b1 [n - 16] 44 | bus3 : 45 | - ports 0 - 11 -> sd_b1 [n] 46 | - ports 12 - 17 -> sd_b0 [n - 12] 47 | - ports 18 - 27 -> emc [32 + (n - 18)] <= only 27 gpio3 ports? 48 | bus4 : ports 0 - 31 -> emc [n] 49 | */ 50 | volatile uint32_t* iomuxc_get_ctl_reg_for_port(bool mux_ctl, int port, int gpio_bus) { 51 | if (!gpio_bus || gpio_bus == 5 || gpio_bus > 9) 52 | return NULL; 53 | 54 | if (gpio_bus > 5) 55 | gpio_bus -= 5; 56 | 57 | if (port > 31 || (gpio_bus == 3 && port > 27)) 58 | return NULL; 59 | 60 | switch (gpio_bus) { 61 | case 1: 62 | return (mux_ctl 63 | ? ((port >= 16) ? &iomuxc.sw_mux_ctl_pad_gpio.ad_b1[port - 16] : &iomuxc.sw_mux_ctl_pad_gpio.ad_b0[port]) 64 | : ((port >= 16) ? &iomuxc.sw_pad_ctl_pad_gpio.ad_b1[port - 16] : &iomuxc.sw_pad_ctl_pad_gpio.ad_b0[port]) 65 | ); 66 | case 2: 67 | return (mux_ctl 68 | ? ((port >= 16) ? &iomuxc.sw_mux_ctl_pad_gpio.b1[port - 16] : &iomuxc.sw_mux_ctl_pad_gpio.b0[port]) 69 | : ((port >= 16) ? &iomuxc.sw_pad_ctl_pad_gpio.b1[port - 16] : &iomuxc.sw_pad_ctl_pad_gpio.b0[port]) 70 | ); 71 | case 3: 72 | if (port >= 12) { 73 | if (port >= 18) 74 | return (mux_ctl ? &iomuxc.sw_mux_ctl_pad_gpio.emc[32 + (port - 18)] : &iomuxc.sw_pad_ctl_pad_gpio.emc[32 + (port - 18)]); 75 | else 76 | return (mux_ctl ? &iomuxc.sw_mux_ctl_pad_gpio.sd_b0[port - 12] : &iomuxc.sw_pad_ctl_pad_gpio.sd_b0[port - 12]); 77 | } else 78 | return (mux_ctl ? &iomuxc.sw_mux_ctl_pad_gpio.sd_b1[port] : &iomuxc.sw_pad_ctl_pad_gpio.sd_b1[port]); 79 | case 4: 80 | return (mux_ctl ? &iomuxc.sw_mux_ctl_pad_gpio.emc[port] : &iomuxc.sw_pad_ctl_pad_gpio.emc[port]); 81 | default: // _-_ 82 | break; 83 | } 84 | 85 | return NULL; // how did we get here? lul 86 | } 87 | 88 | int iomuxc_set_port_ctl(int port, int gpio_bus, int ctl, int mux_ctl, bool wait) { 89 | if (ctl >= 0) { // -1 to skip 90 | volatile uint32_t* ctl_reg = iomuxc_get_ctl_reg_for_port(false, port, gpio_bus); 91 | if (!ctl_reg) 92 | return -1; 93 | *ctl_reg = ctl; 94 | while (wait && ((*ctl_reg & BITF(IOMUXC_PORT_CTL_BITS__END)) != (ctl & BITF(IOMUXC_PORT_CTL_BITS__END)))) 95 | ; 96 | } 97 | 98 | if (mux_ctl >= 0) { // -1 to skip 99 | volatile uint32_t* mux_ctl_reg = iomuxc_get_ctl_reg_for_port(true, port, gpio_bus); 100 | if (!mux_ctl_reg) 101 | return -2; 102 | *mux_ctl_reg = mux_ctl; 103 | while (wait && ((*mux_ctl_reg & BITF(IOMUXC_PORT_MUX_CTL_BITS__END)) != (mux_ctl & BITF(IOMUXC_PORT_MUX_CTL_BITS__END)))) 104 | ; 105 | } 106 | 107 | return 0; 108 | } -------------------------------------------------------------------------------- /source/uart.c: -------------------------------------------------------------------------------- 1 | #include "include/paddr.h" 2 | #include "include/aips.h" 3 | #include "include/utils.h" 4 | #include "include/iomuxc.h" 5 | #include "include/ccm.h" 6 | #include "include/defs.h" 7 | 8 | #include "include/uart.h" 9 | 10 | aips_lpuart* uart_regs[9] = { // legacy support 11 | NULL, // no uart0 12 | UART_1_OFFSET, 13 | UART_2_OFFSET, 14 | UART_3_OFFSET, 15 | UART_4_OFFSET, 16 | UART_5_OFFSET, 17 | UART_6_OFFSET, 18 | UART_7_OFFSET, 19 | UART_8_OFFSET 20 | }; 21 | 22 | uint8_t uart_ccg[9] = { // legacy support 23 | 0, // no uart0 24 | CCM_CCG_LPUART1, 25 | CCM_CCG_LPUART2, 26 | CCM_CCG_LPUART3, 27 | CCM_CCG_LPUART4, 28 | CCM_CCG_LPUART5, 29 | CCM_CCG_LPUART6, 30 | CCM_CCG_LPUART7, 31 | CCM_CCG_LPUART8 32 | }; 33 | 34 | void uart_init(int bus, int baud, int flags, bool wait) { 35 | ccm_control_gate(uart_ccg[bus], CCM_CCG_ALWAYS_ON, wait); // open the uart dev clock gate 36 | uart_regs[bus]->global |= BITN(UART_GLOBAL_BITS_RST); // put uart dev in reset 37 | uart_regs[bus]->global &= ~(BITN(UART_GLOBAL_BITS_RST)); // pull uart dev out of reset, no min delay acc to ref man 38 | uart_regs[bus]->water = BITNVAL(UART_WATER_BITS_TXWATER, 3); 39 | uart_regs[bus]->baud = baud; // BAUD 40 | uart_regs[bus]->stat |= BITNVAL(UART_STAT_BITS_RXINV, !!(flags & BITN(UART_INIT_BITS_RX_INV))) 41 | | BITNVAL(UART_STAT_BITS_MSBF, !!(flags & BITN(UART_INIT_BITS_MSB_FIRST))) 42 | ; // RX inv, MSB first 43 | uart_regs[bus]->fifo |= BITNVAL(UART_FIFO_BITS_TXFE, !!(flags & BITN(UART_INIT_BITS_TX_FIFO_EN))) 44 | | BITNVAL(UART_FIFO_BITS_RXFE, !!(flags & BITN(UART_INIT_BITS_RX_FIFO_EN))) 45 | ; // RX/TX FIFO enable 46 | uart_regs[bus]->ctrl |= BITNVAL(UART_CTRL_BITS_TE, !!(flags & BITN(UART_INIT_BITS_TX_EN))) 47 | | BITNVAL(UART_CTRL_BITS_RE, !!(flags & BITN(UART_INIT_BITS_RX_EN))) 48 | | BITNVAL(UART_CTRL_BITS_TXINV, !!(flags & BITN(UART_INIT_BITS_TX_INV))) 49 | ; // TX inv, RX/TX enable 50 | while (wait && !(uart_regs[bus]->ctrl & (BITNVAL(UART_CTRL_BITS_TE, !!(flags & BITN(UART_INIT_BITS_TX_EN))) | BITNVAL(UART_CTRL_BITS_RE, !!(flags & BITN(UART_INIT_BITS_RX_EN)))))) {}; 51 | } 52 | 53 | void uart_write(int bus, unsigned int data) { 54 | while (!(uart_regs[bus]->stat & BITN(UART_STAT_BITS_TDRE))) {}; 55 | uart_regs[bus]->data = data; 56 | } 57 | 58 | // read [bus] rx reg until there is valid data or [timeout]+1 times 59 | unsigned int uart_read(int bus, unsigned int timeout, bool wait) { 60 | unsigned int data; 61 | do { 62 | data = uart_regs[bus]->data; 63 | } while ((data & BITN(UART_DATA_BITS_RXEMPT)) && (wait || (timeout--, timeout + 1))); 64 | return data; 65 | } 66 | 67 | void uart_print(int bus, char* str) { 68 | while (*str) { 69 | if (*str == '\n') 70 | uart_write(bus, '\r'); 71 | 72 | uart_write(bus, *str++); 73 | } 74 | } 75 | 76 | void uart_printn(int bus, char* str, int n) { 77 | char* z = str; 78 | 79 | while (n && *z) { 80 | if (*z == '\n') 81 | uart_write(bus, '\r'); 82 | 83 | uart_write(bus, *z++); 84 | 85 | n--; 86 | } 87 | } 88 | 89 | // TODO: uart_scan with IDLE-based break? 90 | 91 | // setting [timeout] to 0 will make it wait indefinitely 92 | int uart_scann(int bus, uint8_t* out, int outsize, unsigned int timeout) { 93 | uart_regs[bus]->stat = uart_regs[bus]->stat; // ack current status 94 | unsigned int data; 95 | for (int i = 0; i < outsize; i++) { 96 | data = uart_read(bus, timeout, !timeout); 97 | if (data & BITN(UART_DATA_BITS_RXEMPT)) 98 | return -1; 99 | out[i] = (char)data; 100 | } 101 | return 0; 102 | } 103 | 104 | // setting [timeout] to 0 will make it wait indefinitely 105 | int uart_scanns(int bus, char* out, int outsize, unsigned int timeout) { 106 | uart_regs[bus]->stat = uart_regs[bus]->stat; // ack current status 107 | unsigned int data; 108 | for (int i = 0; i < outsize; i++) { 109 | data = uart_read(bus, timeout, !timeout); 110 | if (data & BITN(UART_DATA_BITS_RXEMPT)) 111 | return -1; 112 | out[i] = (char)data; 113 | if ((char)data == '\n') { 114 | if (i && out[i - 1] == '\r') 115 | return 0; 116 | } 117 | } 118 | return -1; 119 | } -------------------------------------------------------------------------------- /source/include/compile_time.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Created: 29.03.2018 4 | * 5 | * Authors: 6 | * 7 | * Assembled from the code released on Stackoverflow by: 8 | * Dennis (instructable.com/member/nqtronix) | https://stackoverflow.com/questions/23032002/c-c-how-to-get-integer-unix-timestamp-of-build-time-not-string 9 | * and 10 | * Alexis Wilke | https://stackoverflow.com/questions/10538444/do-you-know-of-a-c-macro-to-compute-unix-time-and-date 11 | * 12 | * Assembled by Jean Rabault 13 | * 14 | * UNIX_TIMESTAMP gives the UNIX timestamp (unsigned long integer of seconds since 1st Jan 1970) of compilation from macros using the compiler defined __TIME__ macro. 15 | * This should include Gregorian calendar leap days, in particular the 29ths of February, 100 and 400 years modulo leaps. 16 | * 17 | * Careful: __TIME__ is the local time of the computer, NOT the UTC time in general! 18 | * 19 | */ 20 | 21 | #ifndef COMPILE_TIME_H_ 22 | #define COMPILE_TIME_H_ 23 | 24 | // Some definitions for calculation 25 | #define SEC_PER_MIN 60UL 26 | #define SEC_PER_HOUR 3600UL 27 | #define SEC_PER_DAY 86400UL 28 | #define SEC_PER_YEAR (SEC_PER_DAY*365) 29 | 30 | // extracts 1..4 characters from a string and interprets it as a decimal value 31 | #define CONV_STR2DEC_1(str, i) (str[i]>'0'?str[i]-'0':0) 32 | #define CONV_STR2DEC_2(str, i) (CONV_STR2DEC_1(str, i)*10 + str[i+1]-'0') 33 | #define CONV_STR2DEC_3(str, i) (CONV_STR2DEC_2(str, i)*10 + str[i+2]-'0') 34 | #define CONV_STR2DEC_4(str, i) (CONV_STR2DEC_3(str, i)*10 + str[i+3]-'0') 35 | 36 | // Custom "glue logic" to convert the month name to a usable number 37 | #define GET_MONTH(str, i) (str[i]=='J' && str[i+1]=='a' && str[i+2]=='n' ? 1 : \ 38 | str[i]=='F' && str[i+1]=='e' && str[i+2]=='b' ? 2 : \ 39 | str[i]=='M' && str[i+1]=='a' && str[i+2]=='r' ? 3 : \ 40 | str[i]=='A' && str[i+1]=='p' && str[i+2]=='r' ? 4 : \ 41 | str[i]=='M' && str[i+1]=='a' && str[i+2]=='y' ? 5 : \ 42 | str[i]=='J' && str[i+1]=='u' && str[i+2]=='n' ? 6 : \ 43 | str[i]=='J' && str[i+1]=='u' && str[i+2]=='l' ? 7 : \ 44 | str[i]=='A' && str[i+1]=='u' && str[i+2]=='g' ? 8 : \ 45 | str[i]=='S' && str[i+1]=='e' && str[i+2]=='p' ? 9 : \ 46 | str[i]=='O' && str[i+1]=='c' && str[i+2]=='t' ? 10 : \ 47 | str[i]=='N' && str[i+1]=='o' && str[i+2]=='v' ? 11 : \ 48 | str[i]=='D' && str[i+1]=='e' && str[i+2]=='c' ? 12 : 0) 49 | 50 | // extract the information from the time string given by __TIME__ and __DATE__ 51 | #define __TIME_SECONDS__ CONV_STR2DEC_2(__TIME__, 6) 52 | #define __TIME_MINUTES__ CONV_STR2DEC_2(__TIME__, 3) 53 | #define __TIME_HOURS__ CONV_STR2DEC_2(__TIME__, 0) 54 | #define __TIME_DAYS__ CONV_STR2DEC_2(__DATE__, 4) 55 | #define __TIME_MONTH__ GET_MONTH(__DATE__, 0) 56 | #define __TIME_YEARS__ CONV_STR2DEC_4(__DATE__, 7) 57 | 58 | // Days in February 59 | #define _UNIX_TIMESTAMP_FDAY(year) \ 60 | (((year) % 400) == 0UL ? 29UL : \ 61 | (((year) % 100) == 0UL ? 28UL : \ 62 | (((year) % 4) == 0UL ? 29UL : \ 63 | 28UL))) 64 | 65 | // Days in the year 66 | #define _UNIX_TIMESTAMP_YDAY(year, month, day) \ 67 | ( \ 68 | /* January */ day \ 69 | /* February */ + (month >= 2 ? 31UL : 0UL) \ 70 | /* March */ + (month >= 3 ? _UNIX_TIMESTAMP_FDAY(year) : 0UL) \ 71 | /* April */ + (month >= 4 ? 31UL : 0UL) \ 72 | /* May */ + (month >= 5 ? 30UL : 0UL) \ 73 | /* June */ + (month >= 6 ? 31UL : 0UL) \ 74 | /* July */ + (month >= 7 ? 30UL : 0UL) \ 75 | /* August */ + (month >= 8 ? 31UL : 0UL) \ 76 | /* September */+ (month >= 9 ? 31UL : 0UL) \ 77 | /* October */ + (month >= 10 ? 30UL : 0UL) \ 78 | /* November */ + (month >= 11 ? 31UL : 0UL) \ 79 | /* December */ + (month >= 12 ? 30UL : 0UL) \ 80 | ) 81 | 82 | // get the UNIX timestamp from a digits representation 83 | #define _UNIX_TIMESTAMP(year, month, day, hour, minute, second) \ 84 | ( /* time */ second \ 85 | + minute * SEC_PER_MIN \ 86 | + hour * SEC_PER_HOUR \ 87 | + /* year day (month + day) */ (_UNIX_TIMESTAMP_YDAY(year, month, day) - 1) * SEC_PER_DAY \ 88 | + /* year */ (year - 1970UL) * SEC_PER_YEAR \ 89 | + ((year - 1969UL) / 4UL) * SEC_PER_DAY \ 90 | - ((year - 1901UL) / 100UL) * SEC_PER_DAY \ 91 | + ((year - 1601UL) / 400UL) * SEC_PER_DAY \ 92 | ) 93 | 94 | // the UNIX timestamp 95 | #define UNIX_TIMESTAMP (_UNIX_TIMESTAMP(__TIME_YEARS__, __TIME_MONTH__, __TIME_DAYS__, __TIME_HOURS__, __TIME_MINUTES__, __TIME_SECONDS__)) 96 | 97 | #endif -------------------------------------------------------------------------------- /source/include/glitch.h: -------------------------------------------------------------------------------- 1 | #ifndef __GLITCH_H__ 2 | #define __GLITCH_H__ 3 | 4 | #include "types.h" 5 | #include "defs.h" 6 | #include "teensy.h" 7 | 8 | #define GLITCH_STATIC_CHAIN_N 8 // for static mem alloc 9 | 10 | #define GLITCH_DEFAULT_CLKSPEED 600000000 // 600Mhz 11 | #define GLITCH_DEFAULT_FUNC s_glitch 12 | #define GLITCH_DEFAULT_OFF 300000000 // ~1s 13 | #define GLITCH_DEFAULT_OFF_MULT 1 14 | #define GLITCH_DEFAULT_WIDTH 600 // ~1us 15 | 16 | #define GLITCH_DEFAULT_DRIVER_PAD 22 17 | #define GLITCH_DEFAULT_DRIVER_DSE_DIV 7 18 | 19 | #define GLITCH_DEFAULT_LL_TRIGGER_PAD 23 20 | #define GLITCH_DEFAULT_LL_TRIGGER_EXP_STATE true // trigger on hi 21 | #define GLITCH_DEFAULT_LL_TRIGGER_PK_EN false // disable pull/keep 22 | #define GLITCH_DEFAULT_LL_TRIGGER_PUE false // keeper 23 | #define GLITCH_DEFAULT_LL_TRIGGER_PULL_TYPE 0 // disabled 24 | #define GLITCH_DEFAULT_LL_TRIGGER_HYS_EN false // no hysteresis 25 | 26 | /* enhanced precision? 27 | #define GLITCH_DEFAULT_LL_TRIGGER_PAD 23 28 | #define GLITCH_DEFAULT_LL_TRIGGER_EXP_STATE false // trigger on lo 29 | #define GLITCH_DEFAULT_LL_TRIGGER_PK_EN true // disable pull/keep 30 | #define GLITCH_DEFAULT_LL_TRIGGER_PUE true // pull 31 | #define GLITCH_DEFAULT_LL_TRIGGER_PULL_TYPE IOMUXC_PORT_CTL_PUS_22K_PULL_UP 32 | #define GLITCH_DEFAULT_LL_TRIGGER_HYS_EN false // no hysteresis 33 | */ 34 | 35 | #define GLITCH_DEFAULT_UART_TRIGGER_UARTN DEBUG_UARTN 36 | #define GLITCH_DEFAULT_UART_TRIGGER_EXP_BYTE 0xD9 37 | #define GLITCH_DEFAULT_UART_TRIGGER_PK_EN true 38 | #define GLITCH_DEFAULT_UART_TRIGGER_PUE true // pull 39 | #define GLITCH_DEFAULT_UART_TRIGGER_PULL_TYPE IOMUXC_PORT_CTL_PUS_22K_PULL_UP 40 | #define GLITCH_DEFAULT_UART_TRIGGER_HYS_EN true 41 | #define GLITCH_DEFAULT_UART_TRIGGER_BAUD UART_BAUD_115200 42 | #define GLITCH_DEFAULT_UART_TRIGGER_INIT_TX true 43 | #define GLITCH_DEFAULT_UART_TRIGGER_INIT_TX_FIFO true 44 | 45 | enum GLITCH_CONFIG_DEFAULT_TYPES_BITS { 46 | GLITCH_CONFIG_DEFAULT_TYPE_BITS_LOGIC_LEVEL = 0, 47 | GLITCH_CONFIG_DEFAULT_TYPE_BITS_UART, 48 | GLITCH_CONFIG_DEFAULT_TYPE_BITS_FLAG_CHAIN = 4, 49 | GLITCH_CONFIG_DEFAULT_TYPE_BITS_FLAG_NODRIVER, 50 | GLITCH_CONFIG_DEFAULT_TYPE_BITS_FLAG_NOTRIGGER 51 | }; 52 | #define GLITCH_CONFIG_DEFAULT_TYPE_BITMASK_MODES 0b1111 53 | 54 | enum GLITCH_PAD_CTL_BITS { 55 | GLITCH_PAD_CTL_BITS_TEENSY_PAD = 0, 56 | GLITCH_PAD_CTL_BITS_IGNORE = 6, 57 | GLITCH_PAD_CTL_BITS_RECONFIGURE // apply config 58 | }; 59 | #define GLITCH_PAD_CTL_BITMASK_TEENSY_PAD 0x3f 60 | 61 | enum GLITCH_INPUT_PAD_CTL_BITS { 62 | GLITCH_INPUT_PAD_CTL_BITS_TEENSY_UARTN = 0, 63 | GLITCH_INPUT_PAD_CTL_BITS_UART_MODE = 8, 64 | GLITCH_INPUT_PAD_CTL_BITS_PKE, // enable pull/keep 65 | GLITCH_INPUT_PAD_CTL_BITS_PUE, // 0: Keep | 1: Pull 66 | GLITCH_INPUT_PAD_CTL_BITS_PUS, // pull/keep strength 67 | GLITCH_INPUT_PAD_CTL_BITS_HYS = 13, // enable hysteresis 68 | GLITCH_INPUT_PAD_CTL_BITS_TRIGGER_STATE = 16, 69 | GLITCH_INPUT_PAD_CTL_BITS_TRIGGER_UART_WATERMARK = 16 70 | }; 71 | #define GLITCH_INPUT_PAD_CTL_BITMASK_TEENSY_UARTN GLITCH_PAD_CTL_BITMASK_TEENSY_PAD 72 | #define GLITCH_INPUT_PAD_CTL_BITMASK_TEENSY_UART_WATERMARK 0xff 73 | enum GLITCH_OUTPUT_PAD_CTL_BITS { 74 | GLITCH_OUTPUT_PAD_CTL_BITS_ODE = 8, // open-drain mode 75 | GLITCH_OUTPUT_PAD_CTL_BITS_DSE // drive strength 76 | }; 77 | 78 | struct _glitch_config_s { 79 | uint32_t width; 80 | uint32_t offset; 81 | uint32_t offset_mult; 82 | uint32_t trigger_ctl; 83 | uint32_t driver_ctl; 84 | struct { // custom overrides, enables stuff like multi-pad trigger 85 | uint32_t clockspeed; 86 | struct { // driver aka transistor gate ctl 87 | uint32_t mask; // mask, by default 1<lpuart1) 8 | #define UART_2_OFFSET (&((aips_2_s *)AIPS_2_OFFSET)->lpuart2) 9 | #define UART_3_OFFSET (&((aips_2_s *)AIPS_2_OFFSET)->lpuart3) 10 | #define UART_4_OFFSET (&((aips_2_s *)AIPS_2_OFFSET)->lpuart4) 11 | #define UART_5_OFFSET (&((aips_2_s *)AIPS_2_OFFSET)->lpuart5) 12 | #define UART_6_OFFSET (&((aips_2_s *)AIPS_2_OFFSET)->lpuart6) 13 | #define UART_7_OFFSET (&((aips_2_s *)AIPS_2_OFFSET)->lpuart7) 14 | #define UART_8_OFFSET (&((aips_2_s *)AIPS_2_OFFSET)->lpuart8) 15 | 16 | enum UART_BAUD_BITS { 17 | UART_BAUD_BITS_SBR = 0, 18 | UART_BAUD_BITS_SBNS = 13, 19 | UART_BAUD_BITS_RXEDGIE, 20 | UART_BAUD_BITS_LBKDIE, 21 | UART_BAUD_BITS_RESYNCDIS, 22 | UART_BAUD_BITS_BOTHEDGE, 23 | UART_BAUD_BITS_MATCFG, 24 | UART_BAUD_BITS_RDMAE = 21, 25 | UART_BAUD_BITS_TDMAE = 23, 26 | UART_BAUD_BITS_OSR, 27 | UART_BAUD_BITS_M10 = 29, 28 | UART_BAUD_BITS_MAEN2, 29 | UART_BAUD_BITS_MAEN1 30 | }; 31 | 32 | enum UART_CTRL_BITS { 33 | UART_CTRL_BITS_PT = 0, 34 | UART_CTRL_BITS_PE, 35 | UART_CTRL_BITS_ILT, 36 | UART_CTRL_BITS_WAKE, 37 | UART_CTRL_BITS_M, 38 | UART_CTRL_BITS_RSRC, 39 | UART_CTRL_BITS_DOZEEN, 40 | UART_CTRL_BITS_LOOPS, 41 | UART_CTRL_BITS_IDLECFG, 42 | UART_CTRL_BITS_M7 = 11, 43 | UART_CTRL_BITS_MA2IE = 14, 44 | UART_CTRL_BITS_MA1IE, 45 | UART_CTRL_BITS_SBK, 46 | UART_CTRL_BITS_RWU, 47 | UART_CTRL_BITS_RE, 48 | UART_CTRL_BITS_TE, 49 | UART_CTRL_BITS_ILIE, 50 | UART_CTRL_BITS_RIE, 51 | UART_CTRL_BITS_TCIE, 52 | UART_CTRL_BITS_TIE, 53 | UART_CTRL_BITS_PEIE, 54 | UART_CTRL_BITS_FEIE, 55 | UART_CTRL_BITS_NEIE, 56 | UART_CTRL_BITS_ORIE, 57 | UART_CTRL_BITS_TXINV, 58 | UART_CTRL_BITS_TXDIR, 59 | UART_CTRL_BITS_R9T8, 60 | UART_CTRL_BITS_R8T9 61 | }; 62 | 63 | enum UART_DATA_BITS { 64 | UART_DATA_BITS_DATA = 0, 65 | UART_DATA_BITS_IDLINE = 11, 66 | UART_DATA_BITS_RXEMPT, 67 | UART_DATA_BITS_FRETSC, 68 | UART_DATA_BITS_PARITYPE, 69 | UART_DATA_BITS_NOISY 70 | }; 71 | 72 | enum UART_FIFO_BITS { 73 | UART_FIFO_BITS_RXFIFOSIZE = 0, 74 | UART_FIFO_BITS_RXFE = 3, 75 | UART_FIFO_BITS_TXFIFOSIZE, 76 | UART_FIFO_BITS_TXFE = 7, 77 | UART_FIFO_BITS_RXUFE, 78 | UART_FIFO_BITS_TXOFE, 79 | UART_FIFO_BITS_RXIDEN, 80 | UART_FIFO_BITS_RXFLUSH = 14, 81 | UART_FIFO_BITS_TXFLUSH, 82 | UART_FIFO_BITS_RXUF, 83 | UART_FIFO_BITS_TXOF, 84 | UART_FIFO_BITS_RXEMPT = 22, 85 | UART_FIFO_BITS_TXEMPT 86 | }; 87 | 88 | enum UART_STAT_BITS { 89 | UART_STAT_BITS_MA2F = 14, 90 | UART_STAT_BITS_MA1F, 91 | UART_STAT_BITS_PF, 92 | UART_STAT_BITS_FE, 93 | UART_STAT_BITS_NF, 94 | UART_STAT_BITS_OR, 95 | UART_STAT_BITS_IDLE, 96 | UART_STAT_BITS_RDRF, 97 | UART_STAT_BITS_TC, 98 | UART_STAT_BITS_TDRE, 99 | UART_STAT_BITS_RAF, 100 | UART_STAT_BITS_LBKDE, 101 | UART_STAT_BITS_BRK13, 102 | UART_STAT_BITS_RWUID, 103 | UART_STAT_BITS_RXINV, 104 | UART_STAT_BITS_MSBF, 105 | UART_STAT_BITS_RXEDGIF, 106 | UART_STAT_BITS_LBKDIF 107 | }; 108 | 109 | enum UART_WATER_BITS { 110 | UART_WATER_BITS_TXWATER = 0, 111 | UART_WATER_BITS_TXCOUNT = 8, 112 | UART_WATER_BITS_RXWATER = 16, 113 | UART_WATER_BITS_RXCOUNT = 24 114 | }; 115 | 116 | #define UART_WATER_BITMASK_TXWATER 0b11 117 | #define UART_WATER_BITMASK_TXCOUNT 0b111 118 | #define UART_WATER_BITMASK_RXWATER 0b11 119 | #define UART_WATER_BITMASK_RXCOUNT 0b111 120 | 121 | #define UART_GLOBAL_BITS_RST 1 122 | 123 | #define UART_BUS_1_GPIO_BUS 1 124 | #define UART_BUS_2_GPIO_BUS 1 125 | #define UART_BUS_3_GPIO_BUS 1 126 | #define UART_BUS_4_GPIO_BUS 2 127 | #define UART_BUS_5_GPIO_BUS 2 128 | #define UART_BUS_6_GPIO_BUS 1 129 | #define UART_BUS_7_GPIO_BUS 1 130 | 131 | 132 | // BAUD = CLK / ((OSR+1) * SBR) 133 | // pref OSR+1 close to 16 for ~1-2% tol 134 | // CLK is by default 24MHz 135 | enum UART_BAUD_PRECALC { 136 | UART_BAUD_115200 = (BITNVAL(UART_BAUD_BITS_OSR, 15) | BITNVAL(UART_BAUD_BITS_SBR, 13)), // OSR+1 * SBR = 208 vs 208.33 137 | UART_BAUD_38400 = (BITNVAL(UART_BAUD_BITS_OSR, 15) | BITNVAL(UART_BAUD_BITS_SBR, 39)), // OSR+1 * SBR = 624 vs 625 138 | }; 139 | 140 | enum UART_INIT_FLAGS_BITS { 141 | UART_INIT_BITS_TX_FIFO_EN = 0, // enable TX FIFO 142 | UART_INIT_BITS_RX_FIFO_EN, // enable RX FIFO 143 | UART_INIT_BITS_TX_EN, // enable uart transmitter 144 | UART_INIT_BITS_RX_EN, // enable uart receiver 145 | UART_INIT_BITS_TX_INV, // invert tx data 146 | UART_INIT_BITS_RX_INV, // invert rx data 147 | UART_INIT_BITS_MSB_FIRST // reverse bit order 148 | }; 149 | 150 | extern aips_lpuart* uart_regs[9]; 151 | extern uint8_t uart_ccg[9]; 152 | 153 | void uart_init(int bus, int baud, int flags, bool wait); 154 | void uart_write(int bus, unsigned int data); 155 | void uart_print(int bus, char* str); 156 | void uart_printn(int bus, char* str, int n); 157 | unsigned int uart_read(int bus, unsigned int timeout, bool wait); 158 | int uart_scann(int bus, uint8_t* out, int outsize, unsigned int timeout); 159 | int uart_scanns(int bus, char* out, int outsize, unsigned int timeout); 160 | #define uart_rxfifo_flush(bus) (uart_regs[bus]->fifo |= BITN(UART_FIFO_BITS_RXFLUSH)) 161 | #define uart_txfifo_flush(bus) (uart_regs[bus]->fifo |= BITN(UART_FIFO_BITS_TXFLUSH)) 162 | #define uart_wait_tc(bus) while(!(uart_regs[bus]->stat & BITN(UART_STAT_BITS_TC))){}; 163 | 164 | #endif -------------------------------------------------------------------------------- /source/teensy.c: -------------------------------------------------------------------------------- 1 | #include "include/paddr.h" 2 | #include "include/aips.h" 3 | #include "include/utils.h" 4 | #include "include/iomuxc.h" 5 | #include "include/gpio.h" 6 | 7 | #include "include/teensy.h" 8 | 9 | const uint8_t teensy_pad_to_port[TEENSY_PADS_COUNT] = { 10 | TEENSY_PAD_0_PORT, TEENSY_PAD_1_PORT, TEENSY_PAD_2_PORT, TEENSY_PAD_3_PORT, 11 | TEENSY_PAD_4_PORT, TEENSY_PAD_5_PORT, TEENSY_PAD_6_PORT, TEENSY_PAD_7_PORT, 12 | TEENSY_PAD_8_PORT, TEENSY_PAD_9_PORT, TEENSY_PAD_10_PORT, TEENSY_PAD_11_PORT, 13 | TEENSY_PAD_12_PORT, TEENSY_PAD_13_PORT, TEENSY_PAD_14_PORT, TEENSY_PAD_15_PORT, 14 | TEENSY_PAD_16_PORT, TEENSY_PAD_17_PORT, TEENSY_PAD_18_PORT, TEENSY_PAD_19_PORT, 15 | TEENSY_PAD_20_PORT, TEENSY_PAD_21_PORT, TEENSY_PAD_22_PORT, TEENSY_PAD_23_PORT, 16 | TEENSY_PAD_24_PORT, TEENSY_PAD_25_PORT, TEENSY_PAD_26_PORT, TEENSY_PAD_27_PORT, 17 | TEENSY_PAD_28_PORT, TEENSY_PAD_29_PORT, TEENSY_PAD_30_PORT, TEENSY_PAD_31_PORT, 18 | TEENSY_PAD_32_PORT, TEENSY_PAD_33_PORT, TEENSY_PAD_34_PORT, TEENSY_PAD_35_PORT, 19 | TEENSY_PAD_36_PORT, TEENSY_PAD_37_PORT, TEENSY_PAD_38_PORT, TEENSY_PAD_39_PORT 20 | #ifdef TARGET_TEENSY41 21 | , TEENSY_PAD_40_PORT, TEENSY_PAD_41_PORT, TEENSY_PAD_42_PORT, TEENSY_PAD_43_PORT, 22 | TEENSY_PAD_44_PORT, TEENSY_PAD_45_PORT, TEENSY_PAD_46_PORT, TEENSY_PAD_47_PORT, 23 | TEENSY_PAD_48_PORT, TEENSY_PAD_49_PORT, TEENSY_PAD_50_PORT, TEENSY_PAD_51_PORT, 24 | TEENSY_PAD_52_PORT, TEENSY_PAD_53_PORT, TEENSY_PAD_54_PORT 25 | #endif 26 | }; 27 | 28 | uint8_t teensy_pad_to_gpio_bus[TEENSY_PADS_COUNT] = { 29 | TEENSY_PAD_0_BUS, TEENSY_PAD_1_BUS, TEENSY_PAD_2_BUS, TEENSY_PAD_3_BUS, 30 | TEENSY_PAD_4_BUS, TEENSY_PAD_5_BUS, TEENSY_PAD_6_BUS, TEENSY_PAD_7_BUS, 31 | TEENSY_PAD_8_BUS, TEENSY_PAD_9_BUS, TEENSY_PAD_10_BUS, TEENSY_PAD_11_BUS, 32 | TEENSY_PAD_12_BUS, TEENSY_PAD_13_BUS, TEENSY_PAD_14_BUS, TEENSY_PAD_15_BUS, 33 | TEENSY_PAD_16_BUS, TEENSY_PAD_17_BUS, TEENSY_PAD_18_BUS, TEENSY_PAD_19_BUS, 34 | TEENSY_PAD_20_BUS, TEENSY_PAD_21_BUS, TEENSY_PAD_22_BUS, TEENSY_PAD_23_BUS, 35 | TEENSY_PAD_24_BUS, TEENSY_PAD_25_BUS, TEENSY_PAD_26_BUS, TEENSY_PAD_27_BUS, 36 | TEENSY_PAD_28_BUS, TEENSY_PAD_29_BUS, TEENSY_PAD_30_BUS, TEENSY_PAD_31_BUS, 37 | TEENSY_PAD_32_BUS, TEENSY_PAD_33_BUS, TEENSY_PAD_34_BUS, TEENSY_PAD_35_BUS, 38 | TEENSY_PAD_36_BUS, TEENSY_PAD_37_BUS, TEENSY_PAD_38_BUS, TEENSY_PAD_39_BUS 39 | #ifdef TARGET_TEENSY41 40 | , TEENSY_PAD_40_BUS, TEENSY_PAD_41_BUS, TEENSY_PAD_42_BUS, TEENSY_PAD_43_BUS, 41 | TEENSY_PAD_44_BUS, TEENSY_PAD_45_BUS, TEENSY_PAD_46_BUS, TEENSY_PAD_47_BUS, 42 | TEENSY_PAD_48_BUS, TEENSY_PAD_49_BUS, TEENSY_PAD_50_BUS, TEENSY_PAD_51_BUS, 43 | TEENSY_PAD_52_BUS, TEENSY_PAD_53_BUS, TEENSY_PAD_54_BUS 44 | #endif 45 | }; 46 | 47 | uint8_t teensy_uartn_to_imxbus_rx_tx[TEENSY_UARTN_COUNT + 1][3] = { 48 | {0, 0, 0}, // no uart0 49 | {TEENSY_UART1_IMX_BUS, TEENSY_PAD_UART1_RX, TEENSY_PAD_UART1_TX}, 50 | {TEENSY_UART2_IMX_BUS, TEENSY_PAD_UART2_RX, TEENSY_PAD_UART2_TX}, 51 | {TEENSY_UART3_IMX_BUS, TEENSY_PAD_UART3_RX, TEENSY_PAD_UART3_TX}, 52 | {TEENSY_UART4_IMX_BUS, TEENSY_PAD_UART4_RX, TEENSY_PAD_UART4_TX}, 53 | {TEENSY_UART5_IMX_BUS, TEENSY_PAD_UART5_RX, TEENSY_PAD_UART5_TX}, 54 | {TEENSY_UART6_IMX_BUS, TEENSY_PAD_UART6_RX, TEENSY_PAD_UART6_TX}, 55 | {TEENSY_UART7_IMX_BUS, TEENSY_PAD_UART7_RX, TEENSY_PAD_UART7_TX} 56 | #ifdef TARGET_TEENSY41 57 | , {TEENSY_UART8_IMX_BUS, TEENSY_PAD_UART8_RX, TEENSY_PAD_UART8_TX} 58 | #endif 59 | }; 60 | 61 | void teensy_pad_logic_ctrl_tightness(int pad, bool tight, bool wait) { 62 | if ((tight && (teensy_get_pad_gpio_bus(pad) < GPIO_TCGPIO_OFFSET)) || (!tight && (teensy_get_pad_gpio_bus(pad) > GPIO_TCGPIO_OFFSET))) { 63 | teensy_get_pad_gpio_bus(pad) = gpio_get_bus_tightalt(teensy_get_pad_gpio_bus(pad)); 64 | iomuxc_set_tcgpio(teensy_get_pad_gpio_bus(pad), teensy_get_pad_port(pad), 0, wait); 65 | } 66 | } 67 | 68 | int teensy_uart_init(int teensy_uartn, int baud, int init_bitflags, bool wait) { 69 | if (teensy_uartn == 0 || teensy_uartn > TEENSY_UARTN_COUNT) 70 | return -1; 71 | 72 | int imx_bus = teensy_uart_get_imx_bus(teensy_uartn); 73 | 74 | if (init_bitflags & BITN(UART_INIT_BITS_TX_EN)) { 75 | if (teensy_set_pad_ctl(teensy_uart_get_tx_pad(teensy_uartn), -1, TEENSY_PAD_MODE_UART, wait) < 0) 76 | return -2; 77 | if (imx_bus != 1) { // LPUART1 does not have iomuxc input select 78 | // hopefully noone will ever see this atrocity 79 | volatile uint32_t* lpuart2p_tx_input_select = (imx_bus == 2) ? &iomuxc.input_select.lpuart2_tx : &iomuxc.input_select.lpuart3_cts_b; 80 | 81 | lpuart2p_tx_input_select[(imx_bus - 2) * 2] = teensy_get_uartn_isv(teensy_uartn); 82 | while (wait && (lpuart2p_tx_input_select[(imx_bus - 2) * 2] != teensy_get_uartn_isv(teensy_uartn))) {}; 83 | } 84 | } 85 | 86 | if (init_bitflags & BITN(UART_INIT_BITS_RX_EN)) { 87 | if (teensy_set_pad_ctl(teensy_uart_get_rx_pad(teensy_uartn), -1, TEENSY_PAD_MODE_UART, wait) < 0) // maybe add hysteresis? 88 | return -3; 89 | if (imx_bus != 1) { // LPUART1 does not have iomuxc input select 90 | // cute ^2 91 | volatile uint32_t* lpuart2p_rx_input_select = (imx_bus == 2) ? &iomuxc.input_select.lpuart2_rx : &iomuxc.input_select.lpuart2_tx; 92 | 93 | lpuart2p_rx_input_select[(imx_bus - 2) * 2] = teensy_get_uartn_isv(teensy_uartn); 94 | while (wait && (lpuart2p_rx_input_select[(imx_bus - 2) * 2] != teensy_get_uartn_isv(teensy_uartn))) {}; 95 | } 96 | } 97 | 98 | uart_init(imx_bus, baud, init_bitflags, wait); 99 | 100 | return 0; 101 | } -------------------------------------------------------------------------------- /source/include/teensy.h: -------------------------------------------------------------------------------- 1 | #ifndef __TEENSY_H__ 2 | #define __TEENSY_H__ 3 | 4 | #include "defs.h" 5 | #include "gpio.h" 6 | #include "uart.h" 7 | #include "iomuxc.h" 8 | 9 | #include "teensy_pads.h" // pad defs bloat separately 10 | 11 | // customs 12 | #define TEENSY_PAD_ORANGE_LED 13 13 | #define TEENSY_PAD_UART1_RX 0 14 | #define TEENSY_PAD_UART1_TX 1 15 | #define TEENSY_PAD_UART2_RX 7 16 | #define TEENSY_PAD_UART2_TX 8 17 | #define TEENSY_PAD_UART3_RX 15 18 | #define TEENSY_PAD_UART3_TX 14 19 | #define TEENSY_PAD_UART4_RX 16 20 | #define TEENSY_PAD_UART4_TX 17 21 | #define TEENSY_PAD_UART5_RX 21 22 | #define TEENSY_PAD_UART5_TX 20 23 | #define TEENSY_PAD_UART6_RX 25 24 | #define TEENSY_PAD_UART6_TX 24 25 | #define TEENSY_PAD_UART7_RX 28 26 | #define TEENSY_PAD_UART7_TX 29 27 | #ifdef TARGET_TEENSY41 28 | #define TEENSY_PAD_UART8_RX 34 29 | #define TEENSY_PAD_UART8_TX 35 30 | #endif 31 | 32 | // generic mux modes 33 | #define TEENSY_PAD_MODE_UART 2 34 | #define TEENSY_PAD_MODE_GPIO 5 35 | 36 | // UART stuff 37 | #define TEENSY_UART1_IMX_BUS 6 38 | #define TEENSY_UART2_IMX_BUS 4 39 | #define TEENSY_UART3_IMX_BUS 2 40 | #define TEENSY_UART4_IMX_BUS 3 41 | #define TEENSY_UART5_IMX_BUS 8 42 | #define TEENSY_UART6_IMX_BUS 1 43 | #define TEENSY_UART7_IMX_BUS 7 44 | #ifndef TARGET_TEENSY41 45 | #define TEENSY_UARTN_COUNT 7 46 | #define teensy_get_uartn_isv(uartn) ((0x1f10121f >> (uartn * 4)) & 0xf) 47 | #else 48 | #define TEENSY_UARTN_COUNT 8 49 | #define teensy_get_uartn_isv(uartn) (uartn ? ((0x11f10121 >> ((uartn - 1) * 4)) & 0xf) : 0xf) 50 | #define TEENSY_UART8_IMX_BUS 5 51 | #endif 52 | 53 | 54 | // use _direct funcs only with abs args 55 | #define teensy_get_pad_port_direct(pad) TEENSY_PAD_ ## pad ## _PORT 56 | #define teensy_get_pad_gpio_bus_direct(pad) TEENSY_PAD_ ## pad ## _BUS 57 | #define teensy_get_pad_gpio_tcbus_direct(pad) TEENSY_PAD_ ## pad ## _BUS_TCG 58 | #define teensy_pad_logic_set_direct(pad) gpio_set_direct(teensy_get_pad_gpio_bus_direct(pad), teensy_get_pad_port_direct(pad)) 59 | #define teensy_pad_logic_read_direct(pad) gpio_read_direct(teensy_get_pad_gpio_bus_direct(pad), teensy_get_pad_port_direct(pad)) 60 | #define teensy_pad_logic_clear_direct(pad) gpio_clear_direct(teensy_get_pad_gpio_bus_direct(pad), teensy_get_pad_port_direct(pad)) 61 | #define teensy_pad_logic_toggle_direct(pad) gpio_toggle_direct(teensy_get_pad_gpio_bus_direct(pad), teensy_get_pad_port_direct(pad)) 62 | #define teensy_pad_logic_set_indir_direct(pad) gpio_set_indir_direct(teensy_get_pad_gpio_bus_direct(pad), teensy_get_pad_port_direct(pad)) 63 | #define teensy_pad_logic_set_outdir_direct(pad) gpio_set_outdir_direct(teensy_get_pad_gpio_bus_direct(pad), teensy_get_pad_port_direct(pad)) 64 | #define teensy_tcpad_logic_set_direct(pad) gpio_set_direct(teensy_get_pad_gpio_tcbus_direct(pad), teensy_get_pad_port_direct(pad)) 65 | #define teensy_tcpad_logic_read_direct(pad) gpio_read_direct(teensy_get_pad_gpio_tcbus_direct(pad), teensy_get_pad_port_direct(pad)) 66 | #define teensy_tcpad_logic_clear_direct(pad) gpio_clear_direct(teensy_get_pad_gpio_tcbus_direct(pad), teensy_get_pad_port_direct(pad)) 67 | #define teensy_tcpad_logic_toggle_direct(pad) gpio_toggle_direct(teensy_get_pad_gpio_tcbus_direct(pad), teensy_get_pad_port_direct(pad)) 68 | #define teensy_tcpad_logic_set_indir_direct(pad) gpio_set_indir_direct(teensy_get_pad_gpio_tcbus_direct(pad), teensy_get_pad_port_direct(pad)) 69 | #define teensy_tcpad_logic_set_outdir_direct(pad) gpio_set_outdir_direct(teensy_get_pad_gpio_tcbus_direct(pad), teensy_get_pad_port_direct(pad)) 70 | 71 | // wrappers 72 | #define teensy_get_pad_port(pad) teensy_pad_to_port[pad] 73 | #define teensy_get_pad_gpio_bus(pad) teensy_pad_to_gpio_bus[pad] 74 | #define teensy_pad_logic_set(pad, wait) gpio_port_set(teensy_get_pad_gpio_bus(pad), teensy_get_pad_port(pad), wait) 75 | #define teensy_pad_logic_clear(pad, wait) gpio_port_clear(teensy_get_pad_gpio_bus(pad), teensy_get_pad_port(pad), wait) 76 | #define teensy_pad_logic_toggle(pad, wait) gpio_port_toggle(teensy_get_pad_gpio_bus(pad), teensy_get_pad_port(pad), wait) 77 | #define teensy_pad_logic_mode(pad, output, wait) gpio_port_mode(teensy_get_pad_gpio_bus(pad), teensy_get_pad_port(pad), output, wait) 78 | #define teensy_pad_logic_read(pad, wait, wait_target) gpio_port_read(teensy_get_pad_gpio_bus(pad), teensy_get_pad_port(pad), wait, wait_target) 79 | #define teensy_pad_ctl(pad) iomuxc_port_ctl(teensy_get_pad_port(pad), teensy_get_pad_gpio_bus(pad)) 80 | #define teensy_pad_ctl_mux(pad) iomuxc_port_ctl_mux(teensy_get_pad_port(pad), teensy_get_pad_gpio_bus(pad)) 81 | #define teensy_set_pad_ctl(pad, ctl, mux_ctl, wait) iomuxc_set_port_ctl(teensy_get_pad_port(pad), teensy_get_pad_gpio_bus(pad), ctl, mux_ctl, wait) 82 | #define teensy_uart_get_imx_bus(uartn) teensy_uartn_to_imxbus_rx_tx[uartn][0] 83 | #define teensy_uart_get_rx_pad(uartn) teensy_uartn_to_imxbus_rx_tx[uartn][1] 84 | #define teensy_uart_get_tx_pad(uartn) teensy_uartn_to_imxbus_rx_tx[uartn][2] 85 | #define teensy_uart_write(uartn, data) uart_write(teensy_uart_get_imx_bus(uartn), data) 86 | #define teensy_uart_print(uartn, str) uart_print(teensy_uart_get_imx_bus(uartn), str) 87 | #define teensy_uart_printn(uartn, str, n) uart_printn(teensy_uart_get_imx_bus(uartn), str, n) 88 | #define teensy_uart_read(uartn, timeout, wait) uart_read(teensy_uart_get_imx_bus(uartn), timeout, wait) 89 | #define teensy_uart_scann(uartn, out, out_size, timeout) uart_scann(teensy_uart_get_imx_bus(uartn), out, out_size, timeout) 90 | #define teensy_uart_scanns(uartn, out, out_size, timeout) uart_scanns(teensy_uart_get_imx_bus(uartn), out, out_size, timeout) 91 | #define teensy_uart_rxfifo_flush(uartn) uart_rxfifo_flush(teensy_uart_get_imx_bus(uartn)) 92 | #define teensy_uart_txfifo_flush(uartn) uart_txfifo_flush(teensy_uart_get_imx_bus(uartn)) 93 | #define teensy_uart_wait_tc(uartn) uart_wait_tc(teensy_uart_get_imx_bus(uartn)) 94 | 95 | extern const uint8_t teensy_pad_to_port[TEENSY_PADS_COUNT]; 96 | extern uint8_t teensy_pad_to_gpio_bus[TEENSY_PADS_COUNT]; 97 | extern uint8_t teensy_uartn_to_imxbus_rx_tx[TEENSY_UARTN_COUNT + 1][3]; 98 | 99 | void teensy_pad_logic_ctrl_tightness(int pad, bool tight, bool wait); 100 | int teensy_uart_init(int teensy_uartn, int baud, int init_bitflags, bool wait); 101 | 102 | #endif -------------------------------------------------------------------------------- /source/rp.c: -------------------------------------------------------------------------------- 1 | #include "include/defs.h" 2 | #include "include/clib.h" 3 | #include "include/debug.h" 4 | #include "include/utils.h" 5 | #include "include/glitch.h" 6 | #include "include/custom.h" 7 | #include "include/cfg.h" 8 | 9 | #include "include/rpc.h" 10 | 11 | void rpc_loop(void) { 12 | uint32_t cret; 13 | rpc_cmd_s cmd; 14 | uint32_t data[0x10]; 15 | uint32_t reply_delay = RPC_WRITE_DELAY; 16 | printf("entering RPC mode\n"); 17 | while (true) { 18 | memset(&cmd, 0, sizeof(rpc_cmd_s)); 19 | memset(data, 0, sizeof(data)); 20 | rxflush(); 21 | print(RPC_WATERMARK "G0\n"); 22 | scanb(&cmd, sizeof(rpc_cmd_s)); 23 | if (cmd.magic != RPC_MAGIC || cmd.hash != (cmd.id + cmd.data_size)) { 24 | print(RPC_WATERMARK "E1\n"); 25 | continue; 26 | } 27 | if (cmd.data_size) { 28 | print(RPC_WATERMARK "G1\n"); 29 | scanb(data, cmd.data_size); 30 | } 31 | 32 | cret = -1; 33 | switch (cmd.id) { 34 | case RPC_CMD_NOP: 35 | cret = get_build_timestamp(); 36 | break; 37 | case RPC_CMD_READ32: 38 | cret = vp data[0]; 39 | break; 40 | case RPC_CMD_WRITE32: 41 | vp(data[0]) = data[1]; 42 | cret = 0; 43 | break; 44 | case RPC_CMD_MEMSET: 45 | cret = (uint32_t)memset((void*)data[0], data[1] & 0xFF, data[2]); 46 | break; 47 | case RPC_CMD_MEMCPY: 48 | cret = (uint32_t)memcpy((void*)data[0], (void*)data[1], data[2]); 49 | break; 50 | case RPC_CMD_SET_DELAY: 51 | cret = reply_delay; 52 | reply_delay = data[0]; 53 | break; 54 | case RPC_CMD_STOP_RPC: 55 | cret = 0; 56 | break; 57 | case RPC_CMD_HEXDUMP: 58 | hexdump(data[0], data[1], data[2]); 59 | cret = 0; 60 | break; 61 | case RPC_CMD_MEMSET32: 62 | cret = (uint32_t)memset32((void*)data[0], data[1], data[2]); 63 | break; 64 | case RPC_CMD_GLITCH_PREP_LL: 65 | cret = glitch_configure_default(BITN(GLITCH_CONFIG_DEFAULT_TYPE_BITS_LOGIC_LEVEL) | (data[3] << GLITCH_CONFIG_DEFAULT_TYPE_BITS_FLAG_CHAIN), data[0], data[1], data[2], data[4], data[5], data[6]); 66 | break; 67 | case RPC_CMD_GLITCH_ARM: 68 | if (data[0]) 69 | printf(RPC_WATERMARK "ARMED!\n", cret); 70 | glitch_arm(g_glitch_varray); 71 | cret = 0; 72 | break; 73 | case RPC_CMD_GLITCH_PREP_CUSTOM: 74 | cret = glitch_configure((glitch_config_s*)data, false); 75 | break; 76 | case RPC_CMD_GLITCH_PREP_UART: 77 | cret = glitch_configure_default(BITN(GLITCH_CONFIG_DEFAULT_TYPE_BITS_UART) | (data[3] << GLITCH_CONFIG_DEFAULT_TYPE_BITS_FLAG_CHAIN), data[0], data[1], data[2], data[4], data[5], data[6]); 78 | break; 79 | case RPC_CMD_SET_CLK: 80 | if (data[2]) 81 | cret = g_glitch_clkf = data[1] ?: ccm_calculate_core_clkf(data[0]); 82 | else 83 | cret = ccm_set_core_clkf(data[1], data[0]); 84 | break; 85 | case RPC_CMD_GLITCH_PREP_CUSTOM_CHAIN: 86 | cret = glitch_configure((glitch_config_s*)data, true); 87 | break; 88 | case RPC_CMD_GLITCH_PREP_NONE: 89 | cret = glitch_configure_default(BITN(GLITCH_CONFIG_DEFAULT_TYPE_BITS_FLAG_NOTRIGGER) | (data[3] << GLITCH_CONFIG_DEFAULT_TYPE_BITS_FLAG_CHAIN), data[0], data[1], data[2], 0, 0, data[4]); 90 | break; 91 | case RPC_CMD_CUSTOM: 92 | cret = (uint32_t)custom_main(data[0], data[1], data[2], data); 93 | break; 94 | case RPC_CMD_UART_INIT: 95 | cret = (uint32_t)teensy_uart_init(data[0], data[1], data[2], true); 96 | break; 97 | case RPC_CMD_PAD_CONFIGURE: 98 | cret = (uint32_t)teensy_set_pad_ctl(data[0], data[1], data[2], true); 99 | break; 100 | case RPC_CMD_PAD_CTRL_LOGIC: // arg0: func, arg1: pad, arg2: wait 101 | cret = 0; 102 | switch (data[0]) { 103 | case RPC_CMD_PAD_CTRL_LOGIC_CLEAR: 104 | teensy_pad_logic_clear(data[1], data[2]); 105 | break; 106 | case RPC_CMD_PAD_CTRL_LOGIC_SET: 107 | teensy_pad_logic_set(data[1], data[2]); 108 | break; 109 | case RPC_CMD_PAD_CTRL_LOGIC_TOGGLE: 110 | teensy_pad_logic_toggle(data[1], data[2]); 111 | break; 112 | case RPC_CMD_PAD_CTRL_LOGIC_MODE: // arg3: output? 113 | cret = teensy_pad_logic_mode(data[1], data[3], data[2]); 114 | break; 115 | case RPC_CMD_PAD_CTRL_LOGIC_READ: // arg3: wait target 116 | cret = teensy_pad_logic_read(data[1], data[2], data[3]); 117 | break; 118 | case RPC_CMD_PAD_CTRL_LOGIC_TIGHTNESS: // arg3: tight? 119 | teensy_pad_logic_ctrl_tightness(data[1], data[3], data[2]); 120 | break; 121 | default: 122 | break; 123 | } 124 | break; 125 | case RPC_CMD_GLITCH_SET_CHAIN_MAX: // arg0: new max chain element count, arg1: use """"heap""""?, arg2: memset0 the varray? 126 | if (data[1]) { 127 | g_glitch_varray = (glitch_varray_s *)&cfg_prog_bss_end; 128 | g_glitch_max_chain_n = data[0] ?: GLITCH_STATIC_CHAIN_N; 129 | } else { 130 | g_glitch_varray = g_static_glitch_varray; 131 | g_glitch_max_chain_n = (data[0] && (data[0] <= GLITCH_STATIC_CHAIN_N)) ? data[0] : GLITCH_STATIC_CHAIN_N; 132 | } 133 | if (data[2]) 134 | memset32(g_glitch_varray, 0, (g_glitch_max_chain_n * sizeof(glitch_varray_s))); 135 | cret = (uint32_t)g_glitch_varray; 136 | break; 137 | case RPC_CMD_GET_SP: 138 | cret = 0; 139 | asm volatile ("mov %0, sp\n\t" : "=r" (cret)); 140 | break; 141 | case RPC_CMD_GLITCH_LOOP: 142 | if (data[0]) 143 | printf(RPC_WATERMARK "LOOPIN\n", cret); 144 | cret = glitch_loop_chain(g_glitch_varray); 145 | break; 146 | default: 147 | break; 148 | } 149 | 150 | delay(reply_delay); 151 | printf(RPC_WATERMARK "%X\n", cret); 152 | 153 | if (cmd.id == RPC_CMD_STOP_RPC) 154 | break; 155 | } 156 | 157 | printf("exiting RPC mode\n"); 158 | } -------------------------------------------------------------------------------- /source/include/ccm.h: -------------------------------------------------------------------------------- 1 | #ifndef __CCM_H__ 2 | #define __CCM_H__ 3 | 4 | #include "paddr.h" 5 | #include "aips.h" 6 | 7 | #define ccm ((aips_1_s*)AIPS_1_OFFSET)->ccm 8 | #define anatop ((aips_1_s*)AIPS_1_OFFSET)->anatop 9 | 10 | enum ANATOP_PLL_ARM_BITS { 11 | ANATOP_PLL_ARM_BITS_DIV_SELECT = 0, 12 | ANATOP_PLL_ARM_BITS_POWERDOWN = 12, 13 | ANATOP_PLL_ARM_BITS_ENABLE, 14 | ANATOP_PLL_ARM_BITS_BYPASS_CLK_SRC, 15 | ANATOP_PLL_ARM_BITS_BYPASS = 16, 16 | ANATOP_PLL_ARM_BITS_LOCK = 31 17 | }; 18 | 19 | #define ANATOP_PLL_ARM_BITMASK_DIV_SELECT 0b1111111 20 | #define ANATOP_PLL_ARM_BITMASK_BYPASS_CLK_SRC 0b11 21 | 22 | #define CCM_CACCR_BITS_ARM_PODF 0 23 | #define CCM_CACCR_BITMASK_ARM_PODF 0b111 24 | 25 | enum CCM_CBCDR_BITS { 26 | CCM_CBCDR_BITS_SEMC_CLK_SEL = 6, 27 | CCM_CBCDR_BITS_SEMC_ALT_CLK_SEL, 28 | CCM_CBCDR_BITS_IPG_PODF, 29 | CCM_CBCDR_BITS_AHB_PODF = 10, 30 | CCM_CBCDR_BITS_SEMC_PODF = 16, 31 | CCM_CBCDR_BITS_UNK_P_RESERVED = 19, // preserve this on reg changes 32 | CCM_CBCDR_BITS_PERIPH_CLK_SEL = 25, 33 | CCM_CBCDR_BITS_PERIPH_CLK2_PODF = 27 34 | }; 35 | 36 | #define CCM_CBCDR_BITMASK_UNK_P_RESERVED 0b111111 37 | #define CCM_CBCDR_BITMASK_AHB_PODF 0b111 38 | #define CCM_CBCDR_BITMASK_IPG_PODF 0b11 39 | 40 | enum CCM_CSCDR1_BITS { 41 | CCM_CSCDR1_BITS_UART_CLK_PODF, 42 | CCM_CSCDR1_BITS_UART_CLK_SEL = 6, 43 | CCM_CSCDR1_BITS_USDHC1_PODF = 11, 44 | CCM_CSCDR1_BITS_USDHC2_PODF = 16, 45 | CCM_CSCDR1_BITS_TRACE_PODF = 25, 46 | }; 47 | 48 | #define CCM_CSCDR1_BITMASK_UART_CLK_PODF 0b111111 49 | 50 | enum CCM_CDHIPR_BITS { 51 | CCM_CDHIPR_BITS_SEMC_PODF_BUSY = 0, 52 | CCM_CDHIPR_BITS_AHB_PODF_BUSY, 53 | CCM_CDHIPR_BITS_PERIPH2_CLK_SEL_BUSY = 3, 54 | CCM_CDHIPR_BITS_PERIPH_CLK_SEL_BUSY = 5, 55 | CCM_CDHIPR_BITS_ARM_PODF_BUSY = 16 56 | }; 57 | 58 | #define CCM_MELT_ARM_FREQ 984000000 59 | #define CCM_MAX_OC_ARM_FREQ 792000000 60 | #define CCM_MAX_ARM_FREQ 600000000 61 | #define CCM_FULL_SPEED_ARM_FREQ 528000000 62 | #define CCM_MIN_ARM_FREQ 24000000 63 | #define CCM_MAX_PLL_ARM_FREQ 1300000000 64 | #define CCM_MIN_PLL_ARM_FREQ 650000000 65 | #define CCM_PLL_ARM_REF_OSC_FREQ 24000000 // yh 66 | #define CCM_MAX_IPG_FREQ 150000000 67 | #define CCM_FULL_SPEED_IPG_FREQ 132000000 68 | 69 | #define CCM_1150MV_MAX_IPG_FREQ CCM_FULL_SPEED_IPG_FREQ 70 | #define CCM_1150MV_MAX_ARM_FREQ CCM_FULL_SPEED_ARM_FREQ 71 | #define CCM_1250MV_MAX_ARM_FREQ CCM_MAX_ARM_FREQ 72 | #define CCM_1400MV_MAX_ARM_FREQ CCM_MAX_OC_ARM_FREQ 73 | 74 | #define CCM_ARM_CLKF_984MHZ (82 | (1 << 8) | (1 << 16) | (4 << 24)) 75 | #define CCM_ARM_CLKF_792MHZ (66 | (1 << 8) | (1 << 16) | (4 << 24)) 76 | #define CCM_ARM_CLKF_600MHZ (100 | (2 << 8) | (1 << 16) | (4 << 24)) 77 | #define CCM_ARM_CLKF_528MHZ (88 | (2 << 8) | (1 << 16) | (4 << 24)) 78 | #define CCM_ARM_CLKF_480MHZ (80 | (2 << 8) | (1 << 16) | (4 << 24)) 79 | #define CCM_ARM_CLKF_396MHZ (66 | (2 << 8) | (1 << 16) | (3 << 24)) 80 | #define CCM_ARM_CLKF_300MHZ (100 | (4 << 8) | (1 << 16) | (2 << 24)) 81 | #define CCM_ARM_CLKF_200MHZ (100 | (6 << 8) | (1 << 16) | (2 << 24)) 82 | #define CCM_ARM_CLKF_100MHZ (100 | (6 << 8) | (2 << 16) | (1 << 24)) 83 | #define CCM_ARM_CLKF_24MHZ (56 | (7 << 8) | (4 << 16) | (1 << 24)) 84 | 85 | #define CCM_ARM_CLKF_LP CCM_ARM_CLKF_24MHZ 86 | #define CCM_ARM_CLKF_DEFAULT CCM_ARM_CLKF_396MHZ 87 | #define CCM_ARM_CLKF_FULL_SPEED CCM_ARM_CLKF_528MHZ // normal, safe freq 88 | #define CCM_ARM_CLKF_OVERDRIVE CCM_ARM_CLKF_600MHZ // reqs higher voltage, shortens lifespan 89 | #define CCM_ARM_CLKF_OC CCM_ARM_CLKF_792MHZ // ^ + cooler required 90 | #define CCM_ARM_CLKF_MELT CCM_ARM_CLKF_984MHZ // ^ + it will probably melt 91 | 92 | enum CCM_CORE_CLKF_BITS { 93 | CCM_CORE_CLKF_BITS_DIV_SELECT = 0, 94 | CCM_CORE_CLKF_BITS_ARM_PODF = 8, 95 | CCM_CORE_CLKF_BITS_AHB_PODF = 16, 96 | CCM_CORE_CLKF_BITS_IPG_PODF = 24 97 | }; 98 | 99 | enum CCM_CCG_CLOCK_ACTIVITY_MODES { 100 | CCM_CCG_ALWAYS_OFF = 0, 101 | CCM_CCG_RUN_MODE_ONLY, 102 | CCM_CCG_ALWAYS_ON = 0b11 103 | }; 104 | #define CCM_CCGR_DEVICE_BITMASK 0b11 105 | 106 | enum CCM_CCG_DEVICES { 107 | CCM_CCG_AIPS_TZ1 = 0, 108 | CCM_CCG_AIPS_TZ2, 109 | CCM_CCG_MQS, 110 | CCM_CCG_SIM_M_R = 4, 111 | CCM_CCG_DCP, 112 | CCM_CCG_LPUART3, 113 | CCM_CCG_CAN1_BUS, 114 | CCM_CCG_CAN1_SERIAL, 115 | CCM_CCG_CAN2_BUS, 116 | CCM_CCG_CAN2_SERIAL, 117 | CCM_CCG_TRACE, 118 | CCM_CCG_GPT2_BUS, 119 | CCM_CCG_GPT2_SERIAL, 120 | CCM_CCG_LPUART2, 121 | CCM_CCG_GPIO2, 122 | CCM_CCG_LPSPI1, 123 | CCM_CCG_LPSPI2, 124 | CCM_CCG_LPSPI3, 125 | CCM_CCG_LPSPI4, 126 | CCM_CCG_ADC2, 127 | CCM_CCG_ENET, 128 | CCM_CCG_PIT, 129 | CCM_CCG_AOI2, 130 | CCM_CCG_ADC1, 131 | CCM_CCG_SEMC_EXSC, 132 | CCM_CCG_GPT1_BUS, 133 | CCM_CCG_GPT1_SERIAL, 134 | CCM_CCG_LPUART4, 135 | CCM_CCG_GPIO1, 136 | CCM_CCG_CSU, 137 | CCM_CCG_GPIO5, 138 | CCM_CCG_OCRAM_EXSC, 139 | CCM_CCG_CSI, 140 | CCM_CCG_IOMUXC_SNVS, 141 | CCM_CCG_LPI2C1, 142 | CCM_CCG_LPI2C2, 143 | CCM_CCG_LPI2C3, 144 | CCM_CCG_OCOTP, 145 | CCM_CCG_XBAR3, 146 | CCM_CCG_IPMUX1, 147 | CCM_CCG_IPMUX2, 148 | CCM_CCG_IPMUX3, 149 | CCM_CCG_XBAR1, 150 | CCM_CCG_XBA, 151 | CCM_CCG_GPIO3, 152 | CCM_CCG_LCD, 153 | CCM_CCG_PXP, 154 | CCM_CCG_FLEXIO2, 155 | CCM_CCG_LPUART5, 156 | CCM_CCG_SEMC, 157 | CCM_CCG_LPUART6, 158 | CCM_CCG_AOI1, 159 | CCM_CCG_LCDIF_PIX, 160 | CCM_CCG_GPIO4, 161 | CCM_CCG_EWM, 162 | CCM_CCG_WDOG1, 163 | CCM_CCG_FLEXRAM, 164 | CCM_CCG_ACMP1, 165 | CCM_CCG_ACMP2, 166 | CCM_CCG_ACMP3, 167 | CCM_CCG_ACMP4, 168 | CCM_CCG_OCRAM, 169 | CCM_CCG_IOMUXC_SNVS_GPR, 170 | CCM_CCG_SIM_M7_R, 171 | CCM_CCG_IOMUXC, 172 | CCM_CCG_IOMUXC_GPR, 173 | CCM_CCG_BEE, 174 | CCM_CCG_SIM_M7, 175 | CCM_CCG_TSC_DIG, 176 | CCM_CCG_SIM_M, 177 | CCM_CCG_SIM_EMC, 178 | CCM_CCG_PWM1, 179 | CCM_CCG_PWM2, 180 | CCM_CCG_PWM3, 181 | CCM_CCG_PWM4, 182 | CCM_CCG_QDC1, 183 | CCM_CCG_QDC2, 184 | CCM_CCG_QDC3, 185 | CCM_CCG_QDC4, 186 | CCM_CCG_ROM, 187 | CCM_CCG_FLEXIO1, 188 | CCM_CCG_WDOG3, 189 | CCM_CCG_DMA, 190 | CCM_CCG_KPP, 191 | CCM_CCG_WDOG2, 192 | CCM_CCG_AIPS_TZ4, 193 | CCM_CCG_SPDIF, 194 | CCM_CCG_SIM_MAIN, 195 | CCM_CCG_SAI1, 196 | CCM_CCG_SAI2, 197 | CCM_CCG_SAI3, 198 | CCM_CCG_LPUART1, 199 | CCM_CCG_LPUART7, 200 | CCM_CCG_SNVS_HP, 201 | CCM_CCG_SNVS_LP, 202 | CCM_CCG_USBOH3, 203 | CCM_CCG_USDHC1, 204 | CCM_CCG_USDHC2, 205 | CCM_CCG_DCDC, 206 | CCM_CCG_IPMUX4, 207 | CCM_CCG_FLEXSPI, 208 | CCM_CCG_TRNG, 209 | CCM_CCG_LPUART8, 210 | CCM_CCG_TIMER4, 211 | CCM_CCG_AIPS_TZ3, 212 | CCM_CCG_SIM_PER, 213 | CCM_CCG_ANADIG, 214 | CCM_CCG_LPI2C4, 215 | CCM_CCG_TIMER1, 216 | CCM_CCG_TIMER2, 217 | CCM_CCG_TIMER3, 218 | CCM_CCG_ENET2, 219 | CCM_CCG_FLEXSPI2, 220 | CCM_CCG_AXBS_I, 221 | CCM_CCG_CAN3_BUS, 222 | CCM_CCG_CAN3_SERIAL, 223 | CCM_CCG_AIPS_LITE, 224 | CCM_CCG_FLEXIO3 225 | }; 226 | 227 | #define CCM_CCGR_DEVICE_REG_N(device) (device >> 4) 228 | #define CCM_CCGR_DEVICE_BIT_N(device) ((device & 0b1111) << 1) 229 | 230 | int ccm_set_core_clkf(int core_clkf, int desired_freq); 231 | int ccm_calculate_core_clkf(int desired_freq); 232 | void ccm_control_gate(int device, int activity_mode, bool wait); 233 | void ccm_set_uart_clk(bool sauce_osc_clk_24m, int sauce_div_p2, bool wait); 234 | #define ccm_get_core_freq() (((CCM_PLL_ARM_REF_OSC_FREQ * ((anatop.pll_arm.dr & ANATOP_PLL_ARM_BITMASK_DIV_SELECT) >> 1)) / (ccm.cacrr + 1)) / (((ccm.cbcdr >> CCM_CBCDR_BITS_AHB_PODF) & CCM_CBCDR_BITMASK_AHB_PODF) + 1)) 235 | #define ccm_get_core_clkf() ( \ 236 | BITNVAL(CCM_CORE_CLKF_BITS_DIV_SELECT, (anatop.pll_arm.dr & ANATOP_PLL_ARM_BITMASK_DIV_SELECT)) \ 237 | | BITNVAL(CCM_CORE_CLKF_BITS_ARM_PODF, (((ccm.cacrr >> CCM_CACCR_BITS_ARM_PODF) & CCM_CACCR_BITMASK_ARM_PODF) + 1)) \ 238 | | BITNVAL(CCM_CORE_CLKF_BITS_AHB_PODF, (((ccm.cbcdr >> CCM_CBCDR_BITS_AHB_PODF) & CCM_CBCDR_BITMASK_AHB_PODF) + 1)) \ 239 | | BITNVAL(CCM_CORE_CLKF_BITS_IPG_PODF, (((ccm.cbcdr >> CCM_CBCDR_BITS_IPG_PODF) & CCM_CBCDR_BITMASK_IPG_PODF) + 1)) \ 240 | ) 241 | 242 | #endif -------------------------------------------------------------------------------- /source/ccm.c: -------------------------------------------------------------------------------- 1 | #include "include/paddr.h" 2 | #include "include/aips.h" 3 | #include "include/utils.h" 4 | #include "include/debug.h" 5 | #include "include/dcdc.h" 6 | 7 | #include "include/ccm.h" 8 | 9 | void ccm_control_gate(int device, int activity_mode, bool wait) { 10 | // break down the reg update op into smaller ops, it shows fetch-update hazards 11 | // and optimized its the same as a cute one-liner anyways 12 | uint32_t reg_data = ccm.ccgr[CCM_CCGR_DEVICE_REG_N(device)]; 13 | reg_data &= ~(BITNVAL(CCM_CCGR_DEVICE_BIT_N(device), CCM_CCGR_DEVICE_BITMASK)); 14 | reg_data |= BITNVAL(CCM_CCGR_DEVICE_BIT_N(device), activity_mode & CCM_CCGR_DEVICE_BITMASK); 15 | // maybe disable interrupts between fetch-update, and what about auto-switches and pendings? 16 | ccm.ccgr[CCM_CCGR_DEVICE_REG_N(device)] = reg_data; 17 | while (wait && ( 18 | (ccm.ccgr[CCM_CCGR_DEVICE_REG_N(device)] & BITNVAL(CCM_CCGR_DEVICE_BIT_N(device), CCM_CCGR_DEVICE_BITMASK)) 19 | != BITNVAL(CCM_CCGR_DEVICE_BIT_N(device), activity_mode & CCM_CCGR_DEVICE_BITMASK) 20 | )) { 21 | }; 22 | } 23 | 24 | /* 25 | Calculate ccm_set_core_clkf's core_clkf arg 26 | for a given desired arm frequency 27 | 28 | Based on the i.MX RT1060 Processor Reference Manual 29 | Rev. 3, 07/2021 30 | https://www.nxp.com/docs/en/reference-manual/IMXRT1060RM.pdf 31 | page 1010 32 | 33 | Fpll = Fref * div_select / 2 34 | Fpll: PLL_ARM output freq, range 650-1300 Mhz 35 | Fref: 24Mhz osci by default <= we set it to that anyways here 36 | 37 | Farm = Fpll / arm_podf / ahb_podf, range up to 600Mhz without oc, 984Mhz with oc 38 | Farm: ARM clock freq 39 | 40 | Fahb = Farm, TC^ 41 | Fahb: ARM High Speed Bus clock freq 42 | 43 | Fipg = Fahb / ipg_podf, range up to 150Mhz => TODO: confirm 44 | Fipg: IPS Bus clock freq 45 | 46 | Core_CLKF = div_select | (arm_podf << 8) | (ahb_podf << 16) | (ipg_podf << 24) 47 | */ 48 | int ccm_calculate_core_clkf(int desired_freq) { 49 | int final_div_select = 0; 50 | int final_arm_podf = 0; 51 | int final_ahb_podf = 0; 52 | int final_Farm = 0; 53 | int ipg_podf = 0; 54 | 55 | if (desired_freq < CCM_MIN_ARM_FREQ || desired_freq > CCM_MELT_ARM_FREQ) 56 | return -1; 57 | 58 | int min_diff = 0x7fffffff; 59 | for (int div_select = 1; div_select <= ANATOP_PLL_ARM_BITMASK_DIV_SELECT; div_select++) { 60 | int Fpll = CCM_PLL_ARM_REF_OSC_FREQ * (div_select >> 1); 61 | if (Fpll >= CCM_MIN_PLL_ARM_FREQ && Fpll <= CCM_MAX_PLL_ARM_FREQ) { 62 | for (int ahb_podf = 1; ahb_podf <= (CCM_CBCDR_BITMASK_AHB_PODF + 1); ahb_podf++) { 63 | for (int arm_podf = 1; arm_podf <= (CCM_CACCR_BITMASK_ARM_PODF + 1); arm_podf++) { 64 | int Farm = (Fpll / ahb_podf) / arm_podf; 65 | int diff = Farm - desired_freq; 66 | if (diff < 0) 67 | diff = -diff; 68 | if (diff < min_diff) { 69 | min_diff = diff; 70 | final_Farm = Farm; 71 | final_div_select = div_select; 72 | final_ahb_podf = ahb_podf; 73 | final_arm_podf = arm_podf; 74 | } 75 | } 76 | } 77 | } 78 | } 79 | 80 | if (!final_div_select) 81 | return -2; 82 | 83 | ipg_podf = (final_Farm + (CCM_MAX_IPG_FREQ - 1)) / CCM_MAX_IPG_FREQ; 84 | if (ipg_podf > (CCM_MAX_ARM_FREQ / CCM_MAX_IPG_FREQ)) 85 | ipg_podf = (CCM_MAX_ARM_FREQ / CCM_MAX_IPG_FREQ); 86 | 87 | uint32_t clkf = BITNVAL(CCM_CORE_CLKF_BITS_DIV_SELECT, final_div_select) 88 | | BITNVAL(CCM_CORE_CLKF_BITS_ARM_PODF, final_arm_podf) 89 | | BITNVAL(CCM_CORE_CLKF_BITS_AHB_PODF, final_ahb_podf) 90 | | BITNVAL(CCM_CORE_CLKF_BITS_IPG_PODF, ipg_podf); 91 | 92 | /* 93 | printf("calculate_core_cklf: %x\n desired f: %x\n got f: %x\n div_select: %x\n arm_podf: %x\n ahb_podf: %x\n ipg_podf: %x\n", 94 | clkf, 95 | desired_freq, 96 | final_Farm, 97 | final_div_select, 98 | final_arm_podf, 99 | final_ahb_podf, 100 | ipg_podf 101 | );*/ 102 | 103 | return clkf; 104 | } 105 | 106 | int ccm_set_core_clkf(int core_clkf, int desired_freq) { 107 | // we can slowly calc args here 108 | if (!core_clkf && desired_freq) { 109 | core_clkf = ccm_calculate_core_clkf(desired_freq); 110 | if (core_clkf < 0) 111 | return -1; 112 | } 113 | 114 | // extract args 115 | int div_select = (core_clkf >> CCM_CORE_CLKF_BITS_DIV_SELECT) & ANATOP_PLL_ARM_BITMASK_DIV_SELECT; 116 | int arm_podf = (core_clkf >> CCM_CORE_CLKF_BITS_ARM_PODF) & ((CCM_CACCR_BITMASK_ARM_PODF << 1) | 1); 117 | int ahb_podf = (core_clkf >> CCM_CORE_CLKF_BITS_AHB_PODF) & ((CCM_CBCDR_BITMASK_AHB_PODF << 1) | 1); 118 | int ipg_podf = (core_clkf >> CCM_CORE_CLKF_BITS_IPG_PODF) & ((CCM_CBCDR_BITMASK_IPG_PODF << 1) | 1); 119 | if (!(div_select && arm_podf && ahb_podf && ipg_podf)) 120 | return -2; 121 | 122 | // validate 123 | int Farm = ((CCM_PLL_ARM_REF_OSC_FREQ * (div_select >> 1)) / arm_podf) / ahb_podf; 124 | printf("ccm_set_core_clkf: %X [ %X | %X | %X | %X ]\n", Farm, div_select, arm_podf, ahb_podf, ipg_podf); 125 | if (Farm < CCM_MIN_ARM_FREQ || ((Farm > CCM_MAX_OC_ARM_FREQ) && (Farm != CCM_MELT_ARM_FREQ))) 126 | return -3; 127 | 128 | // min soc voltage for overdrive: 1.25v, OC: 1.4v, melt: 1.6v 129 | int new_voltage = dcdc_get_vdd_soc(); 130 | if (Farm > CCM_1150MV_MAX_ARM_FREQ) { 131 | if (Farm > CCM_1250MV_MAX_ARM_FREQ) { 132 | if (Farm > CCM_1400MV_MAX_ARM_FREQ) 133 | new_voltage = 1575; // RIP 134 | else 135 | new_voltage = 1400; 136 | } else 137 | new_voltage = 1250; 138 | } else 139 | new_voltage = 1150; 140 | 141 | // increase voltage if needed 142 | dcdc_ctrl_vdd_soc(new_voltage, true, true, true); 143 | 144 | // put arm clock on bypass while we change params 145 | anatop.pll_arm.clr = BITNVAL(ANATOP_PLL_ARM_BITS_BYPASS_CLK_SRC, ANATOP_PLL_ARM_BITMASK_BYPASS_CLK_SRC); // 24mhz osci | ALSO CHANGES REFCLK 146 | anatop.pll_arm.set = BITN(ANATOP_PLL_ARM_BITS_BYPASS); 147 | while (!(anatop.pll_arm.dr & BITN(ANATOP_PLL_ARM_BITS_LOCK))) {}; 148 | 149 | // set arm pll loop div 150 | anatop.pll_arm.clr = BITNVAL(ANATOP_PLL_ARM_BITS_DIV_SELECT, ANATOP_PLL_ARM_BITMASK_DIV_SELECT); 151 | anatop.pll_arm.set = BITNVAL(ANATOP_PLL_ARM_BITS_DIV_SELECT, div_select); 152 | while (!(anatop.pll_arm.dr & BITN(ANATOP_PLL_ARM_BITS_LOCK))) {}; 153 | 154 | // set arm, ahb & ipg podf 155 | ccm.cacrr = (arm_podf - 1); 156 | ccm.cbcdr = (((ccm.cbcdr // while it looks good, it might be misleading since we are on ARM 157 | & ~(BITNVAL(CCM_CBCDR_BITS_AHB_PODF, CCM_CBCDR_BITMASK_AHB_PODF))) 158 | & ~(BITNVAL(CCM_CBCDR_BITS_IPG_PODF, CCM_CBCDR_BITMASK_IPG_PODF))) 159 | | BITNVAL(CCM_CBCDR_BITS_AHB_PODF, (ahb_podf - 1)) 160 | | BITNVAL(CCM_CBCDR_BITS_IPG_PODF, (ipg_podf - 1)) 161 | ); 162 | while (ccm.cdhipr & (BITN(CCM_CDHIPR_BITS_AHB_PODF_BUSY) | BITN(CCM_CDHIPR_BITS_ARM_PODF_BUSY))) {}; 163 | 164 | // restore arm clock with new params 165 | anatop.pll_arm.clr = BITN(ANATOP_PLL_ARM_BITS_BYPASS); 166 | while (!(anatop.pll_arm.dr & BITN(ANATOP_PLL_ARM_BITS_LOCK))) {}; 167 | 168 | // drop voltage if possible 169 | if ((new_voltage > 1150) || (CCM_1150MV_MAX_IPG_FREQ >= (Farm / ipg_podf))) 170 | dcdc_ctrl_vdd_soc(new_voltage, true, true, false); 171 | 172 | return core_clkf; 173 | } 174 | 175 | // default: pll3 80Mhz 176 | // uart_clk = sauce_pll_clk / (sauce_div_p2 ^ 2) 177 | void ccm_set_uart_clk(bool sauce_osc_clk_24m, int sauce_div_p2, bool wait) { 178 | uint32_t reg_data = ccm.cscdr1; 179 | reg_data &= ~(BITN(CCM_CSCDR1_BITS_UART_CLK_SEL) | BITNVAL(CCM_CSCDR1_BITS_UART_CLK_PODF, CCM_CSCDR1_BITMASK_UART_CLK_PODF)); 180 | reg_data |= BITNVAL(CCM_CSCDR1_BITS_UART_CLK_SEL, sauce_osc_clk_24m); 181 | reg_data |= BITNVAL(CCM_CSCDR1_BITS_UART_CLK_PODF, sauce_div_p2); 182 | // maybe disable interrupts between fetch-update, and what about auto-switches and pendings? 183 | ccm.cscdr1 = reg_data; 184 | while (wait && ( 185 | (ccm.cscdr1 & (BITN(CCM_CSCDR1_BITS_UART_CLK_SEL) | BITNVAL(CCM_CSCDR1_BITS_UART_CLK_PODF, CCM_CSCDR1_BITMASK_UART_CLK_PODF))) 186 | != (BITNVAL(CCM_CSCDR1_BITS_UART_CLK_SEL, sauce_osc_clk_24m) | BITNVAL(CCM_CSCDR1_BITS_UART_CLK_PODF, sauce_div_p2)) 187 | )) { 188 | }; 189 | } -------------------------------------------------------------------------------- /measurements/README.md: -------------------------------------------------------------------------------- 1 | # Measurements 2 | Detailed below are measurements performed on a Teensy 4.1 running the latest (performance changing) firmware.
3 | The measuring equipment is a [Hantek 6254BD](https://www.hantek.eu/product/hantek-6254bd/) USB oscilloscope.
4 | | Bandwidth 1ch/2ch | RT Sampling Rate | Vertical Resolution | 5 | | ------------------- | ------------------- | ------------------- | 6 | | 250Mhz / 200Mhz | 1GSa/s | 8bit | 7 | 8 | ## Single pin measurements 9 | These tests were performed on a single pin, their focus is measuring speed and consistency.
10 | The Teensy 4.1 board is powered from the microUSB port, and has a uart<->USB adapter connected to pads 0, 1, gnd. 11 | 12 | ### Test 1a: queue speed (with trigger) 13 | This test is a simple measurement of the lowest possible offset, width and queue switching speed. 14 | #### Parameters 15 | Command: ```glitch_add driver=15 trigger=9 trigger_state=0 offset=1 width=1 override=1 clockspeed=792000000``` 16 | - queue: single glitch, glitch->next = glitch (loop) 17 | - driver: pad 15 -> high, header connected to the x10 channel 1 probe 18 | - trigger: pad 9 low, header connected to teensy gnd 19 | - core frequency: 792Mhz 20 | #### Results 21 | Single captures, scope trigger at 2.95v: 22 | | n0 | Width +/- [ns] | Rise / Fall [ns] | Vmax [V] | 23 | | ---- | -------------- | ---------------- | -------- | 24 | | 1 | 3.20 / 24.5 | 19.9 / 2.56 | 3.70 | 25 | | 2 | 3.28 / 24.6 | 19.0 / 2.52 | 3.70 | 26 | | 3 | 3.28 / 24.5 | 19.0 / 2.44 | 3.64 | 27 | | 4 | 3.20 / 24.6 | 19.0 / 2.52 | 3.64 | 28 | | 5 | 3.20 / 24.6 | 18.9 / 2.52 | 3.64 | 29 | | 6 | 3.28 / 24.5 | 19.0 / 2.56 | 3.70 | 30 | 31 | Long: 32 | ![Test 1a](test1a-0.png) 33 | 34 | ### Test 1b: queue speed (without trigger) 35 | This test is a simple measurement of the lowest possible offset, width and queue switching speed. The trigger is replaced by a DTCM memory read and compare. 36 | #### Parameters 37 | Command: ```glitch_add driver=15 no_trigger=1 offset=1 width=1 override=1 clockspeed=792000000``` 38 | - queue: single glitch, glitch->next = glitch (loop) 39 | - driver: pad 15 -> high, header connected to the x10 channel 1 probe 40 | - trigger: n/a (dtcm memory readcmp) 41 | - core frequency: 792Mhz 42 | #### Results 43 | Single captures, scope trigger at 2.95v: 44 | | n0 | Width +/- [ns] | Rise / Fall [ns] | Vmax [V] | 45 | | ---- | -------------- | ---------------- | -------- | 46 | | 1 | 3.44 / 15.4 | 11.9 / 2.56 | 3.80 | 47 | | 2 | 3.36 / 15.6 | 11.1 / 2.52 | 3.83 | 48 | | 3 | 3.44 / 15.4 | 11.7 / 2.64 | 3.83 | 49 | | 4 | 3.44 / 15.5 | 11.5 / 2.56 | 3.80 | 50 | | 5 | 3.44 / 15.5 | 11.2 / 2.52 | 3.76 | 51 | | 6 | 3.44 / 15.5 | 11.4 / 2.52 | 3.76 | 52 | 53 | Long: 54 | ![Test 1b](test1b-0.png) 55 | 56 | ### Test 2: width 57 | This test measures the length, consistency and curve of pulse width. The trigger is replaced by a DTCM memory read and compare. 58 | #### Parameters 59 | Command: ```glitch_add driver=15 no_trigger=1 offset=1 override=1 clockspeed=792000000 width=X``` 60 | - queue: single glitch, glitch->next = glitch (loop) 61 | - driver: pad 15 -> high, header connected to the x10 channel 1 probe 62 | - trigger: n/a (dtcm memory readcmp) 63 | - core frequency: 792Mhz 64 | #### Results 65 | Avg/Long captures, scope trigger at 2.7v: 66 | | X | Width +/- [ns] | Rise / Fall [ns] | Vmax [V] | 67 | | --- | --- | --- | --- | 68 | | 1 | 3.36 / 15.5 | 11.5 / 2.56 | 3.76 | 69 | | 2 | 9.52 / 17.0 | 12.6 / 6.64 | 4.96 | 70 | | 5 | 13.9 / 16.5 | 12.6 / 10.7 | 5.02 | 71 | | 8 | 17.6 / 16.5 | 13.6 / 14.6 | 4.96 | 72 | | 10 | 20.0 / 16.6 | 13.3 / 17.0 | 4.96 | 73 | | 20 | 32.6 / 16.5 | 13.3 / 29.6 | 4.96 | 74 | | 50 | 70.6 / 16.6 | 13.3 / 67.5 | 4.83 | 75 | | 80 | 108 / 16.4 | 13.4 / 106 | 4.89 | 76 | | 100 | 134 / 16.4 | 13.4 / 131 | 4.83 | 77 | | 200 | 260 / 16.0 | 13.6 / 257 | 4.83 | 78 | | 500 | 638 / 16.0 | 13.6 / 635 | 4.83 | 79 | | 800 | 1020 / 16.0 | 14.0 / 1010 | 4.89 | 80 | 81 | ### Test 3a: offset 82 | This test measures the consistency and curve of a glitch offset. 83 | - NOTE: The offset width here is a measure of time between the end of one pulse and start of the next one in the glitch chain. 84 | - so it includes end of one glitch entry, load of the next, branch, trigger check, offset 85 | #### Parameters 86 | Command (with trigger): ```glitch_add driver=15 trigger=9 trigger_state=0 override=1 clockspeed=792000000 width=10 offset=X```
87 | Command (without trigger): ```glitch_add driver=15 no_trigger=1 override=1 clockspeed=792000000 width=10 offset=X``` 88 | - queue: single glitch, glitch->next = glitch (loop) 89 | - driver: pad 15 -> high, header connected to the x10 channel 1 probe 90 | - trigger: pad 9 low, header connected to teensy gnd, or n/a (dtcm memory readcmp) 91 | - core frequency: 792Mhz 92 | #### Results 93 | Avg/Long captures, scope trigger at 2.7v: 94 | | X | TrigOffset width- [ns] | Offset width- [ns] | 95 | | --- | --- | --- | 96 | | 1 | 25.5 | 16.6 | 97 | | 2 | 34.4 | 25.4 | 98 | | 5 | 38.0 | 31.8 | 99 | | 8 | 45.6 | 39.4 | 100 | | 10 | 50.7 | 44.4 | 101 | | 20 | 76 | 69.6 | 102 | | 50 | 152 | 146 | 103 | | 80 | 227 | 221 | 104 | | 100 | 278 | 272 | 105 | | 200 | 530 | 524 | 106 | 107 | ### Test 3b: offset mult 108 | This test measures the consistency and curve of a glitch offset multiplier. 109 | - NOTE: The offset width here is a measure of time between the end of one pulse and start of the next one in the glitch chain. 110 | - so it includes end of one glitch entry, load of the next, branch, trigger check, offset 111 | #### Parameters 112 | Command: ```glitch_add driver=15 no_trigger=1 override=1 clockspeed=792000000 width=10 offset=X offset_mult=Y``` 113 | - queue: single glitch, glitch->next = glitch (loop) 114 | - driver: pad 15 -> high, header connected to the x10 channel 1 probe 115 | - trigger: n/a (dtcm memory readcmp) 116 | - core frequency: 792Mhz 117 | #### Results 118 | Avg/Long Width- captures, scope trigger at 2.7v: 119 | | X\Y | 1 | 2 | 5 | 10 | 20 | 100 | 120 | | --- | --- | --- | --- | --- | --- | --- | 121 | | 1 | 16.6 ns | 28.0 ns | 39.4 ns | 58.4 ns | 96.2 ns | 399 ns | 122 | | 2 | 25.4 ns | 45.6 ns | 88.6 ns | 158 ns | 297 ns | 1410 ns | 123 | | 5 | 31.8 ns | 59.6 ns | 125 ns | 232 ns | 447 ns | 2160 ns | 124 | | 10 | 44.4 ns | 84.8 ns | 188 ns | 359 ns | 700 ns | 3425 ns | 125 | | 20 | 69.6 ns | 135 ns | 314 ns | 611 ns | 1205 ns | 5950 ns | 126 | | 100 | 272 ns | 539 ns | 1325 ns | 2630 ns | 5245 ns | 26150 ns | 127 | 128 | 129 | ## Double pin measurements 130 | These tests were performed with the oscilloscope connected to both "trigger" and "driver" pins. 131 | - Note that the BW/SR becomes 200Mhz/500MSa per channel. 132 | Trigger is driven by a DDS integrated into the oscilloscope. The wave is set to square, frequency 1khz, amplitude 1.65v and Y offset 1.65v.
133 | The Teensy 4.1 board is powered from the microUSB port, and has a uart<->USB adapter connected to pads 0, 1, gnd. 134 | 135 | ### Test 4a: logic high response time 136 | This test measures the time between trigger high -> driver high. 137 | - NOTE: This is highly specific to the test setup and environment, more/less current could lead to more/less consistent results. 138 | #### Parameters 139 | Command: ```glitch_add driver=15 trigger=9 trigger_state=1 override=1 clockspeed=792000000 width=10 offset=1 queue=1``` 140 | - queue: detect low -> detect high -> actual glitch 141 | - driver: pad 15 -> high, header connected to the x10 channel 1 probe 142 | - trigger: pad 9 -> high, header connected to DDS and the x10 channel 2 probe 143 | - core frequency: 792Mhz 144 | #### Results 145 | Single captures, scope trigger at 2.95v: 146 | | n0 | H-H | P-P | 147 | | ---- | --- | --- | 148 | | 1 | 28.1 ns | 20 ns | 149 | | 2 | 30 ns | 22 ns | 150 | | 3 | 32 ns | 22.1 ns | 151 | | 4 | 32.1 ns | 24 ns | 152 | | 5 | 30 ns | 20 ns | 153 | | 6 | 34 ns | 24 ns | 154 | 155 | ### Test 4b: logic low response time 156 | This test measures the time between trigger low -> driver high. 157 | - NOTE: This is highly specific to the test setup and environment, more/less current could lead to more/less consistent results. 158 | #### Parameters 159 | Command: ```glitch_add driver=15 trigger=9 trigger_state=0 override=1 clockspeed=792000000 width=10 offset=1 queue=1``` 160 | - queue: detect high -> detect low -> actual glitch 161 | - driver: pad 15 -> high, header connected to the x10 channel 1 probe 162 | - trigger: pad 9 -> low, header connected to DDS and the x10 channel 2 probe 163 | - core frequency: 792Mhz 164 | #### Results 165 | Single captures, scope trigger at 2.95v: 166 | | n0 | L-H | P(L)-P | P(H)-P | 167 | | ---- | --- | --- | --- | 168 | | 1 | 26.1 ns | 26.1 ns | 38.1 ns | 169 | | 2 | 32.1 ns | 22.1 ns | 34.1 ns | 170 | | 3 | 24 ns | 24 ns | 38 ns | 171 | | 4 | 22 ns | 22 ns | 34.1 ns | 172 | | 5 | 26 ns | 26 ns | 38.1 ns | 173 | | 6 | 22 ns | 22.1 ns | 34.1 ns | -------------------------------------------------------------------------------- /teensy_rpc.py: -------------------------------------------------------------------------------- 1 | # bare-bones rpc client implementation for teensy4vfi 2 | 3 | import sys, struct 4 | import serial 5 | from enum import Enum 6 | 7 | DEFAULT_PORT = 'COM7' # teensy 8 | DEFAULT_BAUD = 115200 # default teensy debug uart baud 9 | RPC_TIMEOOUT = 1 # rpc command timeout 10 | MAX_WAIT_RPC = 0 # max wait timeout count for rpc commands, set to 0 for infinite 11 | 12 | DEFAULT_DRIVER_PAD = 22 # aka mosfet pad for VFI 13 | DEFAULT_LL_TRIGGER_PAD = 23 # logic-level trigger pad 14 | DEFAULT_UART_TRIGGER_N = 1 # uart trigger teensy uartn 15 | DEFAULT_UART_TRIGGER_EXP_BYTE = b'\xD9' # uart trigger byte 16 | DEFAULT_ARG_DICT = { # our glitch_add vars with default preset, translated into glitch_prep_* args 17 | "offset" : [1, "how many ~cycles from trigger to glitch"], 18 | "offset_mult" : [1, "how many times to repeat the offset loop"], 19 | "width" : [1, "how many ~cycles the glitch is held"], 20 | "trigger" : [23, "trigger pad or uartn"], 21 | "trigger_state" : [1, "trigger logic state or uart byte"], 22 | "driver" : [22, "(mosfet) glitch driver pad"], 23 | "queue" : [0, "should this glitch be added to the chain?"], 24 | "no_trigger" : [0, "skip the glitch trigger"], 25 | "no_driver" : [0, "skip the glitch driver"], 26 | 27 | "uart_mode" : [0, "set this glitch to use an uart trigger"], 28 | 29 | "override" : [0, "set this to enable default config overrides (O)"], 30 | "clockspeed" : [0, "(O) glitch clockspeed / core frequency"], 31 | "driver_mask" : [0, "(O) glitch driver start/stop pattern"], 32 | "driver_set_drive" : [0, "(O) glitch driver start register addr"], 33 | "driver_set_stop" : [0, "(O) glitch driver stop register addr"], 34 | "trigger_mask" : [0, "(O) trigger data pattern mask"], # MUST SET trigger_exp TOO 35 | "trigger_exp" : [0, "(O) trigger expected data pattern"], 36 | "trigger_get" : [0, "(O) trigger data pattern register addr"], 37 | 38 | "driver_reconfigure" : [0, "(O) set this to reconfigure the driver pad (D)"], 39 | "driver_ode" : [0, "(O) (D) enable open-drain mode"], 40 | "driver_dse" : [7, "(O) (D) driver impedance divider, from 400ohms, max div 7"], 41 | 42 | "trigger_reconfigure" : [0, "(O) set this to reconfigure the trigger pad (T)"], 43 | "trigger_pke" : [0, "(O) (T) enable pull/keep"], 44 | "trigger_pue" : [0, "(O) (T) set p/k mode (0|1 - keep|pull)"], # requires pke 45 | "trigger_pus" : [0, "(O) (T) set pull type (0|1|2|3 - 100k down|47k up|100k up|22k up)"], # requires pue 46 | "trigger_hys" : [0, "(O) (T) enable hysteresis"], 47 | } 48 | 49 | # bitfield enums for glitch_prep args 50 | class PULL_TYPE(Enum): 51 | PULL_DOWN_100K = 0 52 | PULL_UP_47K = 1 53 | PULL_UP_100K = 2 54 | PULL_UP_22K = 3 55 | 56 | class CFG_TYPES(Enum): 57 | LOGIC_LEVEL = 0 58 | UART = 1 59 | FLAG_CHAIN = 4 60 | FLAG_NODRIVER = 5 61 | FLAG_NOTRIGGER = 6 62 | 63 | class CFG_XPAD_CTL(Enum): 64 | TEENSY_PAD = 0 65 | IGNORE = 6 66 | RECONFIGURE = 7 67 | 68 | class CFG_IPAD_CTL(Enum): 69 | TEENSY_UARTN = 0 70 | UART_MODE = 8 71 | PKE = 9 72 | PUE = 10 73 | PUS = 11 74 | HYS = 13 75 | TRIG_STATE = 16 76 | TRIG_UART_WM = 16 77 | 78 | class CFG_OPAD_CTL(Enum): 79 | ODE = 8 80 | DSE = 9 81 | 82 | class CFG_GLITCH_DFL(Enum): 83 | QUEUE = 0 84 | NODRIVER = 1 85 | NOTRIGGER = 2 86 | 87 | RPC_MAGIC = b'@' # byte indicating we are talking to teensy 88 | RPC_WATERMARK = b'!PC_' # prefix indicating teensy is replying to us 89 | RPC_SENDMORE = b'G1\r\n' # teensy wants more data 90 | RPC_READYNEXT = b'G0\r\n' # teensy is ready for the next command 91 | RPC_COMMANDS = { # supported RPC commands & short descriptions 92 | "ping" : [0x0, "get rpc server firmware build timestamp", ""], 93 | "read32" : [0x1, "read 32bits from a memory address", "[address]"], 94 | "write32" : [0x2, "write 32bits to a memory address", "[address] [data]"], 95 | "memset" : [0x3, "fill a memory range (8bit)", "[start] [fill] [size]"], 96 | "memcpy" : [0x4, "copy a memory range to another address", "[dst] [src] [size]"], 97 | "delay" : [0x5, "set rpc server reply delay", "[delay]"], 98 | "stop" : [0x6, "stop the rpc server", ""], 99 | "hexdump" : [0x7, "print a memory range (hex)", "[address] [size] "], 100 | "memset32" : [0x8, "fill a memory range (32bit)", "[start] [fill] [size]"], 101 | "glitch_prep_ll" : [0x9, "prepare a default logic level -triggered glitch", " "], 102 | "glitch_arm" : [0xa, "execute the glitch chain", ""], 103 | "glitch_prep_custom" : [0xb, "prepare a custom glitch", "[glitch_config]"], 104 | "glitch_prep_uart" : [0xc, "prepare a default uart -triggered glitch", " "], 105 | "set_clk" : [0xd, "set core freq", "[freq] "], 106 | "glitch_prep_custom_chain" : [0xe, "prepare a custom glitch (add to chain)", "[glitch_config]"], 107 | "glitch_prep_none" : [0xf, "prepare a default glitch (no trigger)", " "], 108 | "custom" : [0x10, "run the custom_main func", "[arg0] [arg1] [arg2] "], 109 | "uart_init" : [0x11, "init a teensy uartn", "[uartn] [baud] [flags] "], #TODO: wrap 110 | "pad_configure" : [0x12, "set pad_ctl and mux_ctl for a teensy pad", "[pad] [pad_ctl] [mux_ctl]"], #TODO: wrap 111 | "pad_ctrl_logic" : [0x13, "control pad state (logic level mode)", "[func] [pad] "], 112 | "glitch_set_chain_max" : [0x14, "set glitch varray/chain location and max elements", " "], 113 | "get_sp" : [0x15, "get the current stack pointer", ""], 114 | "glitch_arm_loop" : [0x16, "execute the glitch chain in an infinite loop", ""] 115 | } 116 | 117 | LOGIC_COMMANDS = { # cmd : [func, desc, opt_args] 118 | "clear" : [0, "set pad low", "None"], 119 | "set" : [1, "set pad high", "None"], 120 | "toggle" : [2, "toggle pad state", "None"], 121 | "mode" : [3, "set pad mode", "[in|out]"], 122 | "read" : [4, "read pad state", "None"], 123 | "tight" : [5, "use tight-coupled gpio controller for pad", "[0|1]"], 124 | } 125 | 126 | uart = serial.Serial(DEFAULT_PORT, baudrate=DEFAULT_BAUD, timeout=RPC_TIMEOOUT) 127 | 128 | def send_rpc_cmd(id, argv, max_wait=MAX_WAIT_RPC): 129 | data = bytearray() 130 | for arg in argv: 131 | data.extend(struct.pack('24}" + " : " + "DESCRIPTION") 201 | print(f"{'---':>24}" + " : " + "-----------") 202 | for cmd in RPC_COMMANDS: 203 | print(f"{cmd:>24}" + " : " + RPC_COMMANDS[cmd][1]) 204 | print(f"{' ':>24}" + " ! " + " ") 205 | print(f"{'glitch_add':>24}" + " : " + "wrapper for glitch_prep_* funcs") 206 | print(f"{'manual':>24}" + " : " + "manual trigger for default glitch_prep_uart") 207 | print(f"{'logic':>24}" + " : " + "control pad logic state") 208 | print(f"{'help ':>24}" + " : " + "show me or CMD's expected args") 209 | case "glitch_add": 210 | print("\nUsage: " + focus + " param=value par6=val6 par3=val3 ...") 211 | print("Descr: " + "prepare a glitch with specified params" + "\n") 212 | print(f"{'PARAM':>20}" + " : " + f"{'DEFAULT':^7}" + " : " + "DESCRIPTION") 213 | print(f"{'-----':>20}" + " : " + f"{'-------':^7}" + " : " + "-----------") 214 | for arg in DEFAULT_ARG_DICT: 215 | print(f"{arg:>20}" + " : " + f"{str(DEFAULT_ARG_DICT[arg][0]):^7}" + " : " + DEFAULT_ARG_DICT[arg][1]) 216 | case "logic": 217 | print("\nUsage: " + focus + " [SUBCMD] [ARG] [PAD] ...") 218 | print("Descr: " + "control pad logic state" + "\n") 219 | print(f"{'SUBCMD':>8}" + " : " + f"{'ARG':^8}" + " : " + "DESCRIPTION") 220 | print(f"{'------':>8}" + " : " + f"{'---':^8}" + " : " + "-----------") 221 | for cmd in LOGIC_COMMANDS: 222 | print(f"{cmd:>8}" + " : " + f"{LOGIC_COMMANDS[cmd][2]:^8}" + " : " + LOGIC_COMMANDS[cmd][1]) 223 | case _: 224 | if focus in RPC_COMMANDS: 225 | print("\nUsage: " + focus + " " + RPC_COMMANDS[focus][2]) 226 | print("Descr: " + RPC_COMMANDS[focus][1] + "\n") 227 | else: 228 | print("command not found and/or malformed input") 229 | return "" 230 | 231 | 232 | def handle_cmd(cmd, argv): 233 | match cmd: 234 | case "manual": 235 | return uart.write(DEFAULT_UART_TRIGGER_EXP_BYTE) 236 | case "glitch_add": 237 | arg_dict = {param: value[0] for param, value in DEFAULT_ARG_DICT.copy().items()} 238 | for arg in argv: 239 | key, val = arg.split('=') 240 | if val.startswith('0x'): 241 | arg_dict[key] = int(val, 16) 242 | else: 243 | arg_dict[key] = int(val) 244 | if arg_dict["override"] == 1: 245 | return glitch_add_custom(arg_dict) 246 | else: 247 | return glitch_add_dfl(arg_dict) 248 | case "logic": 249 | if not argv[0] in LOGIC_COMMANDS or len(argv) < 2: 250 | return helper("logic") 251 | op_argv = [LOGIC_COMMANDS[argv[0]][0], 0, 0] 252 | if op_argv[0] == 3: 253 | op_argv.append(1 if argv[1] == "1" or argv[1].startswith("o") else 0) 254 | elif op_argv[0] == 5: 255 | op_argv.append(1 if argv[1] == "1" or argv[1].startswith("t") else 0) 256 | pads_start = 2 if (op_argv[0] == 3 or op_argv[0] == 5) else 1 257 | if len(argv) <= pads_start: 258 | return helper("logic") 259 | op_ret = 0xFFFFDEFA 260 | for pad in argv[pads_start:]: 261 | op_argv[1] = int(pad) 262 | op_ret = send_rpc_cmd("pad_ctrl_logic", op_argv) 263 | return op_ret 264 | case "help": 265 | if len(argv) > 0: 266 | return helper(argv[0]) 267 | return helper("none") 268 | case _: 269 | if cmd in RPC_COMMANDS: 270 | rargv = [] 271 | for arg in argv: 272 | if arg.startswith('0x'): 273 | rargv.append(int(arg, 16)) 274 | else: 275 | rargv.append(int(arg)) 276 | return send_rpc_cmd(cmd, rargv) 277 | else: 278 | print("command not found and/or malformed input") 279 | return "" 280 | 281 | if __name__ == "__main__": 282 | if len(sys.argv) > 1: 283 | handle_cmd(sys.argv[1], sys.argv[2:]) 284 | else: 285 | helper("none") 286 | uart.close() -------------------------------------------------------------------------------- /source/glitch.c: -------------------------------------------------------------------------------- 1 | #include "include/debug.h" 2 | #include "include/clib.h" 3 | #include "include/teensy.h" 4 | #include "include/gpio.h" 5 | #include "include/ccm.h" 6 | 7 | #include "include/glitch.h" 8 | 9 | int g_glitch_max_chain_n = GLITCH_STATIC_CHAIN_N; 10 | glitch_varray_s* g_glitch_varray = g_static_glitch_varray; 11 | glitch_varray_s g_static_glitch_varray[GLITCH_STATIC_CHAIN_N]; 12 | 13 | void (*glitch_arm)(glitch_varray_s* varray) = (void*)GLITCH_DEFAULT_FUNC; // first glitch arm func in chain, for ext callers 14 | 15 | int g_glitch_clkf = CCM_ARM_CLKF_600MHZ; 16 | void (*glitch_w_freq_cg_arm)(glitch_varray_s* varray) = (void*)GLITCH_DEFAULT_FUNC; // next step in chain for this wrapper 17 | void glitch_w_freq_cg(glitch_varray_s* varray) { 18 | int prev_clkf = ccm_get_core_clkf(); 19 | ccm_set_core_clkf(g_glitch_clkf, 0); 20 | glitch_w_freq_cg_arm(varray); 21 | ccm_set_core_clkf(prev_clkf, 0); 22 | } 23 | 24 | // uart mode does NOT configure the uart receiver, only the pad 25 | int glitch_configure(glitch_config_s* config, bool add_to_chain) { 26 | bool uart_mode = false; 27 | 28 | bool use_driver = !(config->driver_ctl & BITN(GLITCH_PAD_CTL_BITS_IGNORE)); 29 | int driver_pad = (config->driver_ctl & GLITCH_PAD_CTL_BITMASK_TEENSY_PAD); 30 | bool ode_mode = !!(config->driver_ctl & BITN(GLITCH_OUTPUT_PAD_CTL_BITS_ODE)); 31 | 32 | bool use_trigger = !(config->trigger_ctl & BITN(GLITCH_PAD_CTL_BITS_IGNORE)); 33 | int trigger_pad = (config->trigger_ctl & GLITCH_PAD_CTL_BITMASK_TEENSY_PAD); 34 | if (config->trigger_ctl & BITN(GLITCH_INPUT_PAD_CTL_BITS_UART_MODE)) { 35 | if (trigger_pad > 7) 36 | return -1; 37 | trigger_pad = teensy_uart_get_rx_pad(trigger_pad); 38 | uart_mode = true; 39 | } 40 | 41 | 42 | // check args 43 | if (driver_pad > (TEENSY_PADS_COUNT - 1) || trigger_pad > (TEENSY_PADS_COUNT - 1)) 44 | return -2; 45 | if (!config->offset || !config->offset_mult || !config->width) 46 | return -3; 47 | 48 | 49 | // add to chain if requested 50 | glitch_varray_s* varray = g_glitch_varray; 51 | add_to_chain = !!add_to_chain; 52 | if (add_to_chain) { 53 | while (varray->next) { 54 | varray = varray->next; 55 | add_to_chain++; 56 | } 57 | if (add_to_chain >= g_glitch_max_chain_n) 58 | return -4; 59 | varray = varray->next = &g_glitch_varray[add_to_chain]; 60 | } 61 | memset(varray, 0, sizeof(glitch_varray_s)); 62 | 63 | 64 | // configure mosfet driver 65 | if (use_driver && (config->driver_ctl & BITN(GLITCH_PAD_CTL_BITS_RECONFIGURE))) { 66 | int driver_pad_ctl = IOMUXC_PORT_CTL_FIELD( 67 | true, // fast slew rate 68 | IOMUXC_PORT_CTL_DSE_R0(((config->driver_ctl >> GLITCH_OUTPUT_PAD_CTL_BITS_DSE) & IOMUXC_PORT_CTL_BITMASK_DSE)),// drive strength 69 | IOMUXC_PORT_CTL_SPEED(4), // 200Mhz 70 | ode_mode, // open drain mode 71 | false, // n/a 72 | false, // n/a 73 | false, // n/a 74 | false // n/a 75 | ); 76 | teensy_set_pad_ctl(driver_pad, driver_pad_ctl, TEENSY_PAD_MODE_GPIO, true); // pad config 77 | teensy_pad_logic_ctrl_tightness(driver_pad, true, true); // change to tight-coupled gpio ctl 78 | teensy_pad_logic_mode(driver_pad, true, true); // set as output 79 | } 80 | 81 | 82 | // configure glitch trigger 83 | if (use_trigger && (config->trigger_ctl & BITN(GLITCH_PAD_CTL_BITS_RECONFIGURE))) { 84 | int trigger_pad_ctl = IOMUXC_PORT_CTL_FIELD( 85 | true, // fast slew rate 86 | false, // n/a 87 | IOMUXC_PORT_CTL_SPEED(4), // 200Mhz, shouldnt matter anyways 88 | false, // n/a 89 | !!(config->trigger_ctl & BITN(GLITCH_INPUT_PAD_CTL_BITS_PKE)), // enable pull/keep 90 | !!(config->trigger_ctl & BITN(GLITCH_INPUT_PAD_CTL_BITS_PUE)), // pull? 91 | ((config->trigger_ctl >> GLITCH_INPUT_PAD_CTL_BITS_PUS) & IOMUXC_PORT_CTL_BITMASK_PUS), // pull strength/type 92 | !!(config->trigger_ctl & BITN(GLITCH_INPUT_PAD_CTL_BITS_HYS)) // enable hysteresis 93 | ); 94 | if (!uart_mode) { 95 | teensy_set_pad_ctl(trigger_pad, trigger_pad_ctl, TEENSY_PAD_MODE_GPIO, true); // pad cfg 96 | teensy_pad_logic_ctrl_tightness(trigger_pad, true, true); // change to tight-coupled gpio ctl 97 | teensy_pad_logic_mode(trigger_pad, false, true); // set as input 98 | } else 99 | teensy_set_pad_ctl(trigger_pad, trigger_pad_ctl, -1, true); 100 | } 101 | 102 | 103 | // configure glitch params 104 | varray->offset = config->offset; // wait period between trigger-drive 105 | varray->offset_mult = config->offset_mult; // multiplicator for the above 106 | varray->width = config->width; // wait period between drive start-stop 107 | 108 | if (config->overrides.driver.mask) // bitfield written to driver_set_reg and driver_clr_reg 109 | varray->driver_ports = config->overrides.driver.mask; 110 | else if (use_driver) 111 | varray->driver_ports = BITN(teensy_get_pad_port(driver_pad)); 112 | 113 | if (config->overrides.driver.set_to_drive) // write a bitfield preset here to open the mosfet gate 114 | varray->driver_set_reg = config->overrides.driver.set_to_drive; 115 | else if (use_driver) 116 | varray->driver_set_reg = &(gpio_get_bus_paddr(teensy_get_pad_gpio_bus(driver_pad))->dr_toggle); 117 | else 118 | varray->driver_set_reg = &varray->driver_ports; 119 | 120 | if (config->overrides.driver.set_to_stop) // write a bitfield preset here to close the mosfet gate 121 | varray->driver_clr_reg = config->overrides.driver.set_to_stop; 122 | else if (use_driver) 123 | varray->driver_clr_reg = &(gpio_get_bus_paddr(teensy_get_pad_gpio_bus(driver_pad))->dr_toggle); 124 | else 125 | varray->driver_clr_reg = &varray->driver_ports; 126 | 127 | if (config->overrides.trigger.mask) { // mask and expected masked value from trigger_data_reg 128 | varray->trigger_ports = config->overrides.trigger.mask; 129 | varray->trigger_exp_state = config->overrides.trigger.exp_data; 130 | } else { 131 | if (uart_mode) { 132 | varray->trigger_ports = GLITCH_INPUT_PAD_CTL_BITMASK_TEENSY_UART_WATERMARK | BITN(UART_DATA_BITS_RXEMPT); 133 | varray->trigger_exp_state = ((config->trigger_ctl >> GLITCH_INPUT_PAD_CTL_BITS_TRIGGER_UART_WATERMARK) & GLITCH_INPUT_PAD_CTL_BITMASK_TEENSY_UART_WATERMARK); 134 | } else if (use_trigger) { 135 | varray->trigger_ports = BITN(teensy_get_pad_port(trigger_pad)); 136 | varray->trigger_exp_state = BITNVALM(teensy_get_pad_port(trigger_pad), !!(config->trigger_ctl & BITN(GLITCH_INPUT_PAD_CTL_BITS_TRIGGER_STATE)), 1); 137 | } 138 | } 139 | 140 | if (config->overrides.trigger.get_to_drive) // read, mask, compareok the bitfield to trigger the glitch 141 | varray->trigger_data_reg = config->overrides.trigger.get_to_drive; 142 | else { 143 | if (uart_mode) 144 | varray->trigger_data_reg = &uart_regs[teensy_uart_get_imx_bus((config->trigger_ctl & GLITCH_PAD_CTL_BITMASK_TEENSY_PAD))]->data; 145 | else if (use_trigger) 146 | varray->trigger_data_reg = &(gpio_get_bus_paddr(teensy_get_pad_gpio_bus(trigger_pad))->dr); 147 | else 148 | varray->trigger_data_reg = &varray->trigger_ports; 149 | } 150 | 151 | if (config->overrides.clockspeed) // teensy core clock freq 152 | g_glitch_clkf = ccm_calculate_core_clkf(config->overrides.clockspeed); 153 | else 154 | g_glitch_clkf = ccm_calculate_core_clkf(GLITCH_DEFAULT_CLKSPEED); 155 | 156 | 157 | // set the main glitch func 158 | glitch_arm = s_glitch; // s_glitch (logic level trigger,waitloop) 159 | 160 | 161 | // add various glitch func wrappers (chain them, we got plenty of stack to spare) 162 | if (g_glitch_clkf != ccm_get_core_clkf()) { // requested special core clocks for glitching 163 | glitch_w_freq_cg_arm = glitch_arm; 164 | glitch_arm = glitch_w_freq_cg; 165 | } 166 | 167 | return 0; 168 | } 169 | 170 | int glitch_configure_default(int type, uint32_t offset, uint32_t offset_mult, uint32_t width, int trigger_pad, int trigger_state, int driver_pad) { 171 | int ret = -1; 172 | glitch_config_s config; 173 | memset(&config, 0, sizeof(glitch_config_s)); 174 | config.width = width; 175 | config.offset = offset; 176 | config.offset_mult = offset_mult; 177 | 178 | if (!driver_pad) 179 | driver_pad = GLITCH_DEFAULT_DRIVER_PAD; 180 | if (type & BITN(GLITCH_CONFIG_DEFAULT_TYPE_BITS_FLAG_NODRIVER)) 181 | config.driver_ctl = BITN(GLITCH_PAD_CTL_BITS_IGNORE); 182 | else { 183 | config.driver_ctl = BITNVALM(GLITCH_PAD_CTL_BITS_TEENSY_PAD, driver_pad, GLITCH_PAD_CTL_BITMASK_TEENSY_PAD) 184 | | BITN(GLITCH_PAD_CTL_BITS_RECONFIGURE) 185 | | BITNVALM(GLITCH_OUTPUT_PAD_CTL_BITS_DSE, GLITCH_DEFAULT_DRIVER_DSE_DIV, IOMUXC_PORT_CTL_BITMASK_DSE) 186 | ; 187 | } 188 | 189 | if (type & BITN(GLITCH_CONFIG_DEFAULT_TYPE_BITS_FLAG_NOTRIGGER)) { 190 | config.trigger_ctl = BITN(GLITCH_PAD_CTL_BITS_IGNORE); 191 | ret = glitch_configure(&config, !!(type & BITN(GLITCH_CONFIG_DEFAULT_TYPE_BITS_FLAG_CHAIN))); 192 | } else { 193 | switch (type & GLITCH_CONFIG_DEFAULT_TYPE_BITMASK_MODES) { 194 | case BITN(GLITCH_CONFIG_DEFAULT_TYPE_BITS_LOGIC_LEVEL): 195 | if (!trigger_pad) { 196 | trigger_pad = GLITCH_DEFAULT_LL_TRIGGER_PAD; 197 | trigger_state = GLITCH_DEFAULT_LL_TRIGGER_EXP_STATE; 198 | } 199 | config.trigger_ctl = BITNVALM(GLITCH_PAD_CTL_BITS_TEENSY_PAD, trigger_pad, GLITCH_PAD_CTL_BITMASK_TEENSY_PAD) 200 | | BITN(GLITCH_PAD_CTL_BITS_RECONFIGURE) 201 | | BITNVALM(GLITCH_INPUT_PAD_CTL_BITS_TRIGGER_STATE, trigger_state, 1) 202 | | BITNVAL(GLITCH_INPUT_PAD_CTL_BITS_PKE, GLITCH_DEFAULT_LL_TRIGGER_PK_EN) 203 | | BITNVAL(GLITCH_INPUT_PAD_CTL_BITS_PUE, GLITCH_DEFAULT_LL_TRIGGER_PUE) 204 | | BITNVAL(GLITCH_INPUT_PAD_CTL_BITS_PUS, GLITCH_DEFAULT_LL_TRIGGER_PULL_TYPE) 205 | | BITNVAL(GLITCH_INPUT_PAD_CTL_BITS_HYS, GLITCH_DEFAULT_LL_TRIGGER_HYS_EN) 206 | ; 207 | ret = glitch_configure(&config, !!(type & BITN(GLITCH_CONFIG_DEFAULT_TYPE_BITS_FLAG_CHAIN))); 208 | break; 209 | case BITN(GLITCH_CONFIG_DEFAULT_TYPE_BITS_UART): 210 | if (!trigger_pad) { 211 | trigger_pad = GLITCH_DEFAULT_UART_TRIGGER_UARTN; 212 | trigger_state = GLITCH_DEFAULT_UART_TRIGGER_EXP_BYTE; 213 | } 214 | config.trigger_ctl = BITNVALM(GLITCH_PAD_CTL_BITS_TEENSY_PAD, trigger_pad, GLITCH_PAD_CTL_BITMASK_TEENSY_PAD) 215 | | BITN(GLITCH_PAD_CTL_BITS_RECONFIGURE) 216 | | BITNVALM(GLITCH_INPUT_PAD_CTL_BITS_TRIGGER_UART_WATERMARK, trigger_state, GLITCH_INPUT_PAD_CTL_BITMASK_TEENSY_UART_WATERMARK) 217 | | BITNVAL(GLITCH_INPUT_PAD_CTL_BITS_PKE, GLITCH_DEFAULT_UART_TRIGGER_PK_EN) 218 | | BITNVAL(GLITCH_INPUT_PAD_CTL_BITS_PUE, GLITCH_DEFAULT_UART_TRIGGER_PUE) 219 | | BITNVAL(GLITCH_INPUT_PAD_CTL_BITS_PUS, GLITCH_DEFAULT_UART_TRIGGER_PULL_TYPE) 220 | | BITNVAL(GLITCH_INPUT_PAD_CTL_BITS_HYS, GLITCH_DEFAULT_UART_TRIGGER_HYS_EN) 221 | | BITN(GLITCH_INPUT_PAD_CTL_BITS_UART_MODE) 222 | ; 223 | ret = glitch_configure(&config, !!(type & BITN(GLITCH_CONFIG_DEFAULT_TYPE_BITS_FLAG_CHAIN))); 224 | if (ret >= 0) { 225 | if (trigger_pad == DEBUG_UARTN) 226 | teensy_uart_wait_tc(trigger_pad); 227 | ret = teensy_uart_init( // TODO: should we actually have RX FIFO enabled? 228 | trigger_pad, 229 | GLITCH_DEFAULT_UART_TRIGGER_BAUD, 230 | BITN(UART_INIT_BITS_RX_EN) | BITN(UART_INIT_BITS_RX_FIFO_EN) | BITNVAL(UART_INIT_BITS_TX_EN, GLITCH_DEFAULT_UART_TRIGGER_INIT_TX) | BITNVAL(UART_INIT_BITS_TX_FIFO_EN, GLITCH_DEFAULT_UART_TRIGGER_INIT_TX_FIFO), 231 | true 232 | ); 233 | } 234 | break; 235 | default: 236 | break; 237 | } 238 | } 239 | 240 | return ret; 241 | } 242 | 243 | // used to test functionality 244 | int glitch_loop_chain(glitch_varray_s* varray) { 245 | if (!varray) 246 | return -1; 247 | 248 | glitch_varray_s* next_v = varray; 249 | while (next_v->next) 250 | next_v = next_v->next; 251 | next_v->next = varray; 252 | 253 | glitch_arm(varray); 254 | 255 | return 0; // should never return anyways 256 | } -------------------------------------------------------------------------------- /source/include/teensy_pads.h: -------------------------------------------------------------------------------- 1 | #ifndef __TEENSY_PADS_H__ 2 | #define __TEENSY_PADS_H__ 3 | 4 | #ifndef TARGET_TEENSY41 5 | #define TEENSY_PADS_COUNT 40 6 | #else 7 | #define TEENSY_PADS_COUNT 55 8 | #endif 9 | 10 | // pain 11 | #define TEENSY_PAD_0_PORT 3 12 | #define TEENSY_PAD_1_PORT 2 13 | #define TEENSY_PAD_2_PORT 4 14 | #define TEENSY_PAD_3_PORT 5 15 | #define TEENSY_PAD_4_PORT 6 16 | #define TEENSY_PAD_5_PORT 8 17 | #define TEENSY_PAD_6_PORT 10 18 | #define TEENSY_PAD_7_PORT 17 19 | #define TEENSY_PAD_8_PORT 16 20 | #define TEENSY_PAD_9_PORT 11 21 | #define TEENSY_PAD_10_PORT 0 22 | #define TEENSY_PAD_11_PORT 2 23 | #define TEENSY_PAD_12_PORT 1 24 | #define TEENSY_PAD_13_PORT 3 25 | #define TEENSY_PAD_14_PORT 18 26 | #define TEENSY_PAD_15_PORT 19 27 | #define TEENSY_PAD_16_PORT 23 28 | #define TEENSY_PAD_17_PORT 22 29 | #define TEENSY_PAD_18_PORT 17 30 | #define TEENSY_PAD_19_PORT 16 31 | #define TEENSY_PAD_20_PORT 26 32 | #define TEENSY_PAD_21_PORT 27 33 | #define TEENSY_PAD_22_PORT 24 34 | #define TEENSY_PAD_23_PORT 25 35 | #define TEENSY_PAD_24_PORT 12 36 | #define TEENSY_PAD_25_PORT 13 37 | #define TEENSY_PAD_26_PORT 30 38 | #define TEENSY_PAD_27_PORT 31 39 | #define TEENSY_PAD_28_PORT 18 40 | #define TEENSY_PAD_29_PORT 31 41 | #define TEENSY_PAD_30_PORT 23 42 | #define TEENSY_PAD_31_PORT 22 43 | #define TEENSY_PAD_32_PORT 12 44 | #define TEENSY_PAD_33_PORT 7 45 | #ifndef TARGET_TEENSY41 46 | #define TEENSY_PAD_34_PORT 15 47 | #define TEENSY_PAD_35_PORT 14 48 | #define TEENSY_PAD_36_PORT 13 49 | #define TEENSY_PAD_37_PORT 12 50 | #define TEENSY_PAD_38_PORT 17 51 | #define TEENSY_PAD_39_PORT 16 52 | #else 53 | #define TEENSY_PAD_34_PORT 29 54 | #define TEENSY_PAD_35_PORT 28 55 | #define TEENSY_PAD_36_PORT 18 56 | #define TEENSY_PAD_37_PORT 19 57 | #define TEENSY_PAD_38_PORT 28 58 | #define TEENSY_PAD_39_PORT 29 59 | #define TEENSY_PAD_40_PORT 20 60 | #define TEENSY_PAD_41_PORT 21 61 | #define TEENSY_PAD_42_PORT 15 62 | #define TEENSY_PAD_43_PORT 14 63 | #define TEENSY_PAD_44_PORT 13 64 | #define TEENSY_PAD_45_PORT 12 65 | #define TEENSY_PAD_46_PORT 17 66 | #define TEENSY_PAD_47_PORT 16 67 | #define TEENSY_PAD_48_PORT 24 68 | #define TEENSY_PAD_49_PORT 27 69 | #define TEENSY_PAD_50_PORT 28 70 | #define TEENSY_PAD_51_PORT 22 71 | #define TEENSY_PAD_52_PORT 26 72 | #define TEENSY_PAD_53_PORT 25 73 | #define TEENSY_PAD_54_PORT 29 74 | #endif 75 | 76 | // au chocolat 77 | #define TEENSY_PAD_0_BUS 1 78 | #define TEENSY_PAD_1_BUS 1 79 | #define TEENSY_PAD_2_BUS 4 80 | #define TEENSY_PAD_3_BUS 4 81 | #define TEENSY_PAD_4_BUS 4 82 | #define TEENSY_PAD_5_BUS 4 83 | #define TEENSY_PAD_6_BUS 2 84 | #define TEENSY_PAD_7_BUS 2 85 | #define TEENSY_PAD_8_BUS 2 86 | #define TEENSY_PAD_9_BUS 2 87 | #define TEENSY_PAD_10_BUS 2 88 | #define TEENSY_PAD_11_BUS 2 89 | #define TEENSY_PAD_12_BUS 2 90 | #define TEENSY_PAD_13_BUS 2 91 | #define TEENSY_PAD_14_BUS 1 92 | #define TEENSY_PAD_15_BUS 1 93 | #define TEENSY_PAD_16_BUS 1 94 | #define TEENSY_PAD_17_BUS 1 95 | #define TEENSY_PAD_18_BUS 1 96 | #define TEENSY_PAD_19_BUS 1 97 | #define TEENSY_PAD_20_BUS 1 98 | #define TEENSY_PAD_21_BUS 1 99 | #define TEENSY_PAD_22_BUS 1 100 | #define TEENSY_PAD_23_BUS 1 101 | #define TEENSY_PAD_24_BUS 1 102 | #define TEENSY_PAD_25_BUS 1 103 | #define TEENSY_PAD_26_BUS 1 104 | #define TEENSY_PAD_27_BUS 1 105 | #define TEENSY_PAD_28_BUS 3 106 | #define TEENSY_PAD_29_BUS 4 107 | #define TEENSY_PAD_30_BUS 3 108 | #define TEENSY_PAD_31_BUS 3 109 | #define TEENSY_PAD_32_BUS 2 110 | #define TEENSY_PAD_33_BUS 4 111 | #ifndef TARGET_TEENSY41 112 | #define TEENSY_PAD_34_BUS 3 113 | #define TEENSY_PAD_35_BUS 3 114 | #define TEENSY_PAD_36_BUS 3 115 | #define TEENSY_PAD_37_BUS 3 116 | #define TEENSY_PAD_38_BUS 3 117 | #define TEENSY_PAD_39_BUS 3 118 | #else 119 | #define TEENSY_PAD_34_BUS 2 120 | #define TEENSY_PAD_35_BUS 2 121 | #define TEENSY_PAD_36_BUS 2 122 | #define TEENSY_PAD_37_BUS 2 123 | #define TEENSY_PAD_38_BUS 1 124 | #define TEENSY_PAD_39_BUS 1 125 | #define TEENSY_PAD_40_BUS 1 126 | #define TEENSY_PAD_41_BUS 1 127 | #define TEENSY_PAD_42_BUS 3 128 | #define TEENSY_PAD_43_BUS 3 129 | #define TEENSY_PAD_44_BUS 3 130 | #define TEENSY_PAD_45_BUS 3 131 | #define TEENSY_PAD_46_BUS 3 132 | #define TEENSY_PAD_47_BUS 3 133 | #define TEENSY_PAD_48_BUS 4 134 | #define TEENSY_PAD_49_BUS 4 135 | #define TEENSY_PAD_50_BUS 4 136 | #define TEENSY_PAD_51_BUS 4 137 | #define TEENSY_PAD_52_BUS 4 138 | #define TEENSY_PAD_53_BUS 4 139 | #define TEENSY_PAD_54_BUS 4 140 | #endif 141 | 142 | #define TEENSY_PAD_0_BUS_TCG 6 143 | #define TEENSY_PAD_1_BUS_TCG 6 144 | #define TEENSY_PAD_2_BUS_TCG 9 145 | #define TEENSY_PAD_3_BUS_TCG 9 146 | #define TEENSY_PAD_4_BUS_TCG 9 147 | #define TEENSY_PAD_5_BUS_TCG 9 148 | #define TEENSY_PAD_6_BUS_TCG 7 149 | #define TEENSY_PAD_7_BUS_TCG 7 150 | #define TEENSY_PAD_8_BUS_TCG 7 151 | #define TEENSY_PAD_9_BUS_TCG 7 152 | #define TEENSY_PAD_10_BUS_TCG 7 153 | #define TEENSY_PAD_11_BUS_TCG 7 154 | #define TEENSY_PAD_12_BUS_TCG 7 155 | #define TEENSY_PAD_13_BUS_TCG 7 156 | #define TEENSY_PAD_14_BUS_TCG 6 157 | #define TEENSY_PAD_15_BUS_TCG 6 158 | #define TEENSY_PAD_16_BUS_TCG 6 159 | #define TEENSY_PAD_17_BUS_TCG 6 160 | #define TEENSY_PAD_18_BUS_TCG 6 161 | #define TEENSY_PAD_19_BUS_TCG 6 162 | #define TEENSY_PAD_20_BUS_TCG 6 163 | #define TEENSY_PAD_21_BUS_TCG 6 164 | #define TEENSY_PAD_22_BUS_TCG 6 165 | #define TEENSY_PAD_23_BUS_TCG 6 166 | #define TEENSY_PAD_24_BUS_TCG 6 167 | #define TEENSY_PAD_25_BUS_TCG 6 168 | #define TEENSY_PAD_26_BUS_TCG 6 169 | #define TEENSY_PAD_27_BUS_TCG 6 170 | #define TEENSY_PAD_28_BUS_TCG 8 171 | #define TEENSY_PAD_29_BUS_TCG 9 172 | #define TEENSY_PAD_30_BUS_TCG 8 173 | #define TEENSY_PAD_31_BUS_TCG 8 174 | #define TEENSY_PAD_32_BUS_TCG 7 175 | #define TEENSY_PAD_33_BUS_TCG 9 176 | #ifndef TARGET_TEENSY41 177 | #define TEENSY_PAD_34_BUS_TCG 8 178 | #define TEENSY_PAD_35_BUS_TCG 8 179 | #define TEENSY_PAD_36_BUS_TCG 8 180 | #define TEENSY_PAD_37_BUS_TCG 8 181 | #define TEENSY_PAD_38_BUS_TCG 8 182 | #define TEENSY_PAD_39_BUS_TCG 8 183 | #else 184 | #define TEENSY_PAD_34_BUS_TCG 7 185 | #define TEENSY_PAD_35_BUS_TCG 7 186 | #define TEENSY_PAD_36_BUS_TCG 7 187 | #define TEENSY_PAD_37_BUS_TCG 7 188 | #define TEENSY_PAD_38_BUS_TCG 6 189 | #define TEENSY_PAD_39_BUS_TCG 6 190 | #define TEENSY_PAD_40_BUS_TCG 6 191 | #define TEENSY_PAD_41_BUS_TCG 6 192 | #define TEENSY_PAD_42_BUS_TCG 8 193 | #define TEENSY_PAD_43_BUS_TCG 8 194 | #define TEENSY_PAD_44_BUS_TCG 8 195 | #define TEENSY_PAD_45_BUS_TCG 8 196 | #define TEENSY_PAD_46_BUS_TCG 8 197 | #define TEENSY_PAD_47_BUS_TCG 8 198 | #define TEENSY_PAD_48_BUS_TCG 9 199 | #define TEENSY_PAD_49_BUS_TCG 9 200 | #define TEENSY_PAD_50_BUS_TCG 9 201 | #define TEENSY_PAD_51_BUS_TCG 9 202 | #define TEENSY_PAD_52_BUS_TCG 9 203 | #define TEENSY_PAD_53_BUS_TCG 9 204 | #define TEENSY_PAD_54_BUS_TCG 9 205 | #endif 206 | 207 | // teensy pad mux modes 208 | enum TEENSY_PAD_0_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_03 209 | TEENSY_PAD_0_MODE_FLEXCAN2_RX = 0, 210 | TEENSY_PAD_0_MODE_XBAR1_INOUT17, 211 | TEENSY_PAD_0_MODE_LPUART6_RX, 212 | TEENSY_PAD_0_MODE_USB_OTG1_OC, 213 | TEENSY_PAD_0_MODE_FLEXPWM1_PWMX01, 214 | TEENSY_PAD_0_MODE_GPIO1_IO03, 215 | TEENSY_PAD_0_MODE_REF_CLK_24M, 216 | TEENSY_PAD_0_MODE_LPSPI3_PCS0 217 | }; 218 | 219 | enum TEENSY_PAD_1_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_02 220 | TEENSY_PAD_1_MODE_FLEXCAN2_TX = 0, 221 | TEENSY_PAD_1_MODE_XBAR1_INOUT16, 222 | TEENSY_PAD_1_MODE_LPUART6_TX, 223 | TEENSY_PAD_1_MODE_USB_OTG1_PWR, 224 | TEENSY_PAD_1_MODE_FLEXPWM1_PWMX00, 225 | TEENSY_PAD_1_MODE_GPIO1_IO02, 226 | TEENSY_PAD_1_MODE_LPI2C1_HREQ, 227 | TEENSY_PAD_1_MODE_LPSPI3_SDI 228 | }; 229 | 230 | enum TEENSY_PAD_2_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_04 231 | TEENSY_PAD_2_MODE_SEMC_DATA04 = 0, 232 | TEENSY_PAD_2_MODE_FLEXPWM4_PWMA02, 233 | TEENSY_PAD_2_MODE_SAI2_TX_DATA, 234 | TEENSY_PAD_2_MODE_XBAR1_INOUT06, 235 | TEENSY_PAD_2_MODE_FLEXIO1_FLEXIO04, 236 | TEENSY_PAD_2_MODE_GPIO4_IO04 237 | }; 238 | 239 | enum TEENSY_PAD_3_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_05 240 | TEENSY_PAD_3_MODE_SEMC_DATA05 = 0, 241 | TEENSY_PAD_3_MODE_FLEXPWM4_PWMB02, 242 | TEENSY_PAD_3_MODE_SAI2_TX_SYNC, 243 | TEENSY_PAD_3_MODE_XBAR1_INOUT07, 244 | TEENSY_PAD_3_MODE_FLEXIO1_FLEXIO05, 245 | TEENSY_PAD_3_MODE_GPIO4_IO05 246 | }; 247 | 248 | enum TEENSY_PAD_4_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_06 249 | TEENSY_PAD_4_MODE_SEMC_DATA06 = 0, 250 | TEENSY_PAD_4_MODE_FLEXPWM2_PWMA00, 251 | TEENSY_PAD_4_MODE_SAI2_TX_BCLK, 252 | TEENSY_PAD_4_MODE_XBAR1_INOUT08, 253 | TEENSY_PAD_4_MODE_FLEXIO1_FLEXIO06, 254 | TEENSY_PAD_4_MODE_GPIO4_IO06 255 | }; 256 | 257 | enum TEENSY_PAD_5_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_08 258 | TEENSY_PAD_5_MODE_SEMC_DM00 = 0, 259 | TEENSY_PAD_5_MODE_FLEXPWM2_PWMA01, 260 | TEENSY_PAD_5_MODE_SAI2_RX_DATA, 261 | TEENSY_PAD_5_MODE_XBAR1_INOUT17, 262 | TEENSY_PAD_5_MODE_FLEXIO1_FLEXIO08, 263 | TEENSY_PAD_5_MODE_GPIO4_IO08 264 | }; 265 | 266 | enum TEENSY_PAD_6_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_10 267 | TEENSY_PAD_6_MODE_LCD_DATA06 = 0, 268 | TEENSY_PAD_6_MODE_QTIMER4_TIMER1, 269 | TEENSY_PAD_6_MODE_FLEXPWM2_PWMA02, 270 | TEENSY_PAD_6_MODE_SAI1_TX_DATA03, 271 | TEENSY_PAD_6_MODE_FLEXIO2_FLEXIO10, 272 | TEENSY_PAD_6_MODE_GPIO2_IO10, 273 | TEENSY_PAD_6_MODE_SRC_BOOT_CFG06, 274 | TEENSY_PAD_6_MODE_ENET2_CRS = 8 275 | }; 276 | 277 | enum TEENSY_PAD_7_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_01 278 | TEENSY_PAD_7_MODE_LCD_DATA13 = 0, 279 | TEENSY_PAD_7_MODE_XBAR1_INOUT15, 280 | TEENSY_PAD_7_MODE_LPUART4_RX, 281 | TEENSY_PAD_7_MODE_SAI1_TX_DATA00, 282 | TEENSY_PAD_7_MODE_FLEXIO2_FLEXIO17, 283 | TEENSY_PAD_7_MODE_GPIO2_IO17, 284 | TEENSY_PAD_7_MODE_FLEXPWM1_PWMB03, 285 | TEENSY_PAD_7_MODE_ENET2_RDATA00 = 8, 286 | TEENSY_PAD_7_MODE_FLEXIO3_FLEXIO17 287 | }; 288 | 289 | enum TEENSY_PAD_8_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_00 290 | TEENSY_PAD_8_MODE_LCD_DATA12 = 0, 291 | TEENSY_PAD_8_MODE_XBAR1_INOUT14, 292 | TEENSY_PAD_8_MODE_LPUART4_TX, 293 | TEENSY_PAD_8_MODE_SAI1_RX_DATA00, 294 | TEENSY_PAD_8_MODE_FLEXIO2_FLEXIO16, 295 | TEENSY_PAD_8_MODE_GPIO2_IO16, 296 | TEENSY_PAD_8_MODE_FLEXPWM1_PWMA03, 297 | TEENSY_PAD_8_MODE_ENET2_RX_ER = 8, 298 | TEENSY_PAD_8_MODE_FLEXIO3_FLEXIO16 299 | }; 300 | 301 | enum TEENSY_PAD_9_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_11 302 | TEENSY_PAD_9_MODE_LCD_DATA07 = 0, 303 | TEENSY_PAD_9_MODE_QTIMER4_TIMER2, 304 | TEENSY_PAD_9_MODE_FLEXPWM2_PWMB02, 305 | TEENSY_PAD_9_MODE_SAI1_TX_DATA02, 306 | TEENSY_PAD_9_MODE_FLEXIO2_FLEXIO11, 307 | TEENSY_PAD_9_MODE_GPIO2_IO11, 308 | TEENSY_PAD_9_MODE_SRC_BOOT_CFG07, 309 | TEENSY_PAD_9_MODE_ENET2_COL = 8 310 | }; 311 | 312 | enum TEENSY_PAD_10_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_00 313 | TEENSY_PAD_10_MODE_LCD_CLK = 0, 314 | TEENSY_PAD_10_MODE_QTIMER1_TIMER0, 315 | TEENSY_PAD_10_MODE_MQS_RIGHT, 316 | TEENSY_PAD_10_MODE_LPSPI4_PCS0, 317 | TEENSY_PAD_10_MODE_FLEXIO2_FLEXIO00, 318 | TEENSY_PAD_10_MODE_GPIO2_IO00, 319 | TEENSY_PAD_10_MODE_SEMC_CSX01, 320 | TEENSY_PAD_10_MODE_ENET2_MDC = 8 321 | }; 322 | 323 | enum TEENSY_PAD_11_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_02 324 | TEENSY_PAD_11_MODE_LCD_HSYNC = 0, 325 | TEENSY_PAD_11_MODE_QTIMER1_TIMER2, 326 | TEENSY_PAD_11_MODE_FLEXCAN1_TX, 327 | TEENSY_PAD_11_MODE_LPSPI4_SDO, 328 | TEENSY_PAD_11_MODE_FLEXIO2_FLEXIO02, 329 | TEENSY_PAD_11_MODE_GPIO2_IO02, 330 | TEENSY_PAD_11_MODE_SEMC_CSX03, 331 | TEENSY_PAD_11_MODE_ENET2_1588_EVENT0_OUT = 8 332 | }; 333 | 334 | enum TEENSY_PAD_12_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_01 335 | TEENSY_PAD_12_MODE_LCD_ENABLE = 0, 336 | TEENSY_PAD_12_MODE_QTIMER1_TIMER1, 337 | TEENSY_PAD_12_MODE_MQS_LEFT, 338 | TEENSY_PAD_12_MODE_LPSPI4_SDI, 339 | TEENSY_PAD_12_MODE_FLEXIO2_FLEXIO01, 340 | TEENSY_PAD_12_MODE_GPIO2_IO01, 341 | TEENSY_PAD_12_MODE_SEMC_CSX02, 342 | TEENSY_PAD_12_MODE_ENET2_MDIO = 8 343 | }; 344 | 345 | enum TEENSY_PAD_13_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_03 346 | TEENSY_PAD_13_MODE_LCD_VSYNC = 0, 347 | TEENSY_PAD_13_MODE_QTIMER2_TIMER0, 348 | TEENSY_PAD_13_MODE_FLEXCAN1_RX, 349 | TEENSY_PAD_13_MODE_LPSPI4_SCK, 350 | TEENSY_PAD_13_MODE_FLEXIO2_FLEXIO03, 351 | TEENSY_PAD_13_MODE_GPIO2_IO03, 352 | TEENSY_PAD_13_MODE_WDOG2_RESET_B_DEB, 353 | TEENSY_PAD_13_MODE_ENET2_1588_EVENT0_IN = 8 354 | }; 355 | 356 | enum TEENSY_PAD_14_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_02 357 | TEENSY_PAD_14_MODE_USB_OTG1_ID = 0, 358 | TEENSY_PAD_14_MODE_QTIMER3_TIMER2, 359 | TEENSY_PAD_14_MODE_LPUART2_TX, 360 | TEENSY_PAD_14_MODE_SPDIF_OUT, 361 | TEENSY_PAD_14_MODE_ENET_1588_EVENT2_OUT, 362 | TEENSY_PAD_14_MODE_GPIO1_IO18, 363 | TEENSY_PAD_14_MODE_USDHC1_CD_B, 364 | TEENSY_PAD_14_MODE_KPP_ROW06, 365 | TEENSY_PAD_14_MODE_GPT2_CLK, 366 | TEENSY_PAD_14_MODE_FLEXIO3_FLEXIO02 367 | }; 368 | 369 | enum TEENSY_PAD_15_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_03 370 | TEENSY_PAD_15_MODE_USB_OTG1_OC = 0, 371 | TEENSY_PAD_15_MODE_QTIMER3_TIMER3, 372 | TEENSY_PAD_15_MODE_LPUART2_RX, 373 | TEENSY_PAD_15_MODE_SPDIF_IN, 374 | TEENSY_PAD_15_MODE_ENET_1588_EVENT2_IN, 375 | TEENSY_PAD_15_MODE_GPIO1_IO19, 376 | TEENSY_PAD_15_MODE_USDHC2_CD_B, 377 | TEENSY_PAD_15_MODE_KPP_COL06, 378 | TEENSY_PAD_15_MODE_GPT2_CAPTURE1, 379 | TEENSY_PAD_15_MODE_FLEXIO3_FLEXIO03 380 | }; 381 | 382 | enum TEENSY_PAD_16_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_07 383 | TEENSY_PAD_16_MODE_FLEXSPIB_DATA00 = 0, 384 | TEENSY_PAD_16_MODE_LPI2C3_SCL, 385 | TEENSY_PAD_16_MODE_LPUART3_RX, 386 | TEENSY_PAD_16_MODE_SPDIF_EXT_CLK, 387 | TEENSY_PAD_16_MODE_CSI_HSYNC, 388 | TEENSY_PAD_16_MODE_GPIO1_IO23, 389 | TEENSY_PAD_16_MODE_USDHC2_DATA3, 390 | TEENSY_PAD_16_MODE_KPP_COL04, 391 | TEENSY_PAD_16_MODE_GPT2_COMPARE3, 392 | TEENSY_PAD_16_MODE_FLEXIO3_FLEXIO07 393 | }; 394 | 395 | enum TEENSY_PAD_17_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_06 396 | TEENSY_PAD_17_MODE_FLEXSPIB_DATA01 = 0, 397 | TEENSY_PAD_17_MODE_LPI2C3_SDA, 398 | TEENSY_PAD_17_MODE_LPUART3_TX, 399 | TEENSY_PAD_17_MODE_SPDIF_LOCK, 400 | TEENSY_PAD_17_MODE_CSI_VSYNC, 401 | TEENSY_PAD_17_MODE_GPIO1_IO22, 402 | TEENSY_PAD_17_MODE_USDHC2_DATA2, 403 | TEENSY_PAD_17_MODE_KPP_ROW04, 404 | TEENSY_PAD_17_MODE_GPT2_COMPARE2, 405 | TEENSY_PAD_17_MODE_FLEXIO3_FLEXIO06 406 | }; 407 | 408 | enum TEENSY_PAD_18_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_01 409 | TEENSY_PAD_18_MODE_USB_OTG1_PWR = 0, 410 | TEENSY_PAD_18_MODE_QTIMER3_TIMER1, 411 | TEENSY_PAD_18_MODE_LPUART2_RTS_B, 412 | TEENSY_PAD_18_MODE_LPI2C1_SDA, 413 | TEENSY_PAD_18_MODE_CCM_PMIC_READY, 414 | TEENSY_PAD_18_MODE_GPIO1_IO17, 415 | TEENSY_PAD_18_MODE_USDHC1_VSELECT, 416 | TEENSY_PAD_18_MODE_KPP_COL07, 417 | TEENSY_PAD_18_MODE_ENET2_1588_EVENT0_IN, 418 | TEENSY_PAD_18_MODE_FLEXIO3_FLEXIO01 419 | }; 420 | 421 | enum TEENSY_PAD_19_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_00 422 | TEENSY_PAD_19_MODE_USB_OTG2_ID = 0, 423 | TEENSY_PAD_19_MODE_QTIMER3_TIMER0, 424 | TEENSY_PAD_19_MODE_LPUART2_CTS_B, 425 | TEENSY_PAD_19_MODE_LPI2C1_SCL, 426 | TEENSY_PAD_19_MODE_WDOG1_B, 427 | TEENSY_PAD_19_MODE_GPIO1_IO16, 428 | TEENSY_PAD_19_MODE_USDHC1_WP, 429 | TEENSY_PAD_19_MODE_KPP_ROW07, 430 | TEENSY_PAD_19_MODE_ENET2_1588_EVENT0_OUT, 431 | TEENSY_PAD_19_MODE_FLEXIO3_FLEXIO00 432 | }; 433 | 434 | enum TEENSY_PAD_20_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_10 435 | TEENSY_PAD_20_MODE_FLEXSPIA_DATA03 = 0, 436 | TEENSY_PAD_20_MODE_WDOG1_B, 437 | TEENSY_PAD_20_MODE_LPUART8_TX, 438 | TEENSY_PAD_20_MODE_SAI1_RX_SYNC, 439 | TEENSY_PAD_20_MODE_CSI_DATA07, 440 | TEENSY_PAD_20_MODE_GPIO1_IO26, 441 | TEENSY_PAD_20_MODE_USDHC2_WP, 442 | TEENSY_PAD_20_MODE_KPP_ROW02, 443 | TEENSY_PAD_20_MODE_ENET2_1588_EVENT1_OUT, 444 | TEENSY_PAD_20_MODE_FLEXIO3_FLEXIO10 445 | }; 446 | 447 | enum TEENSY_PAD_21_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_11 448 | TEENSY_PAD_21_MODE_FLEXSPIA_DATA02 = 0, 449 | TEENSY_PAD_21_MODE_EWM_OUT_B, 450 | TEENSY_PAD_21_MODE_LPUART8_RX, 451 | TEENSY_PAD_21_MODE_SAI1_RX_BCLK, 452 | TEENSY_PAD_21_MODE_CSI_DATA06, 453 | TEENSY_PAD_21_MODE_GPIO1_IO27, 454 | TEENSY_PAD_21_MODE_USDHC2_RESET_B, 455 | TEENSY_PAD_21_MODE_KPP_COL02, 456 | TEENSY_PAD_21_MODE_ENET2_1588_EVENT1_IN, 457 | TEENSY_PAD_21_MODE_FLEXIO3_FLEXIO11 458 | }; 459 | 460 | enum TEENSY_PAD_22_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_08 461 | TEENSY_PAD_22_MODE_FLEXSPIA_SS1_B = 0, 462 | TEENSY_PAD_22_MODE_FLEXPWM4_PWMA00, 463 | TEENSY_PAD_22_MODE_FLEXCAN1_TX, 464 | TEENSY_PAD_22_MODE_CCM_PMIC_READY, 465 | TEENSY_PAD_22_MODE_CSI_DATA09, 466 | TEENSY_PAD_22_MODE_GPIO1_IO24, 467 | TEENSY_PAD_22_MODE_USDHC2_CMD, 468 | TEENSY_PAD_22_MODE_KPP_ROW03, 469 | TEENSY_PAD_22_MODE_FLEXIO3_FLEXIO08 = 9 470 | }; 471 | 472 | enum TEENSY_PAD_23_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_09 473 | TEENSY_PAD_23_MODE_FLEXSPIA_DQS = 0, 474 | TEENSY_PAD_23_MODE_FLEXPWM4_PWMA01, 475 | TEENSY_PAD_23_MODE_FLEXCAN1_RX, 476 | TEENSY_PAD_23_MODE_SAI1_MCLK, 477 | TEENSY_PAD_23_MODE_CSI_DATA08, 478 | TEENSY_PAD_23_MODE_GPIO1_IO25, 479 | TEENSY_PAD_23_MODE_USDHC2_CLK, 480 | TEENSY_PAD_23_MODE_KPP_COL03, 481 | TEENSY_PAD_23_MODE_FLEXIO3_FLEXIO09 = 9 482 | }; 483 | 484 | enum TEENSY_PAD_24_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_12 485 | TEENSY_PAD_24_MODE_LPI2C4_SCL = 0, 486 | TEENSY_PAD_24_MODE_CCM_PMIC_READY, 487 | TEENSY_PAD_24_MODE_LPUART1_TX, 488 | TEENSY_PAD_24_MODE_WDOG2_WDOG_B, 489 | TEENSY_PAD_24_MODE_FLEXPWM1_PWMX02, 490 | TEENSY_PAD_24_MODE_GPIO1_IO12, 491 | TEENSY_PAD_24_MODE_ENET_1588_EVENT1_OUT, 492 | TEENSY_PAD_24_MODE_NMI_GLUE_NMI 493 | }; 494 | 495 | enum TEENSY_PAD_25_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_13 496 | TEENSY_PAD_25_MODE_LPI2C4_SDA = 0, 497 | TEENSY_PAD_25_MODE_GPT1_CLK, 498 | TEENSY_PAD_25_MODE_LPUART1_RX, 499 | TEENSY_PAD_25_MODE_EWM_OUT_B, 500 | TEENSY_PAD_25_MODE_FLEXPWM1_PWMX03, 501 | TEENSY_PAD_25_MODE_GPIO1_IO13, 502 | TEENSY_PAD_25_MODE_ENET_1588_EVENT1_IN, 503 | TEENSY_PAD_25_MODE_REF_CLK_24M 504 | }; 505 | 506 | enum TEENSY_PAD_26_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_14 507 | TEENSY_PAD_26_MODE_FLEXSPIA_SCLK = 0, 508 | TEENSY_PAD_26_MODE_ACMP_OUT02, 509 | TEENSY_PAD_26_MODE_LPSPI3_SDO, 510 | TEENSY_PAD_26_MODE_SAI1_TX_BCLK, 511 | TEENSY_PAD_26_MODE_CSI_DATA03, 512 | TEENSY_PAD_26_MODE_GPIO1_IO30, 513 | TEENSY_PAD_26_MODE_USDHC2_DATA6, 514 | TEENSY_PAD_26_MODE_KPP_ROW00, 515 | TEENSY_PAD_26_MODE_ENET2_1588_EVENT3_OUT, 516 | TEENSY_PAD_26_MODE_FLEXIO3_FLEXIO14 517 | }; 518 | 519 | enum TEENSY_PAD_27_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_15 520 | TEENSY_PAD_27_MODE_FLEXSPIA_SS0_B = 0, 521 | TEENSY_PAD_27_MODE_ACMP_OUT03, 522 | TEENSY_PAD_27_MODE_LPSPI3_SCK, 523 | TEENSY_PAD_27_MODE_SAI1_TX_SYNC, 524 | TEENSY_PAD_27_MODE_CSI_DATA02, 525 | TEENSY_PAD_27_MODE_GPIO1_IO31, 526 | TEENSY_PAD_27_MODE_USDHC2_DATA7, 527 | TEENSY_PAD_27_MODE_KPP_COL00, 528 | TEENSY_PAD_27_MODE_ENET2_1588_EVENT3_IN, 529 | TEENSY_PAD_27_MODE_FLEXIO3_FLEXIO15 530 | }; 531 | 532 | enum TEENSY_PAD_28_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_32 533 | TEENSY_PAD_28_MODE_SEMC_DATA10 = 0, 534 | TEENSY_PAD_28_MODE_FLEXPWM3_PWMB01, 535 | TEENSY_PAD_28_MODE_LPUART7_RX, 536 | TEENSY_PAD_28_MODE_CCM_PMIC_RDY, 537 | TEENSY_PAD_28_MODE_CSI_DATA21, 538 | TEENSY_PAD_28_MODE_GPIO3_IO18, 539 | TEENSY_PAD_28_MODE_ENET2_TX_EN = 8 540 | }; 541 | 542 | enum TEENSY_PAD_29_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_31 543 | TEENSY_PAD_29_MODE_SEMC_DATA09 = 0, 544 | TEENSY_PAD_29_MODE_FLEXPWM3_PWMA01, 545 | TEENSY_PAD_29_MODE_LPUART7_TX, 546 | TEENSY_PAD_29_MODE_LPSPI1_PCS1, 547 | TEENSY_PAD_29_MODE_CSI_DATA22, 548 | TEENSY_PAD_29_MODE_GPIO4_IO31, 549 | TEENSY_PAD_29_MODE_ENET2_TDATA01 = 8 550 | }; 551 | 552 | enum TEENSY_PAD_30_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_37 553 | TEENSY_PAD_30_MODE_SEMC_DATA15 = 0, 554 | TEENSY_PAD_30_MODE_XBAR1_IN23, 555 | TEENSY_PAD_30_MODE_GPT1_COMPARE3, 556 | TEENSY_PAD_30_MODE_SAI3_MCLK, 557 | TEENSY_PAD_30_MODE_CSI_DATA16, 558 | TEENSY_PAD_30_MODE_GPIO3_IO23, 559 | TEENSY_PAD_30_MODE_USDHC2_WP, 560 | TEENSY_PAD_30_MODE_ENET2_RX_EN = 8, 561 | TEENSY_PAD_30_MODE_FLEXCAN3_RX 562 | }; 563 | 564 | enum TEENSY_PAD_31_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_36 565 | TEENSY_PAD_31_MODE_SEMC_DATA14 = 0, 566 | TEENSY_PAD_31_MODE_XBAR1_IN22, 567 | TEENSY_PAD_31_MODE_GPT1_COMPARE2, 568 | TEENSY_PAD_31_MODE_SAI3_TX_DATA, 569 | TEENSY_PAD_31_MODE_CSI_DATA17, 570 | TEENSY_PAD_31_MODE_GPIO3_IO22, 571 | TEENSY_PAD_31_MODE_USDHC1_WP, 572 | TEENSY_PAD_31_MODE_ENET2_RDATA01 = 8, 573 | TEENSY_PAD_31_MODE_FLEXCAN3_TX 574 | }; 575 | 576 | enum TEENSY_PAD_32_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_12 577 | TEENSY_PAD_32_MODE_LCD_DATA08 = 0, 578 | TEENSY_PAD_32_MODE_XBAR1_INOUT10, 579 | TEENSY_PAD_32_MODE_ARM_TRACE_CLK, 580 | TEENSY_PAD_32_MODE_SAI1_TX_DATA01, 581 | TEENSY_PAD_32_MODE_FLEXIO2_FLEXIO12, 582 | TEENSY_PAD_32_MODE_GPIO2_IO12, 583 | TEENSY_PAD_32_MODE_SRC_BOOT_CFG08, 584 | TEENSY_PAD_32_MODE_ENET2_TDATA00 = 8 585 | }; 586 | 587 | enum TEENSY_PAD_33_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_07 588 | TEENSY_PAD_33_MODE_SEMC_DATA07 = 0, 589 | TEENSY_PAD_33_MODE_FLEXPWM2_PWMB00, 590 | TEENSY_PAD_33_MODE_SAI2_MCLK, 591 | TEENSY_PAD_33_MODE_XBAR1_INOUT09, 592 | TEENSY_PAD_33_MODE_FLEXIO1_FLEXIO07, 593 | TEENSY_PAD_33_MODE_GPIO4_IO07 594 | }; 595 | 596 | #ifndef TARGET_TEENSY41 597 | enum TEENSY_PAD_34_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_03 598 | TEENSY_PAD_34_MODE_USDHC1_DATA1 = 0, 599 | TEENSY_PAD_34_MODE_FLEXPWM1_PWMB01, 600 | TEENSY_PAD_34_MODE_LPUART8_RTS_B, 601 | TEENSY_PAD_34_MODE_XBAR1_INOUT07, 602 | TEENSY_PAD_34_MODE_LPSPI1_SDI, 603 | TEENSY_PAD_34_MODE_GPIO3_IO15, 604 | TEENSY_PAD_34_MODE_ENET2_RDATA00 = 8, 605 | TEENSY_PAD_34_MODE_SEMC_CLK6 606 | }; 607 | 608 | enum TEENSY_PAD_35_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_02 609 | TEENSY_PAD_35_MODE_USDHC1_DATA0 = 0, 610 | TEENSY_PAD_35_MODE_FLEXPWM1_PWMA01, 611 | TEENSY_PAD_35_MODE_LPUART8_CTS_B, 612 | TEENSY_PAD_35_MODE_XBAR1_INOUT06, 613 | TEENSY_PAD_35_MODE_LPSPI1_SDO, 614 | TEENSY_PAD_35_MODE_GPIO3_IO14, 615 | TEENSY_PAD_35_MODE_ENET2_RX_ER = 8, 616 | TEENSY_PAD_35_MODE_SEMC_CLK5 617 | }; 618 | 619 | enum TEENSY_PAD_36_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_01 620 | TEENSY_PAD_36_MODE_USDHC1_CLK = 0, 621 | TEENSY_PAD_36_MODE_FLEXPWM1_PWMB00, 622 | TEENSY_PAD_36_MODE_LPI2C3_SDA, 623 | TEENSY_PAD_36_MODE_XBAR1_INOUT05, 624 | TEENSY_PAD_36_MODE_LPSPI1_PCS0, 625 | TEENSY_PAD_36_MODE_GPIO3_IO13, 626 | TEENSY_PAD_36_MODE_FLEXSPIB_SS1_B, 627 | TEENSY_PAD_36_MODE_ENET2_TX_CLK = 8, 628 | TEENSY_PAD_36_MODE_ENET2_REF_CLK2 629 | }; 630 | 631 | enum TEENSY_PAD_37_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_00 632 | TEENSY_PAD_37_MODE_USDHC1_CMD = 0, 633 | TEENSY_PAD_37_MODE_FLEXPWM1_PWMA00, 634 | TEENSY_PAD_37_MODE_LPI2C3_SCL, 635 | TEENSY_PAD_37_MODE_XBAR1_INOUT04, 636 | TEENSY_PAD_37_MODE_LPSPI1_SCK, 637 | TEENSY_PAD_37_MODE_GPIO3_IO12, 638 | TEENSY_PAD_37_MODE_FLEXSPIA_SS1_B, 639 | TEENSY_PAD_37_MODE_ENET2_TX_EN = 8, 640 | TEENSY_PAD_37_MODE_SEMC_DQS4 641 | }; 642 | 643 | enum TEENSY_PAD_38_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_05 644 | TEENSY_PAD_38_MODE_USDHC1_DATA3 = 0, 645 | TEENSY_PAD_38_MODE_FLEXPWM1_PWMB02, 646 | TEENSY_PAD_38_MODE_LPUART8_RX, 647 | TEENSY_PAD_38_MODE_XBAR1_INOUT09, 648 | TEENSY_PAD_38_MODE_FLEXSPIB_DQS, 649 | TEENSY_PAD_38_MODE_GPIO3_IO17, 650 | TEENSY_PAD_38_MODE_CCM_CLKO2, 651 | TEENSY_PAD_38_MODE_ENET2_RX_EN = 8 652 | }; 653 | 654 | enum TEENSY_PAD_39_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_04 655 | TEENSY_PAD_39_MODE_USDHC1_DATA2 = 0, 656 | TEENSY_PAD_39_MODE_FLEXPWM1_PWMA02, 657 | TEENSY_PAD_39_MODE_LPUART8_TX, 658 | TEENSY_PAD_39_MODE_XBAR1_INOUT08, 659 | TEENSY_PAD_39_MODE_FLEXSPIB_SS0_B, 660 | TEENSY_PAD_39_MODE_GPIO3_IO16, 661 | TEENSY_PAD_39_MODE_CCM_CLKO1, 662 | TEENSY_PAD_39_MODE_ENET2_RDATA01 = 8 663 | }; 664 | #else 665 | enum TEENSY_PAD_34_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_13 666 | TEENSY_PAD_34_MODE_WDOG1_B = 0, 667 | TEENSY_PAD_34_MODE_LPUART5_RX, 668 | TEENSY_PAD_34_MODE_CSI_VSYNC, 669 | TEENSY_PAD_34_MODE_ENET_1588_EVENT0_OUT, 670 | TEENSY_PAD_34_MODE_FLEXIO2_FLEXIO29, 671 | TEENSY_PAD_34_MODE_GPIO2_IO29, 672 | TEENSY_PAD_34_MODE_USDHC1_WP, 673 | TEENSY_PAD_34_MODE_SEMC_DQS4 = 8, 674 | TEENSY_PAD_34_MODE_FLEXIO3_FLEXIO29 675 | }; 676 | 677 | enum TEENSY_PAD_35_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_12 678 | TEENSY_PAD_35_MODE_LPUART5_TX = 1, 679 | TEENSY_PAD_35_MODE_CSI_PIXCLK, 680 | TEENSY_PAD_35_MODE_ENET_1588_EVENT0_IN, 681 | TEENSY_PAD_35_MODE_FLEXIO2_FLEXIO28, 682 | TEENSY_PAD_35_MODE_GPIO2_IO28, 683 | TEENSY_PAD_35_MODE_USDHC1_CD_B, 684 | TEENSY_PAD_35_MODE_FLEXIO3_FLEXIO28 = 9 685 | }; 686 | 687 | enum TEENSY_PAD_36_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_02 688 | TEENSY_PAD_36_MODE_LCD_DATA14 = 0, 689 | TEENSY_PAD_36_MODE_XBAR1_INOUT16, 690 | TEENSY_PAD_36_MODE_LPSPI4_PCS2, 691 | TEENSY_PAD_36_MODE_SAI1_TX_BCLK, 692 | TEENSY_PAD_36_MODE_FLEXIO2_FLEXIO18, 693 | TEENSY_PAD_36_MODE_GPIO2_IO18, 694 | TEENSY_PAD_36_MODE_FLEXPWM2_PWMA03, 695 | TEENSY_PAD_36_MODE_ENET2_RDATA01 = 8, 696 | TEENSY_PAD_36_MODE_FLEXIO3_FLEXIO18 697 | }; 698 | 699 | enum TEENSY_PAD_37_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_03 700 | TEENSY_PAD_37_MODE_LCD_DATA15 = 0, 701 | TEENSY_PAD_37_MODE_XBAR1_INOUT17, 702 | TEENSY_PAD_37_MODE_LPSPI4_PCS1, 703 | TEENSY_PAD_37_MODE_SAI1_TX_SYNC, 704 | TEENSY_PAD_37_MODE_FLEXIO2_FLEXIO19, 705 | TEENSY_PAD_37_MODE_GPIO2_IO19, 706 | TEENSY_PAD_37_MODE_FLEXPWM2_PWMB03, 707 | TEENSY_PAD_37_MODE_ENET2_RX_EN = 8, 708 | TEENSY_PAD_37_MODE_FLEXIO3_FLEXIO19 709 | }; 710 | 711 | enum TEENSY_PAD_38_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_12 712 | TEENSY_PAD_38_MODE_FLEXSPIA_DATA01 = 0, 713 | TEENSY_PAD_38_MODE_ACMP_OUT00, 714 | TEENSY_PAD_38_MODE_LPSPI3_PCS0, 715 | TEENSY_PAD_38_MODE_SAI1_RX_DATA00, 716 | TEENSY_PAD_38_MODE_CSI_DATA05, 717 | TEENSY_PAD_38_MODE_GPIO1_IO28, 718 | TEENSY_PAD_38_MODE_USDHC2_DATA4, 719 | TEENSY_PAD_38_MODE_KPP_ROW01, 720 | TEENSY_PAD_38_MODE_ENET2_1588_EVENT2_OUT, 721 | TEENSY_PAD_38_MODE_FLEXIO3_FLEXIO12 722 | }; 723 | 724 | enum TEENSY_PAD_39_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_13 725 | TEENSY_PAD_39_MODE_FLEXSPIA_DATA00 = 0, 726 | TEENSY_PAD_39_MODE_ACMP_OUT01, 727 | TEENSY_PAD_39_MODE_LPSPI3_SDI, 728 | TEENSY_PAD_39_MODE_SAI1_TX_DATA00, 729 | TEENSY_PAD_39_MODE_CSI_DATA04, 730 | TEENSY_PAD_39_MODE_GPIO1_IO29, 731 | TEENSY_PAD_39_MODE_USDHC2_DATA5, 732 | TEENSY_PAD_39_MODE_KPP_COL01, 733 | TEENSY_PAD_39_MODE_ENET2_1588_EVENT2_IN, 734 | TEENSY_PAD_39_MODE_FLEXIO3_FLEXIO13 735 | }; 736 | 737 | enum TEENSY_PAD_40_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_04 738 | TEENSY_PAD_40_MODE_FLEXSPIB_DATA03 = 0, 739 | TEENSY_PAD_40_MODE_ENET_MDC, 740 | TEENSY_PAD_40_MODE_LPUART3_CTS_B, 741 | TEENSY_PAD_40_MODE_SPDIF_SR_CLK, 742 | TEENSY_PAD_40_MODE_CSI_PIXCLK, 743 | TEENSY_PAD_40_MODE_GPIO1_IO20, 744 | TEENSY_PAD_40_MODE_USDHC2_DATA0, 745 | TEENSY_PAD_40_MODE_KPP_ROW05, 746 | TEENSY_PAD_40_MODE_GPT2_CAPTURE2, 747 | TEENSY_PAD_40_MODE_FLEXIO3_FLEXIO04 748 | }; 749 | 750 | enum TEENSY_PAD_41_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_05 751 | TEENSY_PAD_41_MODE_FLEXSPIB_DATA02 = 0, 752 | TEENSY_PAD_41_MODE_ENET_MDIO, 753 | TEENSY_PAD_41_MODE_LPUART3_RTS_B, 754 | TEENSY_PAD_41_MODE_SPDIF_OUT, 755 | TEENSY_PAD_41_MODE_CSI_MCLK, 756 | TEENSY_PAD_41_MODE_GPIO1_IO21, 757 | TEENSY_PAD_41_MODE_USDHC2_DATA1, 758 | TEENSY_PAD_41_MODE_KPP_COL05, 759 | TEENSY_PAD_41_MODE_GPT2_COMPARE1, 760 | TEENSY_PAD_41_MODE_FLEXIO3_FLEXIO05 761 | }; 762 | 763 | enum TEENSY_PAD_42_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_03 764 | TEENSY_PAD_42_MODE_USDHC1_DATA1 = 0, 765 | TEENSY_PAD_42_MODE_FLEXPWM1_PWMB01, 766 | TEENSY_PAD_42_MODE_LPUART8_RTS_B, 767 | TEENSY_PAD_42_MODE_XBAR1_INOUT07, 768 | TEENSY_PAD_42_MODE_LPSPI1_SDI, 769 | TEENSY_PAD_42_MODE_GPIO3_IO15, 770 | TEENSY_PAD_42_MODE_ENET2_RDATA00 = 8, 771 | TEENSY_PAD_42_MODE_SEMC_CLK6 772 | }; 773 | 774 | enum TEENSY_PAD_43_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_02 775 | TEENSY_PAD_43_MODE_USDHC1_DATA0 = 0, 776 | TEENSY_PAD_43_MODE_FLEXPWM1_PWMA01, 777 | TEENSY_PAD_43_MODE_LPUART8_CTS_B, 778 | TEENSY_PAD_43_MODE_XBAR1_INOUT06, 779 | TEENSY_PAD_43_MODE_LPSPI1_SDO, 780 | TEENSY_PAD_43_MODE_GPIO3_IO14, 781 | TEENSY_PAD_43_MODE_ENET2_RX_ER = 8, 782 | TEENSY_PAD_43_MODE_SEMC_CLK5 783 | }; 784 | 785 | enum TEENSY_PAD_44_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_01 786 | TEENSY_PAD_44_MODE_USDHC1_CLK = 0, 787 | TEENSY_PAD_44_MODE_FLEXPWM1_PWMB00, 788 | TEENSY_PAD_44_MODE_LPI2C3_SDA, 789 | TEENSY_PAD_44_MODE_XBAR1_INOUT05, 790 | TEENSY_PAD_44_MODE_LPSPI1_PCS0, 791 | TEENSY_PAD_44_MODE_GPIO3_IO13, 792 | TEENSY_PAD_44_MODE_FLEXSPIB_SS1_B, 793 | TEENSY_PAD_44_MODE_ENET2_TX_CLK = 8, 794 | TEENSY_PAD_44_MODE_ENET2_REF_CLK2 795 | }; 796 | 797 | enum TEENSY_PAD_45_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_00 798 | TEENSY_PAD_45_MODE_USDHC1_CMD = 0, 799 | TEENSY_PAD_45_MODE_FLEXPWM1_PWMA00, 800 | TEENSY_PAD_45_MODE_LPI2C3_SCL, 801 | TEENSY_PAD_45_MODE_XBAR1_INOUT04, 802 | TEENSY_PAD_45_MODE_LPSPI1_SCK, 803 | TEENSY_PAD_45_MODE_GPIO3_IO12, 804 | TEENSY_PAD_45_MODE_FLEXSPIA_SS1_B, 805 | TEENSY_PAD_45_MODE_ENET2_TX_EN = 8, 806 | TEENSY_PAD_45_MODE_SEMC_DQS4 807 | }; 808 | 809 | enum TEENSY_PAD_46_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_05 810 | TEENSY_PAD_46_MODE_USDHC1_DATA3 = 0, 811 | TEENSY_PAD_46_MODE_FLEXPWM1_PWMB02, 812 | TEENSY_PAD_46_MODE_LPUART8_RX, 813 | TEENSY_PAD_46_MODE_XBAR1_INOUT09, 814 | TEENSY_PAD_46_MODE_FLEXSPIB_DQS, 815 | TEENSY_PAD_46_MODE_GPIO3_IO17, 816 | TEENSY_PAD_46_MODE_CCM_CLKO2, 817 | TEENSY_PAD_46_MODE_ENET2_RX_EN = 8 818 | }; 819 | 820 | enum TEENSY_PAD_47_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_04 821 | TEENSY_PAD_47_MODE_USDHC1_DATA2 = 0, 822 | TEENSY_PAD_47_MODE_FLEXPWM1_PWMA02, 823 | TEENSY_PAD_47_MODE_LPUART8_TX, 824 | TEENSY_PAD_47_MODE_XBAR1_INOUT08, 825 | TEENSY_PAD_47_MODE_FLEXSPIB_SS0_B, 826 | TEENSY_PAD_47_MODE_GPIO3_IO16, 827 | TEENSY_PAD_47_MODE_CCM_CLKO1, 828 | TEENSY_PAD_47_MODE_ENET2_RDATA01 = 8 829 | }; 830 | 831 | enum TEENSY_PAD_48_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_24 832 | TEENSY_PAD_48_MODE_SEMC_CAS = 0, 833 | TEENSY_PAD_48_MODE_FLEXPWM1_PWMB00, 834 | TEENSY_PAD_48_MODE_LPUART5_RX, 835 | TEENSY_PAD_48_MODE_ENET_TX_EN, 836 | TEENSY_PAD_48_MODE_GPT1_CAPTURE1, 837 | TEENSY_PAD_48_MODE_GPIO4_IO24, 838 | TEENSY_PAD_48_MODE_FLEXSPI2_A_SS0_B = 8 839 | }; 840 | 841 | enum TEENSY_PAD_49_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_27 842 | TEENSY_PAD_49_MODE_SEMC_CKE = 0, 843 | TEENSY_PAD_49_MODE_FLEXPWM1_PWMA02, 844 | TEENSY_PAD_49_MODE_LPUART5_RTS_B, 845 | TEENSY_PAD_49_MODE_LPSPI1_SCK, 846 | TEENSY_PAD_49_MODE_FLEXIO1_FLEXIO13, 847 | TEENSY_PAD_49_MODE_GPIO4_IO27, 848 | TEENSY_PAD_49_MODE_FLEXSPI2_A_DATA01 = 8 849 | }; 850 | 851 | enum TEENSY_PAD_50_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_28 852 | TEENSY_PAD_50_MODE_SEMC_WE = 0, 853 | TEENSY_PAD_50_MODE_FLEXPWM1_PWMB02, 854 | TEENSY_PAD_50_MODE_LPUART5_CTS_B, 855 | TEENSY_PAD_50_MODE_LPSPI1_SDO, 856 | TEENSY_PAD_50_MODE_FLEXIO1_FLEXIO14, 857 | TEENSY_PAD_50_MODE_GPIO4_IO28, 858 | TEENSY_PAD_50_MODE_FLEXSPI2_A_DATA02 = 8 859 | }; 860 | 861 | enum TEENSY_PAD_51_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_22 862 | TEENSY_PAD_51_MODE_SEMC_BA1 = 0, 863 | TEENSY_PAD_51_MODE_FLEXPWM3_PWMB03, 864 | TEENSY_PAD_51_MODE_LPI2C3_SCL, 865 | TEENSY_PAD_51_MODE_ENET_TDATA00, 866 | TEENSY_PAD_51_MODE_QTIMER2_TIMER3, 867 | TEENSY_PAD_51_MODE_GPIO4_IO22, 868 | TEENSY_PAD_51_MODE_FLEXSPI2_A_SS1_B = 8 869 | }; 870 | 871 | enum TEENSY_PAD_52_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_26 872 | TEENSY_PAD_52_MODE_SEMC_CLK = 0, 873 | TEENSY_PAD_52_MODE_FLEXPWM1_PWMB01, 874 | TEENSY_PAD_52_MODE_LPUART6_RX, 875 | TEENSY_PAD_52_MODE_ENET_RX_ER, 876 | TEENSY_PAD_52_MODE_FLEXIO1_FLEXIO12, 877 | TEENSY_PAD_52_MODE_GPIO4_IO26, 878 | TEENSY_PAD_52_MODE_FLEXSPI2_A_DATA00 = 8 879 | }; 880 | 881 | enum TEENSY_PAD_53_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_25 882 | TEENSY_PAD_53_MODE_SEMC_RAS = 0, 883 | TEENSY_PAD_53_MODE_FLEXPWM1_PWMA01, 884 | TEENSY_PAD_53_MODE_LPUART6_TX, 885 | TEENSY_PAD_53_MODE_ENET_TX_CLK, 886 | TEENSY_PAD_53_MODE_ENET_REF_CLK, 887 | TEENSY_PAD_53_MODE_GPIO4_IO25, 888 | TEENSY_PAD_53_MODE_FLEXSPI2_A_SCLK = 8 889 | }; 890 | 891 | enum TEENSY_PAD_54_MODES { // IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_29 892 | TEENSY_PAD_54_MODE_SEMC_CS0 = 0, 893 | TEENSY_PAD_54_MODE_FLEXPWM3_PWMA00, 894 | TEENSY_PAD_54_MODE_LPUART6_RTS_B, 895 | TEENSY_PAD_54_MODE_LPSPI1_SDI, 896 | TEENSY_PAD_54_MODE_FLEXIO1_FLEXIO15, 897 | TEENSY_PAD_54_MODE_GPIO4_IO29, 898 | TEENSY_PAD_54_MODE_FLEXSPI2_A_DATA03 = 8 899 | }; 900 | #endif 901 | 902 | #endif -------------------------------------------------------------------------------- /output/firmware40.hex: -------------------------------------------------------------------------------- 1 | :0200000460009A 2 | :100000004643464200000156000000000103030081 3 | :1000100000000000000000000000000000000000E0 4 | :1000200000000000000000000000000000000000D0 5 | :1000300000000000000000000000000000000000C0 6 | :1000400000000000010408000000000000000000A3 7 | :100050000000200000000000000000000000000080 8 | :100060000000000000000000000000000000000090 9 | :100070000000000000000000000000000000000080 10 | :10008000EB04180A063204260000000000000000FD 11 | :10009000050404240000000000000000000000002F 12 | :1000A0000000000000000000000000000000000050 13 | :1000B0000604000000000000000000000000000036 14 | :1000C0000000000000000000000000000000000030 15 | :1000D00020041808000000000000000000000000DC 16 | :1000E0000000000000000000000000000000000010 17 | :1000F0000000000000000000000000000000000000 18 | :10010000D8041808000000000000000000000000F3 19 | :100110000204180804200000000000000000000095 20 | :1001200000000000000000000000000000000000CF 21 | :10013000600400000000000000000000000000005B 22 | :1001400000000000000000000000000000000000AF 23 | :10015000000000000000000000000000000000009F 24 | :10016000000000000000000000000000000000008F 25 | :10017000000000000000000000000000000000007F 26 | :10018000000000000000000000000000000000006F 27 | :10019000000000000000000000000000000000005F 28 | :1001A000000000000000000000000000000000004F 29 | :1001B000000000000000000000000000000000003F 30 | :1001C000000100000010000001000000000000001D 31 | :1001D000000001000000000000000000000000001E 32 | :1001E000000000000000000000000000000000000F 33 | :1001F00000000000000000000000000000000000FF 34 | :1002000000000060382B000000000000FFFFFFFF2F 35 | :10021000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE 36 | :10022000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE 37 | :10023000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE 38 | :10024000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE 39 | :10025000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE 40 | :10026000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E 41 | :10027000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E 42 | :10028000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E 43 | :10029000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E 44 | :1002A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E 45 | :1002B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E 46 | :1002C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E 47 | :1002D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E 48 | :1002E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E 49 | :1002F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E 50 | :10030000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD 51 | :10031000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED 52 | :10032000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD 53 | :10033000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD 54 | :10034000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD 55 | :10035000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD 56 | :10036000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D 57 | :10037000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D 58 | :10038000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D 59 | :10039000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D 60 | :1003A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D 61 | :1003B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D 62 | :1003C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D 63 | :1003D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D 64 | :1003E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D 65 | :1003F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D 66 | :10040000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC 67 | :10041000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC 68 | :10042000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC 69 | :10043000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC 70 | :10044000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC 71 | :10045000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC 72 | :10046000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C 73 | :10047000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C 74 | :10048000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C 75 | :10049000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C 76 | :1004A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C 77 | :1004B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C 78 | :1004C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C 79 | :1004D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C 80 | :1004E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C 81 | :1004F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C 82 | :10050000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB 83 | :10051000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB 84 | :10052000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB 85 | :10053000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB 86 | :10054000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB 87 | :10055000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB 88 | :10056000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B 89 | :10057000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B 90 | :10058000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B 91 | :10059000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B 92 | :1005A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B 93 | :1005B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B 94 | :1005C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B 95 | :1005D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B 96 | :1005E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B 97 | :1005F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B 98 | :10060000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA 99 | :10061000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA 100 | :10062000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA 101 | :10063000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA 102 | :10064000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA 103 | :10065000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA 104 | :10066000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A 105 | :10067000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A 106 | :10068000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A 107 | :10069000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A 108 | :1006A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A 109 | :1006B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A 110 | :1006C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A 111 | :1006D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A 112 | :1006E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A 113 | :1006F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A 114 | :10070000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 115 | :10071000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 116 | :10072000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 117 | :10073000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 118 | :10074000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 119 | :10075000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 120 | :10076000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 121 | :10077000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 122 | :10078000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 123 | :10079000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 124 | :1007A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 125 | :1007B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 126 | :1007C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 127 | :1007D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 128 | :1007E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 129 | :1007F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 130 | :10080000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 131 | :10081000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 132 | :10082000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 133 | :10083000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 134 | :10084000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 135 | :10085000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 136 | :10086000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 137 | :10087000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 138 | :10088000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 139 | :10089000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 140 | :1008A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 141 | :1008B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 142 | :1008C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 143 | :1008D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 144 | :1008E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 145 | :1008F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 146 | :10090000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 147 | :10091000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 148 | :10092000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 149 | :10093000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 150 | :10094000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 151 | :10095000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 152 | :10096000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 153 | :10097000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 154 | :10098000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 155 | :10099000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 156 | :1009A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 157 | :1009B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 158 | :1009C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 159 | :1009D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 160 | :1009E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 161 | :1009F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 162 | :100A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 163 | :100A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 164 | :100A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 165 | :100A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 166 | :100A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 167 | :100A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 168 | :100A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 169 | :100A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 170 | :100A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 171 | :100A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 172 | :100AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 173 | :100AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 174 | :100AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 175 | :100AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 176 | :100AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 177 | :100AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 178 | :100B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 179 | :100B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 180 | :100B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 181 | :100B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 182 | :100B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 183 | :100B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 184 | :100B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 185 | :100B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 186 | :100B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 187 | :100B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 188 | :100BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 189 | :100BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 190 | :100BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 191 | :100BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 192 | :100BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 193 | :100BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 194 | :100C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 195 | :100C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 196 | :100C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 197 | :100C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 198 | :100C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 199 | :100C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 200 | :100C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 201 | :100C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 202 | :100C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 203 | :100C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 204 | :100CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 205 | :100CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 206 | :100CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 207 | :100CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 208 | :100CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 209 | :100CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 210 | :100D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 211 | :100D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 212 | :100D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 213 | :100D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 214 | :100D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 215 | :100D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 216 | :100D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 217 | :100D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 218 | :100D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 219 | :100D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 220 | :100DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 221 | :100DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 222 | :100DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 223 | :100DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 224 | :100DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 225 | :100DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 226 | :100E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 227 | :100E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 228 | :100E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 229 | :100E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 230 | :100E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 231 | :100E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 232 | :100E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 233 | :100E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 234 | :100E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 235 | :100E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 236 | :100EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 237 | :100EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 238 | :100EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 239 | :100ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 240 | :100EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 241 | :100EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 242 | :100F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 243 | :100F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 244 | :100F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 245 | :100F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 246 | :100F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 247 | :100F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 248 | :100F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 249 | :100F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 250 | :100F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 251 | :100F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 252 | :100FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 253 | :100FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 254 | :100FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 255 | :100FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 256 | :100FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 257 | :100FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 258 | :10100000D1002040411000600000000000000000FE 259 | :1010100000020060001000600000000000000000FE 260 | :1010200000207047054B4FF0FF305A6842F008022D 261 | :101030005A600822C3F88420704700BF00C01B40DC 262 | :10104000164817494164072101644FF42A0181635E 263 | :10105000144815496FF0030250F8043F42F8043F6A 264 | :101060008842F9D11149884208D01148002805D09A 265 | :1010700010484FF00052A2F10402EDE7DFF838D03B 266 | :10108000FFF7CEFF002801D1DFF830F004462046FC 267 | :10109000FFF7C8FF0028F7D030BFFDE700C00A40C7 268 | :1010A000ABAAAAAAFC13006054290060382B006088 269 | :1010B000E4010000502900600080072001000000CA 270 | :1010C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 271 | :1010D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 272 | :1010E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 273 | :1010F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 274 | :10110000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF 275 | :10111000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF 276 | :10112000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF 277 | :10113000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF 278 | :10114000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF 279 | :10115000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F 280 | :10116000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F 281 | :10117000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F 282 | :10118000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F 283 | :10119000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F 284 | :1011A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F 285 | :1011B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F 286 | :1011C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F 287 | :1011D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F 288 | :1011E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F 289 | :1011F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 290 | :10120000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE 291 | :10121000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE 292 | :10122000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE 293 | :10123000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE 294 | :10124000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE 295 | :10125000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E 296 | :10126000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E 297 | :10127000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E 298 | :10128000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E 299 | :10129000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E 300 | :1012A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E 301 | :1012B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E 302 | :1012C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E 303 | :1012D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E 304 | :1012E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E 305 | :1012F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE 306 | :10130000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED 307 | :10131000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD 308 | :10132000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD 309 | :10133000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD 310 | :10134000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD 311 | :10135000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D 312 | :10136000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D 313 | :10137000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D 314 | :10138000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D 315 | :10139000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D 316 | :1013A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D 317 | :1013B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D 318 | :1013C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D 319 | :1013D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D 320 | :1013E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D 321 | :1013F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD 322 | :10140000DFF800F0390E00002DE9FE5FB0E8F81FAC 323 | :10141000DBF8001001EA0A01B1EB090F7FF4F8AF25 324 | :101420004FEA0302B2F101027FF4FCAFB4F1010410 325 | :101430007FF4F6AFC7F80060B5F101057FF4FCAFAB 326 | :10144000C8F800605FEA0C007FF4E0AFBDE8FE9FE3 327 | :10145000031101F0030140009B0000F01E0003F1A6 328 | :101460008043814003F57C2330B503259C6E854085 329 | :1014700024EA05040C439C661AB19A6E2A409142F4 330 | :10148000FBD130BDA0F1B773274AA3F5585393425F 331 | :101490002DE9F04F42D800216FF000490122DFF81A 332 | :1014A0008CA00B4688468C46214C56106643214C36 333 | :1014B0003419544519D801250124B6FBF5FBBBFBB3 334 | :1014C000F4F7B7EB000E48BFA0EB070ECE4504DAE9 335 | :1014D000F14639462B46A04694460134092CEED1FC 336 | :1014E0000135092DE8D10132DEE70132802ADBD156 337 | :1014F000BCF1000F15D0104A1804914240EA0820B0 338 | :10150000D4BF0E4A042240EA0C00DEBF52180C4938 339 | :10151000B2FBF1F240EA0260BDE8F08F4FF0FF301D 340 | :10152000FAE76FF00100F7E7007038398036BE2621 341 | :1015300000366E0180C941D90046C3237FD1F0082F 342 | :1015400080D1F0082DE9F347044630B929B10846A7 343 | :10155000FFF798FF041EC0F2858014F07F0AC4F3E1 344 | :101560000329C4F30348C4F302677ED0B9F1000F26 345 | :101570007BD0B8F1000F78D0002F76D03E4E4FEAE6 346 | :101580006A054B46524675433C48B5FBF9F5B5FB39 347 | :10159000F8F5CDE90087294600F098F9B54267DBF8 348 | :1015A000374B9D424EDD03F1376303F5D8339D423F 349 | :1015B0005ED1344B40F22766DB68012330461A4681 350 | :1015C000194600F0F9F8304B4FF440429A604FF45E 351 | :1015D00080325A601A68002AFCDA7F229A602A4A0E 352 | :1015E000C3F804A01368002BFCDA284A09F1FF3382 353 | :1015F00008F1FF3813617B1E51691B0221F4F85179 354 | :1016000043EA88230B435361214B916C1942FCD16F 355 | :101610001D4B4FF480329A601A68002AFCDA40F2BF 356 | :101620007E439E4204D11B4BB5FBF7F59D4205DC82 357 | :10163000012200233046114600F0BEF8204602B0D9 358 | :10164000BDE8F0870F4BDB68134B9D4207DD134B62 359 | :1016500040F2E2469D42C8BF4FF4AF66ADE740F2AC 360 | :101660007E46AAE74FF0FF34E8E76FF00104E5E7B4 361 | :101670006FF00204E2E700BF00366E0100000020B8 362 | :1016800000F6342F0000084000800D4000C00F40DD 363 | :10169000020001000029DE0700A4781F0046C323D2 364 | :1016A00030B5084D84016B6A23F07F030B4343EA96 365 | :1016B00080136B622AB10C436B6A03F07F03A34271 366 | :1016C000FAD130BD00C00F400244904200D17047B3 367 | :1016D00000F8011BF9E70244904200D1704740F83E 368 | :1016E000041BF9E70346104310F0030F1A4406D019 369 | :1016F00010469A4200D1704703F8011BF9E74FF0FA 370 | :10170000013041431846904200D1704740F8041B15 371 | :10171000F9E741EA000313430A4413F0030F10B53D 372 | :1017200007D1031F914207D051F8044B43F8044FEF 373 | :10173000F8E7431E914200D110BD11F8014B03F8A8 374 | :10174000014FF7E740EA010313439B0710B504D1AB 375 | :101750000438043982B910460BE001398418A042DC 376 | :1017600001D1002005E0027811F8013F9A4201D032 377 | :10177000D01A10BD0130F2E750F8044F51F8043F81 378 | :101780009C4201D0E01AF4E7043AE3E703461A4624 379 | :10179000013311780029FAD1101A704707B5009368 380 | :1017A00013460A460146034800F090F8002003B0B3 381 | :1017B0005DF804FB2D00002070B515461926024681 382 | :1017C00038B9234BD86800F01F00704300F548700B 383 | :1017D00070BDA0F54874B0F5C86F94FBF6F431DA2B 384 | :1017E0001B48C06800F01F06A6422ED00BB1A642CF 385 | :1017F0002BDC20F0804323F01F031C43144BB1B1BA 386 | :10180000D968192301F01F015943124B01F54871A2 387 | :10181000114800F05BF80E4BDC6015B11A68002A25 388 | :10182000FCDAD868192300F01F005843CEE7D968C6 389 | :10183000192344F0804401F01F015943074B01F57F 390 | :101840004871E5E74FF0FF30C2E70020C0E700BF76 391 | :1018500000000840520000205C00002057000020DB 392 | :1018600030B585B00C220C463021009001A8FFF75E 393 | :1018700039FF782312488DF8053000239C426C46CE 394 | :101880008DF80F300CBF1A460A228DF80E2001AADF 395 | :1018900014F8011B0133023A01F00F050909042B6A 396 | :1018A000455D415CD5729172F2D1064B01A9064AA1 397 | :1018B0001B6803EB4303D05C00F0C0FF05B030BDF4 398 | :1018C0007B000020340100209C0100200FB42DE992 399 | :1018D000F347DDF828804046FFF758FF0746A0B1E0 400 | :1018E00000240BABDFF894902646DFF894A0019318 401 | :1018F000BC4208EB06010DDB204BA21B20481B68F5 402 | :1019000003EB4303C05C00F0A8FF02B0BDE8F04762 403 | :1019100004B0704718F80430252B2CD1D9F80030CA 404 | :10192000651CA21B03EB43031AF8030000F095FFAC 405 | :1019300018F80530732B11D00ED8532B0ED0582B1E 406 | :1019400008D1019B00211A1D18680192FFF788FF3A 407 | :10195000A51C2E466C1CCBE7782BF1E7019AD9F831 408 | :101960000030111D03EB430301911AF803001168C5 409 | :1019700000F064FFECE72546ECE700BF34010020EF 410 | :101980009C0100202DE9F04F054687B091460E4698 411 | :10199000002938D041EA0003584CDFF8648113F085 412 | :1019A000030B584F45D01AB101465748FFF78EFF39 413 | :1019B00000234FF0200A9B468DF80B3015F80B20C2 414 | :1019C0008DF80AA0110902F00F02A25C615C8DF88B 415 | :1019D0000920D8F800208DF8081002A902EB420275 416 | :1019E000B85C00F02BFF0BF00F020BF1010B0F2A7C 417 | :1019F0000CD05E45E2D1D8F80030444903EB4303F4 418 | :101A0000F85C00F01BFF07B0BDE8F08FD8F80020AD 419 | :101A10003E4902EB4202B85C00F010FFB9F1000F42 420 | :101A2000E7D05E45E5D905EB0B013748FFF74EFFE0 421 | :101A3000C4E71AB101463448FFF748FF00224FF0CF 422 | :101A4000200A8DF814204FEA9B022BF003038DF837 423 | :101A50000AA055F822200193C2F303118DF80DA0BE 424 | :101A60008DF810A0615C8DF813A08DF8081002F0BD 425 | :101A70000F01615C8DF80910C2F30331615C8DF8D0 426 | :101A80000B10C2F30321615C8DF80C10C2F30351FB 427 | :101A9000615C8DF80E10C2F30341615C8DF80F108C 428 | :101AA000110FC2F30362615CA25C8DF8111002A9F0 429 | :101AB0008DF81220D8F8002002EB4202B85C00F04A 430 | :101AC000BDFE0BF00C020BF1040B0C2A02D05E459C 431 | :101AD000B9D890E7D8F800200C4902EB4202B85C74 432 | :101AE00000F0ACFEB9F1000FF1D05E4583D9019949 433 | :101AF000054804312944FFF7E9FEA4E77B000020F4 434 | :101B0000340100209C010020730000207800002098 435 | :101B10002DE9F8434FF08043DFF8509080460021D4 436 | :101B200003F5582203F57C23D9F8000014681F69D7 437 | :101B30005E6904F07F0407F007075D69C6F382263B 438 | :101B4000FFF700FD01374046D9F8043001369847C9 439 | :101B5000C5F3012044EA07240021013044EA064489 440 | :101B600044EA0060BDE8F843FFF7ECBC3801002010 441 | :101B70002DE9F04FD0F8109087B0054609F04003EA 442 | :101B800009F03F070493C36803F0400203F03F06E7 443 | :101B9000059213F4807200F0988013F0380F40F033 444 | :101BA0003F81A54B06EB46061E440123767803933E 445 | :101BB000272F00F23881272E00F335816B68002B28 446 | :101BC00000F03481AB68002B00F030812B68002BD3 447 | :101BD00000F02C81DFF86482D8F80840002940F03A 448 | :101BE0008580282200212046FFF77CFD049B33BB23 449 | :101BF0002A69110623D59209914BC9F30029DFF810 450 | :101C000044A202F0380213F807B0052342EAC922C1 451 | :101C10004FF00109584642F0C102CDF800901AF881 452 | :101C2000071000F0D9FA4A464946384600F0FEFC53 453 | :101C30004B464A4659461AF8070000F08FF9059BB3 454 | :101C40008BBBEB681A062ED5DA00DFF8F8B1D900A5 455 | :101C50004FF0010902F4404201F480310A43D900F7 456 | :101C6000DB0001F4805103F400530B431BF8061012 457 | :101C7000CDF800901A43724B13F806A042F0C1024F 458 | :101C8000039B002B35D10523504600F0A5FA4A46A8 459 | :101C90004946304600F0CAFC4B46039A51461BF8B1 460 | :101CA000060000F05BF96B682360AB6863602B682B 461 | :101CB000A360A969EA692B6A09B3E160002A49D1E6 462 | :101CC000049A5AB304F10C021DE0039270E7013349 463 | :101CD0000A46516A0029FAD1D8F80C10994240F30B 464 | :101CE000A880282101FB034454627AE7224601239D 465 | :101CF000EFE74FF0FF33504600F06EFAD3E7049958 466 | :101D000031B1002ADED02261B3B904F10C0313E033 467 | :101D10004B49C85D01218140E1602AB9494AD15D42 468 | :101D2000494A52F821208C3222612BB9454BDA5DA9 469 | :101D3000454B53F822308C3363616A6AEB6A82B197 470 | :101D4000E261AA6AA26113BB039BABB9059B002B9E 471 | :101D500059D060E02261002BEED1049B002BE5D02E 472 | :101D6000D3E7039A002A40D041F2FF02E261EA6819 473 | :101D7000C2F30742A26153B9EB682F4A03F03F0355 474 | :101D800003EB4303D25C314B53F822301C33236204 475 | :101D90006869002842D0FFF775FB2D4A2D4BC8F823 476 | :101DA00000001B681569516903F07F0305F0070502 477 | :101DB0005269C1F38221284C0135C2F3012201315D 478 | :101DC000C8F8104043EA0523013243EA014343EADD 479 | :101DD000026383424FF000001EBF204BC8F804404E 480 | :101DE000C8F8103007B0BDE8F08F059A8AB9144AD8 481 | :101DF000915D01228A40E261EA68C2F300428A40B2 482 | :101E0000A261002BC3D10F4B9A5D0F4B53F82230C8 483 | :101E1000BDE7002BBBD104F11C03B8E71048BAE7BB 484 | :101E20004FF0FF30DEE76FF00100DBE76FF00200FC 485 | :101E3000D8E76FF00300D5E79C01002038010020AF 486 | :101E400009010020740100204C010020C001002085 487 | :101E500000C00F4000800D40090000001107000085 488 | :101E60000046C3232DE9F0478CB0074689469046CB 489 | :101E7000169E3022002168469A46DDE91454FFF789 490 | :101E800031FC002ECDF8088008BF1626B90656BFD3 491 | :101E900006F03F06402646F468667A06CDE900A9BA 492 | :101EA000049607D540230393C7F300116846FFF754 493 | :101EB0005FFE07E007F00F03012B06D0022B11D0C5 494 | :101EC0004FF0FF300CB0BDE8F0870DB91C46172568 495 | :101ED000240405F03F0504F480342C4344F08004CE 496 | :101EE0000394E1E70DB9D9240125240405F03F034B 497 | :101EF000C7F30011684604F47F041C4344F47E5485 498 | :101F00000394FFF735FE0028DCDB012D07D1074BDA 499 | :101F1000DA78074B53F8222053695B02FCD5012382 500 | :101F20000F220449284600F09FFBCBE79C010020CC 501 | :101F3000C00100200D00000F10B550B1044623462B 502 | :101F4000646A002CFBD15862034B1B6998472046FA 503 | :101F500010BD4FF0FF30FBE73801002010B50F4CEB 504 | :101F600054F82000B8B1012404FA01F14AB14268E2 505 | :101F70000A4342600BB9002010BD43681942FCD0EF 506 | :101F8000F9E7426822EA01024260002BF3D043687D 507 | :101F90001942FCD1EFE74FF0FF30EDE74C01002094 508 | :101FA0000C4B53F8200010B570B10123446803FABC 509 | :101FB00001F10C420BD0C0F884101AB10368194229 510 | :101FC000FCD00022104610BD4FF0FF32FAE76FF050 511 | :101FD0000102F7E74C0100200C4B53F8200010B52C 512 | :101FE00068B10123446803FA01F10C420AD0C0F839 513 | :101FF000881012B102680A40FCD1104610BD4FF0A3 514 | :10200000FF32FAE76FF00102F7E700BF4C01002052 515 | :102010000D4B53F8200010B580B10123446803FA3A 516 | :1020200001F10C420DD00468C0F88C1022B1036895 517 | :1020300063400B42FBD00022104610BD4FF0FF3230 518 | :10204000FAE76FF00102F7E74C01002030B5124CBF 519 | :1020500054F82040D4B10120656800FA01F10D4226 520 | :1020600017D12068084022B9031E18BF0123184663 521 | :1020700030BD012BC4BFB0FA80F35B092268114266 522 | :1020800014BF012200229A42F8D1F0E74FF0FF334B 523 | :10209000EDE76FF00103EAE74C01002010B590B3C3 524 | :1020A000052830D009282EDC04284FEA800410DDF2 525 | :1020B0000AB901228A4004F1804101F52C210C6DFE 526 | :1020C00014430C65BFF34F8FABB10B6D1A42FCD0BC 527 | :1020D00011E005300AB901228A4004F1804101F57E 528 | :1020E0002C214C6E24EA02044C66BFF34F8F13B1CF 529 | :1020F0004B6E1A42FCD100F52C304FF08043143067 530 | :1021000053F8200010BD4FF0FF30FBE703461046A8 531 | :102110006AB1052A0AD0092A08DC052AC8BF501F5F 532 | :102120001F2903DC032803D11B2929DD0020704768 533 | :1021300001380328FAD8DFE800F0021423284BB155 534 | :102140000F2903DD89001A4808447047184800EB3E 535 | :10215000810070470F2902DD89001648F4E7154811 536 | :10216000F5E733B10F2902DD89001348ECE7124887 537 | :10217000EDE70F2902DD89001048E5E70F48E6E7A3 538 | :102180000B290DDD112904DD0E31890073B10C48D6 539 | :10219000DAE70C3989000BB10A48D5E70A48D3E7DA 540 | :1021A00089000BB10948CFE70948CDE70948CBE7DB 541 | :1021B000BC801F40AC821F403C811F402C831F40CD 542 | :1021C00014801F40BC811F40AC831F40D4811F403E 543 | :1021D000C4831F4004821F402DE9F041151E0746AD 544 | :1021E00088461C46069E0DDB0A4601460020FFF786 545 | :1021F0008DFFD0B105602EB103686B40C3F31003AF 546 | :10220000002BF9D1002C02DA0020BDE8F081424613 547 | :1022100039460120FFF77AFF50B10460002EF3D059 548 | :1022200003686340DB06FBD1EEE74FF0FF30ECE7DD 549 | :102230006FF00100E9E700BF01220021104608B558 550 | :10224000FFF72EFA01230F220A49184600F00CFA74 551 | :10225000002809DB0122084B1A6000F076FB074AD0 552 | :1022600001460748FFF732FB00210648FFF76AF9ED 553 | :1022700000F00AF80D00000F34010020390E0000B4 554 | :102280008C0000205802010407B500F029F8124B19 555 | :102290000126124C5D7B4FF0FF320523617B2846FF 556 | :1022A0000096FFF799FF334632462946607BFFF7D9 557 | :1022B00055FE29460122607BFFF772FE4FF4803005 558 | :1022C00000F02EFB01222946607BFFF785FE4FF4CC 559 | :1022D000803000F025FBECE70901002074010020AC 560 | :1022E00070B54FF480769E4D96B09E48FFF7EEFA9B 561 | :1022F0000422002105A89C4CFFF7F4F9402200219C 562 | :1023000006A8FFF7EFF92B68984903EB4303E25C5B 563 | :10231000974B53F82220936A43F4804393622B68CF 564 | :1023200003EB4303E05C00F089FA286800230422F1 565 | :1023300000EB400005A9205C00F0A1FA9DF81430E4 566 | :10234000402B08D19DF816209DF815309DF81710E8 567 | :102350001344994207D02B68864903EB4303E05CA2 568 | :1023600000F06CFAC4E782B12B68834903EB4303A6 569 | :10237000E05C00F063FA286800239DF8162000EB6B 570 | :10238000400006A9205C00F07AFA9DF81530162B63 571 | :1023900000F23B81DFE813F017001B001E00330042 572 | :1023A0003A0040002100430049004F005F006C00EC 573 | :1023B00071007F008D008F009C00A300AA00B60072 574 | :1023C00011012B012D0100F0C0FA044606E0069B26 575 | :1023D0001C6803E0DDE906321A600024304600F094 576 | :1023E0009FFA21466548FFF771FA9DF81530062BD4 577 | :1023F0007FF47EAF6248FFF769FA16B070BD089AA5 578 | :102400009DF81C100698FFF76DF9DEE7DDE907126D 579 | :102410000698FFF77EF9D8E73446069EDEE7DDE949 580 | :1024200007120698FFF7AEFAD7E7DDE9071206981C 581 | :10243000FFF751F9C9E70C9B099802930B9B000128 582 | :102440000699019340F001000A9B0093DDE9072300 583 | :10245000FFF708FDB9E7069B23B14FF0FF3149486C 584 | :10246000FFF734FA484A494B10681B689847B4E7AD 585 | :10247000002106A8FFF77CFBA7E70C9B09980293B5 586 | :102480000B9B00010699019340F002000A9B009308 587 | :10249000DDE90723DCE7DDE9070333B110B906986E 588 | :1024A000FEF7F0FF3A4B18608FE70699FFF74AF8FE 589 | :1024B0008BE70121DDE70A9B0998029300230001C5 590 | :1024C0000699CDE9003340F04000DDE90723BFE77E 591 | :1024D00006AB0698DDE90712FFF760F975E70123FF 592 | :1024E0000698DDE9071200F0BFF86EE706980123B1 593 | :1024F000284C29490093095C205CDDE90723FFF79C 594 | :102500006BFE62E7069B052B3FF667AFDFE803F043 595 | :10251000030C151E464FDDE907321E491E48C95CF3 596 | :10252000C05CFFF759FD58E7DDE9073219491A4841 597 | :10253000C95CC05CFFF734FD4FE7DDE907321549A0 598 | :102540001548C95CC05CFFF763FD46E7DDE907039A 599 | :10255000114C1049099A095C205CFFF7FFFC34E735 600 | :1025600034010020AC0000209C010020BF000020AE 601 | :10257000C0010020C7000020CF000020EF00002095 602 | :10258000F7000020D7000020400100204801002073 603 | :1025900038010020090100207401002007A81C4C0C 604 | :1025A0001C490DC8095C205CFFF750FD0DE7DDE913 605 | :1025B0000821079800F03AF80FE7DDE9063282B10A 606 | :1025C000002B154808BF0823144A154C1360089ABD 607 | :1025D000206022B1282200215A43FFF77CF82468AA 608 | :1025E000FCE65A1E0F48082A28BF0823ECE76C4671 609 | :1025F000F4E6069B23B14FF0FF310B48FFF766F975 610 | :10260000074B1868FFF798FCDFE64FF0FF34E5E66C 611 | :102610007401002009010020400300204401002033 612 | :1026200040010020E4010020E300002013460C4A92 613 | :1026300010B40446105C19B1042806D910BC7047C8 614 | :102640000528FBD9411FC8B200E030B90549105533 615 | :102650000022095D10BCFFF721BD411DF3E700BF5B 616 | :1026600074010020090100202DE9F3478846174630 617 | :102670001E460446002872D0072870DCDFF8F0A060 618 | :1026800000EB40037A074FEA4009534493F828507F 619 | :102690002CD593F82A004FF0FF32DFF8D8C0022380 620 | :1026A00000961AF800101CF80000FFF795FD0028AE 621 | :1026B00058DB012D1AD0304B6FF4457E2F4A4FEA7C 622 | :1026C000840CA91E022D18BF1A4603F15F43A3F51F 623 | :1026D000772302EBC100734443FA0CF303F00F03BA 624 | :1026E00042F8313016B102689342FCD13B072CD539 625 | :1026F000A144DFF880C002234FF0FF32D14499F8A3 626 | :10270000290000961AF800101CF80000FFF764FD7D 627 | :1027100000282ADB012D18D0184B6FF4447C184A8E 628 | :10272000A400A91E022D18BF1A4603F15F43A3F5AA 629 | :10273000772302EBC1006344234103F00F0342F807 630 | :10274000313016B102689342FCD1284633463A46EE 631 | :10275000414600F017F8002002B0BDE8F0874FF0C6 632 | :10276000FF30F9E76FF00100F6E76FF00200F3E7E2 633 | :10277000740100200901002034851F4030851F406E 634 | :102780002C851F402DE9F04107461D4E1446884612 635 | :10279000305C06EB87061A4603211D46FEF758FEFD 636 | :1027A000F068E1018368C9B243F002038360836883 637 | :1027B00023F0020383600323C362E305C0F81080A3 638 | :1027C00003F04053426913434361A300826A03F05C 639 | :1027D0000803194363041143E20303F400232406AE 640 | :1027E00002F48022816204F08054816913431C4307 641 | :1027F0000C43846115B182691342FCD0BDE8F081BD 642 | :10280000B4010020044B03EB8003DB685A69120219 643 | :10281000FCD5D961704700BFB4010020064B03EB23 644 | :102820008003DB68D86910F4805F03D0002AF9D1F7 645 | :102830000139F7D2704700BFB401002010B54C1E1B 646 | :1028400014F8013F03B910BD0A2B02D10D21FFF787 647 | :10285000D9FF2178FFF7D6FFF2E738B50C468D187F 648 | :10286000AC4201D0237803B938BD0A2B02D10D2127 649 | :10287000FFF7C8FF14F8011BFFF7C4FFF0E72DE9CD 650 | :10288000F0411E460F4B1746054603EB8003884672 651 | :102890000024DB685A695A61BC4202DB0020BDE8B3 652 | :1028A000F081B6FA86F2314628465209FFF7B6FFA4 653 | :1028B000C30403D408F804000134EDE74FF0FF30FF 654 | :1028C000EDE700BFB40100202DE9F8439946134B12 655 | :1028D0009046074603EB80034D1E0026DB685A69CD 656 | :1028E0005A6146450ADAB9FA89F249463846520928 657 | :1028F000FFF794FF044610F4805003D04FF0FF30F0 658 | :10290000BDE8F883E4B20A2C05F8014F04D11EB1EA 659 | :1029100015F8013C0D2BF3D00136E2E7B40100209D 660 | :1029200082B000220092009B834201D302B0704724 661 | :102930000192019BB3F5167F03D3009B01330093F3 662 | :10294000F1E7019B01330193F3E70148704700BFB2 663 | :042950003E927C67D0 664 | :1029540063636D5F7365745F636F72655F636C6BF4 665 | :10296400663A202558205B202558207C20255820B5 666 | :102974007C202558207C202558205D0A006375732F 667 | :10298400746F6D2066756E63207769746820617258 668 | :102994006773202558202558202558207C20255849 669 | :1029A4000A0053544550004A554D50005644445F64 670 | :1029B400534F43202558203D3E202558205B257346 671 | :1029C4005D0A0025583A2000200A003031323334A1 672 | :1029D4003536373839414243444546000A696E6901 673 | :1029E40074207465656E737934766669205B255846 674 | :1029F4005D2C206D6520402025580A00656E7465A5 675 | :102A040072696E6720525043206D6F64650A00211D 676 | :102A140050435F47300A002150435F45310A00218B 677 | :102A240050435F47310A002150435F41524D4544B2 678 | :102A3400210A002150435F4C4F4F50494E0A002158 679 | :102A440050435F25580A0065786974696E6720529F 680 | :102A54005043206D6F64650A000302040506080AEA 681 | :102A640011100B000201031213171611101A1B1870 682 | :102A7400190C0D1E1F121F17160C070F0E0D0C112B 683 | :102A840010000000010000006402010409000000BD 684 | :102A9400E40100200800000009000000000000001C 685 | :102AA40000801B4000C01B4000001C4000401C4034 686 | :102AB40000000C4000000042004000420080004240 687 | :102AC40000C00042010104040404020202020202E2 688 | :102AD40002020101010101010101010101010101E0 689 | :102AE40003040303020403030303030300000006B7 690 | :102AF4000001040708020F0E031011081514011930 691 | :102B040018071C1D005C0E061C31335D67000000B5 692 | :102B140000000000004018400080184000C0184029 693 | :102B240000001940004019400080194000C01940BD 694 | :042B340000001A4043 695 | :040000056000100087 696 | :00000001FF 697 | --------------------------------------------------------------------------------