Custom Pins on Custom Teensy 4.1 board not working.

Board is teensy 4.1 with these pins
#define M1_PIN GPIO_EMC_03
#define M2_PIN GPIO_EMC_08
#define M3_PIN GPIO_EMC_15
#define M4_PIN GPIO_EMC_20
#define M5_PIN GPIO_EMC_27
#define M6_PIN GPIO_EMC_32

#define M1_PIN2 GPIO_EMC_04
#define M2_PIN2 GPIO_EMC_09
#define M3_PIN2 GPIO_EMC_16
#define M4_PIN2 GPIO_EMC_21
#define M5_PIN2 GPIO_EMC_28
#define M6_PIN2 GPIO_EMC_33

#define M12_ENABLE_PIN GPIO_EMC_00
#define M34_ENABLE_PIN GPIO_EMC_13
#define M56_ENABLE_PIN GPIO_EMC_25

#define M12_FAULT_PIN GPIO_EMC_02
#define M34_FAULT_PIN GPIO_EMC_14
#define M56_FAULT_PIN GPIO_EMC_26

if i simple use simple code to run the motor1 it does not work
C:
#define GPIO_EMC_03     57
#define GPIO_EMC_04     2
#define GPIO_EMC_00     55

#define MOTOR1_FW GPIO_EMC_03
#define MOTOR1_BW GPIO_EMC_04

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(MOTOR1_FW, OUTPUT);
  pinMode(MOTOR1_BW, OUTPUT);
  pinMode(GPIO_EMC_00, OUTPUT);
  digitalWrite(GPIO_EMC_00, HIGH);
  Serial.println("Motor 1 initialized");

}

void loop() {
  // put your main code here, to run repeatedly:

  digitalWrite(MOTOR1_FW, HIGH);
  digitalWrite(MOTOR1_BW, LOW);
  Serial.println("Moving CW");
  delay(10000);
  digitalWrite(MOTOR1_FW, LOW);
  digitalWrite(MOTOR1_BW, HIGH);
  Serial.println("Moving CCW");
  delay(10000);
}
 
Last edited:
No I have added these custom pin in core library as paul mentioned in the another thread link mention above.
 
Yes but that was for a custom PCB based on a T4.1 but bringing out extra pins.
Are you using a custom PCB or a bog standard T4.1?
 
Are you sure you added the custom pins to the right section? There are three different repeated definitions for Teensy 4.0, 4.1, Micromod. As Paul mentioned in the other thread, the fastest way to make sure you're editing the right section is put in an intentional error and check if the compiler hits it.
 
A little confused. Looking at your core_pins.h file you just added the pins:

Code:
#define CORE_NUM_TOTAL_PINS    83
#define CORE_NUM_DIGITAL    83
#define CORE_NUM_INTERRUPT    83
#define CORE_NUM_ANALOG        18
#define CORE_NUM_PWM        31
......
/* New pins bits according to manarharake motor driver */
#define CORE_PIN55_BIT        0
#define CORE_PIN56_BIT        2
#define CORE_PIN57_BIT        3   
#define CORE_PIN58_BIT        10
#define CORE_PIN59_BIT        11
#define CORE_PIN60_BIT        12
#define CORE_PIN61_BIT        13
#define CORE_PIN62_BIT        14

and looks like you just carried that usage through the other 2 files, so why aren't you using your new pin numbers in the sketch instead of the pin names, i.e.,
Code:
#define MOTOR1_FW   57
#define MOTOR1_BW   2

It looks like you took option 1 from Paul's list
1: Edit the core library files for pinMode(), digitalWrite(), digitalRead()

2: Copy and rename the pinMode(), digitalWrite(), digitalRead(), and edit that copy... eg: myPinMode(), myDigitalWrite(), myDigitalRead().
 
Are you sure you added the custom pins to the right section? There are three different repeated definitions for Teensy 4.0, 4.1, Micromod. As Paul mentioned in the other thread, the fastest way to make sure you're editing the right section is put in an intentional error and check if the compiler hits it.
Yes I did check this with syntax error and indeed I am making changes in the right place.
A little confused. Looking at your core_pins.h file you just added the pins:

