teensy 2++ teensyduino USB interrupt latency

Status
Not open for further replies.

styro

New member
Hello,
i am building a device to "sniff" on a spi-buss (1MHz Clk) and give out the data via usb-serial out.
the spi is not standard, so as a hardware guy i use some cd4094 (shiftregisters) to have it in parallel
for the teensy-ports.
the device get selected with CS going HI on PORTE6 (INT6), generating a IRQ,
reading the Portpins connected to the cd4094 and saving it.
the main loop giving the data out via usb.
timer0 is configured as CTC, externaly clocked by the SPI Clk on the D7 Pin and toggles the output B7 after 15 pulses...

So far the thing works, but so every ca half second it giltches, somehow the ISR of INT6_vect
gets delayd and the device get selected to late, missing some data....
on the attached logic-analyser/DSO the delay is visible..

when i power the teeny from a USB 5V PSU that doesent happen, so probably the USB ISR generates this latency.

is there a possibility to reduce this latency, or define the USB ISR as NONBLOCKING, resp. to switch on the irq
in the ISR without negative consequences :)?

running on win7 Arduino 1.8.5 with the teensyduino extention

many thanks for any help!
styro


here the code, very ugly :)
Code:
#include <stdio.h> // for function sprintf

const byte Buffsize = 256;
volatile unsigned int Din_Value=0;
volatile unsigned int Din_Values[Buffsize];
volatile unsigned int Dout_Value=0;
volatile byte strobed = 0;
volatile byte rx_counter = 0;
volatile byte tx_counter = 0;
const int led_pin = 6;  // 6 = Teensy++ 2.0

volatile byte startreceive = 0;
volatile byte tx_received = 0;

volatile unsigned int  last_step = 0;
volatile int  stepcounter = 0;
volatile unsigned int  laststepcounter = 1;
volatile byte tray = 0;
volatile byte lasttray = 0;
volatile byte lastPORTF = 0;
volatile byte PORTFx = 99;
volatile byte CDSelected = 0;
volatile byte DoutStrobed = 0;
unsigned int lastDout_Value=0;

char MsgBuff[50]="";
char MsgBuff2[30]="";

void setup() {
  Serial.begin(9600); // USB is always 12 Mbit/sec
  PORTB = 0x00;
  DDRB = 0x88;      // PB7 OC0A Out
  DDRC = 0x00;
  DDRD = 0x00;      // D7 External in Timer0
  DDRF = 0x00;
  DDRE = 0x02;      // E1 -> strobe output
  DDRA = 0x00;
  PORTE = 0x02;
  PORTA = 0xFF;

  byte Strobe = 19;   // INT7
  byte CS_Bit2 = 18;   // INT6
//  attachInterrupt(Strobe, Strobe_interrupt, RISING);
//  attachInterrupt(CS_Bit2, CS_interrupt, RISING);

  Serial.println("SPI_Serial OLEOLE_TESTER 0.01et");  
  digitalWrite(led_pin, HIGH);
  delay(500);
  digitalWrite(led_pin, LOW);


  EICRB = 0xF0;     // rising interrupt INT7-> Strobe von Controller INT6-> Adresse Mux
  EIMSK = 0xC0;     // interrupts scharf
  
  TCCR0A = 0x42;     // toggle PB7    CTC mode
  OCR0A = 15;
  TIMSK0 = 0x02;    //interrupt OCA
  
}

