Teensy 4.0 First Beta Test

Status
Not open for further replies.
Added pullrequest for input i2s #2 and first changes to the gui.

@Paul.. TDM: Do you want a 2nd TDM, too? That would make really many in- and outputs :)
I'll try TDM tomorrow.
After that, PT8211, then SPDIF or MQS..

Now: Dr. Who in TV, and a cold beer.
 
USBHOST_T36 Joystick test
Sorry for the additional post but I timed out on the edit.

Figured it out - it prints 64 user axes when all you need for the PS4 is the first 9, plus the button values. Once I did figured that out then it all made sense. For those that don't know made a little sketch:
Inked610HPvt615L._SL1500__LI.jpg

EDIT: forgot one thing. For some reason if I try to type a command in the SerMon like 'b' or 'f' in the joystick axis it does take.
 
Kurt let me know when you have updated FlexSPI for TeensyView/ssd1306 and your 64pix tall as you tested that works with Beta9 release to run both SPI's as you did.

Does this look like your SPI 1306 unit? View attachment 15840 If so can you confirm wiring { SDA==MOSI and SCL==CLK ? }

I wondered if the bus design might result in PROGMEM speed oddity:
It does not look like my display (mine is green ;) ) But other than that yes...

I have another one that is blue that I have not tried yet on this setup... But it's lables are GND, VCC D0, D1, RES, DC, CS Which I am pretty sure is again the SPI version and D0 is your SCL which is CLK and likewise D1 is SDA which is Mosi,

Right now I am trying to debug issues that @manitou mentioned that the first byte of TX is being overwritten. Not sure where...
So I have hacked up version of SPI test program:
Code:
#include <Bounce.h>

#include <FlexIO_t4.h>
#include <FlexSPI.h>
#include <EventResponder.h>

#define BUTTON 23
#define SPISPEED 30000000
FlexSPI SPIFLEX(2, 3, 4, -1); // Setup on (int mosiPin, int misoPin, int sckPin, int csPin=-1)
Bounce bounce (BUTTON, 5);

#define SPIT SPIFLEX
#define BUFFER_SIZE 4096

uint8_t rxBuffer[BUFFER_SIZE];
uint8_t foo[50];
uint8_t txBuffer[BUFFER_SIZE];
uint32_t clock_speeds[] = {400000, 2000000, 4000000, 8000000, 15000000, 20000000, 30000000, 40000000};
#define COUNT_CLOCKS (sizeof(clock_speeds)/sizeof(clock_speeds[0]))
#define DBGSerial Serial
#define CS_PIN 6

EventResponder event;
volatile bool event_happened = false;
void asyncEventResponder(EventResponderRef event_responder)
{
  digitalWriteFast(CS_PIN, HIGH);
  event_happened = true;
}

void setup() {
  // debug pins
  pinMode(BUTTON, INPUT_PULLUP);
  pinMode(CS_PIN, OUTPUT);
  digitalWriteFast(CS_PIN, HIGH);
  while (!DBGSerial && millis() < 4000) ;  // wait for Serial port
  DBGSerial.begin(115200);
  SPIT.begin();

  //SPIFLEX.flexIOHandler()->setClockSettings(3, 2, 0);  // clksel(0-3PLL4, Pll3 PFD2 PLL5, *PLL3_sw)
  DBGSerial.println("SPI Test program");
  event.attachImmediate(&asyncEventResponder);
  delay(1000);  // give a slight delay
}