Code:
#define CORE_NUM_TOTAL_PINS    83
#define CORE_NUM_DIGITAL    83
#define CORE_NUM_INTERRUPT    83
#define CORE_NUM_ANALOG        18
#define CORE_NUM_PWM        31
......
/* New pins bits according to manarharake motor driver */
#define CORE_PIN55_BIT        0
#define CORE_PIN56_BIT        2
#define CORE_PIN57_BIT        3  
#define CORE_PIN58_BIT        10
#define CORE_PIN59_BIT        11
#define CORE_PIN60_BIT        12
#define CORE_PIN61_BIT        13
#define CORE_PIN62_BIT        14

and looks like you just carried that usage through the other 2 files, so why aren't you using your new pin numbers in the sketch instead of the pin names, i.e.,
Code:
#define MOTOR1_FW   57
#define MOTOR1_BW   2

It looks like you took option 1 from Paul's list
Yes I took the 1) option from the paul's list.
I added pins after 54 as pins till 54 are declared already, I added more pins with naming convention same as other default pins. Some pins are overlapping.
 
Yes I took the 1) option from the paul's list.
I added pins after 54 as pins till 54 are declared already, I added more pins with naming convention same as other default pins. Some pins are overlapping.
So did you try just using the pin numbers directly that you added
 
Is the custom "DIY_T_4.1" using an 8 MB Flash chip for code storage?

2 MB ID's it as a T_4.0 and 16 MB will register as a T_MM.
 
Last edited:
So did you try just using the pin numbers directly that you added
Reply its working now, I added
Code:
/*new pins */
#define CORE_INT55_PIN 55
#define CORE_INT56_PIN 56
#define CORE_INT57_PIN 57
#define CORE_INT58_PIN 58
#define CORE_INT59_PIN 59
#define CORE_INT60_PIN 60
#define CORE_INT61_PIN 61
#define CORE_INT62_PIN 62
#define CORE_INT63_PIN 63
#define CORE_INT64_PIN 64
#define CORE_INT65_PIN 65
#define CORE_INT66_PIN 66
#define CORE_INT67_PIN 67
#define CORE_INT68_PIN 68
#define CORE_INT69_PIN 69
#define CORE_INT70_PIN 70
#define CORE_INT71_PIN 71
#define CORE_INT72_PIN 72
#define CORE_INT73_PIN 73
#define CORE_INT74_PIN 74
#define CORE_INT75_PIN 75
#define CORE_INT76_PIN 76
#define CORE_INT77_PIN 77
#define CORE_INT78_PIN 78
#define CORE_INT79_PIN 79
#define CORE_INT80_PIN 80
#define CORE_INT81_PIN 81
#define CORE_INT82_PIN 82

I missed these digitalWrite() works now.

Now what should i change for analogWrite in pwm.c as paul wrote :
"Similarly, if you wanted to use analogWrite(), you'd edit pwm.c"

Is the custom "DIY_T_4.1" using an 8 MB Flash chip for code storage?

2 MB ID's it as a T_4.0 and 16 MB will register as a T_MM.
This is the flash chip used W25Q64JVSSIM
 
Last edited:
I have encoder setup on the new pins which i made by modifying the core files, but interrupts are not working on them. Is there any other configurations required for new pin to enable interrupts? Digital and analog write are working, but encoders are not reading.

I want interrupts on

EMC_10
EMC_11
EMC_17
EMC_18
EMC_22
EMC_23
EMC_29
EMC-30
EMC_34
EMC_35

and what happens if I remake the pin in new pins which is already made in the core with different number. like EMC_22 already there as 51 but I also made it with name 70.

Thanks.
 
