KurtE
Senior Member+
Note: I put in a Pull Request to core project to fix DMAChannel.h issue I mentioned.
I now hae test program driving 3 Teensyview displays. The Test code is a mess, but, it tries to run each of the tests or partial tests without blocking the rest of the system. I had them running with no delays and I had the my Logic analyzer showing two of the three buses:
with MOSI, SCLK, CS, DC So the two were using all 8 channels.
Maybe later will use my older 16 channel one for all three buses. ...
This appears to be working well enough to beat up SPI Async code... So far so good for T3.6. Probably next setup will be to try on
T3.5 all three busses. Then T3.2 1 and TLC 2...
I now hae test program driving 3 Teensyview displays. The Test code is a mess, but, it tries to run each of the tests or partial tests without blocking the rest of the system. I had them running with no delays and I had the my Logic analyzer showing two of the three buses:
with MOSI, SCLK, CS, DC So the two were using all 8 channels.
Maybe later will use my older 16 channel one for all three buses. ...
This appears to be working well enough to beat up SPI Async code... So far so good for T3.6. Probably next setup will be to try on
T3.5 all three busses. Then T3.2 1 and TLC 2...
Code:
#include <SPI.h>
#include <TeensyView.h> // Include the SFE_TeensyView library
///////////////////////////////////
// TeensyView Object Declaration //
///////////////////////////////////
//#define TLC_SPI1
//#define T36_SPI1
//#define T36_SPI2
//#define DEFAULT_PINS
#ifdef DEFAULT_PINS
#define PIN_RESET 15
#define PIN_DC 5
#define PIN_CS 10
#define PIN_SCK 13
#define PIN_MOSI 11
#endif
#ifdef TLC_SPI1
#define PIN_RESET 15
#define PIN_SCK 20
#define PIN_MOSI 21
#define PIN_DC 4
#define PIN_CS 3
#endif
#ifdef T36_SPI1
#define PIN_RESET 15
#define PIN_SCK 20
#define PIN_MOSI 21
#define PIN_DC 31
#define PIN_CS 32
#endif
#ifdef T36_SPI2
#define PIN_RESET 15
#define PIN_SCK 53
#define PIN_MOSI 52
#define PIN_DC 55
#define PIN_CS 51
#endif
// Kurt's setup
#ifndef PIN_SCK
#define PIN_RESET 15
#define PIN_SCK 13
#define PIN_MOSI 11
#define PIN_DC 21
#define PIN_CS 20
// Setup 2nd one SPI1
#define PIN_RESET1 16
#define PIN_SCK1 32
#define PIN_MOSI1 0
#define PIN_DC1 31
#define PIN_CS1 30
// Pins on connector on Beta T3.6 board (3.3, GND)(48, 47)(57 56) (51 52) (53 55)
#define PIN_RESET2 48
//#define PIN_MISO2 51
#define PIN_MOSI2 52
#define PIN_SCK2 53
#define PIN_DC2 55
#define PIN_CS2 56
#endif
TeensyView oled(PIN_RESET, PIN_DC, PIN_CS, PIN_SCK, PIN_MOSI);
TeensyView oled1(PIN_RESET1, PIN_DC1, PIN_CS1, PIN_SCK1, PIN_MOSI1, 64);
TeensyView oled2(PIN_RESET2, PIN_DC2, PIN_CS2, PIN_SCK2, PIN_MOSI2);
TeensyView *oleds[] = {&oled, &oled1, &oled2};
uint8_t oled_which_test[] = {0, 0, 0};
uint16_t test_iterations_left[] = {0xffff, 0xffff, 0xffff};
uint32_t last_test_start_time[] = {0, 0, 0};
uint32_t next_test_start_time[] = {0, 0, 0};
extern void testRects(TeensyView *_oled, bool draw_async, uint16_t &iterations_left);
extern void testCircles(TeensyView *_oled, bool draw_async, uint16_t &iterations_left);
extern void TestpixelsAsync(TeensyView *_oled, uint16_t &iterations_left);
extern void TestFillRects(TeensyView *_oled, uint16_t &iterations_left);
extern void testdrawline(TeensyView *_oled, uint16_t &iterations_left, uint32_t &next_test_start_time);
void setup()
{
while (!Serial && millis() < 3000);
Serial.begin(38400);
oled.begin(); // Initialize the OLED
oled.clear(HARDWARE_MEM); // Clear the display's internal memory
oled.display(); // Display what's in the buffer (splashscreen)
oled1.begin(); // Initialize the OLED
oled1.clear(HARDWARE_MEM); // Clear the display's internal memory
oled1.display(); // Display what's in the buffer (splashscreen)''
Serial.println("oled1 displayed");
oled2.begin(); // Initialize the OLED
oled2.clear(HARDWARE_MEM); // Clear the display's internal memory
oled2.display(); // Display what's in the buffer (splashscreen)''
Serial.println("oled2 displayed");
delay(1000); // Delay 1000 ms
oled.clear(HARDWARE_MEM); // Clear the buffer.
oled1.clear(HARDWARE_MEM); // Clear the buffer.
oled2.clear(HARDWARE_MEM);
randomSeed(analogRead(A0) + analogRead(A1));
}
void loop()
{
// Lets see which of our displays is ready to display something different
for (uint8_t i = 0; i < sizeof(oleds)/sizeof(oleds[0]); i++ ) {
if ((millis() > next_test_start_time[i]) &&!oleds[i]->displayAsyncActive()) {
last_test_start_time[i] = millis();
switch(oled_which_test[i]) {
case 0:
testRects(oleds[i], true, test_iterations_left[i]);
break;
case 1:
testRects(oleds[i], true, test_iterations_left[i]);
break;
case 2:
TestpixelsAsync(oleds[i], test_iterations_left[i]);
break;
case 3:
TestFillRects(oleds[i], test_iterations_left[i]);
break;
case 4:
testdrawline(oleds[i], test_iterations_left[i], next_test_start_time[i]);
break;
}
if (test_iterations_left[i] == 0) {
oled_which_test[i]++;
if (oled_which_test[i] > 4)
oled_which_test[i] = 0;
test_iterations_left[i] = 0xffff; // mark it special for first call
next_test_start_time[i] = millis() + 100;
}
} else if ((millis()-last_test_start_time[i]) > 500) {
Serial.printf("Oled %d hung test: %d iter: %d\n ", i, oled_which_test[i], test_iterations_left[i]);
last_test_start_time[i] = millis();
}
}
}
void testRects(TeensyView *_oled, bool draw_async, uint16_t &iterations_left) {
int n, i, i2;
int cx = _oled->getLCDWidth() / 2;
int cy = _oled->getLCDHeight() / 2;
_oled->clear(PAGE);
n = min( _oled->getLCDWidth(), _oled->getLCDHeight());
for(i=2; i<n; i+=6) {
i2 = i / 2;
_oled->rect(cx-i2, cy-i2, i, i);
}
if (draw_async) {
_oled->displayAsync();
} else {
_oled->display();
}
iterations_left = 0;
}
void testCircles(TeensyView *_oled, bool draw_async, uint16_t &iterations_left) {
uint16_t radius = 10;
int x, y, r2 = radius * 2,
w =_oled->getLCDWidth() + radius,
h = _oled->getLCDHeight() + radius;
_oled->clear(PAGE);
for(x=0; x<w; x+=r2) {
for(y=0; y<h; y+=r2) {
_oled->circle(x, y, radius);
}
}
if (draw_async) {
_oled->displayAsync();
} else {
_oled->display();
}
iterations_left = 0;
}
void TestpixelsAsync(TeensyView *_oled, uint16_t &iterations_left)
{
if (iterations_left == 0xffff) {
_oled->clear(PAGE);
iterations_left = 1024;
}
_oled->pixel(random(_oled->getLCDWidth()), random(_oled->getLCDHeight()));
_oled->displayAsync();
iterations_left--;
}
void TestFillRects(TeensyView *_oled, uint16_t &iterations_left)
{
if (iterations_left == 0xffff) {
_oled->clear(PAGE);
iterations_left = 0; // Not really, but makes it simple as we will update
}
_oled->rectFill(iterations_left, iterations_left,
_oled->getLCDWidth()-iterations_left*2, _oled->getLCDHeight()-iterations_left*2, (iterations_left&1)?0 : 1, NORM);
_oled->displayAsync();
iterations_left += 3;
if (iterations_left >= _oled->getLCDHeight()/2) {
iterations_left = 0; // we are done.
}
}
void testdrawline(TeensyView *_oled, uint16_t &iterations_left, uint32_t &next_test_start_time) {
//Serial.printf("testDrawline %x %x\n", _oled, iterations_left);
if (iterations_left == 0xffff) {
_oled->clear(PAGE);
iterations_left = 0; // Not really, but makes it simple as we will update
}
uint8_t line_test = iterations_left >> 8;
uint8_t i = iterations_left & 0xff;
switch(line_test) {
case 0:
_oled->line(0, 0, i, _oled->getLCDHeight()-1);
_oled->displayAsync();
i+=4;
if (i >= _oled->getLCDWidth()) {
i = 0;
line_test++;
}
break;
case 1:
_oled->line(0, 0, _oled->getLCDWidth()-1, i);
_oled->displayAsync();
i+=4;
if (i >= _oled->getLCDHeight()) {
i = 0;
line_test++;
next_test_start_time = millis()+250;
}
case 2:
if (i == 0) {
_oled->clear(PAGE);
}
_oled->line(0, _oled->getLCDHeight()-1, i, 0);
_oled->displayAsync();
i+=4;
if (i >= _oled->getLCDWidth()) {
i = 0;
line_test++;
}
break;
case 3:
_oled->line(0, _oled->getLCDHeight()-1, _oled->getLCDWidth()-1, i);
_oled->displayAsync();
i+=4;
if (i >= _oled->getLCDHeight()) {
i = 0;
line_test++;
next_test_start_time = millis()+250;
}
break;
case 4:
if (i == 0) {
_oled->clear(PAGE);
}
_oled->line(_oled->getLCDWidth()-1, _oled->getLCDHeight()-1, i, 0);
_oled->displayAsync();
i+=4;
if (i >= _oled->getLCDWidth()) {
i = 0;
line_test++;
}
break;
case 5:
_oled->line(_oled->getLCDWidth()-1, _oled->getLCDHeight()-1, 0, i);
_oled->displayAsync();
i+=4;
if (i >= _oled->getLCDHeight()) {
i = 0;
line_test++;
next_test_start_time = millis()+250;
}
break;
case 6:
if (i == 0) {
_oled->clear(PAGE);
}
_oled->line(_oled->getLCDWidth()-1, 0, 0, i);
_oled->displayAsync();
i+=4;
if (i >= _oled->getLCDHeight()) {
i = 0;
line_test++;
}
break;
case 7:
_oled->line(_oled->getLCDWidth()-1, 0, i, _oled->getLCDHeight()-1);
_oled->displayAsync();
i+=4;
if (i >= _oled->getLCDWidth()) {
i = 0;
line_test = 0; // Say we are done
}
}
iterations_left = (line_test << 8) | i;
}