+ noekeon

This commit is contained in:
bg 2008-04-11 17:54:24 +00:00
parent 2c2d732098
commit 9e7453525f
8 changed files with 596 additions and 33 deletions

View File

@ -7,7 +7,8 @@ HASHES :=
MACS :=
PRNGS :=
# we use the gnu make standard library
include gmsl
include avr-makefile.inc
include *.mk
@ -23,6 +24,9 @@ ALGORITHMS_TEST_BIN_IMM = $(foreach a, $(ALGORITHMS_TEST_BIN), $($(a)))
ALGORITHMS_NESSIE_TEST = $(patsubst %,%_NESSIE_TEST, $(ALGORITHMS))
ALGORITHMS_PERFORMANCE_TEST = $(patsubst %,%_PERORMANCE_TEST, $(ALGORITHMS))
#ALGORITHMS_LC = #algorithm names in lowercase
#ALGORITHMS_LC = $(foreach a, $(ALGORITHMS), $$(lc Text))
ALGORITHMS_LC = $(call lc,$(ALGORITHMS))
PRG = remove_me
DEFS =
@ -53,6 +57,9 @@ info:
@echo " $(MACS)"
@echo " PRNG functions:"
@echo " $(PRNGS)"
@echo " LC functions:"
@echo " $(ALGORITHMS_LC)"
# echo $(ALGORITHMS_TEST_BIN_MAIN)
# echo $(ALGORITHMS)
# echo $(firstword $(XTEA_TEST_BIN))
@ -110,6 +117,18 @@ $(PRNGS_OBJ): $(patsubst %,%_OBJ, $(PRNGS))
$(MACS_OBJ): $(patsubst %,%_OBJ, $(MACS))
$(ALGORITHMS_TEST_BIN): $(ALGORITHMS_TEST_BIN_IMM)
define SIZE_TEMPLATE
$(1)_size.txt: $(2)
@echo " ALGO: $(1)"
@echo " REQ: $(2)"
$(SIZE) $(2) > $(1)_size.txt
endef
$(foreach algo, $(ALGORITHMS), $(eval $(call SIZE_TEMPLATE, $(call lc,$(algo)), $($(algo)_OBJ))))
.PHONY: all
all: $(PRG).elf lst text eeprom
@ -163,8 +182,8 @@ esrec: $(PRG)_eeprom.srec
%_eeprom.bin: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@
%_size.txt: %.o
$(SIZE) $< > $@
#%_size.txt: %.o
# $(SIZE) $< > $@

View File

@ -1,8 +1,8 @@
OBJ = $(SERPENT_OBJ)
MCU_TARGET = atmega32
MCU_TARGET = atmega644
OPTIMIZE = -Os
DEFS = -DATMEGA644
FLASHCMD = avrdude -p $(MCU_TARGET) -P /dev/ttyUSB0 -c avr911 -U flash:w:$(PRG).hex
# -U eeprom:w:$(PRG)_eeprom.hex
#uisp -dprog=bsd -dlpt=/dev/parport1 --upload if=$(PRG).hex
@ -10,8 +10,8 @@ ERASECMD =
CC = avr-gcc
override CFLAGS = -pedantic -std=c99 -Wall -Wstrict-prototypes $(OPTIMIZE) -mmcu=$(MCU_TARGET)
$(DEFS)
override CFLAGS = -pedantic -std=c99 -Wall -Wstrict-prototypes $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
override LDFLAGS = -Wl,-Map,
override ASFLAGS = -mmcu=$(MCU_TARGET)

View File

@ -23,5 +23,7 @@
#define UART_CTS_BIT 1
*/
#define ATMEGA644
#endif

226
main-noekeon-test.c Normal file
View File

@ -0,0 +1,226 @@
/*
* serpent test-suit
*
*/
#include "config.h"
#include "serial-tools.h"
#include "uart.h"
#include "debug.h"
#include "noekeon.h"
#include "nessie_bc_test.h"
#include "cli.h"
#include "performance_test.h"
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
char* cipher_name = "Noekeon";
/*****************************************************************************
* additional validation-functions *
*****************************************************************************/
void noekeon_genctx_dummy(uint8_t* key, uint16_t keysize, void* ctx){
noekeon_init(key, ctx);
}
void testrun_nessie_noekeon_indirect(void){
char str[strlen(cipher_name)+10];
strcpy(str, cipher_name);
strcat(str, "-indirect");
nessie_bc_ctx.blocksize_B = 16;
nessie_bc_ctx.keysize_b = 128;
nessie_bc_ctx.name = str;
nessie_bc_ctx.ctx_size_B = sizeof(noekeon_ctx_t);
nessie_bc_ctx.cipher_enc = (nessie_bc_enc_fpt)noekeon_enc;
nessie_bc_ctx.cipher_dec = (nessie_bc_dec_fpt)noekeon_dec;
nessie_bc_ctx.cipher_genctx = (nessie_bc_gen_fpt)noekeon_genctx_dummy;
nessie_bc_run();
}
void noekeon_genctx_dummy_direct(uint8_t* key, uint16_t keysize, void* ctx){
memcpy(ctx, key, 16);
}
void testrun_nessie_noekeon_direct(void){
char str[strlen(cipher_name)+10];
strcpy(str, cipher_name);
strcat(str, "-Direct");
nessie_bc_ctx.blocksize_B = 16;
nessie_bc_ctx.keysize_b = 128;
nessie_bc_ctx.name = str;
nessie_bc_ctx.ctx_size_B = sizeof(noekeon_ctx_t);
nessie_bc_ctx.cipher_enc = (nessie_bc_enc_fpt)noekeon_enc;
nessie_bc_ctx.cipher_dec = (nessie_bc_dec_fpt)noekeon_dec;
nessie_bc_ctx.cipher_genctx = (nessie_bc_gen_fpt)noekeon_genctx_dummy_direct;
nessie_bc_run();
}
void testrun_stdtest_rundirect(void* data, void* key){
uart_putstr_P(PSTR("\r\n "));
uart_putstr_P(PSTR("k = "));
uart_hexdump(key,16);
uart_putstr_P(PSTR("\r\n "));
uart_putstr_P(PSTR("a = "));
uart_hexdump(data,16);
noekeon_enc(data, key);
uart_putstr_P(PSTR("\r\nafter NESSIEencrypt, b = "));
uart_hexdump(data,16);
noekeon_dec(data, key);
uart_putstr_P(PSTR("\r\nafter NESSIEdecrypt, a?= "));
uart_hexdump(data,16);
uart_putstr_P(PSTR("\r\n"));
}
void testrun_stdtest_runindirect(void* data, void* key){
noekeon_ctx_t ctx;
uart_putstr_P(PSTR("\r\n "));
uart_putstr_P(PSTR("k = "));
uart_hexdump(key,16);
uart_putstr_P(PSTR("\r\n "));
uart_putstr_P(PSTR("a = "));
uart_hexdump(data,16);
noekeon_init(key, &ctx);
noekeon_enc(data, &ctx);
uart_putstr_P(PSTR("\r\nafter NESSIEencrypt, b = "));
uart_hexdump(data,16);
noekeon_dec(data, &ctx);
uart_putstr_P(PSTR("\r\nafter NESSIEdecrypt, a?= "));
uart_hexdump(data,16);
uart_putstr_P(PSTR("\r\n"));
}
void testrun_stdtest_noekeon(void){
uint8_t key[16], data[16];
uint8_t key3[16];
noekeon_ctx_t ctx;
uart_putstr_P(PSTR("\r\nTest vectors for block cipher Noekeon in Indirect-Key Mode:\r\n"));
memset(key, 0, 16);
memset(data, 0, 16);
testrun_stdtest_runindirect(data, key);
memset(key, 0xFF, 16);
memset(data, 0xFF, 16);
testrun_stdtest_runindirect(data, key);
memset(key, 0, 16);
memset(data, 0, 16);
noekeon_init(key, &ctx);
noekeon_enc(data, &ctx);
memcpy(key3, data, 16);
memset(key, 0xFF, 16);
memset(data, 0xFF, 16);
noekeon_init(key, &ctx);
noekeon_enc(data, &ctx);
testrun_stdtest_runindirect(data, key3);
uart_putstr_P(PSTR("\r\nTest vectors for block cipher Noekeon in Direct-Key Mode:\r\n"));
memset(key, 0, 16);
memset(data, 0, 16);
testrun_stdtest_rundirect(data, key);
memset(key, 0xFF, 16);
memset(data, 0xFF, 16);
testrun_stdtest_rundirect(data, key);
memset(key, 0, 16);
memset(data, 0, 16);
noekeon_enc(data, key);
memcpy(key3, data, 16);
memset(key, 0xFF, 16);
memset(data, 0xFF, 16);
noekeon_enc(data, key);
testrun_stdtest_rundirect(data, key3);
}
void testrun_performance_noekeon(void){
uint16_t i,c;
uint64_t t;
char str[6];
uint8_t key[16], data[16];
noekeon_ctx_t ctx;
calibrateTimer();
getOverhead(&c, &i);
uart_putstr_P(PSTR("\r\n\r\n=== benchmark ==="));
utoa(c, str, 10);
uart_putstr_P(PSTR("\r\n\tconst overhead: "));
uart_putstr(str);
utoa(i, str, 10);
uart_putstr_P(PSTR("\r\n\tinterrupt overhead: "));
uart_putstr(str);
memset(key, 0, 16);
memset(data, 0, 16);
startTimer(1);
noekeon_init(key, &ctx);
t = stopTimer();
uart_putstr_P(PSTR("\r\n\tctx-gen time: "));
uart_hexdump(&t, 8);
startTimer(1);
noekeon_enc(data, ctx);
t = stopTimer();
uart_putstr_P(PSTR("\r\n\tencrypt time: "));
uart_hexdump(&t, 8);
startTimer(1);
noekeon_dec(data, ctx);
t = stopTimer();
uart_putstr_P(PSTR("\r\n\tdecrypt time: "));
uart_hexdump(&t, 8);
uart_putstr_P(PSTR("\r\n"));
}
/*****************************************************************************
* main *
*****************************************************************************/
typedef void(*void_fpt)(void);
int main (void){
char str[20];
DEBUG_INIT();
uart_putstr("\r\n");
uart_putstr_P(PSTR("\r\n\r\nCrypto-VS ("));
uart_putstr(cipher_name);
uart_putstr_P(PSTR(")\r\nloaded and running\r\n"));
PGM_P u = PSTR("nessie\0test\0direct\0indirect\0performance\0");
void_fpt v[] = {testrun_nessie_noekeon_direct,
testrun_stdtest_noekeon,
testrun_nessie_noekeon_direct,
testrun_nessie_noekeon_indirect,
testrun_performance_noekeon};
while(1){
if (!getnextwordn(str,20)){DEBUG_S("DBG: W1\r\n"); goto error;}
if(execcommand_d0_P(str, u, v)<0){
uart_putstr_P(PSTR("\r\nunknown command\r\n"));
}
continue;
error:
uart_putstr("ERROR\r\n");
}
}