void loop() {
    int rd, wr, n;
 
     
    if (strobed  > 0){
//      PORTD ^= 0x40;
     if (lastPORTF != PORTFx){
        Serial.print("Strobs");
        Serial.print(strobed,DEC);
        Serial.print("IN:_");
        Serial.print(PORTFx,HEX);
        Serial.print("-");
       Serial.println(PORTFx,BIN);
      }
      lastPORTF = PORTFx;
      strobed = 0;
    }

    if (DoutStrobed  > 0){
//      PORTD ^= 0x40;
     if (lastDout_Value != Dout_Value){
        
        int2bin(MsgBuff2, Dout_Value);
        sprintf(MsgBuff,"DoutStrobs %d Out %4X %s",DoutStrobed,Dout_Value,MsgBuff2);
       Serial.println(MsgBuff);
      }
      lastDout_Value = Dout_Value;
      DoutStrobed = 0;
    }

  if (((PINA & 0x80) != 0) && ((PINA & 0x40) == 0)&& ((PINA & 0x20) == 0)){

  }else{
   if (CDSelected == 1){
      PORTB &= ~0x08;  
      CDSelected = 0;
     TCCR0B = 0x00;    // timer off     
    }  
  }

  if (laststepcounter != stepcounter){
//     Serial.print("STEP");
//      Serial.println(stepcounter,DEC);
    
    laststepcounter = stepcounter;
  }

    if (lasttray == 0 && tray > 0){
     Serial.print("CD ");
     Serial.println(((stepcounter - 9)/4) *tray ,DEC);
    }
    lasttray = tray;
}

char *int2bin(char *buff, unsigned int val){

  byte off=0;
  for (byte i=0; i <16; i++){
    buff[i+off] =  (val & (0x8000>>i))>0?'1':'0';
    if ((i>0) && (((i+1)%4) == 0)){
      off++;
      buff[i+off]='\'';
    }   
  }
  buff[15+off]= 0;
  return buff;
}

ISR(INT6_vect ) // CS Device Select
{  
   if (((PINA & 0x80) != 0) && ((PINA & 0x40) == 0)&& ((PINA & 0x20) == 0)){
    if (CDSelected == 0){
      TCNT0= 0;
      TCCR0B = 0x07;    // timer on external in
      PORTB |= 0x08;
      CDSelected = 1;
    }
   }
}

ISR(INT7_vect ) // SPI Strobe
{
  sei();
  Din_Value = PINC | (PINF <<8);
  PORTFx = PINF;
  strobed++;
  rx_counter = 0;
  tx_counter = 0;
  TCNT0= 0;

  if (last_step != (Din_Value & 0x0010)){
    if (((Din_Value & 0x0040)>>2) != (Din_Value & 0x0010)){
      stepcounter++;
    }else{
      stepcounter--;
    }
    if (stepcounter < 0){
      stepcounter = 0;
    }
    last_step = (Din_Value & 0x0010);
  }
  if (((Din_Value & 0x0008)>>1) != (Din_Value & 0x0004)){
    tray = 2;
  }else if (((Din_Value & 0x0002)>>1) != (Din_Value & 0x0001)){
    tray = 1;
  }else{
    tray = 0;
  }
//  PORTD &= ~0x40;
}

ISR(TIMER0_COMPA_vect ) // Timer0 OCA, generate strobe for shiftregisters
{
   PORTE |= 0x02;
   PORTE |= 0x02;
   PORTE |= 0x02;
   PORTE |= 0x02;

   TCCR0B |= 0x80; // force OCA
   TCCR0B = 0x00;    // timer off 
  Dout_Value =  ((PINE&0x01) << 15)|((PIND&0x7F) << 8) | ((PINB & 0x70)>>4);
   DoutStrobed++;
   PORTB &= ~0x08;  
   PORTE &= ~0x02;
}
 
when i power the teeny from a USB 5V PSU that doesent happen, so probably the USB ISR generates this latency.

On Teensy++ 2.0 the USB ISR is only used for communication on endpoint 0. Normally that only happens when the device is plugged in and the PC reads the descriptors and configures the device. All other data flow for Serial.print() and Serial.read() is done by polling the other endpoint registers, so no interrupts should be occurring during normal operation. It is theoretically possible your PC could be sending control transfers on endpoint 0, but that would be highly unusual. Windows, Mac and Linux generally only do that when first detecting the device, and when you do something special like open or close the serial port.
 
Status
Not open for further replies.
Back
Top