Giter Club home page Giter Club logo

avr-uart-lib's Introduction

AVR-UART-lib

An interrupt-driven USART (RS232) library for AVR microcontrollers, with support for multiple hardware UARTs, using ring buffers for receive/transmit. Designed especially for real-time or high throughput applications, with narrow resource limits.

Features

  • selectable support for up to 4 USART's
  • up to 255 byte FIFOs
  • only 2 (+1 wasted slot) byte memory footprint except actual buffer for every implemented RX or TX path
  • no dynamic memory allocations
  • extremly light interrupts
  • software(RTS/CTS) and hardware flow control support (DCE naming)
  • RS 485 compatibility
  • MPCM master and slave mode support
  • printf()/scanf() streams compatibility
  • V-USB compatibility (25 cycle ISR restriction)
  • optimized as much as possible to reduce code size and execution times

Notes

  • Lot of terminals sends only CR character as a newline terminator, instead of CRLF or even unix style LF (BTW PuTTY doesn't allow to change this) but in return requires CRLF terminator to show not broken text. This behaviour can be covered by RX_NEWLINE_MODE macro, by default set to CRLF.

    • 0 - CR
    • 1 - LF
    • 2 - CRLF (default)
  • In order to reinitialize uart baudrate after any traffic was occurring, function uart_reinit() have to be used. (memory FIFO buffers will not be flushed)

  • Any used IO pin have to be accessible from bottom IO address space. (eg. few ports on mega2560 cannot be used as a control IO)

  • In half duplex (RS485) transmission modes, the application code is responsible of starting transmission only when bus is idle. If RE and DE are shorted together additional pullup on RX pin is required. Pin used as a RS485 control line have to be kept in low state during boot process via a pulldown resistor or at least not driving it high even by an internall pull-up. (especially on multi node buses)

  • In MPCM mode first received byte is address by which device was called (own or general call), application is also responsible of restoring into "idle listening" state withing described bus silence time after receiving entire packet.

  • uart_putc() function is not thread/interrupt-safe nor reentrant. It shouldn't be called from within atomic blocks or interrupt handlers since it re-enables interrupt flag on exit or even hangs in infinite loop waiting for execution of UDRE interrupt.

  • this library is written in c99/gnu99 dialect standard.

Flow control

This library provides a software implementation of CTS/RTS control lines (DTR/DSR respectively) to signal whether buffer is full (not an 80' style handshaking). It should be used, in order to achieve stable bidirectional >100kbps transmissions, especially when using non deterministic usb-serial converters (ft232, ch340 etc). The legendary "noise" that causes losing blocks of characters (not damaging) can also be fixed by that.

Config

  • soft CTS pins have to be configured as an input, and both edge interrupt source (INT/PCINT), before entering uart_init(). The application code should call cts_isr_handlers from interrupts corresponding to used pins. (see [example](example(flow control).c)) If CTS line goes high during transmission (before UDRE interrupt is fired), only one additional byte will be transmitted. (due to 2 level transmit register)

  • soft RTS pins have to be configured as input without pullup or output in low state, before entering uart_init(). If interrupts are not missed, the receiver can accept up to 2 additional bytes after buffer is filled, one from next or ongoing transmission and another one if transmitter misses RTS signal (last one is stored in shift register).

  • Any used IO pin have to be accessible from bottom IO address space. (eg. few ports on mega2560 cannot be used as a flow control IO)

  • For proper operation of hardware RTS, USART_EXTEND_RX_BUFFER have to be defined.

ISR timmings (cycles)

ISR case attiny2313 atmega8 atmega328 atmega2560 lgt8f88A
TX best 37 40 40 42 30
TX worst 38 41 44 46 35
RX best 36 36 37 39 27
RX worst 40 42 43 45 32
RX rts full 41 41 44 46 32
RX rts normal 40 42 43 45 32
BUFFER_SIZE = 256 x -1 -1 -1 -1
G_SREG_SAVE -4 -4 -4 -4 -2
G_Z_SAVE -6 -6 -6 -6 -2
  • TX best case - send byte from buffer
  • TX worst case - send byte from buffer and disable UDRIE interrupt (will not generate double shot)
  • RX best case - load byte and do nothing (buffer full)
  • RX worst case - load byte and put it into buffer
  • RX rts full - rise RTS line and disable RXCIE interrupt
  • RX rts normal - load byte and put it into buffer if there is available space

avr-uart-lib's People

Contributors

beeryt avatar fightingdreamer avatar jnk0le avatar smu81 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

avr-uart-lib's Issues

AVR-UART-lib && Atmega328

Hi,

Sorry for the rather vague issue, but I am having some problems getting your library to work with AtmelStudio 7 and Atmega328.
Even a clean project with the example multiple usart.c, and the required headers fails with multiple undeclared warnings. Explicitly defining the prototypes just digs me deeper down a rabbit hole with subsequent errors.
Is this a known incompatibility?

Regards,

Petter.

atmega32u4 failing to build, multiple definition of uart1_hardware_flow_control_init

While I strongly believe my issue is in my build environment I am able to compile when I change the -mmcu to atmega328p. The atmega32u4 does not have UBBR or UBBR0 it only has UBRR1 and that might be causing the issue. However I do see the 32u4 in the header.

pio run -v
Processing atmega32u4 (platform: atmelavr; board_build.mcu: atmega32u4; board_build.f_cpu: 16000000L; upload_protocol: arduino; upload_speed: 115200; build_unflags: -std=gnu11; build_flags: -std=gnu99)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------HARDWARE: ATMEGA32U4 16MHz,
PACKAGES: 
 - toolchain-atmelavr 1.70300.191015 (7.3.0)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 4 compatible libraries
More details about "Library Compatibility Mode": https://docs.platformio.org/page/librarymanager/ldf.html#ldf-compat-mode
Scanning dependencies...
Dependency Graph
|-- <usart> (D:\Documents\OneDrive\Documents\PlatformIO\Projects\delme\lib\usart)
Building in release mode
avr-gcc -o .pio\build\atmega32u4\src\main.o -c -fno-fat-lto-objects -std=gnu99 -Os -Wall -ffunction-sections -fdata-sections -flto -mmcu=atmega32u4 -DF_CPU=16000000L -DPLATFORMIO=50101 -Iinclude -Isrc -Ilib\usart src\main.c
avr-gcc -o .pio\build\atmega32u4\libbd1\usart\usart.o -c -fno-fat-lto-objects -std=gnu99 -Os -Wall -ffunction-sections -fdata-sections -flto -mmcu=atmega32u4 -DF_CPU=16000000L -DPLATFORMIO=50101 -Ilib\usart lib\usart\usart.c
In file included from src\main.c:8:0:
lib\usart/usart.h:1439:7: warning: always_inline function might not be inlinable [-Wattributes]
  void uart1_hardware_flow_control_init(uint8_t ctsenable, uint8_t rtsenable) // pass true to enable
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from lib\usart\usart.c:18:0:
lib\usart\usart.h:1439:7: warning: always_inline function might not be inlinable [-Wattributes]
  void uart1_hardware_flow_control_init(uint8_t ctsenable, uint8_t rtsenable) // pass true to enable
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
avr-gcc-ar rc .pio\build\atmega32u4\libbd1\libusart.a .pio\build\atmega32u4\libbd1\usart\usart.o
avr-gcc -o .pio\build\atmega32u4\firmware.elf -Os -mmcu=atmega32u4 -Wl,--gc-sections -flto -fuse-linker-plugin .pio\build\atmega32u4\src\main.o -L.pio\build\atmega32u4 -Wl,--start-group .pio\build\atmega32u4\libbd1\libusart.a -lm -Wl,--end-group
usart.o (symbol from plugin): In function `uart1_hardware_flow_control_init':
(.text+0x0): multiple definition of `uart1_hardware_flow_control_init'
.pio\build\atmega32u4\src\main.o (symbol from plugin):(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\atmega32u4\firmware.elf] Error 1
================================================================================================== [FAILED] Took 1.66 seconds ==================================================================================================

and the main.c file

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdio.h>
#include <string.h>

#include "usart.h"


int main (void) {


  DDRB = 1 << 5;

  sei();
  uart1_init(BAUD_CALC(115200));
  uart1_putc('c');

  while (1) {
    _delay_ms(500);
    PORTB ^= 1 << 5;
  }

  return 0;
}

warning: 'uart0_putc_' alias between functions of incompatible types char(char)' and 'void(char)'

I get a warning emitted about incompatible types withe an alias.

$ avr-gcc -c -mmcu=atmega328p -DF_CPU=16000000 -O -o usart.o usart.c
usart.c:480:14: warning: 'uart0_putc_' alias between functions of incompatible types char(char)' and 'void(char)' [-Wattribute-alias=]
480 | char uart0_putc_(char data) attribute ((alias ("uart0_putc"))); // alias for uart_putc that returns passed argument unaffected by omitting any existent rule
| ^~~~~~~~~~~
usart.c:315:14: note: aliased declaration here
315 | void uart0_putc(char data)
| ^~~~~~~~~~

I'm not sure if this is due to something missing on my part.

error: expected ‘;’, ‘,’ or ‘)’ before ‘char’

make[1]: Entering directory '/home/paul/Cprojects/Production/Encoder2/MicrocontrollerCode/AVR/Src_Modules/MicroC_Application'

avr-gcc -Wall -Os -DF_CPU=8000000 -mmcu=atmega328p -std=c11 -Wall -D RELEASE -c src/example.c -o ../../Objects/ReleaseAvrStatic/example.o
In file included from src/example.c:8:0:
src/usart.h:1593:27: warning: type defaults to ‘int’ in declaration of ‘__flash’
void uart0_puts_p(const __flash char *string); // send string from flash memory
^
src/usart.h:1593:35: error: expected ‘;’, ‘,’ or ‘)’ before ‘char’
void uart0_puts_p(const __flash char *string); // send string from flash memory
^
src/example.c:12:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
void main(void)
^
src/example.c: In function ‘main’:
src/example.c:24:2: warning: implicit declaration of function ‘uart0_puts_p’ [-Wimplicit-function-declaration]
uart_puts_P("hello from flashed, usart\r\n"); // write string to usart buffer from flash memory // string is parsed by PSTR() macro
^
Makefile:25: recipe for target '../../Objects/ReleaseAvrStatic/example.o' failed
make[1]: *** [../../Objects/ReleaseAvrStatic/example.o] Error 1
make[1]: Leaving directory '/home/paul/Cprojects/Production/Encoder2/MicrocontrollerCode/AVR/Src_Modules/MicroC_Application'
Makefile:28: recipe for target 'Application' failed
make: *** [Application] Error 2

I think it is self explicative

Library cannot build with RS485 functionality

Hello and first of all congratulations on an excellent library.
I have been using it for RS-232 and it works flawlessly.
I am now trying to use t with RS-485 features on on an ATtiny841 and I am getting a lot of build errors.
Most of them are
lvalue required as left operand of assignment wherever a call to ___PORT or ___DDR is done
I am also getting some
pasting "PORT" and "(" does not give a valid preprocessing token.
My configuration for RS-485 is the following:
#define RS485_CONTROL0_IOPORTNAME A #define RS485_CONTROL0_PIN 1
Once again thanks a lot for your great library

Synchronous

hey
thanks for lib
is usart synchronous mode is implemented?
i wanted to use slave sync mode, where UCSR1C=(1<<UMSEL1) and baud rate is = 0
is this possible?

no support for tinyAVR 2-series

Please consider adding support for tinyAVR 2-family, e.g., ATtiny424, ATtiny426, ATtiny427, ATtiny824, ATtiny826, ATtiny827, ATtiny1624, ATtiny1626, ATtiny1627, ATtiny3224, ATtiny3226, ATtiny3227.

small code improvements

Hi - a little advice - you have a lot od #define in code. for example:

void uart0_reinit(uint16_t ubrr_value)
{
	#ifdef USART0_USE_SOFT_RTS
		RTS0_PORT |= (1<<RTS0_IONUM);
	#endif
		
	#ifdef USART0_RS485_MODE
		RS485_CONTROL0_PORT &= ~(1<<RS485_CONTROL0_IONUM); //set low
		RS485_CONTROL0_DDR |= (1<<RS485_CONTROL0_IONUM);
	#endif
		
          // rest of the function
}

you can simply hide #defines by implement static functions:

static void USART0_USE_SOFT_RTS_func(void)
{
	#ifdef USART0_USE_SOFT_RTS
		RTS0_PORT |= (1<<RTS0_IONUM);
	#endif
}
static void USART0_RS485_MODE_on(void)
{
	#ifdef USART0_RS485_MODE
		RS485_CONTROL0_PORT &= ~(1<<RS485_CONTROL0_IONUM); //set low
		RS485_CONTROL0_DDR |= (1<<RS485_CONTROL0_IONUM);
	#endif
}

void uart0_reinit(uint16_t ubrr_value)
{
                USART0_USE_SOFT_RTS_func();
		USART0_RS485_MODE_on();
		
                // rest of the function
}
}

compiler will remove all unused jumps etc - and functions are easier to read. Of course- just in my opinion.

Building an example(multiple usart).c

When I try to compile an example I have an error at those strings:

		fprintf(uart1_io, "Say my name: ");
		fscanf(uart1_io, "%s", buffer);
		fprintf(uart1_io, "So it's %s, You are damn' right.\n", buffer);

Error - incompatible type for argument 1 of 'fprintf'.

I use Atmel Studio 7 (Version: 7.0.2397 - )

NO_USART0 follow on effect

Great library, good work! I tried the NO_USART0 option and generated a couple of errors, reckon the below changes might be the fix...
Line 1622 of usart.h;
shouldn't this be
UCSR3A_REGISTER |= (1<<U2X3_BIT);
instead of
UCSR3A_REGISTER |= (1<<U2X0_BIT);
?

Also, shouldn't line 5439 of usart.c be
[UDR_reg_IO] "M" (_SFR_IO_ADDR(UDR1_REGISTER)),
instead of of
[UDR_reg_IO] "M" (_SFR_IO_ADDR(UDR0_REGISTER)),
?
Hope this is constructive, haven't githubbed before :)

undefined reference to `load_NULL_834' when RX_NEWLINE_MODE is CR or LF

When setting RX_NEWLINE_MODE to anything other than "2", the following error occurs:
usart.o: In function uart0_getlnToFirstWhiteSpace': usart.c:2132: undefined reference to load_NULL_834'

It appears that the definition of the symbol "load_NULL_..." no longer exists in the assembly code.

Freeze within ISR(RX0_INTERRUPT, ISR_NAKED) when invalid data is received

Hi,
upon connecting the RX wire sometimes my ATmega324 hangs somewhere in the RX interrupt handler (found this out with debug LEDs, as I can't use JTAG). I don't know how to proceed further when looking for the error, as I have no clue about assembler.

I have excluded ground loop issues and tried various config options with no success.

Is there any config switch to make the whole thing more robust? A system freeze upon UART cable connection is unfortunately something I can't live with.

Thanks in advance!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.