#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 () {
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;
}
}
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;
Motor motor;
PortExp portExp;
Lcd lcd;
+ Uart1 uart1;
Modbus modbus;
+ Ieee485 ieee485;
}
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;
if (modbus.enabled) {
modbus.handleRxByte(b);
}
+ if (uart1.enabled) {
+ uart1.handleRxByte(b);
+ }
+ if (ieee485.enabled) {
+ ieee485.handleRxByte(b);
+ }
}
ISR (TIMER2_COMPA_vect) { // every 100us
--- /dev/null
+#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;
+}
--- /dev/null
+#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
--- /dev/null
+#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);
+}
--- /dev/null
+#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