From f4387244ef28660a49a685c1a8ab657bb078f196 Mon Sep 17 00:00:00 2001 From: Manfred Steiner Date: Tue, 30 Jul 2024 18:55:03 +0200 Subject: [PATCH] Test-Software Unit UART1, IEEE485 --- software/test_2024-07-23/src/main.cpp | 20 ++-- .../test_2024-07-23/src/units/ieee485.cpp | 91 +++++++++++++++++++ .../test_2024-07-23/src/units/ieee485.hpp | 20 ++++ software/test_2024-07-23/src/units/uart1.cpp | 58 ++++++++++++ software/test_2024-07-23/src/units/uart1.hpp | 19 ++++ 5 files changed, 201 insertions(+), 7 deletions(-) create mode 100644 software/test_2024-07-23/src/units/ieee485.cpp create mode 100644 software/test_2024-07-23/src/units/ieee485.hpp create mode 100644 software/test_2024-07-23/src/units/uart1.cpp create mode 100644 software/test_2024-07-23/src/units/uart1.hpp diff --git a/software/test_2024-07-23/src/main.cpp b/software/test_2024-07-23/src/main.cpp index 9023e1a..264fc64 100644 --- a/software/test_2024-07-23/src/main.cpp +++ b/software/test_2024-07-23/src/main.cpp @@ -15,7 +15,10 @@ #include "units/motor.hpp" #include "units/portexp.hpp" #include "units/lcd.hpp" +#include "units/uart1.hpp" #include "units/modbus.hpp" +#include "units/ieee485.hpp" + extern "C" { void __cxa_pure_virtual () { @@ -28,10 +31,7 @@ extern "C" { if (stream == stdout) { loop_until_bit_is_set(UCSR0A, UDRE0); UDR0 = c; - } else if (stream == stderr) { - loop_until_bit_is_set(UCSR1A, UDRE1); - UDR1 = c; - } + } return 0; } @@ -63,7 +63,6 @@ extern "C" { } static FILE mystdout = { 0, 0, _FDEV_SETUP_WRITE , 0, 0, uart_putchar, NULL, 0 }; - static FILE mystderr = { 0, 0, _FDEV_SETUP_WRITE , 0, 0, uart_putchar, NULL, 0 }; static FILE mystdin = { 0, 0, _FDEV_SETUP_READ , 0, 0, NULL, uart_getchar, 0 }; static volatile uint32_t timer1ms = 0; @@ -79,7 +78,9 @@ extern "C" { Motor motor; PortExp portExp; Lcd lcd; + Uart1 uart1; Modbus modbus; + Ieee485 ieee485; } @@ -122,12 +123,11 @@ int main () { TIMSK2 = (1 << OCIE2A); stdout = &mystdout; - stderr = &mystderr; stdin = &mystdin; sei(); - TestUnit *unit[] = { &led, &sw, &rgb, &seg7, &poti, &encoder, &r2r, &motor, &portExp, &lcd, &modbus }; + TestUnit *unit[] = { &led, &sw, &rgb, &seg7, &poti, &encoder, &r2r, &motor, &portExp, &lcd, &uart1, &modbus, &ieee485 }; while (1) { uint16_t i; @@ -179,6 +179,12 @@ ISR (USART1_RX_vect) { if (modbus.enabled) { modbus.handleRxByte(b); } + if (uart1.enabled) { + uart1.handleRxByte(b); + } + if (ieee485.enabled) { + ieee485.handleRxByte(b); + } } ISR (TIMER2_COMPA_vect) { // every 100us diff --git a/software/test_2024-07-23/src/units/ieee485.cpp b/software/test_2024-07-23/src/units/ieee485.cpp new file mode 100644 index 0000000..4fba45f --- /dev/null +++ b/software/test_2024-07-23/src/units/ieee485.cpp @@ -0,0 +1,91 @@ +#include +#include +#include +#include + +#include "ieee485.hpp" +#include "../main.hpp" + +// PB0 ... nRE .. Read enable +// PB1 ... DE .. Data enable + +#define SET_nRE (PORTB |= (1 << PB0)) +#define CLR_nRE (PORTB &= ~(1 << PB0)) +#define SET_DE (PORTB |= (1 << PB1)) +#define CLR_DE (PORTB &= ~(1 << PB1)) + + +void Ieee485::cleanup () { + enabled = 0; + + ADMUX = 0; + ADCSRA = 0; + + UCSR1A = 0; + UCSR1B = 0; + UCSR1C = 0; + UBRR1H = 0; + UBRR1L = 0; + PORTD &= ~(1 << PD2); + DDRB &= ~((1 << PB1) | (1 << PB0)); + PORTB &= ~((1 << PB1) | (1 << PB0)); +} + +int8_t Ieee485::run (uint8_t subtest) { + if (subtest == 0) { + // Poti + ADMUX = (1 << ADLAR) | (1 << REFS0); // ADC0, VREF=AVCC=3.3V + ADCSRA = (1 << ADEN) | 7; // ADC Enable, Prescaler 128 + + // Modbus + SET_nRE; + CLR_DE; + DDRB |= (1 << PB1) | (1 << PB0); + + // UART1 interface on Nano-644 + PORTD |= (1 << PD2); // enable RxD1 pullup + UCSR1A = (1 << U2X1); + UCSR1B = (1 << RXCIE1) | (1 << RXEN1) | (1 < send Byte 0x%02x", ADCH); + int b; + ATOMIC_BLOCK(ATOMIC_FORCEON) { + b = receivedByte; + receivedByte = -1; + } + if (b >= 0) { + printf("\n => receive Byte: 0x%02x", b); + } + } + + } else { + printf("end"); + return -1; + } + + return 0; +} + +void Ieee485::handleRxByte (uint8_t b) { + receivedByte = b; +} diff --git a/software/test_2024-07-23/src/units/ieee485.hpp b/software/test_2024-07-23/src/units/ieee485.hpp new file mode 100644 index 0000000..d72f337 --- /dev/null +++ b/software/test_2024-07-23/src/units/ieee485.hpp @@ -0,0 +1,20 @@ +#ifndef IEEE485_HPP +#define IEEE485_HPP + +#include +#include "../main.hpp" + +class Ieee485 : public TestUnit { + public: + uint8_t enabled; + int16_t receivedByte; + + public: + Ieee485 () { enabled = 0; receivedByte = -1; } + virtual void cleanup (); + virtual int8_t run (uint8_t subtest); + virtual const char *getName () { return "IEEE485"; } + void handleRxByte (uint8_t); +}; + +#endif \ No newline at end of file diff --git a/software/test_2024-07-23/src/units/uart1.cpp b/software/test_2024-07-23/src/units/uart1.cpp new file mode 100644 index 0000000..7ef9504 --- /dev/null +++ b/software/test_2024-07-23/src/units/uart1.cpp @@ -0,0 +1,58 @@ +#include +#include +#include + +#include "uart1.hpp" +#include "../main.hpp" + +int uart1_putchar(char c, FILE *stream) { + if (c == '\n') { + uart1_putchar('\r', stream); + } + loop_until_bit_is_set(UCSR1A, UDRE1); + UDR1 = c; + return 0; +} + +static FILE mystderr = { 0, 0, _FDEV_SETUP_WRITE , 0, 0, uart1_putchar, NULL, 0 }; + +void Uart1::cleanup () { + enabled = 0; + UCSR1A = 0; + UCSR1B = 0; + UCSR1C = 0; + UBRR1H = 0; + UBRR1L = 0; + stderr = NULL; +} + +int8_t Uart1::run (uint8_t subtest) { + if (subtest == 0) { + // UART1 interface on Nano-644 + PORTD |= (1 << PD2); // enable RxD1 pullup + UCSR1A = (1 << U2X1); + UCSR1B = (1 << RXCIE1) | (1 << RXEN1) | (1 < send text via UART1 now..."); + fprintf(stderr, "Hello UART1, ECHO-Modus active\n"); + } while (wait(5000) == EOF); + + } else { + printf("end"); + return -1; + } + wait(500); + return 0; +} + +void Uart1::handleRxByte (uint8_t b) { + uart1_putchar(b, stderr); +} diff --git a/software/test_2024-07-23/src/units/uart1.hpp b/software/test_2024-07-23/src/units/uart1.hpp new file mode 100644 index 0000000..23c9b7f --- /dev/null +++ b/software/test_2024-07-23/src/units/uart1.hpp @@ -0,0 +1,19 @@ +#ifndef UART1_HPP +#define UART1_HPP + +#include +#include "../main.hpp" + +class Uart1 : public TestUnit { + public: + uint8_t enabled; + + public: + Uart1 () { enabled = 0; } + virtual void cleanup (); + virtual int8_t run (uint8_t subtest); + virtual const char *getName () { return "Uart1"; } + void handleRxByte (uint8_t); +}; + +#endif \ No newline at end of file -- 2.39.5