From 5c90424829087600178b16fed575240ee444e31c Mon Sep 17 00:00:00 2001 From: Manfred Steiner Date: Sat, 14 Sep 2024 17:11:48 +0200 Subject: [PATCH] software/.../test_2024-07-23: unit portexp fertig (V1a/V2a) --- .../nano-644/test_2024-07-23/src/main.cpp | 12 +-- .../test_2024-07-23/src/units/portexp.cpp | 84 ++++++++++++------- .../test_2024-07-23/src/units/portexp.hpp | 2 + 3 files changed, 63 insertions(+), 35 deletions(-) diff --git a/software/nano-644/test_2024-07-23/src/main.cpp b/software/nano-644/test_2024-07-23/src/main.cpp index 34abcb6..18ee2d3 100644 --- a/software/nano-644/test_2024-07-23/src/main.cpp +++ b/software/nano-644/test_2024-07-23/src/main.cpp @@ -162,20 +162,20 @@ uint8_t detectHardwareVersion () { } #endif #if defined(__AVR_ATmega328P__) - if (ADCH < 0xd0 && ADCH >= 0xc0) { + if (ADCH < 0xd8 && ADCH >= 0xc0) { hardwareVersion = 1; - } else if (ADCH < 0xd0 && ADCH >= 0xb0) { + } else if (ADCH < 0xd8 && ADCH >= 0xb0) { hardwareVersion = 2; } #endif if (hardwareVersion == 0) { #ifdef __AVR_ATmega644P__ - printf("Invalid Hardware-Version: ADC7H = %d (ATmega644P, 3.3V)\n", ADCH); + printf("\nInvalid Hardware-Version: ADC7H = %d (ATmega644P, 3.3V)\n", ADCH); #elif __AVR_ATmega1284P__ - printf("Invalid Hardware-Version: ADC7H = %d (ATmega1284P, 3.3V)\n", ADCH); + printf("\nInvalid Hardware-Version: ADC7H = %d (ATmega1284P, 3.3V)\n", ADCH); #elif __AVR_ATmega328P__ - printf("Invalid Hardware-Version: ADC7H = %d (ATmega328P, 5V)\n", ADCH); + printf("\nInvalid Hardware-Version: ADC7H = %d (ATmega328P, 5V)\n", ADCH); #endif } @@ -250,7 +250,7 @@ int main () { #ifdef __AVR_ATmega328P__ TestUnit *unit[] = { - &led, &sw, &rgb, &seg7, &poti, &encoder, &r2r, &motor, &lcd, + &led, &sw, &rgb, &seg7, &poti, &encoder, &r2r, &motor, &portExp, &lcd, &i2cMaster, &i2cSlave, &i2cSparkfun }; #endif diff --git a/software/nano-644/test_2024-07-23/src/units/portexp.cpp b/software/nano-644/test_2024-07-23/src/units/portexp.cpp index 7eac74d..a153589 100644 --- a/software/nano-644/test_2024-07-23/src/units/portexp.cpp +++ b/software/nano-644/test_2024-07-23/src/units/portexp.cpp @@ -21,7 +21,7 @@ #if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) - // Nano-644 + // Nano-644 / Nano1284 // -------------------------------------------------------- // PA7 ... nCS // PB5 ... MOSI @@ -35,9 +35,10 @@ // 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) + DDRB &= ~(1 << PB6); - // 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 + 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 } void PortExp::cleanup () { @@ -76,8 +77,13 @@ PORTB |= (1 << PB2); // nSS must be HIGH, otherwise SPI master will not become active!! DDRB |= (1 << PB5) | (1 << PB3) | (1 << PB2); // SPI SCK (=PB5), SPI MOSI (=PB3), SPI nSS (=PB2) - // SPCR |= (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0); // SPI enable , Master, f=16MHz/128=125kHz - SPCR = (1 << SPE) | (1 << MSTR); // SPI enable , Master, f=12MHz/4 = 3MHz + SPCR |= (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0); // SPI enable , Master, f=16MHz/128=125kHz + // SPCR = (1 << SPE) | (1 << MSTR); // SPI enable , Master, f=12MHz/4 = 3MHz + + if (hardwareVersion == 2) { + PORTD |= (1 << PD7); // nCS when V2a/JP39.2-3 jumpered + DDRD |= (1 << PD7); + } } void PortExp::cleanup () { @@ -89,11 +95,15 @@ } void PortExp::setChipEnable () { - PORTC &= ~(1 << PC1); + if (hardwareVersion == 2) { + PORTD &= ~(1 << PD7); + } } void PortExp::clearChipEnable () { - PORTC |= (1 << PC1); + if (hardwareVersion == 2) { + PORTD |= (1 << PD7); + } } #endif @@ -101,62 +111,78 @@ int8_t PortExp::writeByte (uint8_t addr, uint8_t b) { - + // no response via SPI MISO because SO stays tristate on write cycle setChipEnable(); - SPDR = 0x40; // WRITE BYTE while ((SPSR & (1 << SPIF)) == 0) {} - if (SPDR != 0) { - printf_P(PSTR("E1")); - clearChipEnable(); - return -1; - } - SPDR = addr; // register address while ((SPSR & (1 << SPIF)) == 0) {} - if (SPDR != 0) { - printf_P(PSTR("E2")); - clearChipEnable(); - return -1; - } - SPDR = b; // value while ((SPSR & (1 << SPIF)) == 0) {} - if (SPDR != 0) { - printf_P(PSTR("E3")); - clearChipEnable(); - return -1; - } - clearChipEnable(); _delay_us(5); return 0; } +uint8_t PortExp::readByte (uint8_t addr) { + // response via SPI MISO only on third byte + setChipEnable(); + SPDR = 0x41; // write "READ BYTE" + while ((SPSR & (1 << SPIF)) == 0) {} + SPDR = addr; // write "register address" + while ((SPSR & (1 << SPIF)) == 0) {} + SPDR = 0; // additional 8 clocks to get response from port expander + while ((SPSR & (1 << SPIF)) == 0) {} + clearChipEnable(); + return SPDR; +} + +void PortExp::checkResponse (uint8_t address, uint8_t response, uint8_t desired) { + printf_P(PSTR(" (read 0x%02x -> 0x%02x"), address, response); + if (response != desired) { + printf_P(PSTR(" ERROR")); + if (response == 0xff) { + printf_P(PSTR(" JP39.2/3 jumpered (left)?")); + } + } else { + printf_P(PSTR(" OK")); + } + printf_P(PSTR(")")); +} + + int8_t PortExp::run (uint8_t subtest) { + #ifdef __AVR_ATmega328P__ + if (hardwareVersion == 1) { + printf_P(PSTR("ERROR - nCS not controlable\n")); + return -1; + } + #endif if (subtest == 0) { while (wait(500) == EOF) { printf_P(PSTR("\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_P(PSTR("\n Bank0 - GPA%d = 1"), i); + checkResponse (0x12, readByte(0x12), (1 << i)); wait(200); writeByte(0x12, 0); // GPIOA (Bank = 0) printf_P(PSTR("\n Bank0 - GPA%d = 0"), i); + checkResponse (0x12, readByte(0x12), 0); 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_P(PSTR("\n Bank0 - GPB%d = 1"), i); + checkResponse (0x13, readByte(0x13), (1 << i)); wait(200); writeByte(0x13, 0); // GPIOB (Bank = 0) printf_P(PSTR("\n Bank0 - GPB%d = 0"), i); + checkResponse (0x13, readByte(0x13), 0); writeByte(1, 0xff); // IODIRB (Bank = 0) wait(200); } diff --git a/software/nano-644/test_2024-07-23/src/units/portexp.hpp b/software/nano-644/test_2024-07-23/src/units/portexp.hpp index 2fb665c..8705662 100644 --- a/software/nano-644/test_2024-07-23/src/units/portexp.hpp +++ b/software/nano-644/test_2024-07-23/src/units/portexp.hpp @@ -17,6 +17,8 @@ class PortExp : public TestUnit { void setChipEnable (); void clearChipEnable (); int8_t writeByte (uint8_t addr, uint8_t b); + uint8_t readByte (uint8_t addr); + void checkResponse (uint8_t address, uint8_t response, uint8_t desired); }; #endif \ No newline at end of file -- 2.39.5