Freitag, 5. Juli 2013

Das Mega2560 und MCP23S17 Problem

Die Hardware des CSQ1 Step Sequencers hat sich weiterentwickelt. Nun stehen die Hardwaretests an und offenbaren auch das ein oder andere Software-Problem bzw. noch offene Bildungslücken.

Wie im Post Musik - Schritt für Schritt (Teil 4): Erste Gehversuche mit Koffer gezeigt, funktioniert das SPI-Board. Die Hardware ist nun aus dem Koffer ausgezogen und in ein "neues Heim" eingezogen.






Um mehr als nur eine MIDI Schnittstelle zu haben, habe ich den Arduino Uno gegen den Mega2560 getauscht. 

Jedoch das SPI-Board gab kein Lebenszeichen von sich. Spannungsversorgung und Verbindungskabel waren in Ordnung. Eigentlich hätte es funktionieren müssen. Testweise den Uno angeschlossen: geht.

Ein Anschließen eines Micro SD-Card Breakout an den Mega2560 zeigt, dass das SPI funktioniert. Ein Internet Recherche brachte keine Ergebnisse. Es hat den Anschein, als hätte noch niemand diese Hardware-Kombination betrieben, bzw. Probleme damit.

Es gab nur noch ein Glied in der Kette, dass ich nicht untersucht habe: die Software und hier speziell die MCP23S17 Class von Cort Buffington. Irgendwo in deren Tiefen muss die Ursache des Problems zu finden sein. 
Die Suche konzentrierte sich auf Angaben zu den verwendeten SPI-Pins, die sich zwischen Uno und Mega unterscheiden:

      UNO  MEGA
MOSI   11   51
MISO   12   50
SCK    13   52
SS     10   53

In der Datei MCP23S17.cpp fand  ich die Zeile:

#define    SS            (10)          // SPI bus slave select output to pin 10 - READ ARDUINO SPI DOCS BEFORE CHANGING!!!


Die (10) habe ich in (53) geändert, weil dies beim Mega mein Slave Select Pin ist. Aber auch nach dieser Änderung verweigerte das SPI-Board weiterhin den Dienst.

Erst eine Anfrage im Arduino Forum brachte den entscheidenden Hinweis. Ein freundlicher Mensch namens Nick Gammon aus Melbourne, seines Zeichens "Global Moderator" im Forum machte mich auf diese Zeilen im Code aufmerksam:


  PORTB &= 0b11111011;                                 // Direct port manipulation speeds taking Slave Select LOW before SPI action


  PORTB |= 0b00000100;                                 // Direct port manipulation speeds taking Slave Select HIGH after SPI action
}



Mit diesen Zuweisungen wird der Zustand von Port B (8 pins, B0-B7) direkt verändert.
&= bedeutet dabei eine bit-weise UND-Verknüpfung und |= eine bit-weise ODER-Verknüpfung.


Pin:   B7 B6 B5 B4 B3 B2 B1 B0
   UND  1  1  1  1  1  0  1  1
      -------------------------
     = B7 B6 B5 B4 B3  0 B1 B0

Pin:   B7 B6 B5 B4 B3 B2 B1 B0
  ODER  0  0  0  0  0  1  0  0
      -------------------------
     = B7 B6 B5 B4 B3  1 B1 B0



Ergebnis: durch diese Zuweisungen wird Pin B2 auf 0 bzw. 1 gesetzt, während der Zustand aller anderen Pins unverändert bleibt. Und ein Blick auf das Pin-Mapping des Arduino Uno Boards zeigt, dass Pin B2 dem Arduino Pin 10 entspricht.

Die Lösung: beim Arduino Mega2560 liegt Pin53 (SS) auf dem ATmega Pin B0. Ich musste demnach die entsprechenden Codezeilen in der Datei zu



  PORTB &= 0b11111110; bzw. PORTB |= 0b00000001;

ändern.
Gespeichert - getestet - geht!

Many thanks to Nick Gammon for support and also many thanks to all Arduino Forum members for spreading their knowledge. Keep it up!