160
noekeon.c Normal file
View File

@ -0,0 +1,160 @@
/*
* author: Daniel Otte
* email: daniel.otte@rub.de
* license: GPLv3
*
*
*
*/
#include <stdint.h>
#include <string.h>
#include <avr/pgmspace.h>
#include "noekeon.h"
#define ROUND_NR 16
#define RC_POS 0
static
void gamma(uint32_t* a){
uint32_t tmp;
a[1] ^= ~((a[3]) | (a[2]));
a[0] ^= a[2] & a[1];
tmp=a[3]; a[3]=a[0]; a[0]=tmp;
a[2] ^= a[0] ^ a[1] ^ a[3];
a[1] ^= ~((a[3]) | (a[2]));
a[0] ^= a[2] & a[1];
}
#define ROTL32(a,n) (((a)<<n)|((a)>>(32-n)))
#define ROTR32(a,n) (((a)>>n)|((a)<<(32-n)))
static
void pi1(uint32_t* a){
a[1] = ROTL32(a[1], 1);
a[2] = ROTL32(a[2], 5);
a[3] = ROTL32(a[3], 2);
}
static
void pi2(uint32_t* a){
a[1] = ROTR32(a[1], 1);
a[2] = ROTR32(a[2], 5);
a[3] = ROTR32(a[3], 2);
}
static
void theta(uint32_t* k, uint32_t* a){
uint32_t temp;
temp = a[0] ^ a[2]; temp ^= ROTR32(temp, 8) ^ ROTL32(temp, 8);
a[1] ^= temp;
a[3] ^= temp;
a[0] ^= k[0];
a[1] ^= k[1];
a[2] ^= k[2];
a[3] ^= k[3];
temp = a[1] ^ a[3]; temp ^= ROTR32(temp, 8) ^ ROTL32(temp, 8);
a[0] ^= temp;
a[2] ^= temp;
}
static
void noekeon_round(uint32_t* key, uint32_t* state, uint8_t const1, uint8_t const2){
((uint8_t*)state)[RC_POS] ^= const1;
theta(key, state);
((uint8_t*)state)[RC_POS] ^= const2;
pi1(state);
gamma(state);
pi2(state);
}
uint8_t rc_tab[] PROGMEM = {
/* 0x80, */
0x1B, 0x36, 0x6C, 0xD8, 0xAB, 0x4D, 0x9A,
0x2F, 0x5E, 0xBC, 0x63, 0xC6, 0x97, 0x35, 0x6A,
0xD4
};
/* for more rounds
0xD4, 0xB3, 0x7D, 0xFA, 0xEF, 0xC5, 0x91, 0x39,
0x72, 0xE4, 0xD3, 0xBD, 0x61, 0xC2, 0x9F, 0x25,
*/
static
void changendian32(void* a){
((uint8_t*)a)[0] ^= ((uint8_t*)a)[3];
((uint8_t*)a)[3] ^= ((uint8_t*)a)[0];
((uint8_t*)a)[0] ^= ((uint8_t*)a)[3];
((uint8_t*)a)[1] ^= ((uint8_t*)a)[2];
((uint8_t*)a)[2] ^= ((uint8_t*)a)[1];
((uint8_t*)a)[1] ^= ((uint8_t*)a)[2];
}
static
void changendian(void* a){
changendian32((uint32_t*)(&(((uint32_t*)a)[0])));
changendian32((uint32_t*)(&(((uint32_t*)a)[1])));
changendian32((uint32_t*)(&(((uint32_t*)a)[2])));
changendian32((uint32_t*)(&(((uint32_t*)a)[3])));
}
/******************************************************************************/
void noekeon_enc(void* buffer, void* key){
uint8_t rc=0x80;
int8_t i;
changendian(buffer);
changendian(key);
for(i=0; i<ROUND_NR; ++i){
noekeon_round((uint32_t*)key, (uint32_t*)buffer, rc, 0);
rc = pgm_read_byte(rc_tab+i);
}
((uint8_t*)buffer)[RC_POS] ^= rc;
theta((uint32_t*)key, (uint32_t*)buffer);
changendian(buffer);
changendian(key);
}
void noekeon_dec(void* buffer, void* key){
uint8_t rc;
int8_t i;
uint8_t nullv[16];
uint8_t dkey[16];
changendian(buffer);
changendian(key);
memset(nullv, 0, 16);
memcpy(dkey, key, 16);
theta((uint32_t*)nullv, (uint32_t*)dkey);
for(i=ROUND_NR-1; i>=0; --i){
rc = pgm_read_byte(rc_tab+i);
noekeon_round((uint32_t*)dkey, (uint32_t*)buffer, 0, rc);
}
theta((uint32_t*)dkey, (uint32_t*)buffer);
((uint8_t*)buffer)[RC_POS] ^= 0x80;
changendian(buffer);
changendian(key);
}
void noekeon_init(void* key, noekeon_ctx_t* ctx){
uint8_t nullv[16];
memset(nullv, 0, 16);
memcpy(ctx, key, 16);
noekeon_enc(ctx, nullv);
}

