Teensy 4.x - Maybe support for custom boards using variants.

@KurtE - can you post a ZIP of the PJRC CORES current with the applied PR changes in it?

When I got your github Windows GITHUB desktop grumbled about something on what should have been the right branch. I pulled a ZIP and it worked in combination with the Variants add and the FlexIO for building with DevBoards.

With a ZIP 'WE' could verify that a Clean IDE install w/TeensyDuino can build all the Teensy4 products without issue or change. "WE" could then make note of that on the PR and it might help Paul appreciate the addition and changes to 'weak' do not affect general usage by whoever "WE" is.

The use of variants would be a WIP for any DIY user buying PJRC bootloader MCU's.
 
Quick note: The way I have mine setup is like:
Code:
C:\Users\kurte\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.59.0>dir
 Volume in drive C is OS
 Volume Serial Number is 7E8D-E873

 Directory of C:\Users\kurte\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.59.0

02/18/2024  01:09 PM    <DIR>          .
02/09/2024  05:19 AM    <DIR>          ..
02/09/2024  05:19 AM            95,265 boards.txt
02/18/2024  01:09 PM    <JUNCTION>     cores [d:\github\cores]
02/09/2024  05:19 AM    <DIR>          cores_release
02/09/2024  05:19 AM            47,301 installed.json
02/09/2024  05:19 AM            11,154 keywords.txt
02/09/2024  05:19 AM    <DIR>          libraries
02/09/2024  05:19 AM             8,025 platform.txt
               4 File(s)        161,745 bytes
               5 Dir(s)  94,319,235,072 bytes free

C:\Users\kurte\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.59.0>
I renamed the cores that came with the release (cores_release) here.
then I created a junction link to my github:

mklink /j cores d:\github\cores

Currently setup with the fork/branch: https://github.com/KurtE/cores/tree/variants_override
I have tried to keep this branch up to sync with Paul's master branch

FlexIO - all of the latest stuff in the main branch: https://github.com/KurtE/FlexIO_t4
 

Attachments

  • cores-variants_override.zip
    1.1 MB · Views: 53
