Commit 18fda8fe authored by Christian Dietrich's avatar Christian Dietrich
Browse files

firmware source imported, wrote an README

parent bd85bfcc
# $Id: Makefile 5 2006-01-12 21:41:36Z matled $
CC=avr-gcc
LD=avr-gcc
RM=rm -f --
MCU=attiny2313
ISP=usbasp
-include Makefile.local
OBJECTS+= firmware.o
HEADERS+=$(shell echo *.h)
TARGET=firmware
LDFLAGS+=
CFLAGS+=-std=c99 -pedantic-errors -Wall -W -mmcu=$(MCU)
ifneq ($(DEBUG),) # {{{
CFLAGS+=-ggdb3
CFLAGS+=-Wchar-subscripts -Wmissing-prototypes
CFLAGS+=-Wmissing-declarations -Wredundant-decls
CFLAGS+=-Wstrict-prototypes -Wshadow -Wbad-function-cast
CFLAGS+=-Winline -Wpointer-arith -Wsign-compare
CFLAGS+=-Wunreachable-code -Wdisabled-optimization
CFLAGS+=-Wcast-align -Wwrite-strings -Wnested-externs -Wundef
CFLAGS+=-DDEBUG
LDFLAGS+=
else
CFLAGS+=-O2
LDFLAGS+=
endif
# }}}
ifneq ($(PROFILING),) # {{{
CFLAGS+=-pg -DPROFILING
LDFLAGS+=-pg
endif
# }}}
all: $(TARGET)
clean:
$(RM) $(TARGET) $(OBJECTS) $(TARGET).hex
.PHONY: clean all
%.o: $(HEADERS)
$(TARGET): $(OBJECTS)
$(LD) -o $@ $^ $(LDFLAGS)
$(TARGET).hex: $(TARGET)
avr-objcopy -R .eeprom -O ihex $^ $@
avr-size $@
load: $(TARGET).hex
avrdude -p $(MCU) -U flash:w:$^.hex -c $(ISP)
!! RS232-RS485 Converter
This Project wants to be a simple, low cost, open-source rs232 to rs485
converter (half duplex). So you can simply attach the converter to your serial port
(com-port) and start to talk on a rs485 bus.
!!! Why the hell is there an ATTiny2313 on the converter?
Because this is a half duplex rs485 converter, we must toggle the RE/DE pins
at the MAX485 in order to enable sending. My first thought was to to this with
the RTS pin of the serial port. But there were a few problems:
* The sending toggle should be done within userspace, were we can't guarantee
real time. So it would be possible that our RE/DE pins is high 500ms too
long and we miss the answer to our packet.
* With the 16550 ( the chip on your mainboard, if you have an x86, which does
the serial port for you ), you can't drive the RTS pin in an rs485
compatible mode in hardware, so it would have be done in a kernel modul, and
then it is also only estimation, when the last byte is sent.
So i decided to attach an ATTiny2313 ( the smallest avr I had here ), which
does the toggling of the RE/DE pin. It enables the RE/DE pin for sending, when
it does detect a rising edge on the RTS pin. The RE/DE is enabled until there
is no pin change for about 1ms on the TX line. It also drives the RX/TX leds
of the dongle.
If you have comments, critic write a mail to
stettberger(at)dokucode(dot)de
/* Copyright(C) 2008 Christian Dietrich <stettberger@dokucode.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define F_CPU 8000000L
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
#include <avr/eeprom.h>
#define RTS_INT SIG_INTERRUPT0
#define TX_INT SIG_INTERRUPT1
#define DE_PORT PORTD
#define DE_DDR DDRD
#define DE_IN PIND
#define DE_PIN 4
#define RECV_IN PINA
#define RECV_PIN 0
#define TX_PORT PORTB
#define TX_DDR DDRB
#define TX_LED 1
#define RX_PORT PORTD
#define RX_DDR DDRD
#define RX_LED 6
static inline void
timer_init(void)
{
/* 256 Prescaler */
TCCR0B = _BV(CS02);
OCR0A = 33;
/* Int. bei Overflow und CompareMatch einschalten */
TIMSK |= _BV(OCIE0A);
}
static inline void
interrupt_init(void)
{
/* Interrupt on:
* - rising edge of RTS
* - any logical change of TX
*/
MCUCR |= _BV(ISC01) | _BV(ISC00) | _BV(ISC10);
GIMSK |= _BV(INT0) | _BV(INT1);
}
SIGNAL(RTS_INT) {
DE_PORT |= _BV(DE_PIN);
TCNT0 = 0;
}
SIGNAL(TX_INT) {
TCNT0 = 0;
}
SIGNAL(SIG_OUTPUT_COMPARE0A) {
DE_PORT &= ~_BV(DE_PIN);
}
int
main(void)
{
DE_DDR |= _BV(DE_PIN);
TX_DDR |= _BV(TX_LED);
RX_DDR |= _BV(RX_LED);
timer_init();
interrupt_init();
sei();
for(;;) {
if (DE_IN & _BV(DE_PIN))
TX_PORT |= _BV(TX_LED);
else
TX_PORT &= ~_BV(TX_LED);
if (!(RECV_IN & _BV(RECV_PIN)))
RX_PORT |= _BV(RX_LED);
else
RX_PORT &= ~_BV(RX_LED);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment