├── 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 | 
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 | 
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 |
--------------------------------------------------------------------------------