It does not look like my display (mine is greenKurt 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:
#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
}
}
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
/**************************************************************************
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);
}
}
}
}
}
}
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...
This ILI9488 will be a good place to start- I just ordered a pair from your AliExp link to be delivered in hopefully under 42 days … maybe longer …
set model=teensy4b
set speed=60
set opt=o2std
set usb=serial
"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),
"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
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.
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
SPIT.beginTransaction(FlexSPISettings(clock_speeds[iClock], MSBFIRST, SPI_MODE0))
SPIT.beginTransaction(FlexSPISettings(clock_speeds[iClock], MSBFIRST, SPI_MODE0 | SPI_WRITE_ONLY))
#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
}
}
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
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.
This does not break the IDE build - but then the Compile.cmd build ends up broken with another unexpanded item :: {build.flags.ldspecs}teensy4b.build.fcpu=396000000
teensy4b.build.keylayout=US_ENGLISH
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
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...
... question on the D-/D+. D- is the left most pogo pin then D+ (nearest pin 0).
@mjs: Thank youI'll test MP3 and SID-Emulation.
@Paul: There is an updated document "Hardware Development Guide for the MIMXRT1050/MIMXRT1060Processor"
@Tim: I'll look![]()
teensy4b.menu.speed.600=600 MHz
teensy4b.menu.speed.600.build.fcpu=600000000
...
"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
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]
@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).
OSH Park only manufactures in the US, and is not affected by Chinese Lunar New Year.
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:
Yes, some patch-wires will do until then-- I decided to wait for the final t4-pinout before I order the board.The Ebay unit Kurt linked is setup for rPi header to SPI - FrankB's style board would be nice there!
#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() {
}
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();
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>
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();
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();
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();
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();