can't find a pin ! D10 - T3.5

Status
Not open for further replies.

gony

Well-known member
hello everyone , 2 questions i have today -
it seems like there is no pin that represents D10 in teensy 3.5 . i mean i'm using port manipulation and i need to send 12 bit information , my free port is D (others are occupied) so i cant find in the schematic any pin which is D10. hope i'm clear ...

second question is a follow-up, is there a way to manually adjust ports ? or just to adjust pins so they are joined together ?
the point is i receive input through several pins at the same time , the inputs form together a binary value and i need to manipulate it a little and send it forward as output . but if ,say , there isn't pin 10 in port D , i can't use the command GPIOD_PDOR = GPIOC_PDIR

so what is the alternative?

hope my question makes sense , appreciate your help ! :eek:
 
set all the pins as INPUT_PULLUP
then run prints to monitor in your loop the binary value of the PORTS
then start grounding pins (yeah your smart enough to not ground the 3.3v pins right? :)
this can often make it easy to find which pins are on what ports for different microcontrollers
 
From the schematic it looks like PTD10 is not broken out. If you really need it, you'll have to create your own custom PCB (which will be hard for a BGA package). You can't really "adjust pins" since PTD10 is only available on one of the BGA pads. What you can try is some sort of DMA trickery, where a bunch of DMA channels collect pin data via bit-banding. I'm not very optimistic that it's possible to transfer data from a row of pins to another row of pins, which seems to be what you would like to do.

Can you tell us more about what you want to achieve? Maybe there's a totally different approach to your problem.
 
have an interrupt fire on another pin you assign as your "virtual D10" pin that you write the actual missing D10 as INPUT_PULLUP/INPUT_PULLDOWN and then read the PORT when needed? this could work (at least in my head :) )
 
Maybe just avoid the issue? That is if you are simpy doing something like: GPIOD_PDOR = GPIOC_PDIR
Can you maybe instead use C11/D11 for the one bit?
 
my code as it is before i knew there is no D10 :
Code:
// PTA (12 13) = [3 4] // ready signal and XS2
// PTB (0 1 2 3) = [16 17 19 18] // For address bits
// PTC (0 1 2 3 4 5 6 7 8 9 10 11) = [15 22 23 9 10 13 11 12 35 36 37 38] // For digital inputs from NI cards
// PTD (0 1 2 3 4 5 6 7 ) = [2 14 7 8 6 20 21 5] // For digital output to marker
// PTE (25) = [34] // for digital output to reward

byte inputPins[] = {3, 4, 16, 17, 19, 18, 15, 22, 23, 9, 10, 13, 11, 12, 35, 36, 37, 38};
byte outputPIns[] = {2, 14, 7, 8, 6, 20, 21, 5, 34};
int k;// set to 1 when marker activated , and to 0 when deactivated
unsigned long rewardON;
unsigned long T1;
unsigned long T2;
elapsedMillis rewardTime;
elapsedMicros markerTime;
IntervalTimer myTimerOne;
IntervalTimer myTimerTwo;


void reward(void) {
  if (!digitalReadFast(3)  && ((GPIOB_PDIR & 0xF) == 4)){// reward command received
     rewardON = GPIOC_PDIR;
     //Serial.println("rewardIFtest - GPIOC_PDIR-");
     //Serial.println(GPIOC_PDIR);
     //Serial.println(rewardON);
     digitalWriteFast(34, HIGH);//reward
     rewardTime = 0;//start counting until stop
  }
}

void marker(void) {
  if (!digitalReadFast(3) && ((GPIOB_PDIR & 0xF) == 1)){//marker command received
    //Serial.println("markerIFtest - GPIOC_PDIR-");
    //Serial.println(GPIOC_PDIR,BIN);
    GPIOD_PDOR= (GPIOC_PDIR >>1) & 0x7FF;
    k=1;
    //Serial.println("GPIOD_PDOR-");
    //Serial.println(GPIOD_PDOR,BIN);
    markerTime = 0;//start counting until stop
    
  }
}

void setup() {
  //Serial.begin(9600); while(!Serial);
  pinMode(34,OUTPUT);
  for (int pinnum = 0; pinnum < 18; pinnum++) {
        pinMode(inputPins[pinnum], INPUT_PULLDOWN);
    //pinMode(inputPins[pinnum], INPUT);
  }
  for (int pinnum = 0; pinnum < 9; pinnum++) {
    pinMode(outputPIns[pinnum], OUTPUT);
  }
  myTimerOne.priority(0);
  myTimerOne.begin(reward,1);
  myTimerTwo.priority(1);
  myTimerTwo.begin(marker,1);
}

void loop() {
  T1=micros();
  if ( digitalReadFast(34) && rewardTime > rewardON) {//if the reward output is being sent for the input time
    digitalWriteFast(34, LOW);//stop reward
    //Serial.println("looprewardtest TIME");
    //Serial.println(rewardTime);
    //Serial.println(rewardON);
      }
  if (k == 1 && markerTime > 25){//if the marker message is being sent for 25us (maybe the interval is too long\short for some devices)
    GPIOD_PDOR = 0x00;//stop marker 
    k=0;
    //Serial.println("loopmarkertest - markerTIME ");
    //Serial.println(markerTime);
    T2=micros();
    Serial.print(T2-T1);
  delay(1000);
  }
  
}