@KurtE - got a fail - on first two builds ... user errors :(
Did this in the Clean DUPE install of 1.8.19 and TD 1.59:
>> First was not getting full path copy into mklink :(
>> Second was restoring to cores_release - then proper mklink and it used a TMP prior build file because I didn't close the iDE :(

END RESULT T_4.1 :: Verify build of CardInfo and Code4Code and the MCUID {printf() of HW_OCOTP_CFG#} posted the other day worked.
>> And without error repeated those three Verify builds for T_4.0

So {as expected} it seems that the 'weak' and other adds don't cause any obvious build issues for standard PJRC boards from those CORES edits.
--> though failed copy paste and mixed builds caused by user actions can break anything :)

Using the ZIP:
here is the CMDLINE to do mklink to the downloaded and extracted XIP above:
Code:
T:\T_Drive\Arduino_1.8.19_TD\hardware\teensy\avr>ren cores cores_release
T:\T_Drive\Arduino_1.8.19_TD\hardware\teensy\avr>mklink /j cores  C:\Users\duser\Downloads\cores-variants_override_KE21July\cores-variants_override
Junction created for cores <<===>> C:\Users\duser\Downloads\cores-variants_override_KE21July\cores-variants_override
T:\T_Drive\Arduino_1.8.19_TD\hardware\teensy\avr>dir cores
 Volume in drive T is Tdrv1TB_tmp
 Volume Serial Number is 6C95-76D9

 Directory of T:\T_Drive\Arduino_1.8.19_TD\hardware\teensy\avr\cores

07/22/2024  01:50 AM    <DIR>          .
07/22/2024  01:50 AM    <DIR>          ..
07/22/2024  01:50 AM    <DIR>          .github
07/22/2024  01:50 AM                64 .gitignore
07/22/2024  01:50 AM            11,154 keywords.txt
07/22/2024  01:50 AM               214 README.md
07/22/2024  01:50 AM    <DIR>          teensy
07/22/2024  01:50 AM    <DIR>          teensy3
07/22/2024  01:50 AM    <DIR>          teensy4
07/22/2024  01:50 AM    <DIR>          usb_disk
07/22/2024  01:50 AM    <DIR>          usb_flightsim
07/22/2024  01:50 AM    <DIR>          usb_hid
07/22/2024  01:50 AM    <DIR>          usb_midi
07/22/2024  01:50 AM    <DIR>          usb_rawhid
07/22/2024  01:50 AM    <DIR>          usb_serial
07/22/2024  01:50 AM    <DIR>          usb_serial_hid

OH _ BTW:: this rmdir drops the mklink junction - does not actually remove the directory
to remove: <JUNCTION> cores [C:\Users\duser\Downloads\cores-variants_override_KE21July\cores-variants_override]
use: rmdir cores
 
Last edited:
@KurtE thanks for working on getting this rolling.

I've had some time to sift through the cores along with your experimental variants repo and I threw together a (currently very messy) script that generates a bunch of defines using data scraped from the annotated reference manual.

My goal is to allow anyone to throw together a list of pins, specify some flash/extmem/sdram properties, and then generate a single file that contains required defines that can be used in cores. This single file would then be included in cores, and similar files could be generated and tweaked for the "core variants", perhaps eventually leading to a single include block in cores like so:
C:
#if defined(__IMXRT1062__) && defined(__has_include) && __has_include("teensy4_custom_variant.h")
#include "teensy4_custom_variant.h"
#elif defined(__IMXRT1062__) && defined(ARDUINO_TEENSY40)
#include "variants/teensy_40.h"
#elif defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41)
#include "variants/teensy_41.h"
#elif defined(__IMXRT1062__) && defined(ARDUINO_TEENSY_MICROMOD)
#include "variants/teensy_mm.h"
#else
#error "failed to determine teensy variant"
#endif

Regarding the generated code, and the input that it is derived from, you can see examples (script is WIP, there are likely some bugs at this point) in this gist:
- definition for DevBoard v5
- generated .h file
- data scraped from reference manual

From a custom PCB standpoint, I think this approach is pretty swell. If I'd had such a tool when I was designing my custom PCB it would have been much easier to see which components of what peripherals I needed to route, and in code pin mapping should just work.

As far as the concept of a single file per "core variant" goes, it introduces a bunch of code duplication for the shared pin definitions, but if the code is generated I think that is fine. I would also expect the generated code to be more correct, as I've noted a few instances of missing and/or unused defines in my exploration.

I realize this is a large change that impacts a small percentage of PJRC customers, but I believe this could be done safely by dumping preprocessor defines and other conditionally configured values before and after adding the changes and diffing them.

Please let me know what you think!
 
From a custom PCB standpoint, I think this approach is pretty swell. If I'd had such a tool when I was designing my custom PCB it would have been much easier to see which components of what peripherals I needed to route, and in code pin mapping should just work.

As far as the concept of a single file per "core variant" goes, it introduces a bunch of code duplication for the shared pin definitions, but if the code is generated I think that is fine. I would also expect the generated code to be more correct, as I've noted a few instances of missing and/or unused defines in my exploration.

I realize this is a large change that impacts a small percentage of PJRC customers, but I believe this could be done safely by dumping preprocessor defines and other conditionally configured values before and after adding the changes and diffing them.

Please let me know what you think!
Thanks for all of the input and suggestions.

My main goal with all of this, up till now, is for a proof of concept. Which I personally believe it is worthwhile. I have no doubts that there are probably some missing defines in some of my quick and dirty setups for the DB4 4.5 and DB5 setups. And for the most part, the current
changes should not impact the current boards. Which I was trying to avoid.

And I agree with you that the pin table generation could probably be improved. For this I simply replicated the stuff that @PaulStoffregen did when he added T4 and then T4.1 and then Micromod the list of pins.

As I mentioned in some other posts, for the fun of it I added some code (core_pin_names.h) which allows you tto do things like:
Code:
pinMode(AD_B0_00, OUTPUT);
DigitalWrite(AD_B0. HIGH);

I did this for I believe all possible pins, by creating a simple enum:
Code:
// PinName values: 32 bit top 16 - offset in EMC table, low 8 bits 0-4 GPIO PIN 5-7 On Port #
typedef enum {
    AD_B0_00 = 0x0BC0000, AD_B0_01 = 0x0C00001, AD_B0_02 = 0x0C40002, AD_B0_03 = 0x0C80003, AD_B0_04 = 0x0CC0004, AD_B0_05 = 0x0D00005, AD_B0_06 = 0x0D40006, AD_B0_07 = 0x0D80007,
    AD_B0_08 = 0x0DC0008, AD_B0_09 = 0x0E00009, AD_B0_10 = 0x0E4000A, AD_B0_11 = 0x0E8000B, AD_B0_12 = 0x0EC000C, AD_B0_13 = 0x0F0000D, AD_B0_14 = 0x0F4000E, AD_B0_15 = 0x0F8000F,
    AD_B1_00 = 0x0FC0010, AD_B1_01 = 0x1000011, AD_B1_02 = 0x1040012, AD_B1_03 = 0x1080013, AD_B1_04 = 0x10C0014, AD_B1_05 = 0x1100015, AD_B1_06 = 0x1140016, AD_B1_07 = 0x1180017,
    AD_B1_08 = 0x11C0018, AD_B1_09 = 0x1200019, AD_B1_10 = 0x124001A, AD_B1_11 = 0x128001B, AD_B1_12 = 0x12C001C, AD_B1_13 = 0x130001D, AD_B1_14 = 0x134001D, AD_B1_15 = 0x138001F,
    B0_00 = 0x13C0020, B0_01 = 0x1400021, B0_02 = 0x1440022, B0_03 = 0x1480023, B0_04 = 0x14C0024, B0_05 = 0x1500025, B0_06 = 0x1540026, B0_07 = 0x1580027,
    B0_08 = 0x15C0028, B0_09 = 0x1600029, B0_10 = 0x164002A, B0_11 = 0x168002B, B0_12 = 0x16C002C, B0_13 = 0x170002D, B0_14 = 0x174002E, B0_15 = 0x178002F,
    B1_00 = 0x17C0030, B1_01 = 0x1800031, B1_02 = 0x1840032, B1_03 = 0x1880033, B1_04 = 0x18C0034, B1_05 = 0x1900035, B1_06 = 0x1940036, B1_07 = 0x1980037,
    B1_08 = 0x19C0038, B1_09 = 0x1A00039, B1_10 = 0x1A4003A, B1_11 = 0x1A8003B, B1_12 = 0x1AC003C, B1_13 = 0x1B0003D, B1_14 = 0x1B4003D, B1_15 = 0x1B8003F,
    EMC_00 = 0x0140060, EMC_01 = 0x0180061, EMC_02 = 0x01C0062, EMC_03 = 0x0200063, EMC_04 = 0x0240064, EMC_05 = 0x0280065, EMC_06 = 0x02C0066, EMC_07 = 0x0300067,
    EMC_08 = 0x0340068, EMC_09 = 0x0380069, EMC_10 = 0x03C006A, EMC_11 = 0x040006B, EMC_12 = 0x044006C, EMC_13 = 0x048006D, EMC_14 = 0x04C006E, EMC_15 = 0x050006F,
    EMC_16 = 0x0540070, EMC_17 = 0x0580071, EMC_18 = 0x05C0072, EMC_19 = 0x0600073, EMC_20 = 0x0640074, EMC_21 = 0x0680075, EMC_22 = 0x06C0076, EMC_23 = 0x0700077,
    EMC_24 = 0x0740078, EMC_25 = 0x0780079, EMC_26 = 0x07C007A, EMC_27 = 0x080007B, EMC_28 = 0x084007C, EMC_29 = 0x088007D, EMC_30 = 0x08C007D, EMC_31 = 0x090007F,
    EMC_32 = 0x0940052, EMC_33 = 0x0980053, EMC_34 = 0x09C0054, EMC_35 = 0x0A00055, EMC_36 = 0x0A40056, EMC_37 = 0x0A80057, EMC_38 = 0x0AC0058, EMC_39 = 0x0B00059,
    EMC_40 = 0x0B4005A, EMC_41 = 0x0B8005B, SD_B0_00 = 0x1BC004C, SD_B0_01 = 0x1C0004D, SD_B0_02 = 0x1C4004E, SD_B0_03 = 0x1C8004F, SD_B0_04 = 0x1CC0050, SD_B0_05 = 0x1D00051,
    SD_B1_00 = 0x1D40040, SD_B1_01 = 0x1D80041, SD_B1_02 = 0x1DC0042, SD_B1_03 = 0x1E00043, SD_B1_04 = 0x1E40044, SD_B1_05 = 0x1E80045, SD_B1_06 = 0x1EC0046, SD_B1_07 = 0x1F00047,
    SD_B1_08 = 0x1F40048, SD_B1_09 = 0x1F80049, SD_B1_10 = 0x1FC004A, SD_B1_11 = 0x200004B
} IMXRT_PIN_t;
Code:
inline void digitalWrite(IMXRT_PIN_t pin_name, uint8_t val) {
    uint32_t mask = 1 << (pin_name & 0x1f);
    if (val) {
        volatile uint32_t *reg = (volatile uint32_t*)((uint8_t *)&GPIO6_DR_SET + 0x4000 * ((pin_name >> 5) & 0x7));
        *reg = mask;
    } else {
        volatile uint32_t *reg = (volatile uint32_t*)((uint8_t *)&GPIO6_DR_CLEAR + 0x4000 * ((pin_name >> 5) & 0x7));
        *reg = mask;
    }
}
Lots of fun!

As for how much farther to take any of this? depends...
 
Back
Top