PaulStoffregen / cores

Teensy Core Libraries for Arduino
507 stars 372 forks source link

Basic support for adding board variants for Teensy 4.x boards. #750

Open KurtE opened 2 months ago

KurtE commented 2 months ago

As discussed on the forum thread: https://forum.pjrc.com/index.php?threads/teensy-4-x-maybe-support-for-custom-boards-using-variants.75372/

I believe it would benefit the Teensy 4.x community if it was easier for PJRC and other builders who wish to generate custom teensy boards, if there was at least some minimal support for adding variant boards. I personally do not want to necessarily have to hack up a teensy install, to for example support the Devboard 4 4.5 or 5 boards, where the changes could directly impact in this case the setup for Micromod boards.

So I have this branch of my fork setup to allow me to create the different variants for these above boards. Note: I have not done anything specific for the 4.5 as it is simply the 4 plus SDIO and USB Host changes.

So far the changes have included:

1) change core_pins.h that checks for a variant.h file like:

#if __has_include("variant.h")
#  include "variant.h"
//#pragma message "core_pins.h" - included variant.h
// Default no override file
#elif defined(__IMXRT1062__) && defined(ARDUINO_TEENSY40)

2) digital.c - have the pin table digital_pin_bitband_and_config_table_struct defined with weak attribute.

3) XBAR - define the table as attribute weak likewise the count variable.

4) PWM table - weak

5) Analog table - weak

6) Serial objects - this was a little more complex - Simply put, I defined the Serial objects, using a set of defines: Which allow the variant to define them first. Example Serial1

#ifndef SERIAL1_RX_PINS 
#define SERIAL1_UART_ADDR IMXRT_LPUART6_ADDRESS
#define SERIAL1_LPUART IRQ_LPUART6, CCM_CCGR3, CCM_CCGR3_LPUART6(CCM_CCGR_ON),  XBARA1_OUT_LPUART6_TRG_INPUT
#define SERIAL1_CTS_PIN 0xff, 0 
#if defined(ARDUINO_TEENSY41)
#define SERIAL1_RX_PINS {{0,2, &IOMUXC_LPUART6_RX_SELECT_INPUT, 1}, {52, 2, &IOMUXC_LPUART6_RX_SELECT_INPUT, 0}}
#define SERIAL1_TX_PINS {{1,2, &IOMUXC_LPUART6_TX_SELECT_INPUT, 1}, {53, 2, &IOMUXC_LPUART6_TX_SELECT_INPUT, 0}}
#else
#define SERIAL1_RX_PINS {{0,2, &IOMUXC_LPUART6_RX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}}
#define SERIAL1_TX_PINS {{1,2, &IOMUXC_LPUART6_TX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}}
#endif
#endif
...
const HardwareSerialIMXRT::hardware_t Serial1_Hardware = {
    0, 
    &IRQHandler_Serial1, 
    &serialEvent1,
    IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark
    // Stuff that can be overwritten easily by variant
    SERIAL1_LPUART, SERIAL1_RX_PINS, SERIAL1_TX_PINS, SERIAL1_CTS_PIN
};
HardwareSerialIMXRT Serial1(SERIAL1_UART_ADDR, &Serial1_Hardware, tx_buffer1,
    SERIAL1_TX_BUFFER_SIZE, rx_buffer1, SERIAL1_RX_BUFFER_SIZE);

Pin Names - I checked this in to play with but obviously optional. There are times when I wish to set the state of a pin that is not in the pin table. I have found it useful on some of the Arduino boards that support something like that as well. Often times they include names that match their MicroPython or CircuitPython pin names.

So I created an enum with all of the pin names like: AD_B0_00 and their values is actually the offset in address for this pins from the start of a main section. The actual addresses for registers and the like can be computed. With this I have stuff in the header file that allows me to do something like: pinMode(AD_B0_00, OUTPUT); digitalWrite(AD_B0_00, HIGH);

I have variants defined using all of this up in the github project: https://github.com/KurtE/teensy4_variant_experiment

Where I defined variants for DB4 and DB5, which appear to be working reasonably well.
One issue we have is with the Teensly loader. The arduino 2.x setup does not want to reboot and program the boards if we have the Teensy Serial port selected, however if we have the Arduino Serial port selected it does work.

There are a few of us like @mjs513 and myself who have been using this for awhile now, and a few others are now trying it with the DB5 board.

Thought it would be great if we could get some or all of this into an early beta build for the next Teensyduino release.

EDIT: Note - I have also updated the Flexio_t4 library to not include pin tables per different teensy boards, instead it has a table of all of the possible Flexio pins, and when you pass in a pin number, I map that to one of the registers associated with that IO pin and look it up in the flexio table.

Likewise in our teensy_camera library (https://github.com/mjs513/Teensy_Camera) I have similar table, that maps IO pins to CSI pins.

Kurt

mjs513 commented 1 month ago

@PaulStoffregen Just to confirm I have been using @KurtE variant core since he put it together for all the testing I have been doing with Teensy Camera and the SDRAM Variant board testing and haven't run into an issue with it yet.