Looking ... perhaps it resolves to an issue in teeny4\interrupt.c:
Are all the pin 'port' items and #define's properly resolved and the logic involve to set up the interrupt as it does for 'factory' pins?
Code:
void attachInterrupt(uint8_t pin, void (*function)(void), int mode)
{
    if (pin >= CORE_NUM_DIGITAL) return;
    //printf("attachInterrupt, pin=%u\n", pin);
    volatile uint32_t *gpio = portOutputRegister(pin);
    volatile uint32_t *mux = portConfigRegister(pin);
    volatile uint32_t *pad = portControlRegister(pin);
    uint32_t mask = digitalPinToBitMask(pin);
    
    ...
 
Yes the configuration defined by Paul are done correctly, all the #define etc. But could not find to configure interrupts. here are my modified files.
 

Attachments

  • core_pins.h
    114.8 KB · Views: 8
  • digital.c
    14.2 KB · Views: 9
  • pins_arduino.h
    7.8 KB · Views: 12
  • pwm.c
    14.1 KB · Views: 9
Are you sure the issue is with the core code?

Or for example are you expecting the interrupts to work in the Encoder library?
The reason I mention this, is the header file in that library has stuff like:
Code:
#ifdef CORE_INT58_PIN
            case CORE_INT58_PIN:
                interruptArgs[58] = state;
                attachInterrupt(58, isr58, CHANGE);
                break;
        #endif
        #ifdef CORE_INT59_PIN
            case CORE_INT59_PIN:
                interruptArgs[59] = state;
                attachInterrupt(59, isr59, CHANGE);
                break;
        #endif
            default:
                return 0;
        }
        return 1;
that is it is only setup to handle up to 60 pins.

Which is also confirmed in the comments at the top of the file
Code:
/* Encoder Library, for measuring quadrature encoded signals
 * http://www.pjrc.com/teensy/td_libs_Encoder.html
 * Copyright (c) 2011,2013 PJRC.COM, LLC - Paul Stoffregen <paul@pjrc.com>
 *
 * Version 1.2 - fix -2 bug in C-only code
 * Version 1.1 - expand to support boards with up to 60 interrupts
 * Version 1.0 - initial release

P.S - still wish we had variant support, but...
 
I am not using the encoder library, I wrote own code for the encoders

this is the ISR.

C++:
static void updateEncoderState(RotaryEncoder *encObj) {
    encObj->currentStateA = digitalRead(encObj->pinA);
    encObj->currentStateB = digitalRead(encObj->pinB);
    if (encObj->currentStateA != encObj->previousStateA && encObj->currentStateA == HIGH) {
        if (encObj->currentStateA != encObj->currentStateB) {
            encObj->currentPosition++;
        } else {
            encObj->currentPosition--;
        }
    }
    encObj->previousStateA = encObj->currentStateA;
}

this is the begin:
C++:
void RotaryEncoder::begin() {
    currentStateA = digitalRead(pinA);
    currentStateB = digitalRead(pinB);
    previousStateA = currentStateA;
    previousStateB = currentStateB;
    pinMode(pinB, INPUT_PULLUP);
    pinMode(pinA, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(pinA), isrCallback, CHANGE);
    attachInterrupt(digitalPinToInterrupt(pinB), isrCallback, CHANGE);
    Serial.println("Encoder Begin!");
}

This is working on a encoder pin which are already by defualt teensy pin. EMC_04 and EMC_06.
 
Perhaps write a simple sketch to control some digitalOutput pins in loop to trigger ISR()'s on the desired pins and see if the ISR() code gets called when done manually by pin #?

In same interrupt.c file is this code that gets the common gpio6789 interrupts and then calls the code when attached - are any of these details missing?
Code:
#if defined(__IMXRT1062__)
FASTRUN static inline __attribute__((always_inline))
inline void irq_anyport(volatile uint32_t *gpio, voidFuncPtr *table)
{
    uint32_t status = gpio[ISR_INDEX] & gpio[IMR_INDEX];
    if (status) {
        gpio[ISR_INDEX] = status;
        while (status) {
            uint32_t index = __builtin_ctz(status);
            table[index]();
            status = status & ~(1 << index);
            //status = status & (status - 1);
        }
    }
}

FASTRUN
void irq_gpio6789(void)
{
    irq_anyport(&GPIO6_DR, isr_table_gpio1);
    irq_anyport(&GPIO7_DR, isr_table_gpio2);
    irq_anyport(&GPIO8_DR, isr_table_gpio3);
    irq_anyport(&GPIO9_DR, isr_table_gpio4);
    asm volatile ("dsb":::"memory");
}

#endif
 
Back
Top