basically , i get a constant stream of pulses into port C , 12 bits each time . than i need to send C<11-9> as a group , C<8-1> as a group somewhere else and C0 to another output. my original idea was to send them together C<11-0> to port D after i remove C0 (which goes somewhere else ) thats why i did
Code:
 GPIOD_PDOR= (GPIOC_PDIR >>1) & 0x7FF;

about your comments , i don't understand the terms you are using ... what's an PCB and BGA ?

what do you mean by that ?
set all the pins as INPUT_PULLUP
then run prints to monitor in your loop the binary value of the PORTS
then start grounding pins (yeah your smart enough to not ground the 3.3v pins right?
this can often make it easy to find which pins are on what ports for different microcontrollers

p.s
efficiency is my prime consideration , the functions runn every microsecond and i can't bend it , so i would also appreciate other tips for that :eek:
(you can see the loop() at the bottom i tried to check the timing of my second IF and its about 6 micros , why is it so long ? any tips to reduce the time ?)

thanks!!!!
 
my code as it is before i knew there is no D10 :

about your comments , i don't understand the terms you are using ... what's an PCB and BGA ?

what do you mean by that ?

thanks!!!!

PCB - printed circuit board (The green thing the Teensy pins are soldered to.)

BGA - ball grid array. (The package which the Teensy 3.5's MK64 chip uses).
 
well setting T2 to micros() and then subtracting looses precision there
should just do micros()-T1
you could also do pin read/write the port/pin register directly like you did for gpiod

other than that, at 6 micros, not fast enough? ;)
 
i want to bring it down to 1 microsec , is that at all possible ?
if i switch to T3.6 would it do the trick ?

i wonder what takes so much time , is it the IF statment itself ? anyway to bypass that ?
 
To me, seeing two different Timer ISR's happening every microsecond might be an issue. Especially since they both have some common stuff...
Code:
void reward(void) {
  if (!digitalReadFast(3)  && ((GPIOB_PDIR & 0xF) == 4)){// reward command received
     rewardON = GPIOC_PDIR;
     //Serial.println("rewardIFtest - GPIOC_PDIR-");
     //Serial.println(GPIOC_PDIR);
     //Serial.println(rewardON);
     digitalWriteFast(34, HIGH);//reward
     rewardTime = 0;//start counting until stop
  }
}

void marker(void) {
  if (!digitalReadFast(3) && ((GPIOB_PDIR & 0xF) == 1)){//marker command received
    //Serial.println("markerIFtest - GPIOC_PDIR-");
    //Serial.println(GPIOC_PDIR,BIN);
    GPIOD_PDOR= (GPIOC_PDIR >>1) & 0x7FF;
    k=1;
    //Serial.println("GPIOD_PDOR-");
    //Serial.println(GPIOD_PDOR,BIN);
    markerTime = 0;//start counting until stop
    
  }
}
Wonder if it would make sense to combine these and try to eliminate common things begin done?
Example Quick and dirty...
Code:
void reward(void) {
  if (!digitalReadFast(3)) {
    switch (GPIOB_PDIR & 0xF) {
        case 4: // reward command received
           rewardON = GPIOC_PDIR;
           //Serial.println("rewardIFtest - GPIOC_PDIR-");
           //Serial.println(GPIOC_PDIR);
           //Serial.println(rewardON);
           digitalWriteFast(34, HIGH);//reward
           rewardTime = 0;//start counting until stop
           break;
       case 1:
          //Serial.println("markerIFtest - GPIOC_PDIR-");
          //Serial.println(GPIOC_PDIR,BIN);
          GPIOD_PDOR= (GPIOC_PDIR >>1) & 0x7FF;
          k=1;
          //Serial.println("GPIOD_PDOR-");
         //Serial.println(GPIOD_PDOR,BIN);
         markerTime = 0;//start counting until stop
    }
  }
}
}
This would eliminate the extra interrupts, kplus extra calls to digitalReadFast, probably multiple tests of GPIOB...

Obviously going to a T3.6 might help as you have a higher clock speed. But it is only 3.3v so depending on what you hook up to it...

As for getting around not having D10... Again I would play with what pins you do have... That is for example could you work with:

D0-7 and D12-15. In which case you could simply grab the top 4 bits of your C and shift it up to the top 4 bits of D...

Edit: Should also mention, you should carefully use some of the nice system features like elapsed micros... There are great, but when your stuff is that time critical you may want to
look at how they work...
Code:
if ( digitalReadFast(34) && rewardTime > rewardON) {//if the reward output is being sent for the input time

So this if Test really is two calls. The ditalReadFast and the getting the current rewardTime
Which is defined as: operator unsigned long () const { return micros() - us; }

So this is calling micros() subtracting off the base time and return it... Again not sure how much time you might save, but your code could do the same by calling micros() once and doing the subtraction and compare...
 
Last edited:
Status
Not open for further replies.
Back
Top