21
noekeon.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef NOEKEON_H_
#define NOEKEON_H_
/*
* author: Daniel Otte
* email: daniel.otte@rub.de
* license: GPLv3
*
*
*
*/
#include <stdint.h>
typedef uint8_t noekeon_ctx_t[16];
void noekeon_enc(void* buffer, void* key);
void noekeon_dec(void* buffer, void* key);
void noekeon_init(void* key, noekeon_ctx_t* ctx);
#endif /*NOEKEON_H_*/

View File

@ -1,15 +1,25 @@
/*
* author: Daniel Otte
* email: daniel.otte@rub.de
* license: GPLv3
*
*
*
*/
**/
#include "config.h"
#include <stdint.h>
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "performance_test.h"
#ifdef ATMEGA644
#define TIMSK TIMSK1
#endif
uint32_t ovfcounter;
uint16_t const_overhead=0;
@ -37,7 +47,7 @@ void startTimer(uint8_t granularity){
ovfcounter = 0;
TCCR1A = 0x00;
TIMSK &= 0xC3;
TIMSK |= _BV(2); /* enable TOIE1 */
TIMSK |= _BV(TOIE1); /* enable TOIE1 */
TCCR1B = granularity & 0x7; /* start timer */
}

169
uart.c
View File

@ -3,7 +3,6 @@
#include "config.h"
#include <avr/io.h>
//#include <avr/signal.h>
#include <avr/interrupt.h>
#include <stdlib.h>
@ -18,9 +17,42 @@
#define URSEL UMSEL
#endif
#ifdef ATMEGA644
#define UCSRB UCSR0B
#define UCSRC UCSR0C
#define UDR UDR0
#define UBRRH UBRR0H
#define UBRRL UBRR0L
#define URSEL UMSEL00
#define USART_UDRE_vect USART0_UDRE_vect
#define USART_RXC_vect USART0_RX_vect
#define UDRIE UDRIE0
#define TXEN TXEN0
#define UMSEL UMSEL0
#define RXEN RXEN0
#define RXCIE RXCIE0
#define UCSZ0 UCSZ00
#define UCSRA UCSR0A
#define UDRE UDRE0
#define RXC RXC0
#endif
#ifdef UART_XON_XOFF
#ifdef UART_INTERRUPT
void uart_insertc(char c);
#else
#define uart_insertc uart_putc
#endif /* UART_INTERRUPT */
#endif
#define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC)/((UART_BAUD_RATE)*16L)-1)
#ifdef UART_XON_XOFF
typedef enum{go=1,nogo=0} gonogo;
static gonogo txon=go;
static gonogo rxon=go;
#endif
#ifdef UART_INTERRUPT
volatile static char rxbuf[UART_RXBUFSIZE];
@ -28,8 +60,11 @@ volatile static char txbuf[UART_TXBUFSIZE];
volatile static char *volatile rxhead, *volatile rxtail;
volatile static char *volatile txhead, *volatile txtail;
#ifdef UART_HOOK
void (*uart_hook) (uint8_t) = (void*)0; /* this is a pointer to a function ;-) */
#endif
SIGNAL(SIG_UART_DATA) {
ISR(USART_UDRE_vect) {
#ifdef UART_LEDS
PORTC ^= 0x01;
#endif
@ -37,39 +72,89 @@ SIGNAL(SIG_UART_DATA) {
if ( txhead == txtail ) {
UCSRB &= ~(1 << UDRIE); /* disable data register empty IRQ */
} else {
#ifdef UART_XON_XOFF
while(txon==nogo)
;
#endif
UDR = *txtail; /* schreibt das Zeichen x auf die Schnittstelle */
if (++txtail == (txbuf + UART_TXBUFSIZE)) txtail = txbuf;
}
}
SIGNAL(SIG_UART_RECV) {
ISR(USART_RXC_vect) {
int diff;
char c;
#ifdef UART_HOOK
static volatile uint8_t hook_running=0;
#endif
#ifdef UART_LEDS
PORTC ^= 0x02;
#endif
c=UDR;
#ifdef UART_XON_XOFF
if (c==XON){
txon=go;
return;
}
if (c==XOFF){
txon=nogo;
return;
}
#endif
/* buffer full? */
diff = rxhead - rxtail;
if ( diff < 0 ) diff += UART_RXBUFSIZE;
if (diff < 0) diff += UART_RXBUFSIZE; /* diff is the amount of bytes in buffer */
if (diff < UART_RXBUFSIZE -1) {
// buffer NOT full
*rxhead = UDR;
if (++rxhead == (rxbuf + UART_RXBUFSIZE)) rxhead = rxbuf;
#ifdef UART_HOOK
if(!hook_running && uart_hook){
uint8_t t=c;
hook_running = 1;
sei(); /* reenable interrupts, avoid recursion!!! */
do {
uart_hook(t);
} while(uart_getc_nb((char*)&t));
hook_running = 0;
} else {
*rxhead = c;
++rxhead;
if (rxhead == (rxbuf + UART_RXBUFSIZE)) rxhead = rxbuf;
}
#else
*rxhead = c;
++rxhead;
if (rxhead == (rxbuf + UART_RXBUFSIZE))
rxhead = rxbuf;
#endif
} else {
UDR; //reads the buffer to clear the interrupt condition
//reads the buffer to clear the interrupt condition
}
#ifdef UART_XON_XOFF
if((diff > UART_XON_XOFF_THRESHOLD_1) && (rxon==go)){
rxon=nogo;
uart_insertc(XOFF);
}
if((diff < UART_XON_XOFF_THRESHOLD_2) && (rxon==nogo)){
rxon=go;
uart_insertc(XON);
}
#endif
}
#endif // UART_INTERRUPT
void uart_init(void) {
void uart_init() {
PORTD |= 0x01; //Pullup an RXD an
UCSRB |= (1<<TXEN); //UART TX einschalten
#ifdef ATMEGA644
UCSRA = 0;
UCSRC = (3<<UCSZ0); //Asynchron 8N1
#else
UCSRA = 0;
UCSRC |= (1<<URSEL)|(3<<UCSZ0); //Asynchron 8N1
#endif
UCSRB |= ( 1 << RXEN ); //Uart RX einschalten
UBRRH=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU)>>8);
@ -81,11 +166,32 @@ void uart_init(void) {
txhead = txtail = txbuf;
// activate rx IRQ
UCSRB |= (1 << RXCIE);
UCSRB |= _BV(RXCIE) | _BV(UDRIE);
sei();
// #ifdef ATMEGA644
// UCSRB |= _BV(UDRIE);
// #endif
#endif // UART_INTERRUPT
}
#ifdef UART_INTERRUPT
#ifdef UART_XON_XOFF
void uart_insertc(char c){
volatile int diff;
do {
diff = txhead - txtail;
if ( diff < 0 ) diff += UART_TXBUFSIZE;
} while ( diff >= UART_TXBUFSIZE -1 );
cli();
if (--txtail == (txbuf-1)) txtail += UART_TXBUFSIZE;
*txtail = c;
UCSRB |= (1 << UDRIE); /* enable data register empty IRQ */
sei();
}
#endif /* UART_XON_XOFF */
void uart_putc(char c) {
volatile int diff;
@ -104,8 +210,13 @@ void uart_putc(char c) {
}
#else // WITHOUT INTERRUPT
void uart_putc(char c) {
while (!(UCSRA & (1<<UDRE))); /* warten bis Senden moeglich */
UDR = c; /* schreibt das Zeichen x auf die Schnittstelle */
while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */
;
#ifdef UART_XON_XOFF
while (txon==nogo) /* warte bis XON empfangen */
;
#endif
UDR = c; /* schreibt das Zeichen x auf die Schnittstelle */
}
#endif // UART_INTERRUPT
@ -126,13 +237,13 @@ void uart_putstr_P(PGM_P str) {
void uart_hexdump(void* buf, int len)
{
unsigned char table[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
unsigned char table[]={'0','1','2','3','4','5','6','7',
'8','9','a','b','c','d','e','f'};
while(len--){
uart_putc(table[((*((char*)buf))>>4)&0xf]);
uart_putc(table[(*((char*)buf))&0xf]);
uart_putc(' ');
buf=(char*)buf+1;
buf=(uint8_t*)buf+1;
}
}
@ -142,18 +253,28 @@ char uart_getc(void)
{
char val;
while(rxhead==rxtail) ;
while(rxhead==rxtail)
;
val = *rxtail;
if (++rxtail == (rxbuf + UART_RXBUFSIZE)) rxtail = rxbuf;
++rxtail;
if (rxtail == (rxbuf + UART_RXBUFSIZE))
rxtail = rxbuf;
return val;
}
#else // WITHOUT INTERRUPT
char uart_getc(void)
{
while (!(UCSRA & (1<<RXC))); // warten bis Zeichen verfuegbar
return UDR; // Zeichen aus UDR zurueckgeben
char t;
while (!(UCSRA & (1<<RXC)))
; // warten bis Zeichen verfuegbar
t=UDR;
#ifdef UART_XON_XOFF
if (t==XON) txon=go;
if (t==XOFF) txon=nogo;
#endif
return t; // Zeichen aus UDR zurueckgeben
}
#endif // UART_INTERRUPT
@ -173,6 +294,10 @@ char uart_getc_nb(char *c)
{
if (UCSRA & (1<<RXC)) { // Zeichen verfuegbar
*c = UDR;
#ifdef UART_XON_XOFF
if (*c==XON) txon=go;
if (*c==XOFF) txon=nogo;
#endif
return 1;
}