I have been doing some experiments reading Teensy registers on the Teensy 4.1 and I am a bit puzzled by the results. I a setting 8 pins simmultaneously as an 8-bit bus. If I set the pins outputs and set a value and then read back the DR register I get the correct result. LEDs attached to the pins light up in the correct pattern. However, if I try to read back with the Arduino digitalRead() function I get all zeros.
Similarly if I set all pins to input_pullup with 22k resistor value (also confirmed by LEDs lighting up dimly) I get all zeros when reading back both ways. A bit of googling suggests to use the PSR register for reading back when in input mode, but that seems to give the same result.
I have attached my code. What am I missing?
```
Similarly if I set all pins to input_pullup with 22k resistor value (also confirmed by LEDs lighting up dimly) I get all zeros when reading back both ways. A bit of googling suggests to use the PSR register for reading back when in input mode, but that seems to give the same result.
I have attached my code. What am I missing?
Code:
/***** NOTE: Teensy 4.1 board *****/
#define DIO1_PIN 23 /* GPIB 1 : AD_B1_09 : GPIO1_25 */
#define DIO2_PIN 22 /* GPIB 2 : AD_B1_08 : GPIO1_24 */
#define DIO3_PIN 21 /* GPIB 3 : AD_B1_11 : GPIO1_27 */
#define DIO4_PIN 20 /* GPIB 4 : AD_B1_10 : GPIO1_26 */
#define DIO5_PIN 19 /* GPIB 13 : AD_B1_00 : GPIO1_16 */
#define DIO6_PIN 18 /* GPIB 14 : AD_B1_01 : GPIO1_17 */
#define DIO7_PIN 17 /* GPIB 15 : AD_B1_06 : GPIO1_22 */
#define DIO8_PIN 16 /* GPIB 16 : AD_B1_07 : GPIO1_23 */
#define IFC_PIN 15 /* GPIB 9 : AD_B1_03 : GPIO1_19 */
#define NDAC_PIN 14 /* GPIB 8 : AD_B1_02 : GPIO1_18 */
#define NRFD_PIN 41 /* GPIB 7 : AD_B1_05 : GPIO1_21 */
#define DAV_PIN 40 /* GPIB 6 : AD_B1_04 : GPIO1_20 */
#define EOI_PIN 39 /* GPIB 5 : AD_B1_13 : GPIO1_29 */
#define SRQ_PIN 38 /* GPIB 10 : AD_B1_12 : GPIO1_28 */
#define REN_PIN 26 /* GPIB 17 : AD_B1_14 : GPIO1_30 */
#define ATN_PIN 27 /* GPIB 11 : AD_B1_15 : GPIO1_31 */
#define PIN_PULLUP_ENABLE IOMUXC_PAD_PUS(1) | IOMUXC_PAD_PUE | IOMUXC_PAD_PKE | IOMUXC_PAD_DSE(6)
#define PIN_PULLUP_DISABLE ~IOMUXC_PAD_PKE
/***** PIN to GPIO1 map*****/
uint8_t gpioDbBits[8] = {25, 24, 27, 26, 16, 17, 24, 25};
uint8_t gpioCtrlBits[8] = {19, 18, 21, 20, 29, 28, 30, 31};
/***** GPIB data and control buses ******/
const uint8_t databus[2][8] = {
{ DIO1_PIN, DIO2_PIN, DIO3_PIN, DIO4_PIN, DIO5_PIN, DIO6_PIN, DIO7_PIN, DIO8_PIN },
{ 25, 24, 27, 26, 16, 17, 22, 23 }
};
const uint8_t ctrlreg[2][8] = {
{ IFC_PIN, NDAC_PIN, NRFD_PIN, DAV_PIN, EOI_PIN, REN_PIN, SRQ_PIN, ATN_PIN },
{ 19, 18, 21, 20, 29, 28, 30, 31 }
};
/***** GPIO6 register value *****/
uint32_t gpioDbReg = 0;
uint32_t gpioCtrlReg = 0;
volatile uint32_t * iomuxcRegB1[] = {
&IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_00,
&IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_01,
&IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_02,
&IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_03,
&IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_04,
&IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_05,
&IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_06,
&IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_07,
&IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_08,
&IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_09,
&IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_10,
&IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_11,
&IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_12,
&IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_13,
&IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_14,
&IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_15
};
/***** Generate GPIO mask from assigned pin map *****/
uint64_t genGpioMask(const uint8_t buspins[][8], uint8_t bitmask) {
uint64_t gpioreg = 0;
for (uint8_t i=0; i<8; i++) {
if (bitmask & (1 << i)) {
gpioreg |= ( 1ULL << buspins[1][i] );
}
}
return gpioreg;
}
void setPullupsMasked(const uint8_t bus[][8], uint8_t mask, bool enable){
volatile uint32_t * regptr = 0;
if (enable) {
for (uint8_t i=0; i<8; i++){
if ( mask & (1<<i) ){
regptr = iomuxcRegB1[ (bus[1][i] - 16) ];
*regptr = PIN_PULLUP_ENABLE;
}
}
return;
}
for (uint8_t i=0; i<8; i++){
if ( mask & (1<<1) ){
regptr = iomuxcRegB1[ (bus[1][i] - 16) ];
*regptr = PIN_PULLUP_DISABLE;
}
}
}
uint8_t readGpioVal(uint32_t reg){
uint32_t regval = reg;
uint8_t result = 0;
for (uint8_t i=0; i<8; i++){
if ( regval & (1UL<<databus[1][i]) ) result |= (1<<i);
}
return result;
}
uint8_t arduGpioRead(){
uint8_t result = 0;
for (uint8_t i=0; i<8; i++){
Serial.print(digitalRead(databus[0][i]));
if (digitalRead(databus[0][i])) result |= (1U<<i);
}
Serial.println();
return result;
}
/***** Init GPIO registers *****/
void initTsyGpioMasks(){
gpioDbReg = genGpioMask(databus, 0xFF);
}
void outputTest(){
uint32_t gpioVal = genGpioMask(databus, 0xAA);
uint8_t result = 0;
Serial.println("\nOutput test:");
// Prepare register bits
GPIO6_GDIR |= gpioDbReg; // Set pins as output
GPIO6_DR &= ~gpioDbReg; // Clear pins to zero
// Set output value
GPIO6_DR |= gpioVal; // Set value 0xAA
delay(200);
// Read back output value
result = readGpioVal(GPIO6_DR);
Serial.print("Teensy Result:");
Serial.println(result, HEX);
result = arduGpioRead();
Serial.print("Arduino Result:");
Serial.println(result, HEX);
}
void inputTest() {
uint8_t result = 0;
Serial.println("\nInput test:");
GPIO6_DR &= ~gpioDbReg; // Clear pins to zero
GPIO6_GDIR &= ~gpioDbReg; // Clear = set as input
setPullupsMasked(databus, 0xFF, true);
// Read back output value
result = readGpioVal(GPIO6_DR);
Serial.print("Teensy Result DR:");
Serial.println(result, HEX);
result = readGpioVal(GPIO6_PSR);
Serial.print("Teensy Result PSR:");
Serial.println(result, HEX);
result = arduGpioRead();
Serial.print("Arduino Result:");
Serial.println(result, HEX);
}
void setup() {
Serial.begin(115200);
while (!Serial && millis()<5000){};
Serial.println("Teensy Hello :-)\n");
initTsyGpioMasks();
// Serial.print("Databus: ");
// Serial.println(gpioDbReg, BIN);
// Serial.print("Ctrlbus: ");
// Serial.println(gpioCtrlReg, BIN);
outputTest();
inputTest();
Serial.flush();
}
void loop() {
}
```