void loop() {
  Serial.println("\nTest FlexSPI.transfer(buf, retbuf, cnt");
  for (uint8_t iClock = 0; iClock < COUNT_CLOCKS; iClock++) {
    Serial.printf("Speed %u ", clock_speeds[iClock]);
    SPIT.beginTransaction(FlexSPISettings(clock_speeds[iClock], MSBFIRST, SPI_MODE0));
    for (uint32_t i = 0; i < BUFFER_SIZE; i++) {
      txBuffer[i] = i & 0xff;
      rxBuffer[i] = 0x5a;
    }
    digitalWriteFast(CS_PIN, LOW);
    uint32_t timeStart = micros();
    SPIT.transfer(txBuffer, rxBuffer, BUFFER_SIZE);
    uint32_t deltaTime = micros() - timeStart;
    digitalWriteFast(CS_PIN, HIGH);
    SPIT.endTransaction();

    uint32_t count_tx_errors = 0;
    uint32_t count_rx_errors = 0;
    uint32_t firxt_tx_error = (uint32_t) - 1;
    uint32_t firxt_rx_error = (uint32_t) - 1;
    for (uint32_t i = 0; i < BUFFER_SIZE; i++) {
      if (txBuffer[i] != (i & 0xff)) {
        count_tx_errors++;
        if (firxt_tx_error == (uint32_t) - 1) firxt_tx_error = i;
      }
      if (rxBuffer[i] != (i & 0xff)) {
        count_rx_errors++;
        if (firxt_rx_error == (uint32_t) - 1) firxt_rx_error = i;
      }
    }
    Serial.printf(" dt: %u TX Errors: %u %u RX Error: %u (%u)\n    TX:",
                  deltaTime, count_tx_errors, firxt_tx_error, count_rx_errors, firxt_rx_error);
    for (uint32_t i = 0; i < 16; i++) Serial.printf("%x ", txBuffer[i]);
    Serial.print(" ... ");
    for (uint32_t i = sizeof(txBuffer) - 16; i < sizeof(txBuffer); i++) Serial.printf("%x ", txBuffer[i]);
    Serial.print("\n    RX: ");
    for (uint32_t i = 0; i < 16; i++) Serial.printf("%x ", rxBuffer[i]);
    Serial.print(" ... ");
    for (uint32_t i = sizeof(rxBuffer) - 16; i < sizeof(rxBuffer); i++) Serial.printf("%x ", rxBuffer[i]);
    Serial.println();
    delay(10);
  }

  Serial.println("\nTest FlexSPI.transfer(buf, retbuf, cnt, ");
  for (uint8_t iClock = 0; iClock < COUNT_CLOCKS; iClock++) {
    Serial.printf("Speed %u ", clock_speeds[iClock]);
    SPIT.beginTransaction(FlexSPISettings(clock_speeds[iClock], MSBFIRST, SPI_MODE0));
    for (uint32_t i = 0; i < BUFFER_SIZE; i++) {
      txBuffer[i] = i & 0xff;
      rxBuffer[i] = 0x5a;
    }
    digitalWriteFast(CS_PIN, LOW);
    uint32_t timeStart = micros();
    event_happened = false;
    SPIT.transfer(txBuffer, rxBuffer, BUFFER_SIZE, event);
    while (!event_happened) ;
    uint32_t deltaTime = micros() - timeStart;
    SPIT.endTransaction();

    uint32_t count_tx_errors = 0;
    uint32_t count_rx_errors = 0;
    uint32_t firxt_tx_error = (uint32_t) - 1;
    uint32_t firxt_rx_error = (uint32_t) - 1;
    for (uint32_t i = 0; i < BUFFER_SIZE; i++) {
      if (txBuffer[i] != (i & 0xff)) {
        count_tx_errors++;
        if (firxt_tx_error == (uint32_t) - 1) firxt_tx_error = i;
      }
      if (rxBuffer[i] != (i & 0xff)) {
        count_rx_errors++;
        if (firxt_rx_error == (uint32_t) - 1) firxt_rx_error = i;
      }
    }
    Serial.printf(" dt: %u TX Errors: %u (%u)  RX Error: %u (%u)\n",
                  deltaTime, count_tx_errors, firxt_tx_error, count_rx_errors, firxt_rx_error);
    delay(10);
  }

  // Test write from read only memory
  static const PROGMEM uint8_t const_str[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";  
    Serial.printf("Try transfer from const str");
    SPIT.beginTransaction(FlexSPISettings(8000000, MSBFIRST, SPI_MODE0));
    for (uint32_t i = 0; i < BUFFER_SIZE; i++) {
      rxBuffer[i] = 0x5a;
    }
    
    digitalWriteFast(CS_PIN, LOW);
    uint32_t timeStart = micros();
    SPIT.transfer(const_str, rxBuffer, sizeof(const_str));
    uint32_t deltaTime = micros() - timeStart;
    digitalWriteFast(CS_PIN, HIGH);
    SPIT.endTransaction();
   Serial.printf(" dt: %u \n    TX:", deltaTime);
    for (uint32_t i = 0; i < sizeof(const_str); i++) Serial.printf("%x ", const_str[i]);
    Serial.print("\n    RX: ");
    for (uint32_t i = 0; i < sizeof(const_str); i++) Serial.printf("%x ", rxBuffer[i]);

    Serial.println();
    delay(10);
   

  
  bounce.update();
  int bounce_value = bounce.read();
  while ((DBGSerial.read() != -1) && (bounce_value))  {
    bounce.update();
    bounce_value = bounce.read();
  }
  DBGSerial.println("Press any key to rerun test");
  while ((DBGSerial.read() == -1) && (bounce_value))  {
    bounce.update();
    bounce_value = bounce.read();
  }
  if (bounce_value) {
    while (DBGSerial.read() != -1) ; // loop until queue is empty
  }
}
Which tries to cycle through several requested SPI speeds and copy 4K... And try to get an idea of which things work or don't I also have it trying using the DMA as well...

Since it appeared to consistently overwrite the first byte (non-dma version), and I put a buffer between the two to make sure it was not just overwrtie?

Code:
SPI Test program

Test FlexSPI.transfer(buf, retbuf, cnt
Speed 400000  dt: 83033 TX Errors: 1 0 RX Error: 0 (4294967295)
    TX:b0 1 2 3 4 5 6 7 8 9 a b c d e f  ... f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 
    RX: 0 1 2 3 4 5 6 7 8 9 a b c d e f  ... f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 
Speed 2000000  dt: 17481 TX Errors: 1 0 RX Error: 0 (4294967295)
    TX:b0 1 2 3 4 5 6 7 8 9 a b c d e f  ... f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 
    RX: 0 1 2 3 4 5 6 7 8 9 a b c d e f  ... f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 
Speed 4000000  dt: 8741 TX Errors: 1 0 RX Error: 0 (4294967295)
    TX:b0 1 2 3 4 5 6 7 8 9 a b c d e f  ... f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 
    RX: 0 1 2 3 4 5 6 7 8 9 a b c d e f  ... f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 
Speed 8000000  dt: 4371 TX Errors: 1 0 RX Error: 0 (4294967295)
    TX:b0 1 2 3 4 5 6 7 8 9 a b c d e f  ... f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 
    RX: 0 1 2 3 4 5 6 7 8 9 a b c d e f  ... f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 
Speed 15000000  dt: 2186 TX Errors: 1 0 RX Error: 4095 (1)
    TX:d8 1 2 3 4 5 6 7 8 9 a b c d e f  ... f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 
    RX: 0 0 81 1 82 2 83 3 84 4 85 5 86 6 87 7  ... f8 78 f9 79 fa 7a fb 7b fc 7c fd 7d fe 7e ff 7f 
Speed 20000000  dt: 2186 TX Errors: 1 0 RX Error: 4095 (1)
    TX:d8 1 2 3 4 5 6 7 8 9 a b c d e f  ... f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 
    RX: 0 0 81 1 82 2 83 3 84 4 85 5 86 6 87 7  ... f8 78 f9 79 fa 7a fb 7b fc 7c fd 7d fe 7e ff 7f 
Speed 30000000  dt: 2186 TX Errors: 1 0 RX Error: 4095 (1)
    TX:d8 1 2 3 4 5 6 7 8 9 a b c d e f  ... f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 
    RX: 0 0 81 1 82 2 83 3 84 4 85 5 86 6 87 7  ... f8 78 f9 79 fa 7a fb 7b fc 7c fd 7d fe 7e ff 7f 
Speed 40000000  dt: 2186 TX Errors: 1 0 RX Error: 4095 (1)
    TX:d8 1 2 3 4 5 6 7 8 9 a b c d e f  ... f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 
    RX: 0 0 81 1 82 2 83 3 84 4 85 5 86 6 87 7  ... f8 78 f9 79 fa 7a fb 7b fc 7c fd 7d fe 7e ff 7f 

Test FlexSPI.transfer(buf, retbuf, cnt, 
Speed 400000  dt: 83018 TX Errors: 0 (4294967295)  RX Error: 0 (4294967295)
Speed 2000000  dt: 17479 TX Errors: 0 (4294967295)  RX Error: 0 (4294967295)
Speed 4000000  dt: 8740 TX Errors: 0 (4294967295)  RX Error: 0 (4294967295)
Speed 8000000  dt: 4371 TX Errors: 0 (4294967295)  RX Error: 0 (4294967295)
Speed 15000000  dt: 2187 TX Errors: 0 (4294967295)  RX Error: 4095 (1)
Speed 20000000  dt: 2187 TX Errors: 0 (4294967295)  RX Error: 4095 (1)
Speed 30000000  dt: 2187 TX Errors: 0 (4294967295)  RX Error: 4095 (1)
Speed 40000000  dt: 2187 TX Errors: 0 (4294967295)  RX Error: 4095 (1)
Try transfer from const str dt: 30 
    TX:41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 0 
    RX: 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 0 
Press any key to rerun test
So I thought maybe try TX from a static const PROGMEM memory, which I believe should fault if I try to write to it... That one went through did not overwrite TX buffer and not fault...

Still debugging! Also noted that the DMA version failed miserably on the higher speeds, like it lost the 2nd byte or something.
 
@mjs513 - edit time limits... Maybe time to become a Senior Member+ group member ;)

@Paul and other - Soon I will plug T4 back into Adapter board, so I can start playing with USB Host and Audio... But need all of the IO pins to test out things like SPI and Flex... So been bread boarding it mostly lately... Paul if you come out with another version of the adapter board, would be great if you had another set of all of the pins to connect up to... I have almost started to hack up my own, but not sure how long until maybe different form factor...

@defragster - I have tested out my updated multi display app with three displays...
Hardware SPI is using pins: 11, 12, 13, 20, 21, 15
Flex 1: 2, 3, 4, 5, 6, 7
Flex 2: 8, 9, 10, 18, 19
Serial4 I don't use, yet but reserved: 16, 17
Logical Button to run tests: 23 - not needed here yet
Likewise I have left 0, 1 free...
Code:
/**************************************************************************
  This is an example for our Monochrome OLEDs based on SSD1306 drivers

  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/category/63_98

  This example is for a 128x32 pixel display using SPI to communicate
  4 or 5 pins are required to interface.

  Adafruit invests time and resources providing this open
  source code, please support Adafruit and open-source
  hardware by purchasing products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries,
  with contributions from the open source community.
  BSD license, check license.txt for more information
  All text above, and the splash screen below must be
  included in any redistribution.
 **************************************************************************/

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <SSD1306_FlexIO.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Declaration for SSD1306 display connected using Hardware SPI (SPI)
#define OLED_DC    21
#define OLED_CS    20
#define OLED_RESET 15
SSD1306_FlexIO_32 display1(OLED_DC, OLED_RESET, OLED_CS, &SPI);

// Declaration for SSD1306 display connected using FlexIO 1: SPI
#define OLED_DC2    5
#define OLED_CS2    6
#define OLED_RESET2 7
FlexSPI SPIFLEX(2, 3, 4, -1); // Setup on (int mosiPin, int misoPin, int sckPin,  int csPin=-1) :
SSD1306_FlexIO_32 display2(OLED_DC2, OLED_RESET2, OLED_CS2, &SPIFLEX);

// Declaration for SSD1306 display connected using FlexIO 2: SPI
#define OLED_DC3    18
#define OLED_CS3    19
#define OLED_RESET3 14
FlexSPI SPIFLEX2(8, 9, 10, -1); // Setup on (int mosiPin, int misoPin, int sckPin,  int csPin=-1)
SSD1306_FlexIO_64 display3(OLED_DC3, OLED_RESET3, OLED_CS3, &SPIFLEX2);

SSD1306_FlexIO *display_list[] = {&display1, &display2, &display3};
#define NUM_DISPLAYS (sizeof(display_list)/sizeof(display_list[0]))

/* Comment out above, uncomment this block to use hardware SPI
  #define OLED_DC     6
  #define OLED_CS     7
  #define OLED_RESET  8
  SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,
  &SPI, OLED_DC, OLED_RESET, OLED_CS);
*/

#define NUMFLAKES     10 // Number of snowflakes in the animation example

#define LOGO_HEIGHT   16
#define LOGO_WIDTH    16
static const unsigned char PROGMEM logo_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000
};

void setup() {
  Serial.begin(9600);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display1.begin(SSD1306_SWITCHCAPVCC)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }
  if (!display2.begin(SSD1306_SWITCHCAPVCC)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }
  if (!display3.begin(SSD1306_SWITCHCAPVCC)) {
    Serial.println(F("SSD1306 allocation failed"));
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display1.setClockRate(8000000);
  display2.setClockRate(8000000);
  display1.display();
  display2.display();
  display3.display();
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
  display1.clearDisplay();
  display2.clearDisplay();
  display3.clearDisplay();
  // Draw a single pixel in white
  display1.drawPixel(10, 10, WHITE);
  display2.drawPixel(10, 10, WHITE);

  // Show the display buffer on the screen. You MUST call display() after
  // drawing commands to make them visible on screen!
  display1.display();
  display2.display();
  display3.display();
  delay(2000);
  // display1.display() is NOT necessary after every single drawing command,
  // unless that's what you want...rather, you can batch up a bunch of
  // drawing operations and then update the screen all at once by calling
  // display1.display(). These examples demonstrate both approaches...

  testdrawline(display1);      // Draw many lines
  testdrawline(display2);      // Draw many lines
  testdrawline(display3);      // Draw many lines
#if 0

  testdrawrect(display1);      // Draw rectangles (outlines)
  testdrawrect(display2);      // Draw rectangles (outlines)

  testfillrect(display1);      // Draw rectangles (filled)
  testfillrect(display2);      // Draw rectangles (filled)

  testdrawcircle(display1);    // Draw circles (outlines)
  testdrawcircle(display2);    // Draw circles (outlines)

  testfillcircle(display1);    // Draw circles (filled)

  testdrawroundrect(display1); // Draw rounded rectangles (outlines)

  testfillroundrect(display1); // Draw rounded rectangles (filled)

  testdrawtriangle(display1);  // Draw triangles (outlines)

  testfilltriangle(display1);  // Draw triangles (filled)

  testdrawchar(display1);      // Draw characters of the default font

  testdrawstyles(display1);    // Draw 'stylized' characters

  testscrolltext(display1);    // Draw scrolling text

  testdrawbitmap(display1);    // Draw a small bitmap image

  // Invert and restore display, pausing in-between
  display1.invertDisplay(true);
  delay(1000);
  display1.invertDisplay(false);
  delay(1000);
#endif
  testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps
}

void loop() {
}

void testdrawline(SSD1306_FlexIO &disp) {
  int16_t i;

  disp.clearDisplay(); // Clear display buffer

  for (i = 0; i < disp.width(); i += 4) {
    disp.drawLine(0, 0, i, disp.height() - 1, WHITE);
    disp.display(); // Update screen with each newly-drawn line
    delay(1);
  }
  for (i = 0; i < disp.height(); i += 4) {
    disp.drawLine(0, 0, disp.width() - 1, i, WHITE);
    disp.display();
    delay(1);
  }
  delay(250);

  disp.clearDisplay();

  for (i = 0; i < disp.width(); i += 4) {
    disp.drawLine(0, disp.height() - 1, i, 0, WHITE);
    disp.display();
    delay(1);
  }
  for (i = disp.height() - 1; i >= 0; i -= 4) {
    disp.drawLine(0, disp.height() - 1, disp.width() - 1, i, WHITE);
    disp.display();
    delay(1);
  }
  delay(250);

  disp.clearDisplay();

  for (i = disp.width() - 1; i >= 0; i -= 4) {
    disp.drawLine(disp.width() - 1, disp.height() - 1, i, 0, WHITE);
    disp.display();
    delay(1);
  }
  for (i = disp.height() - 1; i >= 0; i -= 4) {
    disp.drawLine(disp.width() - 1, disp.height() - 1, 0, i, WHITE);
    disp.display();
    delay(1);
  }
  delay(250);

  disp.clearDisplay();

  for (i = 0; i < disp.height(); i += 4) {
    disp.drawLine(disp.width() - 1, 0, 0, i, WHITE);
    disp.display();
    delay(1);
  }
  for (i = 0; i < disp.width(); i += 4) {
    disp.drawLine(disp.width() - 1, 0, i, disp.height() - 1, WHITE);
    disp.display();
    delay(1);
  }

  delay(2000); // Pause for 2 seconds
}

void testdrawrect(SSD1306_FlexIO &disp) {
  disp.clearDisplay();

  for (int16_t i = 0; i < disp.height() / 2; i += 2) {
    disp.drawRect(i, i, disp.width() - 2 * i, disp.height() - 2 * i, WHITE);
    disp.display(); // Update screen with each newly-drawn rectangle
    delay(1);
  }

  delay(2000);
}

void testfillrect(SSD1306_FlexIO &disp) {
  disp.clearDisplay();

  for (int16_t i = 0; i < disp.height() / 2; i += 3) {
    // The INVERSE color is used so rectangles alternate white/black
    disp.fillRect(i, i, disp.width() - i * 2, disp.height() - i * 2, INVERSE);
    disp.display(); // Update screen with each newly-drawn rectangle
    delay(1);
  }

  delay(2000);
}

void testdrawcircle(SSD1306_FlexIO &disp) {
  disp.clearDisplay();

  for (int16_t i = 0; i < max(disp.width(), disp.height()) / 2; i += 2) {
    disp.drawCircle(disp.width() / 2, disp.height() / 2, i, WHITE);
    disp.display();
    delay(1);
  }

  delay(2000);
}

void testfillcircle(SSD1306_FlexIO &disp) {
  disp.clearDisplay();

  for (int16_t i = max(disp.width(), disp.height()) / 2; i > 0; i -= 3) {
    // The INVERSE color is used so circles alternate white/black
    disp.fillCircle(disp.width() / 2, disp.height() / 2, i, INVERSE);
    disp.display(); // Update screen with each newly-drawn circle
    delay(1);
  }

  delay(2000);
}

void testdrawroundrect(SSD1306_FlexIO &disp) {
  disp.clearDisplay();

  for (int16_t i = 0; i < disp.height() / 2 - 2; i += 2) {
    disp.drawRoundRect(i, i, disp.width() - 2 * i, disp.height() - 2 * i,
                       disp.height() / 4, WHITE);
    disp.display();
    delay(1);
  }

  delay(2000);
}

void testfillroundrect(SSD1306_FlexIO &disp) {
  disp.clearDisplay();

  for (int16_t i = 0; i < disp.height() / 2 - 2; i += 2) {
    // The INVERSE color is used so round-rects alternate white/black
    disp.fillRoundRect(i, i, disp.width() - 2 * i, disp.height() - 2 * i,
                       disp.height() / 4, INVERSE);
    disp.display();
    delay(1);
  }

  delay(2000);
}

void testdrawtriangle(SSD1306_FlexIO &disp) {
  disp.clearDisplay();

  for (int16_t i = 0; i < max(disp.width(), disp.height()) / 2; i += 5) {
    disp.drawTriangle(
      disp.width() / 2  , disp.height() / 2 - i,
      disp.width() / 2 - i, disp.height() / 2 + i,
      disp.width() / 2 + i, disp.height() / 2 + i, WHITE);
    disp.display();
    delay(1);
  }

  delay(2000);
}

void testfilltriangle(SSD1306_FlexIO &disp) {
  disp.clearDisplay();

  for (int16_t i = max(disp.width(), disp.height()) / 2; i > 0; i -= 5) {
    // The INVERSE color is used so triangles alternate white/black
    disp.fillTriangle(
      disp.width() / 2  , disp.height() / 2 - i,
      disp.width() / 2 - i, disp.height() / 2 + i,
      disp.width() / 2 + i, disp.height() / 2 + i, INVERSE);
    disp.display();
    delay(1);
  }

  delay(2000);
}

void testdrawchar(SSD1306_FlexIO &disp) {
  disp.clearDisplay();

  disp.setTextSize(1);      // Normal 1:1 pixel scale
  disp.setTextColor(WHITE); // Draw white text
  disp.setCursor(0, 0);     // Start at top-left corner
  disp.cp437(true);         // Use full 256 char 'Code Page 437' font

  // Not all the characters will fit on the disp. This is normal.
  // Library will draw what it can and the rest will be clipped.
  for (int16_t i = 0; i < 256; i++) {
    if (i == '\n') disp.write(' ');
    else          disp.write(i);
  }

  disp.display();
  delay(2000);
}

void testdrawstyles(SSD1306_FlexIO &disp) {
  disp.clearDisplay();

  disp.setTextSize(1);             // Normal 1:1 pixel scale
  disp.setTextColor(WHITE);        // Draw white text
  disp.setCursor(0, 0);            // Start at top-left corner
  disp.println(F("Hello, world!"));

  disp.setTextColor(BLACK, WHITE); // Draw 'inverse' text
  disp.println(3.141592);

  disp.setTextSize(2);             // Draw 2X-scale text
  disp.setTextColor(WHITE);
  disp.print(F("0x")); disp.println(0xDEADBEEF, HEX);

  disp.display();
  delay(2000);
}

void testscrolltext(SSD1306_FlexIO &disp) {
  disp.clearDisplay();

  disp.setTextSize(2); // Draw 2X-scale text
  disp.setTextColor(WHITE);
  disp.setCursor(10, 0);
  disp.println(F("scroll"));
  disp.display();      // Show initial text
  delay(100);

  // Scroll in various directions, pausing in-between:
  disp.startscrollright(0x00, 0x0F);
  delay(2000);
  disp.stopscroll();
  delay(1000);
  disp.startscrollleft(0x00, 0x0F);
  delay(2000);
  disp.stopscroll();
  delay(1000);
  disp.startscrolldiagright(0x00, 0x07);
  delay(2000);
  disp.startscrolldiagleft(0x00, 0x07);
  delay(2000);
  disp.stopscroll();
  delay(1000);
}

void testdrawbitmap(SSD1306_FlexIO &disp) {
  disp.clearDisplay();

  disp.drawBitmap(
    (disp.width()  - LOGO_WIDTH ) / 2,
    (disp.height() - LOGO_HEIGHT) / 2,
    logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
  disp.display();
  delay(1000);
}

#define XPOS   0 // Indexes into the 'icons' array in function below
#define YPOS   1
#define DELTAY 2
typedef struct  {
  int8_t x;
  int8_t y;
  int8_t deltaY;
} star_positions;

void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) {
  int8_t f;
  star_positions icons[NUMFLAKES][ NUM_DISPLAYS];
  uint32_t loop_count[NUM_DISPLAYS];
  uint8_t iDisplay;
  for (iDisplay = 0; iDisplay < NUM_DISPLAYS; iDisplay++) {
    SSD1306_FlexIO *pdisp = display_list[iDisplay];
    // Initialize 'snowflake' positions
    Serial.printf("Display %d\n", iDisplay);
    for (f = 0; f < NUMFLAKES; f++) {
      icons[f][iDisplay].x   = random(1 - LOGO_WIDTH, pdisp->width());
      icons[f][iDisplay].y   = -LOGO_HEIGHT;
      icons[f][iDisplay].deltaY = random(1, 6);
      Serial.print(F("x: "));
      Serial.print(icons[f][iDisplay].x, DEC);
      Serial.print(F(" y: "));
      Serial.print(icons[f][iDisplay].y, DEC);
      Serial.print(F(" dy: "));
      Serial.println(icons[f][iDisplay].deltaY, DEC);
    }
    loop_count[iDisplay] = 0;
    pdisp->setTextSize(2);      // Normal 1:1 pixel scale
    pdisp->setTextColor(WHITE); // Draw white text
  }

  // Main loop
  for (;;) { // Loop forever...
    for (iDisplay = 0; iDisplay < NUM_DISPLAYS; iDisplay++) {
      SSD1306_FlexIO *pdisp = display_list[iDisplay];
      if (!pdisp->displayAsyncActive()) {
        pdisp->clearDisplay();
        // Draw each snowflake:
        for (f = 0; f < NUMFLAKES; f++) {
          pdisp->drawBitmap(icons[f][iDisplay].x, icons[f][iDisplay].y, bitmap, w, h, WHITE);
        }
        loop_count[iDisplay]++;
        pdisp->setCursor(0, 0);     // Start at top-left corner
        pdisp->print(loop_count[iDisplay], DEC);
        pdisp->displayAsync(); // Show the display buffer on the screen

        // Then update coordinates of each flake...
        for (f = 0; f < NUMFLAKES; f++) {
          icons[f][iDisplay].y += icons[f][iDisplay].deltaY;
          // If snowflake is off the bottom of the screen...
          if (icons[f][iDisplay].y >= pdisp->height()) {
            // Reinitialize to a random position, just off the top
            icons[f][iDisplay].x   = random(1 - LOGO_WIDTH, pdisp->width());
            icons[f][iDisplay].y   = -LOGO_HEIGHT;
            icons[f][iDisplay].deltaY = random(1, 6);
          }
        }
      }
    }
  }
}
But still debugging the transfer functions...

EDIT Update
- fixed a off by 1 bug in transfer so no longer outputting one extra byte...
 
Last edited:
USBHOST AGAIN
This time I ran "Mouse" example with a USB 2.0 Hub attached along with my old Logitech wireless mouse + PS4 controller. It recognized all three and identified them correctly. Read and printed mouse and joystick data no problem. Can't find my extra wired keyboard so have to leave that to someone else to test.

It didn't read my logitech bluetooth dongle/mouse though when i attached that one.
 
Paul if you come out with another version of the adapter board, would be great if you had another set of all of the pins to connect up to... I have almost started to hack up my own, but not sure how long until maybe different form factor...

@Paul, I second Kurt said. Maybe you should consider selling these in the future especially if you come out with one with all the pins broken out.
 
Flex SPI - Transfer Issues

As I mentioned in update of previous message, I fixed the overwrite by 1 error...

As for the RX issue, I believe I know what is going on. If you for example: use the default settings.
The FlexIO Speed is 30mhz. So if you ask for 15mhz (or greater). The computations are that you setup the TIMCMP low order byte to: give you:
timer = 30mhz/((n+1)*2) so for 15mhz you have n=0...

Setting this to zero appears to work OK if you are doing TX only, but if you do any RX it fails...
So the obvious simple fix to allow RX is to limit the N >= 1 which would imply in default that you can only do 7.5mhz...

Note: I tried a simple hack that if N==0, I try simple loop like *rxBuffer++ = transfer(*txBuffer++);
It did not work either...

If I set up to change the timer to give me timer=160mhz it appears like there is also issue when N==1 (40mhz). Worked OK at 30mhz...
And that is consistent between directly or with DMA...
 
Last edited:
Kurt I ordered one of those too - will be here weeks before the other ... which I got a note they would use accelerated shipping to make up for the fact that it won't ship for 10 days. That is one of the ones I looked at - but it wasn't clear what controller was in use from the 'buy it' page.

I'm trying to include Teensy40 in the mod I made to create Frank's Compile.cmd and the starts but fails:
FrankB - the core added to Compile.cmd is:
set model=teensy4b
set speed=60
set opt=o2std
set usb=serial

The resultant errors building look like this here with Beta9 installed::
"T:\\arduino-1.8.8T4_146\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-gcc" -c -Os -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1052__ -DTEENSYDUINO=146 -DARDUINO=10600 -DF_CPU=396000000 -DUSB_SERIAL -DLAYOUT_{build.keylayout} "-IT:\\arduino-1.8.8T4_146\\hardware\\teensy\\avr\\cores\\teensy4" "T:\\arduino-1.8.8T4_146\\hardware\\teensy\\avr\\cores\\teensy4\\interrupt.c" -o "T:\\TEMP\\arduino_build_DebugMin_tt.ino\\core\\interrupt.c.o"
<command-line>:0:8: warning: ISO C99 requires whitespace after the macro name
In file included from T:\arduino-1.8.8T4_146\hardware\teensy\avr\cores\teensy4\keylayouts.c:34:0:
T:\arduino-1.8.8T4_146\hardware\teensy\avr\cores\teensy4\keylayouts.h:5782:14: error: unknown type name 'KEYCODE_TYPE'
extern const KEYCODE_TYPE keycodes_ascii[];
^
T:\arduino-1.8.8T4_146\hardware\teensy\avr\cores\teensy4\keylayouts.h:5783:14: error: unknown type name 'KEYCODE_TYPE'
extern const KEYCODE_TYPE keycodes_iso_8859_1[];
^
T:\arduino-1.8.8T4_146\hardware\teensy\avr\cores\teensy4\keylayouts.c:41:7: error: unknown type name 'KEYCODE_TYPE'
const KEYCODE_TYPE keycodes_ascii[] = {
^
T:\arduino-1.8.8T4_146\hardware\teensy\avr\cores\teensy4\keylayouts.c:42:11: error: 'ASCII_20' undeclared here (not in a function)
M(ASCII_20), M(ASCII_21), M(ASCII_22), M(ASCII_23),

This is not expanding right "-DLAYOUT_{build.keylayout}" … >> should be :: -DLAYOUT_US_ENGLISH - it works on T_3.1 usage?

Here's the primary sketch line for T_3.1 where expansion went right:
"T:\\arduino-1.8.8T4_146\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant -D__MK20DX256__ -DTEENSYDUINO=146 -DARDUINO=10600 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IT:\\arduino-1.8.8T4_146\\hardware\\teensy\\avr\\cores\\teensy3" "T:\\TEMP\\arduino_build_EchoBoth.ino\\sketch\\EchoBoth.ino.cpp" -o nul
 
Last edited:
@Frank
Tried using your audio codec library but ran into some interesting problems (fixed a couple but the others don't know). I am attaching the error log. Have a couple of thoughts but probably wrong.
 

Attachments

  • mp3errors.txt
    12.4 KB · Views: 79
Display
Kurt I ordered one of those too - will be here weeks before the other ... which I got a note they would use accelerated shipping to make up for the fact that it won't ship for 10 days. That is one of the ones I looked at - but it wasn't clear what controller was in use from the 'buy it' page.

I must have gotten the last one they had local... I ordered it yesterday afternoon and it already shipped from California...

Took a chance as the description page said:
EastRising ER-TFT035-6 LCD 3.5" 320x480 TFT Display Module,OPTL Touch Screen w/Breakout Board .
Part Number ER-TFTM035-6
Display Format 320x480 Dots
Interface 8080 8-bit Parallel , 8080 9-bit Parallel , 8080 16-bit Parallel , 8080 18-bit Parallel , 3-Wire Serial SPI, 4-Wire Serial SPI, RGB
IC or Equivalent ILI9488
Appearance RGB
Diagonal Size 3.5”
Connection Pin Header, FFC-Connector

And I always hate the words (or Equivalent), but...

Flex SPI
Currently I have put in a limit to TIMCMP lower byte to not allow it to be 0... as reads don't work at all when 0... So with default clock configuration.
I can go up to 7.5mhz... At the 160mhz, there is also an issue where TIMCMP lower byte = 1 has read problems as well. So far I have left that...
But will probably auto set that one to 2 as well...

But I also may put in a hack... Like if I change a call like:
Code:
SPIT.beginTransaction(FlexSPISettings(clock_speeds[iClock], MSBFIRST, SPI_MODE0))

To something like:
Code:
SPIT.beginTransaction(FlexSPISettings(clock_speeds[iClock], MSBFIRST, SPI_MODE0 | SPI_WRITE_ONLY))
Than will allow the 0,1 values to be set in TIMCMP as writes appear to work...

But with current test app, configured to 160mhz:
Code:
#include <Bounce.h>

#include <FlexIO_t4.h>
#include <FlexSPI.h>
#include <EventResponder.h>

#define BUTTON 23
#define SPISPEED 30000000
FlexSPI SPIFLEX(2, 3, 4, -1); // Setup on (int mosiPin, int misoPin, int sckPin, int csPin=-1)
Bounce bounce (BUTTON, 5);

#define SPIT SPIFLEX
#define BUFFER_SIZE 256 //4096

uint8_t rxBuffer[BUFFER_SIZE];
uint8_t foo[50];
uint8_t txBuffer[BUFFER_SIZE];
uint32_t clock_speeds[] = {400000, 2000000, 4000000, 8000000,
                           15000000, 15000000,
                           20000000, 30000000, 40000000, 40000000
                          };
uint32_t spi_modes[] = {SPI_MODE0, SPI_MODE0, SPI_MODE0, SPI_MODE0,
                        SPI_MODE0, SPI_MODE0 | SPI_MODE_TRANSMIT_ONLY,
                        SPI_MODE0, SPI_MODE0, SPI_MODE0, SPI_MODE0 | SPI_MODE_TRANSMIT_ONLY
                       };
#define COUNT_CLOCKS (sizeof(clock_speeds)/sizeof(clock_speeds[0]))
#define DBGSerial Serial
#define CS_PIN 6

EventResponder event;
volatile bool event_happened = false;
void asyncEventResponder(EventResponderRef event_responder)
{
  digitalWriteFast(CS_PIN, HIGH);
  event_happened = true;
}

void setup() {
  // debug pins
  pinMode(BUTTON, INPUT_PULLUP);
  pinMode(CS_PIN, OUTPUT);
  digitalWriteFast(CS_PIN, HIGH);
  while (!DBGSerial && millis() < 4000) ;  // wait for Serial port
  DBGSerial.begin(115200);
  SPIT.begin();

  SPIFLEX.flexIOHandler()->setClockSettings(3, 2, 0);  // clksel(0-3PLL4, Pll3 PFD2 PLL5, *PLL3_sw)
  DBGSerial.printf("SPI Test program FlexIO Clock Speed %u\n", SPIFLEX.flexIOHandler()->computeClockRate());
  event.attachImmediate(&asyncEventResponder);
  delay(1000);  // give a slight delay
}

void loop() {
  Serial.println("\nTest FlexSPI.transfer(buf, retbuf, cnt");
  for (uint8_t iClock = 0; iClock < COUNT_CLOCKS; iClock++) {
    Serial.printf("Speed %u Mode %x", clock_speeds[iClock],  spi_modes[iClock]);
    SPIT.beginTransaction(FlexSPISettings(clock_speeds[iClock], MSBFIRST, spi_modes[iClock]));
    for (uint32_t i = 0; i < BUFFER_SIZE; i++) {
      txBuffer[i] = i & 0xff;
      rxBuffer[i] = 0x5a;
    }
    digitalWriteFast(CS_PIN, LOW);
    uint32_t timeStart = micros();
    SPIT.transfer(txBuffer, rxBuffer, BUFFER_SIZE);
    uint32_t deltaTime = micros() - timeStart;
    digitalWriteFast(CS_PIN, HIGH);
    SPIT.endTransaction();

    uint32_t count_tx_errors = 0;
    uint32_t count_rx_errors = 0;
    uint32_t firxt_tx_error = (uint32_t) - 1;
    uint32_t firxt_rx_error = (uint32_t) - 1;
    for (uint32_t i = 0; i < BUFFER_SIZE; i++) {
      if (txBuffer[i] != (i & 0xff)) {
        count_tx_errors++;
        if (firxt_tx_error == (uint32_t) - 1) firxt_tx_error = i;
      }
      if (rxBuffer[i] != (i & 0xff)) {
        count_rx_errors++;
        if (firxt_rx_error == (uint32_t) - 1) firxt_rx_error = i;
      }
    }
    Serial.printf(" dt: %u TX Errors: %u (%u) RX Error: %u (%u)\n",
                  deltaTime, count_tx_errors, firxt_tx_error, count_rx_errors, firxt_rx_error);
    if (count_tx_errors || count_rx_errors) {
      Serial.print("    TX:");
      for (uint32_t i = 0; i < 16; i++) Serial.printf("%x ", txBuffer[i]);
      Serial.print(" ... ");
      for (uint32_t i = sizeof(txBuffer) - 16; i < sizeof(txBuffer); i++) Serial.printf("%x ", txBuffer[i]);
      Serial.print("\n    RX: ");
      for (uint32_t i = 0; i < 16; i++) Serial.printf("%x ", rxBuffer[i]);
      Serial.print(" ... ");
      for (uint32_t i = sizeof(rxBuffer) - 16; i < sizeof(rxBuffer); i++) Serial.printf("%x ", rxBuffer[i]);
      Serial.println();
    }
    delay(10);
  }

  Serial.println("\nTest FlexSPI.transfer(buf, retbuf, cnt, event");
  for (uint8_t iClock = 0; iClock < COUNT_CLOCKS; iClock++) {
    Serial.printf("Speed %u Mode %x", clock_speeds[iClock],  spi_modes[iClock]);
    SPIT.beginTransaction(FlexSPISettings(clock_speeds[iClock], MSBFIRST, spi_modes[iClock]));
    for (uint32_t i = 0; i < BUFFER_SIZE; i++) {
      txBuffer[i] = i & 0xff;
      rxBuffer[i] = 0x5a;
    }
    digitalWriteFast(CS_PIN, LOW);
    uint32_t timeStart = micros();
    event_happened = false;
    SPIT.transfer(txBuffer, rxBuffer, BUFFER_SIZE, event);
    while (!event_happened) ;
    uint32_t deltaTime = micros() - timeStart;
    SPIT.endTransaction();

    uint32_t count_tx_errors = 0;
    uint32_t count_rx_errors = 0;
    uint32_t firxt_tx_error = (uint32_t) - 1;
    uint32_t firxt_rx_error = (uint32_t) - 1;
    for (uint32_t i = 0; i < BUFFER_SIZE; i++) {
      if (txBuffer[i] != (i & 0xff)) {
        count_tx_errors++;
        if (firxt_tx_error == (uint32_t) - 1) firxt_tx_error = i;
      }
      if (rxBuffer[i] != (i & 0xff)) {
        count_rx_errors++;
        if (firxt_rx_error == (uint32_t) - 1) firxt_rx_error = i;
      }
    }
    Serial.printf(" dt: %u TX Errors: %u (%u) RX Error: %u (%u)\n",
                  deltaTime, count_tx_errors, firxt_tx_error, count_rx_errors, firxt_rx_error);
    if (count_tx_errors || count_rx_errors) {
      Serial.print("    TX:");
      for (uint32_t i = 0; i < 16; i++) Serial.printf("%x ", txBuffer[i]);
      Serial.print(" ... ");
      for (uint32_t i = sizeof(txBuffer) - 16; i < sizeof(txBuffer); i++) Serial.printf("%x ", txBuffer[i]);
      Serial.print("\n    RX: ");
      for (uint32_t i = 0; i < 16; i++) Serial.printf("%x ", rxBuffer[i]);
      Serial.print(" ... ");
      for (uint32_t i = sizeof(rxBuffer) - 16; i < sizeof(rxBuffer); i++) Serial.printf("%x ", rxBuffer[i]);
      Serial.println();
    }
    delay(10);
  }


  bounce.update();
  int bounce_value = bounce.read();
  while ((DBGSerial.read() != -1) && (bounce_value))  {
    bounce.update();
    bounce_value = bounce.read();
  }
  DBGSerial.println("Press any key to rerun test");
  while ((DBGSerial.read() == -1) && (bounce_value))  {
    bounce.update();
    bounce_value = bounce.read();
  }
  if (bounce_value) {
    while (DBGSerial.read() != -1) ; // loop until queue is empty
  }
}
Test output:
Code:
SPI Test program FlexIO Clock Speed 160000000

Test FlexSPI.transfer(buf, retbuf, cnt
Speed 400000 Mode 0 dt: 5120 TX Errors: 0 (4294967295) RX Error: 0 (4294967295)
Speed 2000000 Mode 0 dt: 1025 TX Errors: 0 (4294967295) RX Error: 0 (4294967295)
Speed 4000000 Mode 0 dt: 513 TX Errors: 0 (4294967295) RX Error: 0 (4294967295)
Speed 8000000 Mode 0 dt: 257 TX Errors: 0 (4294967295) RX Error: 0 (4294967295)
Speed 15000000 Mode 0 dt: 154 TX Errors: 0 (4294967295) RX Error: 0 (4294967295)
Speed 15000000 Mode 80 dt: 154 TX Errors: 0 (4294967295) RX Error: 0 (4294967295)
Speed 20000000 Mode 0 dt: 103 TX Errors: 0 (4294967295) RX Error: 0 (4294967295)
Speed 30000000 Mode 0 dt: 77 TX Errors: 0 (4294967295) RX Error: 0 (4294967295)
Speed 40000000 Mode 0 dt: 77 TX Errors: 0 (4294967295) RX Error: 0 (4294967295)
Speed 40000000 Mode 80 dt: 62 TX Errors: 0 (4294967295) RX Error: 255 (1)
    TX:0 1 2 3 4 5 6 7 8 9 a b c d e f  ... f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 
    RX: 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7  ... 78 78 79 79 7a 7a 7b 7b 7c 7c 7d 7d 7e 7e 7f 7f 

Test FlexSPI.transfer(buf, retbuf, cnt, event
Speed 400000 Mode 0 dt: 5126 TX Errors: 0 (4294967295) RX Error: 0 (4294967295)
Speed 2000000 Mode 0 dt: 1026 TX Errors: 0 (4294967295) RX Error: 0 (4294967295)
Speed 4000000 Mode 0 dt: 514 TX Errors: 0 (4294967295) RX Error: 0 (4294967295)
Speed 8000000 Mode 0 dt: 258 TX Errors: 0 (4294967295) RX Error: 0 (4294967295)
Speed 15000000 Mode 0 dt: 155 TX Errors: 0 (4294967295) RX Error: 0 (4294967295)
Speed 15000000 Mode 80 dt: 155 TX Errors: 0 (4294967295) RX Error: 0 (4294967295)
Speed 20000000 Mode 0 dt: 104 TX Errors: 0 (4294967295) RX Error: 0 (4294967295)
Speed 30000000 Mode 0 dt: 78 TX Errors: 0 (4294967295) RX Error: 0 (4294967295)
Speed 40000000 Mode 0 dt: 79 TX Errors: 0 (4294967295) RX Error: 0 (4294967295)
Speed 40000000 Mode 80 dt: 63 TX Errors: 0 (4294967295) RX Error: 255 (1)
    TX:0 1 2 3 4 5 6 7 8 9 a b c d e f  ... f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 
    RX: 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7  ... 78 78 79 79 7a 7a 7b 7b 7c 7c 7d 7d 7e 7e 7f 7f 
Press any key to rerun test
If debug printing turned on in the FleSPI.cpp file: //#define DEBUG_FlexSPI Serial

It prints out additional info, like when the beginTransaction clock changes shows the TIMCMP register...

EDIT
- made the change to also disable 40mhz mode and added the hack SPI_MODE_TRANSMIT_ONLY
 
Last edited:
Do you have one of the breakout boards, with the switch for I2S1 vs I2S2?

If you remove the T4 and audio shield, and power it up with external 3.3V, you can check the signal paths with an ohm-meter. The switch controlls five 74LVC1G3157 analog switches, which should measure approx 6 ohms.

For I2S2, MCLK is pin 33 on the bottom side.

EDIT: for anyone who doesn't have the breakout board and wants try audio or USB host, email me directly. I have more parts coming Friday, so we should have 8 more of those available next week.

@Paul
Did as you suggest and this is what I got for SAI1:
MCLK => 23 (SAI1)
LRCLK => 20
BCLK => 21
RX => 7
TX => 6

If I can ask one more question on the D-/D+. D- is the left most pogo pin then D+ (nearest pin 0).
 
Some progress on the Compile.cmd usage for T4b. The problem is the missing SPEED menu item as it is hardcoded in boards.txt? I got over that with this edit following the harcoded speed adding hardcoded keylayout.
teensy4b.build.fcpu=396000000
teensy4b.build.keylayout=US_ENGLISH
This does not break the IDE build - but then the Compile.cmd build ends up broken with another unexpanded item :: {build.flags.ldspecs}
Code:
Linking everything together...
"T:\\arduino-1.8.8T4_146\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-gcc" -Os -Wl,--gc-sections,--relax "-TT:\\arduino-1.8.8T4_146\\hardware\\teensy\\avr\\cores\\teensy4/imxrt.ld" {build.flags.ldspecs} -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -o "T:\\TEMP\\\\arduino_build_DebugMin_tt.ino/DebugMin_tt.ino.elf" "T:\\TEMP\\arduino_build_DebugMin_tt.ino\\sketch\\DebugMin_tt.ino.cpp.o" "T:\\TEMP\\arduino_build_DebugMin_tt.ino\\libraries\\debug_tt\\debug_tt.cpp.o" "T:\\TEMP\\\\arduino_build_DebugMin_tt.ino/core\\core.a" "-LT:\\TEMP\\\\arduino_build_DebugMin_tt.ino" -larm_cortexM7lfsp_math -lm -lstdc++
arm-none-eabi-gcc: error: {build.flags.ldspecs}: No such file or directory

... Off to add a speed menu to see if that resutls in a normal build ...

Display
I must have gotten the last one they had local... I ordered it yesterday afternoon and it already shipped from California...

Took a chance as the description page said: … IC or Equivalent ILI9488

And I always hate the words (or Equivalent), but...

… I was saying this one will arrive weeks before the others … it is … xGuaranteed delivery: Monday, Feb 11, 2019

They still have two left - 3 ordered in 24 hours so that is yours and mine and another. My page shows it uses the same TOUCH controller 'Touch chip : xpt2046' from current ILI9341, but no display controller note like you show - odd.
 
... question on the D-/D+. D- is the left most pogo pin then D+ (nearest pin 0).

The D+ pogo pin is closer to GND - pin 0 - pin 1, which I usually call the bottom of the board.

The D- pogo pin is closer to VIN - GND - 3.3V, which I usually call the top of the board.
 
@mjs: Thank you :) I'll test MP3 and SID-Emulation.
@Paul: There is an updated document "Hardware Development Guide for the MIMXRT1050/MIMXRT1060Processor"
@Tim: I'll look :)

<EDIT> FRANK - updated github Tset with the changes that work for me

Opps - I saw that HDUG doc was updated - before recent post and should have included the link.

I put 600 MHz speed menu in and that did not help. When I removed the hardcoded KEYCODE - it went back to not being defined and the original fault.
teensy4b.menu.speed.600=600 MHz
teensy4b.menu.speed.600.build.fcpu=600000000

So leaving this :: teensy4b.build.keylayout=US_ENGLISH

Looks like the HEX isn't being made.
Code:
...
"T:\\arduino-1.8.8T4_146\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-size" -A "T:\\TEMP\\\\arduino_build_DebugMin_tt.ino/DebugMin_tt.ino.elf"
Sketch uses 40272 bytes (2%) of program storage space. Maximum is 1572864 bytes.
Global variables use 37568 bytes (14%) of dynamic memory, leaving 224576 bytes for local variables. Maximum is 262144 bytes.
File 'T:\TEMP\\arduino_build_DebugMin_tt.ino\DebugMin_tt.ino.teensy4b.hex' does not exist

What does exist is: "T:\TEMP\arduino_build_DebugMin_tt.ino\DebugMin_tt.ino.TEENSY40.hex"

But if the "set model=teensy4b" is replaced with "set model=teensy4b0" - then the builder fails to find it.

It works << Compile.cmd and IDE>> with this edit to boards.txt first section - I left in the menu.speed - not sure if that is required:
Code:
teensy4b.name=Teensy 4-Beta1
   //…
teensy4b.build.board=[B]TEENSY4b[/B]  [U]<< CHANGE[/U]
teensy4b.build.core=teensy4
   //…
teensy4b.build.fcpu=396000000
[B]teensy4b.build.keylayout=US_ENGLISH[/B]  [U]<< ADD[/U]

<edit>:: Just tested and the above lines for Speed menu are needed or the " {build.flags.ldspecs} " returns.

Paul is there some change needed/possible to make this build act like T.3 builds?
 
Last edited:
@Paul
Did as you suggest and this is what I got for SAI1:
MCLK => 23 (SAI1)
LRCLK => 20
BCLK => 21
RX => 7
TX => 6

If I can ask one more question on the D-/D+. D- is the left most pogo pin then D+ (nearest pin 0).

@Paul
Just sent my the board to PCBWay but will be a while - still in the New Years break. Looks like they are back Feb 11, then it will be a few more days before I get it.
 
Mike: Did you fit pins rows at 9 and 7 spacing in case it works on later boards?

note:
OSH Park only manufactures in the US, and is not affected by Chinese Lunar New Year.

Note from the ordered displays was:
I'm very sorry to inform you that we're in China Spring Festival Holiday(Jan 28th-Feb 15th) already, and some shipping agent has been stopped the shipping service also.
 
Mike: Did you fit pins rows at 9 and 7 spacing in case it works on later boards?

note:

Note from the ordered displays was:

Hi Tim
I measured tine pins at 9 and 8 from the edge pin. I checked OSHPark after I sent the oder to PCBWay but they at a lead time of 3 weeks and price was a bit high for 3 boards. I am getting 5 at $26. The board has a 5v pwr supply, a battery, on/off button and pgm button on the side. I also put the pins for the Audioshield/Propshield on the board and of course the second usb connector. So the board is rather large - 83x131 mm (3.26x5.16inches). Once I get this batch and check it out I probably will adjust the length downward. The breakout only has the edge pins broken out right now - maybe will break them out in later revisions :)

Just as a FYI, so far on my first batch of boards I never got connections right - always had to do a second.

EDIT: Wanted to add connections for a display (ILI9341 type) but wasn't 100% sure if the pinouts were the same for all the displays. Also not sure the connections for touch yet.
 
TDM:

I think I have to calculate the PLL speed for 2 x AUDIO_SAMPLE_RATE_EXACT - that allows TDM on SAI1 and I2S on SAI2, I hope -> means I have to edit i2s-output and input again.
I have all signals now, they look correct, but again no output from my CS42448 TDM-Board... lol.. I'll find the reason...

@Paul: Thank you! DHL tried to deliver, but I was not @home. They left a message and want 21€.. don't know for what :). I asked them via contact-form on their site but have no answer - have to wait for the invoice.
 
Paul has this qvgatest_touch that fits the ILI9341 - hopefully the pinout matches the new boards like Paul linked?

The Ebay unit Kurt linked is setup for rPi header to SPI - FrankB's style board would be nice there!

Just wondered about pin duplication - T4b1 is 9 pins and std T_3.2 is 7 pins tall. That is a rather LargE board! Worth the wait for cost - hopefully it runs right.

Posted updated working Tset Compile.cmd builder - working for me w/TyComm upload from SubLimeText [ very cool to click ERROR FILE and the editor opens to line with error text bubble! ]- though only fought to get two sample sketch compiles to work then chores in the snow. Nice to ignore the IDE again - and things working more smoothly without SerMon.
 
Last edited:
SPI SPISettings - Inline does not appear to inline with current stuff...

As I mentioned in previous post wondered if the current SPISettings was actually still making use of the inline stuff... The answer is no.

Simple test app:
Code:
#include <SPI.h>
uint32_t spiSpeed = 8000000;

SPISettings mySettings(8000000, MSBFIRST, SPI_MODE0);

void setup() {
  while (!Serial && millis() < 4000);
  Serial.begin(115200);
  
  SPI.begin();
  test1();
  test2();
  test3();
 }

void test1() {
  SPI.beginTransaction(mySettings);
  Serial.println(SPI.transfer(1));
  SPI.endTransaction();
}

void test2() {
  SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
  Serial.println(SPI.transfer(2));
  SPI.endTransaction();
}

void test3() {
  SPI.beginTransaction(SPISettings(spiSpeed, MSBFIRST, SPI_MODE0));
  Serial.println(SPI.transfer(3));
  SPI.endTransaction();
}

void loop() {
  
}
Then look at generated code Then look at generated code up till if(interrupt...)
For Test1: All of the init happened earlier...
Code:
0000007c <test1()>:
      7c:	b5f8      	push	{r3, r4, r5, r6, r7, lr}
      7e:	4c38      	ldr	r4, [pc, #224]	; (160 <test1()+0xe4>)

	// Before using SPI.transfer() or asserting chip select pins,
	// this function is used to gain exclusive access to the SPI bus
	// and configure the correct settings.
	void beginTransaction(SPISettings settings) {
		if (interruptMasksUsed) {
      80:	7ae24b38 	.word	0x7ae24b38
      84:	e893 0003 	ldmia.w	r3, {r0, r1}
      88:	d0282a00 	.word	0xd0282a00
			__disable_irq();

If you look at test2, with all constants passed in:
Code:
void test2() {
     194:	b5f0      	push	{r4, r5, r6, r7, lr}
		// TODO: Need to check timings as related to chip selects?
				
		const uint32_t clk_sel[4] = {664615384,  // PLL3 PFD1
					     720000000,  // PLL3 PFD0
					     528000000,  // PLL2
					     396000000}; // PLL2 PFD2				
     196:	4b4e      	ldr	r3, [pc, #312]	; (2d0 <test2()+0x13c>)
     198:	b085      	sub	sp, #20
		uint32_t cbcmr = CCM_CBCMR;
     19a:	4d4e      	ldr	r5, [pc, #312]	; (2d4 <test2()+0x140>)
		// TODO: Need to check timings as related to chip selects?
				
		const uint32_t clk_sel[4] = {664615384,  // PLL3 PFD1
					     720000000,  // PLL3 PFD0
					     528000000,  // PLL2
					     396000000}; // PLL2 PFD2				
     19c:	ae04      	add	r6, sp, #16
		uint32_t cbcmr = CCM_CBCMR;
		uint32_t clkhz = clk_sel[(cbcmr >> 4) & 0x03] / (((cbcmr >> 26 ) & 0x07 ) + 1);  // LPSPI peripheral clock
		
		uint32_t d, div;		
		if (clock == 0) clock =1;
		d= clkhz/clock;
     19e:	4c4e      	ldr	r4, [pc, #312]	; (2d8 <test2()+0x144>)
		// TODO: Need to check timings as related to chip selects?
				
		const uint32_t clk_sel[4] = {664615384,  // PLL3 PFD1
					     720000000,  // PLL3 PFD0
					     528000000,  // PLL2
					     396000000}; // PLL2 PFD2				
     1a0:	cb0f      	ldmia	r3, {r0, r1, r2, r3}
     1a2:	e906 000f 	stmdb	r6, {r0, r1, r2, r3}
		uint32_t cbcmr = CCM_CBCMR;
     1a6:	69ab      	ldr	r3, [r5, #24]
		uint32_t clkhz = clk_sel[(cbcmr >> 4) & 0x03] / (((cbcmr >> 26 ) & 0x07 ) + 1);  // LPSPI peripheral clock
     1a8:	f3c3 1201 	ubfx	r2, r3, #4, #2
     1ac:	f3c3 6382 	ubfx	r3, r3, #26, #3
     1b0:	eb06 0282 	add.w	r2, r6, r2, lsl #2
     1b4:	3301      	adds	r3, #1
     1b6:	f852 2c10 	ldr.w	r2, [r2, #-16]
     1ba:	fbb2 f2f3 	udiv	r2, r2, r3
		
		uint32_t d, div;		
		if (clock == 0) clock =1;
		d= clkhz/clock;
     1be:	fba4 1302 	umull	r1, r3, r4, r2
		if (d && clkhz/d > clock) d++;
     1c2:	0d5b      	lsrs	r3, r3, #21
     1c4:	d00a      	beq.n	1dc <test2()+0x48>
     1c6:	4945      	ldr	r1, [pc, #276]	; (2dc <test2()+0x148>)
     1c8:	fbb2 f2f3 	udiv	r2, r2, r3
     1cc:	428a      	cmp	r2, r1
     1ce:	bf88      	it	hi
     1d0:	3301      	addhi	r3, #1
		if (d > 257) d= 257;  // max div
     1d2:	f5b3 7f81 	cmp.w	r3, #258	; 0x102
     1d6:	d371      	bcc.n	2bc <test2()+0x128>
     1d8:	f647 73ff 	movw	r3, #32767	; 0x7fff

	// Before using SPI.transfer() or asserting chip select pins,
	// this function is used to gain exclusive access to the SPI bus
	// and configure the correct settings.
	void beginTransaction(SPISettings settings) {
		if (interruptMasksUsed) {
     1dc:	4c40      	ldr	r4, [pc, #256]	; (2e0 <test2()+0x14c>)
     1de:	7ae2      	ldrb	r2, [r4, #11]
     1e0:	2a00      	cmp	r2, #0
     1e2:	d028      	beq.n	236 <test2()+0xa2>
Which is very similar to test3 where we use a variable:
Code:
void test3() {
     310:	b570      	push	{r4, r5, r6, lr}
		// TODO: Need to check timings as related to chip selects?
				
		const uint32_t clk_sel[4] = {664615384,  // PLL3 PFD1
					     720000000,  // PLL3 PFD0
					     528000000,  // PLL2
					     396000000}; // PLL2 PFD2				
     312:	4b4f      	ldr	r3, [pc, #316]	; (450 <test3()+0x140>)
     314:	b084      	sub	sp, #16
		uint32_t cbcmr = CCM_CBCMR;
     316:	4d4f      	ldr	r5, [pc, #316]	; (454 <test3()+0x144>)
		// TODO: Need to check timings as related to chip selects?
				
		const uint32_t clk_sel[4] = {664615384,  // PLL3 PFD1
					     720000000,  // PLL3 PFD0
					     528000000,  // PLL2
					     396000000}; // PLL2 PFD2				
     318:	ae04      	add	r6, sp, #16
  SPI.beginTransaction(SPISettings(spiSpeed, MSBFIRST, SPI_MODE0));
     31a:	4c4f      	ldr	r4, [pc, #316]	; (458 <test3()+0x148>)
     31c:	cb0f      	ldmia	r3, {r0, r1, r2, r3}
     31e:	e906 000f 	stmdb	r6, {r0, r1, r2, r3}
		uint32_t cbcmr = CCM_CBCMR;
     322:	69ab      	ldr	r3, [r5, #24]
     324:	6822      	ldr	r2, [r4, #0]
		uint32_t clkhz = clk_sel[(cbcmr >> 4) & 0x03] / (((cbcmr >> 26 ) & 0x07 ) + 1);  // LPSPI peripheral clock
     326:	f3c3 1101 	ubfx	r1, r3, #4, #2
     32a:	f3c3 6382 	ubfx	r3, r3, #26, #3
		
		uint32_t d, div;		
		if (clock == 0) clock =1;
     32e:	2a00      	cmp	r2, #0
		const uint32_t clk_sel[4] = {664615384,  // PLL3 PFD1
					     720000000,  // PLL3 PFD0
					     528000000,  // PLL2
					     396000000}; // PLL2 PFD2				
		uint32_t cbcmr = CCM_CBCMR;
		uint32_t clkhz = clk_sel[(cbcmr >> 4) & 0x03] / (((cbcmr >> 26 ) & 0x07 ) + 1);  // LPSPI peripheral clock
     330:	eb06 0181 	add.w	r1, r6, r1, lsl #2
     334:	f103 0301 	add.w	r3, r3, #1
		
		uint32_t d, div;		
		if (clock == 0) clock =1;
     338:	bf08      	it	eq
     33a:	2201      	moveq	r2, #1
		const uint32_t clk_sel[4] = {664615384,  // PLL3 PFD1
					     720000000,  // PLL3 PFD0
					     528000000,  // PLL2
					     396000000}; // PLL2 PFD2				
		uint32_t cbcmr = CCM_CBCMR;
		uint32_t clkhz = clk_sel[(cbcmr >> 4) & 0x03] / (((cbcmr >> 26 ) & 0x07 ) + 1);  // LPSPI peripheral clock
     33c:	f851 1c10 	ldr.w	r1, [r1, #-16]
     340:	fbb1 f3f3 	udiv	r3, r1, r3
		
		uint32_t d, div;		
		if (clock == 0) clock =1;
		d= clkhz/clock;
     344:	fbb3 f1f2 	udiv	r1, r3, r2
		if (d && clkhz/d > clock) d++;
     348:	b149      	cbz	r1, 35e <test3()+0x4e>
     34a:	fbb3 f3f1 	udiv	r3, r3, r1
     34e:	429a      	cmp	r2, r3
     350:	bf38      	it	cc
     352:	3101      	addcc	r1, #1
		if (d > 257) d= 257;  // max div
     354:	f5b1 7f81 	cmp.w	r1, #258	; 0x102
     358:	d370      	bcc.n	43c <test3()+0x12c>
     35a:	f647 71ff 	movw	r1, #32767	; 0x7fff

	// Before using SPI.transfer() or asserting chip select pins,
	// this function is used to gain exclusive access to the SPI bus
	// and configure the correct settings.
	void beginTransaction(SPISettings settings) {
		if (interruptMasksUsed) {
     35e:	4c3f      	ldr	r4, [pc, #252]	; (45c <test3()+0x14c>)
     360:	7ae3      	ldrb	r3, [r4, #11]
     362:	2b00      	cmp	r3, #0
     364:	d028      	beq.n	3b8 <test3()+0xa8>
			__disable_irq();
If I build it for Teensy 3.6... Test1 is more or less the same...
Code:
void test1() {
     46c:	b538      	push	{r3, r4, r5, lr}

	// Before using SPI.transfer() or asserting chip select pins,
	// this function is used to gain exclusive access to the SPI bus
	// and configure the correct settings.
	void beginTransaction(SPISettings settings) {
		if (interruptMasksUsed) {
     46e:	4c33      	ldr	r4, [pc, #204]	; (53c <test1()+0xd0>)
     470:	4b33      	ldr	r3, [pc, #204]	; (540 <test1()+0xd4>)
     472:	7ae2      	ldrb	r2, [r4, #11]
     474:	681b      	ldr	r3, [r3, #0]
     476:	b302      	cbz	r2, 4ba <test1()+0x4e>
			__disable_irq();
And as expected test2 is using the inline code removed as it can fill in the two members with constants:
Code:
void test2() {
     570:	b538      	push	{r3, r4, r5, lr}

	// Before using SPI.transfer() or asserting chip select pins,
	// this function is used to gain exclusive access to the SPI bus
	// and configure the correct settings.
	void beginTransaction(SPISettings settings) {
		if (interruptMasksUsed) {
     572:	4c32      	ldr	r4, [pc, #200]	; (63c <test2()+0xcc>)
     574:	7ae3      	ldrb	r3, [r4, #11]
     576:	2b00      	cmp	r3, #0
     578:	d026      	beq.n	5c8 <test2()+0x58>
			__disable_irq();

Test3: Again only when you pass in variables does it have to execute code
Code:
void test3() {
     678:	b570      	push	{r4, r5, r6, lr}
  SPI.beginTransaction(SPISettings(spiSpeed, MSBFIRST, SPI_MODE0));
     67a:	2200      	movs	r2, #0
     67c:	681d      	ldr	r5, [r3, #0]
				t = SPI_CTAR_PBR(1) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7);
			}
		} else {
			for (uint32_t i=0; i<23; i++) {
				t = ctar_clock_table[i];
				if (clock >= F_BUS / ctar_div_table[i]) break;
     67e:	4c3d      	ldr	r4, [pc, #244]	; (774 <test3()+0x100>)
     680:	e002      	b.n	688 <test3()+0x14>
				t = SPI_CTAR_PBR(2) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6);
			} else {	 /* F_BUS / 768 */
				t = SPI_CTAR_PBR(1) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7);
			}
		} else {
			for (uint32_t i=0; i<23; i++) {
     682:	2917      	cmp	r1, #23
     684:	d008      	beq.n	698 <test3()+0x24>
     686:	460a      	mov	r2, r1
				t = ctar_clock_table[i];
				if (clock >= F_BUS / ctar_div_table[i]) break;
     688:	f830 3f02 	ldrh.w	r3, [r0, #2]!
     68c:	fb94 f3f3 	sdiv	r3, r4, r3
     690:	429d      	cmp	r5, r3
				t = SPI_CTAR_PBR(2) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6);
			} else {	 /* F_BUS / 768 */
				t = SPI_CTAR_PBR(1) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7);
			}
		} else {
			for (uint32_t i=0; i<23; i++) {
     692:	f102 0101 	add.w	r1, r2, #1
				t = ctar_clock_table[i];
				if (clock >= F_BUS / ctar_div_table[i]) break;
     696:	d3f4      	bcc.n	682 <test3()+0xe>
			} else {	 /* F_BUS / 768 */
				t = SPI_CTAR_PBR(1) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7);
			}
		} else {
			for (uint32_t i=0; i<23; i++) {
				t = ctar_clock_table[i];
     698:	4b37      	ldr	r3, [pc, #220]	; (778 <test3()+0x104>)

	// Before using SPI.transfer() or asserting chip select pins,
	// this function is used to gain exclusive access to the SPI bus
	// and configure the correct settings.
	void beginTransaction(SPISettings settings) {
		if (interruptMasksUsed) {
     69a:	4c38      	ldr	r4, [pc, #224]	; (77c <test3()+0x108>)
			} else {	 /* F_BUS / 768 */
				t = SPI_CTAR_PBR(1) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7);
			}
		} else {
			for (uint32_t i=0; i<23; i++) {
				t = ctar_clock_table[i];
     69c:	f853 3022 	ldr.w	r3, [r3, r2, lsl #2]

	// Before using SPI.transfer() or asserting chip select pins,
	// this function is used to gain exclusive access to the SPI bus
	// and configure the correct settings.
	void beginTransaction(SPISettings settings) {
		if (interruptMasksUsed) {
     6a0:	7ae2      	ldrb	r2, [r4, #11]
		}
		if (dataMode & 0x04) {
			c |= SPI_CTAR_CPHA;
			t = (t & 0xFFFF0FFF) | ((t & 0xF000) >> 4);
		}
		ctar = c | t;
     6a2:	f043 5160 	orr.w	r1, r3, #939524096	; 0x38000000

	// Before using SPI.transfer() or asserting chip select pins,
	// this function is used to gain exclusive access to the SPI bus
	// and configure the correct settings.
	void beginTransaction(SPISettings settings) {
		if (interruptMasksUsed) {
     6a6:	b302      	cbz	r2, 6ea <test3()+0x76>
			__disable_irq();
Again not sure what is the best thing to do here for T4. Obviously an app can create a SPISettings object at their begin and use it, which would give you fastest/smallest code. I suggested that maybe the SPISettings in this case could simply hold onto their values and beginTransaction could see if settings changed and if so do the calculations... That is what I do in the flex code.

Now back to playing
 
Status
Not open for further replies.
Back
Top