PDA

View Full Version : Teensy 3.0 /3.1 + W5100 ethernet shield.



Julien.bresciani
02-05-2014, 03:23 PM
Hi Paul,

First I thank you immensely for making such a nice product, this is my first steps in microcontrollers /embedded electronics, your product is so tiny and can become a real use in everyday life.
I m working with a colleague on a wireless project, and try to use the RFM 22 from hoperf in combination with the arduino ethernet shield.

Im just trying to make these work together at this time.

first point :

While playing with the ethernet shield + teensy inside arduino IDE, I have tried to relocate the SPI SS pin of the arduino shield.

Unfortunately, arduino developpers made a lot of stuff very static and never thougt material possibilities will evolve very quickly, so the ss pin is defined statically somewhere in the libraries.

The caveat in the arduino IDE : it seems to be impossible to simply override a static definition #DEFINE made in a library you are including just by putting a #DEFINE inside your sketch e.g :

inside W5100.cpp :
#define W5200_SS_PIN 10

If I want to change from my sketch this definition, I found no else mean than editing directly the W5100.cpp and changing the #define W5200_SS_PIN wich may seem an easy job, but when you begin to have multiple peripherals, going inside each .h or .cpp file may become difficult.
a call to a very General file like Global_definitions.h where you could put all your #DEFINES overrides could be a good idea inside the arduino IDE, this .h file should just be called inside each already existing arduino library.
Nevertheless, this point is just to have your mind about it, since i think you may suffer from the lack of flexibility of the arduino libs (interrupts, ans SPI specillay.

second point (and more relating to the teensy):

While poking around this library, I noticed the PIN 10 was hardcoded inside W5100.h (libraries/Ethernet/utility)
So i did this small change to the .h :
replaced the static pin number by the defined variable W5200_SS_PIN
moved the #DEFINE W5200_SS_PIN from w5100.cpp to w5100.h for this variable to be set and not having compilation errors.

so inside w5100.h i got :
at the top of the file :


#ifndef W5100_H_INCLUDED
#define W5100_H_INCLUDED

#include <avr/pgmspace.h>
#include <SPI.h>

#define MAX_SOCK_NUM 4
#define W5200_SS_PIN 6


line 323 :


/*#elif defined(__MK20DX128__)
// ugly static pin definition.
inline static void initSS() { pinMode(10, OUTPUT); };
inline static void setSS() { digitalWriteFast(10, LOW); };
inline static void resetSS() { digitalWriteFast(10, HIGH); };
*/

#elif defined(__MK20DX128__)
// try this instead
inline static void initSS() { pinMode(W5200_SS_PIN, OUTPUT); };
inline static void setSS() { digitalWriteFast(W5200_SS_PIN, LOW); };
inline static void resetSS() { digitalWriteFast(W5200_SS_PIN, HIGH); };


and got rid of the W5200_SS_PIN 6 inside the W5100.cpp file (line 29).

did the test with teensy 3.0 + arduino ethernet shield REV 3, the webserver example runs successfully.

as my experience is very low in programmation and microcontrollers world, I hope my analysis and correction is correct and is improving a bit the code.

hope you can integrate this in the next teensyduino or push it directly through arduino IDE.

Regards.

Headroom
02-05-2014, 05:07 PM
Hi Julien,

Welcome to the forum. Did your mdification work past having compilation errors ? Or, in other words, were you able to establish a connection between teh Ethernet Shiled and perhaps a router ?

The Ethernet shield is a rater outdated product and uses the older W5100 Ethernet chip. Newer products like the WIZ820io (http://www.saelig.com/product/BRD032.htm) embedded Ethernet Module use the W5200. I am not at my home computer at the moment but I believe the W5200 pin definition will not change the SS pin assignement on the W5100 based ethernet shield.

BTW, PJRC makes an adapter board (http://www.pjrc.com/store/wiz820_sd_adaptor.html)for the WIZ820io and that combo works out of the box with the Ethernet Library. In fact the Teesnyduino 1.18RC2 Ethernet Library contains an autodetect mechanism for the W5100/W5200 chip. For that to function, however, you'll have to leave the SS pin assignent as they are. That is also very likely the reason for the current implementation.

stevech
02-05-2014, 06:18 PM
On the Teensy 3, is the normal SPI hardware operation that, with the Teensy 3 in master mode, the SS pin is asserted by the SPI hardware rather than by software?

Julien.bresciani
02-06-2014, 12:00 AM
Thanks for your precisions,

My modification was compiled successfully and I was able to run the webserver sketch and get the data through my web browser given in the ethernet examples. I dont think my modification is much clever, but it may add a little bit flexibility for some use cases.

I ll have a look at the teensyduino 1.18RC2, actually running 1.17 and check if there is noticeable differences in the W5100.h.

The problem to leave these SS pins hardcoded is the lack of flexibility , since in our project, we ll run two SPI slave chips : RFM22 and ethernet stuff, We have to move One SS pin to the other harware SS pins available on the teensy,pin 6 for example (I still didnt check deeply in the code if PJRC is using the hardware capable SS (called PCS in the MK20 datasheet.) )

I ll have a look to the WIZ820io an try to procure it quickly, it may solve some issues.

For the moment I m able to play with the RFM22 in SPI with the teensy, able to play with the ethernet shield, but while using them together, I have some unresolved issues at this time.

For being rid of clock problems , I took a common denominator for the CLK frequency (wich I reallocated to PIN14 for being able to use integrated LED). but I still dont understand if there is the possibility to change the clock speed on each SS assertion to be able to manage two devices with two different clock speeds.

a nice thing to prototype ethernet applications on the teensy would be to implement an USBnet profile to be able to connect the teensy through a logical usb network interface (USB0 under linux) like most of android phones are emulating. :-) (I d like to see how much useful and versatile stuff of this kind resides on Pauls todo list).

Regards.


Hi Julien,

Welcome to the forum. Did your mdification work past having compilation errors ? Or, in other words, were you able to establish a connection between teh Ethernet Shiled and perhaps a router ?

The Ethernet shield is a rater outdated product and uses the older W5100 Ethernet chip. Newer products like the WIZ820io (http://www.saelig.com/product/BRD032.htm) embedded Ethernet Module use the W5200. I am not at my home computer at the moment but I believe the W5200 pin definition will not change the SS pin assignement on the W5100 based ethernet shield.

BTW, PJRC makes an adapter board (http://www.pjrc.com/store/wiz820_sd_adaptor.html)for the WIZ820io and that combo works out of the box with the Ethernet Library. In fact the Teesnyduino 1.18RC2 Ethernet Library contains an autodetect mechanism for the W5100/W5200 chip. For that to function, however, you'll have to leave the SS pin assignent as they are. That is also very likely the reason for the current implementation.

nikorun
11-27-2014, 07:45 AM
Hi,

Despite this discussion is rather old, this is one of the rare source of information concerning the use of w5100 chip with teensy3.1.
I will try theses hacks to make them run together.

Just to add some information, i just mentionned another post from Paul Stoffregen concerning this subject (here (http://www.adafruit.com/blog/2012/10/19/teensy-3-0-software-update/)):

"If you do try Ethernet, please keep in mind the Wiznet W5100 chip draws more than the 100 mA current Teensy 3.0 can provide on the 3.3 volt pin. An external regulator or source of power for the W5100 is needed."

i guess this could concern the issue that Julien faces when using the w5100 together with another SPI module.

Bye,

nicolas

PaulStoffregen
11-27-2014, 10:53 AM
W5100 should work with Teensy 3.0 and 3.1. I have tested it several times, though not recently. Little has changed with that code, so I believe it will work.

Aside from the power issue, which is easy to spot by simply watching the 3.3V line with a voltmeter, there's a known issue with the W5100 tri-state on MISO. Wiznet documents a workaround in an app note, where chip select connects to 2 places. You must use that workaround, or a tri-state buffer, to make the W5100 work together with any other SPI device. Arduino's ethernet shield has the MISO workaround. Other boards may or may not have it.

I recently wrote a blog article about SPI sharing issues. It describes simple test with 2 resistors and a voltmeter, to tell if you have the MISO tri-state issue.

http://www.dorkbotpdx.org/blog/paul/better_spi_bus_design_in_3_steps

nikorun
11-27-2014, 11:20 AM
W5100 should work with Teensy 3.0 and 3.1. I have tested it several times, though not recently. Little has changed with that code, so I believe it will work.

Aside from the power issue, which is easy to spot by simply watching the 3.3V line with a voltmeter, there's a known issue with the W5100 tri-state on MISO. Wiznet documents a workaround in an app note, where chip select connects to 2 places. You must use that workaround, or a tri-state buffer, to make the W5100 work together with any other SPI device. Arduino's ethernet shield has the MISO workaround. Other boards may or may not have it.

I recently wrote a blog article about SPI sharing issues. It describes simple test with 2 resistors and a voltmeter, to tell if you have the MISO tri-state issue.

http://www.dorkbotpdx.org/blog/paul/better_spi_bus_design_in_3_steps

Hi Paul thanks to come back in this discussion.

I'm not involved with SPI sharing problem, as I plan to only use a single W5100 with my teensy31, and nothing else. but I pomise that as soon as I come back home, I will try to make a w5100 work with my teensy (actualy one of the half dozen teensy o have .. :) ). And let you know if it works. This will help me to avoid the use of a mega and then make benefit of the ARM proc for my Modbus gateway :!!


Nicolas

PaulStoffregen
11-27-2014, 12:07 PM
Are you using Serial1.transmitterEnable() to control the RS-485 chip for Modbus?

nikorun
11-27-2014, 01:07 PM
Well, in previous times I deeply read your comments on DE facility shiped with teensy, wich has been very usefull for a slave libray i used before (see here (http://forum.pjrc.com/threads/25724-Need-Help-porting-Modbus-lib)).

But the library I use now (ModbusMaster Written by Doc Walker) does not seem to use this functionality, so I added a few lines to switch RTS_PIN to high just before sending DATA to Modbus line (and of course set it to LOW after ...)
I'm not a king of programming so this is the way I choosed to permit clean sent of DATA but I suppose there is a clever way to do it ...

Finaly, it seems to work well as I can see it through the graph joined.
3009

nicolas

local_dani_21
02-26-2015, 10:14 PM
Hi all
I'm trying to use an official ethernet shield (R3, with W5100) with a teensy 3.1 (using pin 10 as W5100-CS). Ethernet runs well by itself. But I run into trouble as soon as I insert (!) an SD card into it's slot (CS for SD is pin 9). Then SPI seems to stop working until the SD card is removed again. Could this have something to do with the missing tri state of the W5100 as mentioned above?

That is the sketch I'm running:

/* Web client */

#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xE1 };
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(74,125,232,128); // numeric IP for Google (no DNS)
//char server[] = "www.google.com"; // name address for Google (using DNS)
IPAddress server(192,168,1,1);

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192,168,1,2);

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

void setup() {
// Open serial communications and wait for port to open:
Serial.begin(57600);
while (!Serial) {
; // wait for serial port to connect.
}
Serial.println("Hello");

// start the Ethernet connection:
Ethernet.begin(mac, ip);
// give the Ethernet shield a second to initialize:
delay(2000);
Serial.print("My IP address: ");
Serial.println(Ethernet.localIP());
Serial.println("Setup done, all clear!"); Serial.println("connecting...");

// if you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.println(" connected.");
// Make a HTTP request:
client.println("GET /index.html HTTP/1.1");
client.println("Host: 192.168.1.1");
client.println("Connection: close");
client.println();
}
else {
// kf you didn't get a connection to the server:
Serial.println("connection failed.");
}
}

void loop()
{
// if there are incoming bytes available
// from the server, read them and print them:
if (client.available()) {
char c = client.read();
Serial.print(c);
}

// if the server's disconnected, stop the client:
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();

// do nothing forevermore:
while(true){Serial.println("ok"); delay(10000);}
}
}
Serial monitor shows

Hello
My IP address: 192.168.1.2
Setup done, all clear!
connecting...
connected.
HTTP/1.1 200 OK
Date: Thu, 26 Feb 2015 21:18:53 GMT
Server: Apache/2.4.10 (Raspbian)
Last-Modified: Sat, 14 Feb 2015 14:58:27 GMT
ETag: "3d-50f0d95e3c80c"
Accept-Ranges: bytes
Content-Length: 61
Connection: close
Content-Type: text/html

<html><head><title>Hoi</title></head><body>Hoi</body></html>

disconnecting.
ok
while no SD card is inserted.

As soon as I insert a card, the ethernet card stops as follows (until the card is removed again):

Hello
My IP address: 192.168.1.2
Setup done, all clear!
connecting...

Sometimes, with a SD card in the slot, the IP address is corrupt (showing 0.0.0.0 or any fantasy-number).

How would I insert a tri state buffer since the MISO line from the shield already combines the outputs from the SD card and the W5100. Or is it something else?

Thank you for a hint. Dani

stevech
02-26-2015, 11:21 PM
I used the '5100 on several MCU types and never needed to buffer the SPI signals.
I also config to NOT use the slave select in hardware controlled mode. I always control via software. Esp. for DMA.

Sharing the same SPI port you'll need to provide mutual exclusion for use of the SPI port for two reasons. Either by how your app is designed, or by using SPI Transactions which is in some drivers.

Plugging in the SD card might glitch all the SPI lines. Might have to reset the '5100 aftwards. And don't plug/unplug while the '5100 is doing I/O.

PaulStoffregen
02-26-2015, 11:31 PM
I'm trying to use an official ethernet shield (R3, with W5100) with a teensy 3.1 (using pin 10 as W5100-CS). Ethernet runs well by itself. But I run into trouble as soon as I insert (!) an SD card into it's slot (CS for SD is pin 9).


The official Arduino Ethernet Shield (R3) (http://arduino.cc/en/Main/ArduinoEthernetShield) has the SD card CS signal on Arduino pin 4, not pin 9.

local_dani_21
02-27-2015, 05:03 AM
The official Arduino Ethernet Shield (R3) (http://arduino.cc/en/Main/ArduinoEthernetShield) has the SD card CS signal on Arduino pin 4, not pin 9.

That is right - I remapped it to 9 (I tried it with 4 as well - same result).

PaulStoffregen
02-27-2015, 11:40 AM
At the beginning of setup(), try adding these:



pinMode(9, INPUT_PULLUP); // or pin 4 if the shield if unmodified
pinMode(10, INPUT_PULLUP);


A known (at least well known to me) issue with the Arduino Ethernet Shield R3 involves the SD card chip select "floating" low if the SD library isn't used, which causes the SD card to interfere with using the Ethetnet chip.

Adding those 2 lines at the very beginning of setup() will prevent the unconfigured chip selects from floating low before either library is used. Alternately, you could solder real 10K pullup resistors on the shield's two CS signals (at the Arduno pins, before the buffer chips). That's the ideal solution.

Please let me know if this solves the problem? I've been pestering the Arduino devs to revise their ethernet shield design. If all this trouble turned out to be only because their shield lacked pullup resistors... well, I'll bug them again! ;)

local_dani_21
02-27-2015, 06:21 PM
You saved my day. Partially. Thank you. Setting only the INPUT_PULLUPs enabled only the ethernet-test (code see above) dispite inserted SD card. With additional physical 10k pullup-resistors, the SdFat SdInfo-sketch started to work as well.

BUT: When trying to read different SD cards using the official SD library-sketch (listfiles), the setup only works with some of my SD cards... So Paul, maybe the developers should add a 74hc125 to the shield after all.

In the light of wanting to add 7 more SPI devices to the setup (of course with tri-state MISOs), do you think it would make sense to give up the SD slot on the ethernet shield, put a 74hc125 into to MISO-line to tristate the MISO-line coming from the W5100 and add a separate SD card reader to the setup? Thanks for your advice.

local_dani_21
03-19-2015, 11:01 AM
Hi all
I'm still stumbeling over issues with using the Ethernet Shield with SD-card with teensy 3.1 and dare asking another question. I'm not completely sure I read the teensy 3.1 pinout correctly concerning the SPI bus.

I have connected seven RA8875 displays using SPI. I tri-state their MISO-pins using a 74HC125 and use the teensy pins 2,6,15,20,21,22,23 as CS-lines. So far so good, all displays come up and are adressable separately. All CS and RESET of the RA8875 lines are pulled up using 10k resistors.

I have also connected the ethernet shield to the SPI-bus: SD-CS is on teensy pin 9, Ethernet-CS is on teensy pin 10, the MISO from the ethernet-shield goes directly to teensy's MISO pin. Both CS 9 and 10 are pulled up using 10k resistors.

My setup:
3881

Running the code gives the following in the serial monitor:
Starting TFT setup...
Found RA8875 1
Found RA8875 2
Found RA8875 3
Found RA8875 4
Found RA8875 5
Found RA8875 6
Found RA8875 7
SD initialization failed!
:

#include <SPI.h>
#include "Adafruit_GFX.h"
#include "Adafruit_RA8875.h"
#include <SD.h>

#define sd_cs 9
#define ethernet_cs 10


// Library only supports hardware SPI at this time
// Connect SCLK to UNO Digital #13 (Hardware SPI clock)
// Connect MISO to UNO Digital #12 (Hardware SPI MISO)
// Connect MOSI to UNO Digital #11 (Hardware SPI MOSI)
#define RA8875_CS_1 20
#define RA8875_CS_2 15
#define RA8875_CS_3 21
#define RA8875_CS_4 6
#define RA8875_CS_5 22
#define RA8875_CS_6 2
#define RA8875_CS_7 23
#define RA8875_RESET 14

Adafruit_RA8875 tft1 = Adafruit_RA8875(RA8875_CS_1);
Adafruit_RA8875 tft2 = Adafruit_RA8875(RA8875_CS_2);
Adafruit_RA8875 tft3 = Adafruit_RA8875(RA8875_CS_3);
Adafruit_RA8875 tft4 = Adafruit_RA8875(RA8875_CS_4);
Adafruit_RA8875 tft5 = Adafruit_RA8875(RA8875_CS_5);
Adafruit_RA8875 tft6 = Adafruit_RA8875(RA8875_CS_6);
Adafruit_RA8875 tft7 = Adafruit_RA8875(RA8875_CS_7);

const int powerButtonPin = 8; // the number of the pushbutton pin
const int relayPin = 0; // the number of the LED pin
const int ledOnPin = 3; // grün --> blinkt so lange, wie RPi am booten ist, dann solid
const int ledOffPin = 4; // rot --> blinkt so lange, wie RPi am runterfahren ist, dann off

void setup(){
pinMode(sd_cs, INPUT_PULLUP);
pinMode(ethernet_cs, INPUT_PULLUP);

// Power Setup
pinMode(relayPin, OUTPUT);
digitalWrite (relayPin, HIGH);

// initialize the pushbutton pin as an input:
pinMode(powerButtonPin, INPUT);

pinMode(ledOnPin, OUTPUT);
pinMode(ledOffPin, OUTPUT);

for(int i = 0; i < 10; i++){ // Willkommensblinken, schnell
digitalWrite(ledOnPin, LOW);
delay(100);
digitalWrite(ledOnPin, HIGH);
delay(100);
}
// Ende Power Setup

Serial.begin(57600);
//while(!Serial){}


reset_tfts(RA8875_RESET); // Resetting manually to be able to use a common reset-line for all TFT's

Serial.println("Starting TFT setup...");

/* Initialise the display using 'RA8875_480x272' or 'RA8875_800x480' */
if (!tft1.begin_without_reset(RA8875_800x480)) {Serial.println("RA8875 1 Not Found!");while (1);} Serial.println("Found RA8875 1");
if (!tft2.begin_without_reset(RA8875_800x480)) {Serial.println("RA8875 2 Not Found!");while (1);} Serial.println("Found RA8875 2");
if (!tft3.begin_without_reset(RA8875_800x480)) {Serial.println("RA8875 3 Not Found!");while (1);} Serial.println("Found RA8875 3");
if (!tft4.begin_without_reset(RA8875_800x480)) {Serial.println("RA8875 4 Not Found!");while (1);} Serial.println("Found RA8875 4");
if (!tft5.begin_without_reset(RA8875_800x480)) {Serial.println("RA8875 5 Not Found!");while (1);} Serial.println("Found RA8875 5");
if (!tft6.begin_without_reset(RA8875_800x480)) {Serial.println("RA8875 6 Not Found!");while (1);} Serial.println("Found RA8875 6");
if (!tft7.begin_without_reset(RA8875_800x480)) {Serial.println("RA8875 7 Not Found!");while (1);} Serial.println("Found RA8875 7");

tftSetup(&tft1);
tftSetup(&tft2);
tftSetup(&tft3);
tftSetup(&tft4);
tftSetup(&tft5);
tftSetup(&tft6);
tftSetup(&tft7);

if (!SD.begin(sd_cs))
{
Serial.println("SD initialization failed!");
return;
}

Serial.println("SD initialization done.");

bmpDraw(&tft1, "1.bmp", 0, 0);
bmpDraw(&tft2, "2.bmp", 0, 0);
bmpDraw(&tft3, "3.bmp", 0, 0);
bmpDraw(&tft4, "4.bmp", 0, 0);
bmpDraw(&tft5, "5.bmp", 0, 0);
bmpDraw(&tft6, "6.bmp", 0, 0);
bmpDraw(&tft7, "7.bmp", 0, 0);
}

void loop() {
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (digitalRead(powerButtonPin) == HIGH) { // Taste gedrückt --> Abstellen
digitalWrite(ledOnPin, LOW);
for(int i = 0; i < 10; i++){ // Zuerst langsam 10x blinken
digitalWrite(ledOffPin, HIGH);
delay(200);
digitalWrite(ledOffPin, LOW);
delay(200);
}
digitalWrite(relayPin, LOW); //Strom abstellen
}
}

void tftSetup(Adafruit_RA8875 *tft)
{
tft->displayOn(true);
tft->GPIOX(true); // Enable TFT - display enable tied to GPIOX
tft->PWM1config(true, RA8875_PWM_CLK_DIV1024); // PWM output for backlight
tft->PWM1out(255);

// With hardware accelleration this is instant
tft->fillScreen(RA8875_WHITE);
}
#define BUFFPIXEL 20

void bmpDraw(Adafruit_RA8875 *tft, char *filename, int x, int y) {
File bmpFile;
int bmpWidth, bmpHeight; // W+H in pixels
uint8_t bmpDepth; // Bit depth (currently must be 24)
uint32_t bmpImageoffset; // Start of image data in file
uint32_t rowSize; // Not always = bmpWidth; may have padding
uint8_t sdbuffer[3*BUFFPIXEL]; // pixel in buffer (R+G+B per pixel)
uint16_t lcdbuffer[BUFFPIXEL]; // pixel out buffer (16-bit per pixel)
uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer
boolean goodBmp = false; // Set to true on valid header parse
boolean flip = true; // BMP is stored bottom-to-top
int w, h, row, col;
uint8_t r, g, b;
uint32_t pos = 0, startTime = millis();
uint8_t lcdidx = 0;
boolean first = true;

if((x >= tft->width()) || (y >= tft->height())) return;

Serial.println();
Serial.print(F("Loading image '"));
Serial.print(filename);
Serial.println('\'');

// Open requested file on SD card
if ((bmpFile = SD.open(filename)) == NULL) {
Serial.println(F("File not found"));
return;
}

// Parse BMP header
if(read16(bmpFile) == 0x4D42) { // BMP signature // Bytes 1,2
Serial.println(F("File size: "));
Serial.println(read32(bmpFile)); // Bytes 3,4,5,6
(void)read32(bmpFile); // Read & ignore creator bytes // Bytes 7,8,9,10
bmpImageoffset = read32(bmpFile); // Start of image data // Bytes 11,12,13,14
Serial.print(F("Image Offset: "));
Serial.println(bmpImageoffset, DEC);

// Read DIB header
Serial.print(F("Header size: "));
Serial.println(read32(bmpFile)); // Bytes 15,16,17,18
bmpWidth = read32(bmpFile); // Bytes 19,20,21,22
bmpHeight = read32(bmpFile); // Bytes 23,24,25,26

if(read16(bmpFile) == 1) { // # planes -- must be '1' // Bytes 27,28
bmpDepth = read16(bmpFile); // bits per pixel // Bytes 29,30
Serial.print(F("Bit Depth: "));
Serial.println(bmpDepth);
if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed // Bytes 31,32,33,34
goodBmp = true; // Supported BMP format -- proceed!
Serial.print(F("Image size: "));
Serial.print(bmpWidth);
Serial.print('x');
Serial.println(bmpHeight);

// BMP rows are padded (if needed) to 4-byte boundary
rowSize = (bmpWidth * 3 + 3) & ~3;

// If bmpHeight is negative, image is in top-down order.
// This is not canon but has been observed in the wild.
if(bmpHeight < 0) {
bmpHeight = -bmpHeight;
flip = false;
}

// Crop area to be loaded
w = bmpWidth;
h = bmpHeight;
if((x+w-1) >= tft->width()) w = tft->width() - x;
if((y+h-1) >= tft->height()) h = tft->height() - y;

// Set TFT address window to clipped image bounds

for (row=0; row<h; row++) { // For each scanline...
// Seek to start of scan line. It might seem labor-
// intensive to be doing this on every line, but this
// method covers a lot of gritty details like cropping
// and scanline padding. Also, the seek only takes
// place if the file position actually needs to change
// (avoids a lot of cluster math in SD library).
if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
else // Bitmap is stored top-to-bottom
pos = bmpImageoffset + row * rowSize;
if(bmpFile.position() != pos) { // Need seek?
bmpFile.seek(pos);
buffidx = sizeof(sdbuffer); // Force buffer reload
}

for (col=0; col<w; col++) { // For each column...
// Time to read more pixel data?
if (buffidx >= sizeof(sdbuffer)) { // Indeed
// Push LCD buffer to the display first
if(lcdidx > 0) {
tft->drawPixel(col, row, lcdbuffer[lcdidx]);
lcdidx = 0;
first = false;
}

bmpFile.read(sdbuffer, sizeof(sdbuffer));
buffidx = 0; // Set index to beginning
}

// Convert pixel from BMP to TFT format
b = sdbuffer[buffidx++];
g = sdbuffer[buffidx++];
r = sdbuffer[buffidx++];
lcdbuffer[lcdidx] = color565(r,g,b);
tft->drawPixel(col, row, lcdbuffer[lcdidx]);
} // end pixel

} // end scanline

// Write any remaining data to LCD
if(lcdidx > 0) {
tft->drawPixel(col, row, lcdbuffer[lcdidx]);
}

Serial.print(F("Loaded in "));
Serial.print(millis() - startTime);
Serial.println(" ms");

} // end goodBmp
}
}

bmpFile.close();
if(!goodBmp) Serial.println(F("BMP format not recognized."));

}

// These read 16- and 32-bit types from the SD card file.
// BMP data is stored little-endian, Arduino is little-endian too.
// May need to reverse subscript order if porting elsewhere.

uint16_t read16(File f) {
uint16_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read(); // MSB
return result;
}

uint32_t read32(File f) {
uint32_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read();
((uint8_t *)&result)[2] = f.read();
((uint8_t *)&result)[3] = f.read(); // MSB
return result;
}

uint16_t color565(uint8_t r, uint8_t g, uint8_t b) {
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
}

byte decToBcd(byte val){
// Convert normal decimal numbers to binary coded decimal
return ( (val/10*16) + (val%10) );
}
void reset_tfts(int reset_pin){
pinMode(reset_pin, OUTPUT);
digitalWrite(reset_pin, LOW);
delay(100);
digitalWrite(reset_pin, HIGH);
delay(100);
}


I can use the SD card and the ethernet only when disconnecting the MISO coming from the seven displays. Otherwise the ethernet shield cannot set an IP nor connect to anything and the SD initialization fails.

Now my question: Is it correct that I can use all these pins (Pinout-diagram light green: 2,6,9,10,15,20,21,22,23) as CS-pins? Should I tri-state the MISO coming from the ethernet-shield as well (using an OR on the CS of the SD and the Ethernet) as enabling signal to the 74HC125?

Any suggestions? Thank you very much. Dani