#include "units/encoder.hpp"
#include "units/r2r.hpp"
#include "units/motor.hpp"
+#include "units/portexp.hpp"
extern "C" {
void __cxa_pure_virtual () {
Encoder encoder;
R2r r2r;
Motor motor;
+ PortExp portExp;
}
return keyUart0;
}
-
int main () {
// Nano-644 LEDs (Green, Orange, Red)
printf("======================================");
- TestUnit *unit[] = { &led, &sw, &rgb, &seg7, &poti, &encoder, &r2r, &motor };
+ TestUnit *unit[] = { &led, &sw, &rgb, &seg7, &poti, &encoder, &r2r, &motor, &portExp };
for (uint8_t i = 0; i < sizeof(unit) / sizeof(unit[0]); i++) {
TestUnit *pu = unit[i];
--- /dev/null
+#include <stdio.h>
+#include <avr/io.h>
+#include <util/delay.h>
+
+#include "portexp.hpp"
+#include "../main.hpp"
+
+// Port-Expander MCP23S17
+
+// SN-Print Stecker IO16
+// MCP23S17 | IO16 (MEGA2560) | Ampel-Print | | MCP23S17 | IO16 (MEGA2560) | Ampel-Print |
+// ------------------------------------------ --------------------------------------------
+// GPA0 | IO16O7 (PA7) | Taster RU | | GPB0 | IO16U7 (PC7) | Taster LU |
+// GPA1 | IO16O6 (PA6) | Taster RO | | GPB1 | IO16U6 (PC6) | Taster LO |
+// GPA2 | IO16O5 (PA5) | U-Gruen | | GPB2 | IO16U5 (PC5) | R-Gruen |
+// GPA3 | IO16O4 (PA4) | U-Gelb | | GPB3 | IO16U4 (PC4) | R-Gelb |
+// GPA4 | IO16O3 (PA3) | U-Rot | | GPB4 | IO16U3 (PC3) | R-Rot |
+// GPA5 | IO16O2 (PA2) | L-Gruen | | GPB5 | IO16U2 (PC2) | O-Gruen |
+// GPA6 | IO16O1 (PA1) | L-Gelb | | GPB6 | IO16U1 (PC1) | O-Gelb |
+// GPA7 | IO16O0 (PA0) | L-Rot | | GPB7 | IO16U0 (PC0) | O-Rot |
+
+
+void PortExp::cleanup () {
+ DDRB &= ~(1 << PB6); // // SPI MISO (=PB6)
+ DDRB &= ~((1 << PB7) | (1 << PB5)); // SPI SCK (=PB7) and SPI MOSI (=PB5)
+ DDRA &= ~(1 << PA7);
+ PORTA &= ~(1 << PA7); // SPI nCS
+ SPCR = 0;
+
+}
+
+int8_t writeByte (uint8_t addr, uint8_t b) {
+
+ PORTA &= ~(1 << PA7); // SPI nCS 1 -> 0
+
+ SPDR = 0x40; // WRITE BYTE
+ while ((SPSR & (1 << SPIF)) == 0) {}
+ if (SPDR != 0) {
+ printf("E1");
+ PORTA |= (1 << PA7); // SPI nCS 0 -> 1
+ return -1;
+ }
+
+ SPDR = addr; // register address
+ while ((SPSR & (1 << SPIF)) == 0) {}
+ if (SPDR != 0) {
+ printf("E2");
+ PORTA |= (1 << PA7); // SPI nCS 0 -> 1
+ return -1;
+ }
+
+ SPDR = b; // value
+ while ((SPSR & (1 << SPIF)) == 0) {}
+ if (SPDR != 0) {
+ printf("E3");
+ PORTA |= (1 << PA7); // SPI nCS 0 -> 1
+ return -1;
+ }
+
+ PORTA |= (1 << PA7); // SPI nCS 0 -> 1
+
+ _delay_us(5);
+ return 0;
+}
+
+int8_t PortExp::run (uint8_t subtest) {
+ if (subtest == 0) {
+ PRR &= (1 << PRSPI);
+ PORTA |= (1 << PA7);
+ DDRA |= (1 << PA7); // SPI nCS
+ // PORTB/DDRB must be configured before SPCR !!
+ PORTB |= (1 << PB4); // nSS must be HIGH, otherwise SPI master will not become active!!
+ DDRB |= (1 << PB7) | (1 << PB5) | (1 << PB4); // SPI SCK (=PB7) and SPI MOSI (=PB5)
+
+ // SPCR |= (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0); // SPI enable , Master, f=12MHz/128=93,75kHz
+ SPCR = (1 << SPE) | (1 << MSTR); // SPI enable , Master, f=12MHz/4 = 3MHz
+ printf("init");
+
+ } else if (subtest == 1) {
+ while (wait(500) == EOF) {
+ printf("\n => start ...");
+ for (uint8_t i = 0; i < 8; i++) {
+ writeByte(0, ~(1 << i)); // IODIRA (Bank = 0)
+ // writeByte(0, 0x00); // IODIRA (Bank = 0) - all output
+ writeByte(0x12, (1 << i)); // GPIOA (Bank = 0)
+ printf("\n Bank0 - GPA%d = 1", i);
+ wait(200);
+ writeByte(0x12, 0); // GPIOA (Bank = 0)
+ printf("\n Bank0 - GPA%d = 0", i);
+ writeByte(0, 0xff); // IODIRA (Bank = 0)
+ wait(200);
+ }
+ for (uint8_t i = 0; i < 8; i++) {
+ writeByte(1, ~(1 << i)); // IODIRB (Bank = 0)
+ // writeByte(1, 0x00); // IODIRB (Bank = 0) - all output
+ writeByte(0x13, (1 << i)); // GPIOB (Bank = 0)
+ printf("\n Bank0 - GPB%d = 1", i);
+ wait(200);
+ writeByte(0x13, 0); // GPIOB (Bank = 0)
+ printf("\n Bank0 - GPB%d = 0", i);
+ writeByte(1, 0xff); // IODIRB (Bank = 0)
+ wait(200);
+ }
+ }
+
+ } else {
+ printf("end");
+ return -1;
+ }
+ wait(500);
+ return 0;
+}
+