Commit f4387244ef28660a49a685c1a8ab657bb078f196
receivedTue, 30. Jul 2024, 18:55:06 (by user sx)
Tue, 30 Jul 2024 16:55:06 +0000 (18:55 +0200)
authorManfred Steiner <sx@htl-kaindorf.at>
Tue, 30 Jul 2024 16:55:03 +0000 (18:55 +0200)
committerManfred Steiner <sx@htl-kaindorf.at>
Tue, 30 Jul 2024 16:55:03 +0000 (18:55 +0200)
5 files changed:
software/test_2024-07-23/src/main.cpp
software/test_2024-07-23/src/units/ieee485.cpp [new file with mode: 0644]
software/test_2024-07-23/src/units/ieee485.hpp [new file with mode: 0644]
software/test_2024-07-23/src/units/uart1.cpp [new file with mode: 0644]
software/test_2024-07-23/src/units/uart1.hpp [new file with mode: 0644]

index 9023e1ac3490ea97262f04bee9343931cd2a447f..264fc6491ba2e5802eb958bb1b2690f60662b6e5 100644 (file)
 #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 (file)
index 0000000..4fba45f
--- /dev/null
@@ -0,0 +1,91 @@
+#include <stdio.h>
+#include <avr/io.h>
+#include <util/delay.h>
+#include <util/atomic.h>
+
+#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 <<TXEN1);
+      UCSR1C = (1 << UCSZ11) | ( 1<< UCSZ10);
+      // UCSR1C |= (1 <<UPM11); // even Parity
+      // UCSR1C |= (1 << UPM11) | (1 << UPM10); // odd Parity
+      UBRR1H = 0;
+      UBRR1L = F_CPU / 8 / 9600 - 1;
+
+      enabled = 1;
+      printf("init");
+
+   } else if (subtest == 1) {
+      CLR_nRE; CLR_DE;
+      while (wait(500) == EOF) {
+         ADCSRA |= (1 << ADSC); // start ADC
+         while (ADCSRA & (1 << ADSC)) {} // wait for result
+         UCSR1A |= (1 << TXC1);
+         SET_nRE;
+         SET_DE;
+         UDR1 = ADCH;
+         while ((UCSR1A & (1 << TXC1)) == 0) {}
+         CLR_DE;
+         CLR_nRE;
+         printf("\n  => 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 (file)
index 0000000..d72f337
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef IEEE485_HPP
+#define IEEE485_HPP
+
+#include <stdint.h>
+#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 (file)
index 0000000..7ef9504
--- /dev/null
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <avr/io.h>
+#include <util/delay.h>
+
+#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 <<TXEN1);
+      UCSR1C = (1 << UCSZ11) | ( 1<< UCSZ10);
+      UBRR1H = 0;
+      UBRR1L = F_CPU / 8 / 115200 - 1;
+      stderr = &mystderr;
+      enabled = 1;
+      printf("init");
+
+   } else if (subtest == 1) {
+      do {
+         printf("\n => 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 (file)
index 0000000..23c9b7f
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef UART1_HPP
+#define UART1_HPP
+
+#include <stdint.h>
+#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