From 9ef5896d674c02b7fa10340aee05d91459639d59 Mon Sep 17 00:00:00 2001 From: Thomas von Dein Date: Mon, 17 Feb 2020 19:43:07 +0100 Subject: [PATCH] +tests --- 2313-avr-only-test/Makefile | 168 +++++++++++++++ 2313-avr-only-test/analog.c | 34 +++ 2313-avr-only-test/analog.h | 12 ++ 2313-avr-only-test/delay.h | 285 ++++++++++++++++++++++++++ 2313-avr-only-test/digital.c | 35 ++++ 2313-avr-only-test/digital.h | 16 ++ 2313-avr-only-test/main.c | 40 ++++ 2313-avr-only-test/picoUART.h | 193 +++++++++++++++++ 2313-avr-only-test/serial.S | 44 ++++ 2313-avr-only-test/serial.h | 23 +++ 2313-tinycore-test/Blink.ino | 24 +++ 2313-tinycore-test/Makefile | 33 +++ 2313-tinycore-test/hardware | 1 + 841-tinycore-test/Blink.ino | 24 +++ 841-tinycore-test/Makefile | 47 +++++ 841-tinycore-test/hardware | 1 + 841-tinycore-test/libraries/GFX | 1 + 841-tinycore-test/libraries/SPI | 1 + 841-tinycore-test/libraries/SSD1306 | 1 + 841-tinycore-test/libraries/TinyWireM | 1 + 841-tinycore-test/libraries/Wire | 1 + 85-avr-only-test/Makefile | 156 ++++++++++++++ 85-avr-only-test/analog.c | 34 +++ 85-avr-only-test/analog.h | 12 ++ 85-avr-only-test/delay.h | 285 ++++++++++++++++++++++++++ 85-avr-only-test/digital.c | 35 ++++ 85-avr-only-test/digital.h | 16 ++ 85-avr-only-test/main.c | 26 +++ 85-tinycore-test/Blink.ino | 24 +++ 85-tinycore-test/Makefile | 47 +++++ 85-tinycore-test/hardware | 1 + 31 files changed, 1621 insertions(+) create mode 100755 2313-avr-only-test/Makefile create mode 100644 2313-avr-only-test/analog.c create mode 100644 2313-avr-only-test/analog.h create mode 100644 2313-avr-only-test/delay.h create mode 100644 2313-avr-only-test/digital.c create mode 100644 2313-avr-only-test/digital.h create mode 100755 2313-avr-only-test/main.c create mode 100644 2313-avr-only-test/picoUART.h create mode 100644 2313-avr-only-test/serial.S create mode 100644 2313-avr-only-test/serial.h create mode 100644 2313-tinycore-test/Blink.ino create mode 100644 2313-tinycore-test/Makefile create mode 120000 2313-tinycore-test/hardware create mode 100644 841-tinycore-test/Blink.ino create mode 100644 841-tinycore-test/Makefile create mode 120000 841-tinycore-test/hardware create mode 120000 841-tinycore-test/libraries/GFX create mode 120000 841-tinycore-test/libraries/SPI create mode 120000 841-tinycore-test/libraries/SSD1306 create mode 120000 841-tinycore-test/libraries/TinyWireM create mode 120000 841-tinycore-test/libraries/Wire create mode 100755 85-avr-only-test/Makefile create mode 100644 85-avr-only-test/analog.c create mode 100644 85-avr-only-test/analog.h create mode 100644 85-avr-only-test/delay.h create mode 100644 85-avr-only-test/digital.c create mode 100644 85-avr-only-test/digital.h create mode 100755 85-avr-only-test/main.c create mode 100644 85-tinycore-test/Blink.ino create mode 100644 85-tinycore-test/Makefile create mode 120000 85-tinycore-test/hardware diff --git a/2313-avr-only-test/Makefile b/2313-avr-only-test/Makefile new file mode 100755 index 0000000..bc3674a --- /dev/null +++ b/2313-avr-only-test/Makefile @@ -0,0 +1,168 @@ +#------------------------------------------------------------------------------------------------------- +# makefile +# +# written by Steffen from mikrocontrollerspielwiese.de +# +# inspired from Guido Socher's makefile +# http://www.linuxfocus.org/Deutsch/November2004/article352.shtml +# +# license: GPL (http://www.gnu.org/licenses/gpl.txt) +#------------------------------------------------------------------------------------------------------- + + +AVRDUDE=/usr/local/bin/avrdude + +# avr-gcc part name +MCU=attiny2313 + +# avrdude part name +#PART=t85 +PART=t2313 + +CC=avr-gcc +CPP=avr-c++ +ASM=avr-as + +#CPP=env -P/usr/local/bin:/usr/bin - avr-c++ +#CC=env -P/usr/local/bin:/usr/bin - avr-gcc +OBJCOPY=avr-objcopy + +PORT=$(shell ls /dev/ttyACM*) + +#------------------- +# Programmieradapter + +# hier kannst Du Deinen Programmieradapter angeben, wenn Du einen +# anderen nimmst, als in der Mikrocontrollerspielwiese vorgeschlagen + +# Diamex +PROGRAMMER = -c stk500v2 -P $(PORT) -b 9600 -B 10 -v + +#der USB-Programmieradapter der Mikrocontrollerspielwiese: +#PROGRAMMER = -c usbasp + +#mein Mac-Programmieradapter: +#PROGRAMMER = -c stk500v2 -P /dev/tty.usbmodem431 + +# CPU Speed +DEFS=-DF_CPU=8000000UL + +# +# attiny compatibility layer +#COMPAT=-I/home/scip/devel/at/tiny/cores/tiny + +# gloabal defines + +#------------------- +# auf Kleinheit optimieren: +CFLAGS=-g -mmcu=$(MCU) -Wall -Wstrict-prototypes -Os -mcall-prologues -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wundef -I. $(COMPAT) $(DEFS) +CPPFLAGS=-g -mmcu=$(MCU) -Wall -Os -mcall-prologues -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wundef -I. $(COMPAT) $(DEFS) + +PWD=$(shell pwd) +SRC=$(shell basename $(PWD)) +OBJ=$(shell ls *.S *.c *.cpp | sed -e 's/\.S/\.o/' -e 's/\.cpp/.o/' -e 's/\.c/.o/') + + +#------------------- +all: $(SRC).hex + +#------------------- +help: + @echo + @echo "Moegliche Befehle:" + @echo " make all - compiliert Dein Programm und erzeugt die .hex-Datei" + @echo " make load - compiliert Dein Programm und schiebt es in den AVR" + @echo " make clean - loescht die beim Compilieren erzeugten Dateien" + @echo " make rdfuses - gibt Dir Informationen ueber die gesetzten Fusebits und mehr" + @echo " make wrfuse4.8mhz - setzt Fusebit fuer 4.8 MHz intern" + @echo " make wrfuse8.0mhz - set 8MHz fuse intern" + @echo " make wrfuse9.6mhz - setzt Fusebit fuer 9.6 MHz intern" + @echo " make wrfuse128khz - setzt Fusebit fuer 128 kHz intern" + @echo " make wrfusecrystal - setzt Fusebit fuer externen Quarz / Crystal (Achtung!)" + @echo " make wrfusenoreset - setzt Fusebit fuer PB5 (Achtung!)" + @echo " make help - zeigt diesen Hilfetext" + @echo + @echo "Achtung: ohne Quarz hast Du keine Chance wrfusecrystal rueckgaengig zu machen!" + @echo + @echo "Achtung: wrfusenoreset schaltet PB5 frei und deaktiviert RESET !!!" + @echo + +#------------------- +$(SRC).hex : $(SRC).out + $(OBJCOPY) -R .eeprom -O ihex $(SRC).out $(SRC).hex + +$(SRC).out : $(OBJ) + $(CC) $(CFLAGS) -o $(SRC).out -Wl,-Map,$(SRC).map $(OBJ) + +%.o : %.c + $(CC) $(CFLAGS) -Os -c $< -o $@ + +%.o : %.S + $(CC) $(CFLAGS) -Os -c $< -o $@ + +%.o : %.cpp + $(CPP) $(CPPFLAGS) -Os -c $< -o $@ +#------------------ +load: $(SRC).hex + $(AVRDUDE) -p $(PART) $(PROGRAMMER) -e -U flash:w:"$(SRC).hex" + + + + + + + +#------------------- +# fuse byte settings attiny13: +# +# Fuse Low Byte = 0x69 (4,8MHz internal), 0x6a (9.6MHz internal) +# Fuse High Byte = 0xff (RESET enabled), 0xfe (PB5 enabled, RESET disabled) +# Factory default is 0x6a / 0xff +# Check this with make rdfuses + +rdfuses: + $(AVRDUDE) -p $(PART) $(PROGRAMMER) -v -q + +# 2313: internal osci 8Mhz, ena WDT, ena SPI prog +wrfuse8.0mhz: + $(AVRDUDE) -p $(PART) $(PROGRAMMER) -u -v -U lfuse:w:0x64:m -U hfuse:w:0xcf:m -U efuse:w:0xff:m + +# use internal RC oscillator 4.8 MHz +wrfuse4.8mhz: + + $(AVRDUDE) -p $(PART) $(PROGRAMMER) -u -v -U lfuse:w:0x69:m + $(AVRDUDE) -p $(PART) $(PROGRAMMER) -u -v -U hfuse:w:0xff:m + +# use internal RC oscillator 9.6 MHz +wrfuse9.6mhz: + $(AVRDUDE) -p $(PART) $(PROGRAMMER) -u -v -U lfuse:w:0x6a:m + $(AVRDUDE) -p $(PART) $(PROGRAMMER) -u -v -U hfuse:w:0xff:m + +# use external crystal +wrfusecrystal: + clear + @echo "Warnung: Das Setzen des Quarz-Fusebits kann nur mit Quarz rueckgaengig gemacht werden!" + @echo " Du hast 15 Sekunden, um mit crtl-c abzubrechen." + @echo + @echo "Warning: The external crystal setting can not be changed back without a working crystal" + @echo " You have 15 seconds to abort this with crtl-c" + @sleep 15 + $(AVRDUDE) -p $(PART) $(PROGRAMMER) -u -v -U lfuse:w:0x68:m + $(AVRDUDE) -p $(PART) $(PROGRAMMER) -u -v -U hfuse:w:0xff:m + +# fuse byte setting for using PB5 (disables RESET) +wrfusenoreset: + clear + @echo "Warnung:" + @echo + @echo "Das Setzen des Reset-Fusebits kann nicht rueckgaengig gemacht werden!" + @echo "Du hast 15 Sekunden, um mit crtl-c abzubrechen." + @echo + @sleep 15 + $(AVRDUDE) -p $(PART) $(PROGRAMMER) -u -v -U hfuse:w:0xfe:m + +#------------------- +clean: + rm -f *.o *.map *.out *.hex + +#------------------- diff --git a/2313-avr-only-test/analog.c b/2313-avr-only-test/analog.c new file mode 100644 index 0000000..9b21ecd --- /dev/null +++ b/2313-avr-only-test/analog.c @@ -0,0 +1,34 @@ +#include "analog.h" + +#ifdef ADCSRA + +int analogRead (uint8_t pin){ + int a=1, i=a, j=a; + long int analogwert=0, analogwert1=0, analogwert2=0 ; + + while(j){ + while(i){ + ADCSRA=0x80; // ADC eingeschaltet, kein Prescale + ADMUX=pin; + ADCSRA |=_BV(ADSC); // single conversion mode ein + while (ADCSRA & (1< +int analogRead (uint8_t pin) { + // No ADC on this MCU + abort(); +} + +#endif diff --git a/2313-avr-only-test/analog.h b/2313-avr-only-test/analog.h new file mode 100644 index 0000000..293c20f --- /dev/null +++ b/2313-avr-only-test/analog.h @@ -0,0 +1,12 @@ +#ifndef ANALOG_H +#define ANALOG_H + +/* + * via http://www.sachsendreier.com/msw/projekte/attiny13_analog_bargraph/atiny13_analog_bargraph.html + * Alternative: http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Analoge_Ein-_und_Ausgabe#Nutzung_des_ADC + */ + +#include + +int analogRead(uint8_t pin); +#endif diff --git a/2313-avr-only-test/delay.h b/2313-avr-only-test/delay.h new file mode 100644 index 0000000..b00cced --- /dev/null +++ b/2313-avr-only-test/delay.h @@ -0,0 +1,285 @@ +/* + Copyright (c) 2005, Hans-Juergen Heinrichs + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + + +/* + * delay_x.h + * + * Accurate delays ranging from a single CPU cycle up to + * more than 500 second (e.g. with 8MHz device): + * + * The idea for the functions below was heavily inspired by the + * file which is part of the excellent WinAVR + * distribution. Therefore, thanks to Marek Michalkiewicz and + * Joerg Wunsch. + * + * The idea is to have the GCC preprocessor handle all calculations + * necessary for determining the exact implementation of a delay + * algorithm. The implementation itself is then inlined into the + * user code. + * In this way it is possible to always get the code size optimized + * delay implementation. + * + * !!======================================================!! + * !! Requires compile time constants for the delay !! + * !! Requires compiler optimization !! + * !!======================================================!! + * + */ + +#ifndef _AVR_DELAY_X_H_ +#define _AVR_DELAY_X_H_ 1 + +#include + +#ifndef F_CPU +# warning "Macro F_CPU must be defined" +#endif + + +/* + * + * _ d e l a y _ n s (double __ns) + * _ d e l a y _ u s (double __us) + * _ d e l a y _ m s (double __ms) + * _ d e l a y _ s (double __s) + * + * Perform a very exact delay with a resolution as accurate as a + * single CPU clock (the macro F_CPU is supposed to be defined to a + * constant defining the CPU clock frequency in Hertz). + * + */ +#define _delay_ns(__ns) _delay_cycles( (double)(F_CPU)*((double)__ns)/1.0e9 + 0.5 ) +#define _delay_us(__us) _delay_cycles( (double)(F_CPU)*((double)__us)/1.0e6 + 0.5 ) +#define _delay_ms(__ms) _delay_cycles( (double)(F_CPU)*((double)__ms)/1.0e3 + 0.5 ) +#define _delay_s( __s) _delay_cycles( (double)(F_CPU)*((double)__s )/1.0e0 + 0.5 ) + +/* ==========================================================================*/ + +/* + * Forward declaration for all functions with attribute + * 'always_inline' enforces GCC to inline the code (even + * if it would be better not to do so from optimization + * perspective). + * Without this attribute GCC is free to implement + * inline code or not (using the keyword 'inline' + * alone is not sufficient). + * + */ +static __inline__ void _NOP1( void) __attribute__((always_inline)); +static __inline__ void _NOP2( void) __attribute__((always_inline)); +static __inline__ void _NOP3( void) __attribute__((always_inline)); +static __inline__ void _NOP4( void) __attribute__((always_inline)); +static __inline__ void _NOP5( void) __attribute__((always_inline)); +static __inline__ void _NOP6( void) __attribute__((always_inline)); +static __inline__ void _NOP7( void) __attribute__((always_inline)); +static __inline__ void _NOP8( void) __attribute__((always_inline)); +static __inline__ void _NOP9( void) __attribute__((always_inline)); +static __inline__ void _NOP10(void) __attribute__((always_inline)); +static __inline__ void _NOP11(void) __attribute__((always_inline)); +static __inline__ void _NOP12(void) __attribute__((always_inline)); + +static __inline__ void _delay_loop_3( uint32_t) __attribute__((always_inline)); +static __inline__ void _delay_loop_1_x( uint8_t) __attribute__((always_inline)); +static __inline__ void _delay_loop_2_x(uint16_t) __attribute__((always_inline)); +static __inline__ void _delay_loop_3_x(uint32_t) __attribute__((always_inline)); + +static __inline__ void _delay_cycles(const double) __attribute__((always_inline)); + + +/* + * _ N O P x ( void ) + * + * Code size optimized NOPs - not using any registers + * + * These NOPs will be used for very short delays where + * it is more code efficient than executing loops. + * + */ +static __inline__ void _NOP1 (void) { __asm__ volatile ( "nop " "\n\t" ); } +static __inline__ void _NOP2 (void) { __asm__ volatile ( "rjmp 1f" "\n\t" "1:" "\n\t" ); } +static __inline__ void _NOP3 (void) { __asm__ volatile ( "lpm " "\n\t" ); } +static __inline__ void _NOP4 (void) { _NOP3(); _NOP1(); } +static __inline__ void _NOP5 (void) { _NOP3(); _NOP2(); } +static __inline__ void _NOP6 (void) { _NOP3(); _NOP3(); } +static __inline__ void _NOP7 (void) { _NOP3(); _NOP3(); _NOP1(); } +static __inline__ void _NOP8 (void) { _NOP3(); _NOP3(); _NOP2(); } +static __inline__ void _NOP9 (void) { _NOP3(); _NOP3(); _NOP3(); } +static __inline__ void _NOP10(void) { _NOP3(); _NOP3(); _NOP3(); _NOP1(); } +static __inline__ void _NOP11(void) { _NOP3(); _NOP3(); _NOP3(); _NOP2(); } +static __inline__ void _NOP12(void) { _NOP3(); _NOP3(); _NOP3(); _NOP3(); } + + + +/* + * _ d e l a y _ l o o p _ 3( uint32_t __count ) + * + * This delay loop is not used in the code below: It is + * a supplement to the _delay_loop_1() and _delay_loop_2() + * within standard WinAVR giving a wider + * (32 bit) delay range. + * + */ +static __inline__ void +_delay_loop_3( uint32_t __count ) +{ + __asm__ volatile ( + "1: sbiw %A0,1" "\n\t" + "sbc %C0,__zero_reg__" "\n\t" + "sbc %D0,__zero_reg__" "\n\t" + "brne 1b" + : "=w" (__count) + : "0" (__count) + ); +} + + +/* + * _ d e l a y _ l o o p _ 1 _ x( uint8_t __n ) + * _ d e l a y _ l o o p _ 2 _ x( uint16_t __n ) + * _ d e l a y _ l o o p _ 3 _ x( uint32_t __n ) + * + * These delay loops always have exactly 4(8) cycles per loop. + * They use a 8/16/32 bit register counter respectively. + * + */ +static __inline__ void /* exactly 4 cycles/loop, max 2**8 loops */ +_delay_loop_1_x( uint8_t __n ) +{ /* cycles per loop */ + __asm__ volatile ( /* __n..one zero */ + "1: dec %0" "\n\t" /* 1 1 */ + " breq 2f" "\n\t" /* 1 2 */ + "2: brne 1b" "\n\t" /* 2 1 */ + : "=r" (__n) /* ----- ----- */ + : "0" (__n) /* 4 4 */ + ); +} + +static __inline__ void /* exactly 4 cycles/loop, max 2**16 loops */ +_delay_loop_2_x( uint16_t __n ) +{ /* cycles per loop */ + __asm__ volatile ( /* __n..one zero */ + "1: sbiw %0,1" "\n\t" /* 2 2 */ + " brne 1b " "\n\t" /* 2 1 */ + " nop " "\n\t" /* 1 */ + : "=w" (__n) /* ----- ----- */ + : "0" (__n) /* 4 4 */ + ); +} + +static __inline__ void /* exactly 8 cycles/loop, max 2**32 loops */ +_delay_loop_3_x( uint32_t __n ) +{ /* cycles per loop */ + __asm__ volatile ( /* __n..one zero */ + "1: sbiw %A0,1 " "\n\t" /* 2 2 */ + " sbc %C0,__zero_reg__" "\n\t" /* 1 1 */ + " sbc %D0,__zero_reg__" "\n\t" /* 1 1 */ + " nop " "\n\t" /* 1 1 */ + " breq 2f " "\n\t" /* 1 2 */ + "2: brne 1b " "\n\t" /* 2 1 */ + : "=w" (__n) /* ----- ----- */ + : "0" (__n) /* 8 8 */ + ); +} + + +/* + * + * _ d e l a y _ c y c l e s (double __ticks_d) + * + * Perform an accurate delay of a given number of processor cycles. + * + * All the floating point arithmetic will be handled by the + * GCC Preprocessor and no floating point code will be generated. + * Allthough the parameter __ticks_d is of type 'double' this + * function can be called with any constant integer value, too. + * GCC will handle the casting appropriately. + * + * With an 8 MHz clock e.g., delays ranging from 125 nanoseconds + * up to (2**32-1) * 125ns ~= 536,87 seconds are feasible. + * + */ +static __inline__ void +_delay_cycles(const double __ticks_d) +{ + uint32_t __ticks = (uint32_t)(__ticks_d); + uint32_t __padding; + uint32_t __loops; + + /* + * Special optimization for very + * small delays - not using any register. + */ + if( __ticks <= 12 ) { /* this can be done with 4 opcodes */ + __padding = __ticks; + + /* create a single byte counter */ + } else if( __ticks <= 0x400 ) { + __ticks -= 1; /* caller needs 1 cycle to init counter */ + __loops = __ticks / 4; + __padding = __ticks % 4; + if( __loops != 0 ) + _delay_loop_1_x( (uint8_t)__loops ); + + /* create a two byte counter */ + } else if( __ticks <= 0x40001 ) { + __ticks -= 2; /* caller needs 2 cycles to init counter */ + __loops = __ticks / 4; + __padding = __ticks % 4; + if( __loops != 0 ) + _delay_loop_2_x( (uint16_t)__loops ); + + /* create a four byte counter */ + } else { + __ticks -= 4; /* caller needs 4 cycles to init counter */ + __loops = __ticks / 8; + __padding = __ticks % 8; + if( __loops != 0 ) + _delay_loop_3_x( (uint32_t)__loops ); + } + + if( __padding == 1 ) _NOP1(); + if( __padding == 2 ) _NOP2(); + if( __padding == 3 ) _NOP3(); + if( __padding == 4 ) _NOP4(); + if( __padding == 5 ) _NOP5(); + if( __padding == 6 ) _NOP6(); + if( __padding == 7 ) _NOP7(); + if( __padding == 8 ) _NOP8(); + if( __padding == 9 ) _NOP9(); + if( __padding == 10 ) _NOP10(); + if( __padding == 11 ) _NOP11(); + if( __padding == 12 ) _NOP12(); +} + + +#endif /* _AVR_DELAY_X_H_ */ diff --git a/2313-avr-only-test/digital.c b/2313-avr-only-test/digital.c new file mode 100644 index 0000000..c261dbb --- /dev/null +++ b/2313-avr-only-test/digital.c @@ -0,0 +1,35 @@ +#include "digital.h" +#include + +void pinMode(uint8_t pin, uint8_t mode) { + uint8_t sreg_local = SREG; + cli(); + if(mode) { + DDRB |= _BV(pin); + } + else { + DDRB &= ~_BV(pin); + } + SREG = sreg_local; +} + +void digitalWrite(uint8_t pin, uint8_t val) { + uint8_t sreg_local = SREG; + cli(); + if(val) { + PORTB |= _BV(pin); + } + else { + PORTB &= ~_BV(pin); + } + SREG = sreg_local; +} + +int digitalRead(uint8_t pin) { + if ( PINB & _BV(pin) ) { + return 1; + } + else { + return 0; + } +} diff --git a/2313-avr-only-test/digital.h b/2313-avr-only-test/digital.h new file mode 100644 index 0000000..7e49041 --- /dev/null +++ b/2313-avr-only-test/digital.h @@ -0,0 +1,16 @@ +#ifndef DIGITAL_H +#define DIGITAL_H + +#define INPUT 0 +#define OUTPUT 1 +#define LOW 0 +#define HIGH 1 + +#include + +void pinMode(uint8_t pin, uint8_t mode); +void digitalWrite(uint8_t pin, uint8_t val); +int digitalRead(uint8_t pin); + + +#endif diff --git a/2313-avr-only-test/main.c b/2313-avr-only-test/main.c new file mode 100755 index 0000000..c8fec98 --- /dev/null +++ b/2313-avr-only-test/main.c @@ -0,0 +1,40 @@ + +//************************************************************************* +// steffen wrote this stuff for mikrocontrollerspielwiese.de +// have fun! +//************************************************************************* + +#include "delay.h" +#include "digital.h" +#include "analog.h" +//#define BAUD_RATE 57600 //115200 +//#include "serial.h" // serial Port (TX) defined in serial.S! + +#define PU_BAUD_RATE 38400 +#include + +#define LED PB4 + +void serOut(const char* str) { + prints_P(str); + /* + while (*str) + TxByte(*str++); + */ +} + +int main(void){ + pinMode(LED, OUTPUT); + + while (1) { + serOut("Turning on LED\n"); + digitalWrite(LED, HIGH); + _delay_ms(2550); + serOut("Turning off LED\n"); + digitalWrite(LED, LOW); + _delay_ms(2550); + } + + return 0; +} + diff --git a/2313-avr-only-test/picoUART.h b/2313-avr-only-test/picoUART.h new file mode 100644 index 0000000..b6e8812 --- /dev/null +++ b/2313-avr-only-test/picoUART.h @@ -0,0 +1,193 @@ +/* optimized half-duplex high-speed AVR serial uart + * Ralph Doncaster 2020 open source MIT license + * + * picoUART is accurate to the cycle (+- 0.5 cycle error) + * 0.64% error at 115.2k/8M and 0.4% error at 115.2k/9.6M + * + * define PU_BAUD_RATE before #include to change default baud rate + * + * capable of single-pin operation (PU_TX = PU_RX) as follows: + * connect MCU pin to host RX line, and a 1.5k-4.7k resistor between + * host RX and TX line. Note this also gives local echo. + * + * 20200123 version 0.5 + * 20200123 version 0.6 - improve inline asm + * 20200201 version 0.7 - use push/pull during tx + * 20200203 version 0.8 - add prints_P, prefix globals with PU_ + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef PU_BAUD_RATE +#define PU_BAUD_RATE 115200L // default baud rate +#endif + +#ifndef PU_TX +#define PU_TX D,1 +#define PU_RX D,0 +#endif + +// use static inline functions for type safety +extern inline float PUBIT_CYCLES() {return F_CPU/(PU_BAUD_RATE*1.0);} + +// delay based on cycle count of asm code + 0.5 for rounding +extern inline int PUTXWAIT() {return PUBIT_CYCLES() - 7 + 0.5;} +extern inline int PURXWAIT() {return PUBIT_CYCLES() - 5 + 0.5;} + +// correct for PURXWAIT skew in PURXSTART calculation +// skew is half of 7 delay intervals between 8 bits +extern inline float PUSKEW() { + return (PUBIT_CYCLES() - (int)(PUBIT_CYCLES() + 0.5)) * 3.5; +} +// Time from falling edge of start bit to sample 1st bit is 1.5 * +// bit-time. Subtract 2 cycles for sbic, 1 for lsr, and PURXWAIT. +// Subtract 1.5 cycles because start bit detection is accurate to +// +-1.5 cycles. Add 0.5 cycles for int rounding, and add skew. +extern inline int PURXSTART() { + return (PUBIT_CYCLES()*1.5 -3 -PURXWAIT() -1 +PUSKEW()); +} + +// min rx/tx turn-around time in resistor-only 1-wire mode +inline void pu_rxtx_wait() +{ + __builtin_avr_delay_cycles(PUBIT_CYCLES()*1.5); +} + +// I/O register macros +#define BIT(r,b) (b) +#define PORT(r,b) (PORT ## r) +#define DDR(r,b) (DDR ## r) +#define PIN(r,b) (PIN ## r) +#define bit(io) BIT(io) +#define port(io) PORT(io) +#define ddr(io) DDR(io) +#define pin(io) PIN(io) + +// use up registers so only r25:r24 are free for the compiler +#define alloc_regs()\ + register int dummy1 asm("r20");\ + asm volatile ("" : "=r" (dummy1));\ + register int dummy2 asm("r26");\ + asm volatile ("" : "=r" (dummy2));\ + register int dummy3 asm("r30");\ + asm volatile ("" : "=r" (dummy3)); + +#define touch_regs()\ + asm volatile ("" :: "r" (dummy1));\ + asm volatile ("" :: "r" (dummy2));\ + asm volatile ("" :: "r" (dummy3)); + +__attribute((naked)) +void _pu_tx() +{ + alloc_regs(); + register char c asm("r18"); + register char sr asm("r19"); + asm volatile ( + "cbi %[tx_port], %[tx_bit]\n" // disable pullup + "cli\n" + "sbi %[tx_port]-1, %[tx_bit]\n" // start bit + "in r0, %[tx_port]\n" // save DDR in r0 + "ldi %[sr], 3\n" // stop bit & idle state + "Ltxbit:\n" + : [c] "+r" (c), + [sr] "+r" (sr) + : [tx_port] "I" (_SFR_IO_ADDR(port(PU_TX))), + [tx_bit] "I" (bit(PU_TX)) + ); + __builtin_avr_delay_cycles(PUTXWAIT()); + // 7 cycle loop + asm volatile ( + "bst %[c], 0\n" // store lsb in T + "bld r0, %[tx_bit]\n" + "lsr %[sr]\n" // 2-byte shift register + "ror %[c]\n" // shift for next bit + "out %[tx_port], r0\n" + "brne Ltxbit\n" + "cbi %[tx_port]-1, %[tx_bit]\n" // set to input mode + "reti\n" // return & enable interrupts + : [c] "+r" (c), + [sr] "+r" (sr) + : [tx_port] "I" (_SFR_IO_ADDR(port(PU_TX))), + [tx_bit] "I" (bit(PU_TX)) + ); + touch_regs(); +} + +inline void pu_tx(char c) +{ + register char ch asm("r18") = c; + asm volatile ("%~call %x1" : "+r"(ch) : "i"(_pu_tx) : "r19", "r24", "r25"); +} + +inline void prints_P(const char* s) +{ + register char c asm("r18"); + asm volatile ( + "1:\n" + "lpm %[c], %a0+\n" // read next char + "tst %[c]\n" + "breq 1f\n" + "%~call %x2\n" + "rjmp 1b\n" + "1:\n" + : "+e" (s), [c] "+r" (c) + : "i" (_pu_tx) + : "r19", "r24", "r25" + ); +} + +__attribute((naked)) +void _pu_rx() +{ + alloc_regs(); + register char c asm("r18"); + register char dummy4 asm("r19"); + asm volatile ( + // wait for idle state (high) + "1: sbis %[rx_pin], %[rx_bit]\n" + "rjmp 1b\n" + "ldi %[c], 0x80\n" // bit shift counter + "cli\n" + // wait for start bit (low) + "1: sbic %[rx_pin], %[rx_bit]\n" + "rjmp 1b\n" + : [c] "=d" (c) + : [rx_pin] "I" (_SFR_IO_ADDR(pin(PU_RX))), + [rx_bit] "I" (bit(PU_RX)) + ); + __builtin_avr_delay_cycles(PURXSTART()); + asm volatile ("Lrxbit:"); + __builtin_avr_delay_cycles(PURXWAIT()); + // 5 cycle loop + asm volatile ( + "lsr %[c]\n" + "sbic %[rx_pin], %[rx_bit]\n" + "ori %[c], 0x80\n" + "brcc Lrxbit\n" + "reti\n" + : [c] "+d" (c) + : [rx_pin] "I" (_SFR_IO_ADDR(pin(PU_RX))), + [rx_bit] "I" (bit(PU_RX)), + "r" (dummy4) + ); + touch_regs(); +} + +inline char pu_rx() +{ + register char c asm("r18"); + asm ("%~call %x1" : "=r"(c) : "i"(_pu_rx) : "r24", "r25"); + return c; +} + +#ifdef __cplusplus +} // extern "C" +#endif + diff --git a/2313-avr-only-test/serial.S b/2313-avr-only-test/serial.S new file mode 100644 index 0000000..10637b9 --- /dev/null +++ b/2313-avr-only-test/serial.S @@ -0,0 +1,44 @@ +;; via http://nerdralph.blogspot.com/2013/12/writing-avr-assembler-code-with-arduino.html +/* Optimized AVR305 half-duplex serial uart implementation + * timing for 81N, 115.2kbps @8Mhz = 69.4 cycles/bit + * and @16Mhz = 138.9 cycles/bit + * @author: Ralph Doncaster + * @version: $Id$ + */ + +#include +; correct for avr/io.h 0x20 port offset for io instructions +#define UART_Port (PORTB-0x20) +#define UART_Tx 0 + +#define bitcnt r18 +#define delayArg 19 + +.global TxTimedByte +; transmit byte in r24 with bit delay in r22 - 15 instructions +; calling code must set Tx line to idle state (high) or 1st byte may be lost +; i.e. PORTB |= (1< 255 + #error low baud rates unsupported - use higher BAUD_RATE +#endif + +void TxTimedByte(char, char); + + +#define TxByte(C) TxTimedByte(C , TXDELAY) + diff --git a/2313-tinycore-test/Blink.ino b/2313-tinycore-test/Blink.ino new file mode 100644 index 0000000..9db4318 --- /dev/null +++ b/2313-tinycore-test/Blink.ino @@ -0,0 +1,24 @@ +/* -*-c++-*- + Blink + Turns on an LED on for one second, then off for one second, repeatedly. + This example code is in the public domain. + */ + +void setup() { + // initialize the digital pin as an output. + // Pin 13 has an LED connected on most Arduino boards: + Serial.begin(9600); + Serial.print("Press any key: "); + + pinMode(PB0, OUTPUT); +} + +void loop() { + digitalWrite(13, HIGH); // set the LED on + delay(1000); // wait for a second + digitalWrite(13, LOW); // set the LED off + delay(1000); // wait for a second + if (Serial.available()) { + Serial.println("blinked\n"); + } +} diff --git a/2313-tinycore-test/Makefile b/2313-tinycore-test/Makefile new file mode 100644 index 0000000..9eee11f --- /dev/null +++ b/2313-tinycore-test/Makefile @@ -0,0 +1,33 @@ +# Arduino Make file. Refer to https://github.com/sudar/Arduino-Makefile + +# Arduino stuff +PROJECT_DIR = $(shell pwd) +BOARD_TAG = attinyx313 +BOARD_SUB = 2313 +ARDUINO_DIR = /usr/local/arduino +ARDMK_DIR = /usr/local/arduino/Arduino-Makefile +MONITOR_PORT = /dev/ttyACM0 +ISP_PORT = /dev/ttyACM0 +AVRDUDE = /usr/local/bin/avrdude +ARDUINO_LIBS = +ARDUINO_SKETCHBOOK = . + +# mk stuff +ALTERNATE_CORE = ATTinyCore +F_CPU = 8000000L +MONITOR_BAUDRATE = 115200 +AVRDUDE_ARD_PROGRAMMER = stk500v2 +AVRDUDE_ARD_BAUDRATE = 9600 +AVR_TOOLS_DIR = /usr/local/avr +AVRDUDE_CONF = /usr/local/etc/avrdude.conf + +# compiler stuff +CFLAGS_STD = -std=gnu11 +CXXFLAGS_STD = -std=gnu++11 +CXXFLAGS += -pedantic -Wall -Wextra +CURRENT_DIR = $(shell pwd) + +# keep this! +include $(ARDMK_DIR)/Arduino.mk + + diff --git a/2313-tinycore-test/hardware b/2313-tinycore-test/hardware new file mode 120000 index 0000000..d34e522 --- /dev/null +++ b/2313-tinycore-test/hardware @@ -0,0 +1 @@ +/usr/local/arduino/hardware \ No newline at end of file diff --git a/841-tinycore-test/Blink.ino b/841-tinycore-test/Blink.ino new file mode 100644 index 0000000..9db4318 --- /dev/null +++ b/841-tinycore-test/Blink.ino @@ -0,0 +1,24 @@ +/* -*-c++-*- + Blink + Turns on an LED on for one second, then off for one second, repeatedly. + This example code is in the public domain. + */ + +void setup() { + // initialize the digital pin as an output. + // Pin 13 has an LED connected on most Arduino boards: + Serial.begin(9600); + Serial.print("Press any key: "); + + pinMode(PB0, OUTPUT); +} + +void loop() { + digitalWrite(13, HIGH); // set the LED on + delay(1000); // wait for a second + digitalWrite(13, LOW); // set the LED off + delay(1000); // wait for a second + if (Serial.available()) { + Serial.println("blinked\n"); + } +} diff --git a/841-tinycore-test/Makefile b/841-tinycore-test/Makefile new file mode 100644 index 0000000..786474b --- /dev/null +++ b/841-tinycore-test/Makefile @@ -0,0 +1,47 @@ +# Arduino Make file. Refer to https://github.com/sudar/Arduino-Makefile + +# attiny841: +# BOARD_TAG = attinyx41 +# BOARD_SUB = 841 +# attiny861: +# BOARD_TAG = attinyx61 +# BOARD_SUB = 861 +# attiny85: +# BOARD_TAG = attinyx5 +# BOARD_SUB = 85 +# attiny84: +# BOARD_TAG = attinyx4 +# BOARD_SUB = 84 + +# Arduino stuff +PROJECT_DIR = $(shell pwd) +BOARD_TAG = attinyx41 +BOARD_SUB = 841 +ARDUINO_DIR = /usr/local/arduino +ARDMK_DIR = /usr/local/arduino/Arduino-Makefile +MONITOR_PORT = /dev/ttyACM0 +ISP_PORT = /dev/ttyACM0 +AVRDUDE = /usr/local/bin/avrdude +#ARDUINO_LIB_PATH = $(ARDUINO_DIR)/hardware/ATTinyCore/avr/libraries +ARDUINO_LIBS = #Wire SPI GFX SSD1306 # SPI +ARDUINO_SKETCHBOOK = . + +# mk stuff +ALTERNATE_CORE = ATTinyCore +F_CPU = 8000000L +MONITOR_BAUDRATE = 115200 +AVRDUDE_ARD_PROGRAMMER = stk500v2 +AVRDUDE_ARD_BAUDRATE = 9600 +AVR_TOOLS_DIR = /usr/local/avr +AVRDUDE_CONF = /usr/local/etc/avrdude.conf + +# compiler stuff +CFLAGS_STD = -std=gnu11 +CXXFLAGS_STD = -std=gnu++11 +CXXFLAGS += -pedantic -Wall -Wextra +CURRENT_DIR = $(shell pwd) + +# keep this! +include $(ARDMK_DIR)/Arduino.mk + + diff --git a/841-tinycore-test/hardware b/841-tinycore-test/hardware new file mode 120000 index 0000000..d34e522 --- /dev/null +++ b/841-tinycore-test/hardware @@ -0,0 +1 @@ +/usr/local/arduino/hardware \ No newline at end of file diff --git a/841-tinycore-test/libraries/GFX b/841-tinycore-test/libraries/GFX new file mode 120000 index 0000000..4ade844 --- /dev/null +++ b/841-tinycore-test/libraries/GFX @@ -0,0 +1 @@ +/usr/local/esp32/arduino-core/libraries/GFX \ No newline at end of file diff --git a/841-tinycore-test/libraries/SPI b/841-tinycore-test/libraries/SPI new file mode 120000 index 0000000..56e807e --- /dev/null +++ b/841-tinycore-test/libraries/SPI @@ -0,0 +1 @@ +/usr/local/arduino/hardware/ATTinyCore/avr/libraries/SPI \ No newline at end of file diff --git a/841-tinycore-test/libraries/SSD1306 b/841-tinycore-test/libraries/SSD1306 new file mode 120000 index 0000000..c2d18df --- /dev/null +++ b/841-tinycore-test/libraries/SSD1306 @@ -0,0 +1 @@ +/usr/local/esp32/arduino-core/libraries/SSD1306 \ No newline at end of file diff --git a/841-tinycore-test/libraries/TinyWireM b/841-tinycore-test/libraries/TinyWireM new file mode 120000 index 0000000..a6a4ed0 --- /dev/null +++ b/841-tinycore-test/libraries/TinyWireM @@ -0,0 +1 @@ +/usr/local/esp32/arduino-core/libraries/TinyWireM \ No newline at end of file diff --git a/841-tinycore-test/libraries/Wire b/841-tinycore-test/libraries/Wire new file mode 120000 index 0000000..0211f71 --- /dev/null +++ b/841-tinycore-test/libraries/Wire @@ -0,0 +1 @@ +/usr/local/arduino/hardware/ATTinyCore/avr/libraries/Wire \ No newline at end of file diff --git a/85-avr-only-test/Makefile b/85-avr-only-test/Makefile new file mode 100755 index 0000000..73cbaff --- /dev/null +++ b/85-avr-only-test/Makefile @@ -0,0 +1,156 @@ +#------------------------------------------------------------------------------------------------------- +# makefile +# +# written by Steffen from mikrocontrollerspielwiese.de +# +# inspired from Guido Socher's makefile +# http://www.linuxfocus.org/Deutsch/November2004/article352.shtml +# +# license: GPL (http://www.gnu.org/licenses/gpl.txt) +#------------------------------------------------------------------------------------------------------- + + +AVRDUDE=/usr/local/bin/avrdude + +# avr-gcc part name +MCU=attiny85 + +# avrdude part name +PART=t85 + +CC=avr-gcc +CPP=avr-c++ +#CPP=env -P/usr/local/bin:/usr/bin - avr-c++ +#CC=env -P/usr/local/bin:/usr/bin - avr-gcc +OBJCOPY=avr-objcopy + +PORT=$(shell ls /dev/ttyACM*) + +#------------------- +# Programmieradapter + +# hier kannst Du Deinen Programmieradapter angeben, wenn Du einen +# anderen nimmst, als in der Mikrocontrollerspielwiese vorgeschlagen + +# Diamex +PROGRAMMER = -c stk500v2 -P $(PORT) -b 9600 -B 1 -v + +#der USB-Programmieradapter der Mikrocontrollerspielwiese: +#PROGRAMMER = -c usbasp + +#mein Mac-Programmieradapter: +#PROGRAMMER = -c stk500v2 -P /dev/tty.usbmodem431 + +# +# attiny compatibility layer +#COMPAT=-I/home/scip/devel/at/tiny/cores/tiny + +# gloabal defines +DEFS=-DF_CPU=1000000UL + +#------------------- +# auf Kleinheit optimieren: +CFLAGS=-g -mmcu=$(MCU) -Wall -Wstrict-prototypes -Os -mcall-prologues -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wundef -I. $(COMPAT) $(DEFS) +CPPFLAGS=-g -mmcu=$(MCU) -Wall -Os -mcall-prologues -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wundef -I. $(COMPAT) $(DEFS) + +PWD=$(shell pwd) +SRC=$(shell basename $(PWD)) +OBJ=$(shell ls *.c *.cpp | sed -e 's/\.cpp/.o/' -e 's/\.c/.o/') + + +#------------------- +all: $(SRC).hex + +#------------------- +help: + @echo + @echo "Moegliche Befehle:" + @echo " make all - compiliert Dein Programm und erzeugt die .hex-Datei" + @echo " make load - compiliert Dein Programm und schiebt es in den AVR" + @echo " make clean - loescht die beim Compilieren erzeugten Dateien" + @echo " make rdfuses - gibt Dir Informationen ueber die gesetzten Fusebits und mehr" + @echo " make wrfuse4.8mhz - setzt Fusebit fuer 4.8 MHz intern" + @echo " make wrfuse9.6mhz - setzt Fusebit fuer 9.6 MHz intern" + @echo " make wrfuse128khz - setzt Fusebit fuer 128 kHz intern" + @echo " make wrfusecrystal - setzt Fusebit fuer externen Quarz / Crystal (Achtung!)" + @echo " make wrfusenoreset - setzt Fusebit fuer PB5 (Achtung!)" + @echo " make help - zeigt diesen Hilfetext" + @echo + @echo "Achtung: ohne Quarz hast Du keine Chance wrfusecrystal rueckgaengig zu machen!" + @echo + @echo "Achtung: wrfusenoreset schaltet PB5 frei und deaktiviert RESET !!!" + @echo + +#------------------- +$(SRC).hex : $(SRC).out + $(OBJCOPY) -R .eeprom -O ihex $(SRC).out $(SRC).hex + +$(SRC).out : $(OBJ) + $(CC) $(CFLAGS) -o $(SRC).out -Wl,-Map,$(SRC).map $(OBJ) + +%.o : %.c + $(CC) $(CFLAGS) -Os -c $< -o $@ + +%.o : %.cpp + $(CPP) $(CPPFLAGS) -Os -c $< -o $@ +#------------------ +load: $(SRC).hex + $(AVRDUDE) -p $(PART) $(PROGRAMMER) -e -U flash:w:"$(SRC).hex" + + + + + + + +#------------------- +# fuse byte settings attiny13: +# +# Fuse Low Byte = 0x69 (4,8MHz internal), 0x6a (9.6MHz internal) +# Fuse High Byte = 0xff (RESET enabled), 0xfe (PB5 enabled, RESET disabled) +# Factory default is 0x6a / 0xff +# Check this with make rdfuses + +rdfuses: + $(AVRDUDE) -p $(PART) $(PROGRAMMER) -v -q + + +# use internal RC oscillator 4.8 MHz +wrfuse4.8mhz: + + $(AVRDUDE) -p $(PART) $(PROGRAMMER) -u -v -U lfuse:w:0x69:m + $(AVRDUDE) -p $(PART) $(PROGRAMMER) -u -v -U hfuse:w:0xff:m + +# use internal RC oscillator 9.6 MHz +wrfuse9.6mhz: + $(AVRDUDE) -p $(PART) $(PROGRAMMER) -u -v -U lfuse:w:0x6a:m + $(AVRDUDE) -p $(PART) $(PROGRAMMER) -u -v -U hfuse:w:0xff:m + +# use external crystal +wrfusecrystal: + clear + @echo "Warnung: Das Setzen des Quarz-Fusebits kann nur mit Quarz rueckgaengig gemacht werden!" + @echo " Du hast 15 Sekunden, um mit crtl-c abzubrechen." + @echo + @echo "Warning: The external crystal setting can not be changed back without a working crystal" + @echo " You have 15 seconds to abort this with crtl-c" + @sleep 15 + $(AVRDUDE) -p $(PART) $(PROGRAMMER) -u -v -U lfuse:w:0x68:m + $(AVRDUDE) -p $(PART) $(PROGRAMMER) -u -v -U hfuse:w:0xff:m + +# fuse byte setting for using PB5 (disables RESET) +wrfusenoreset: + clear + @echo "Warnung:" + @echo + @echo "Das Setzen des Reset-Fusebits kann nicht rueckgaengig gemacht werden!" + @echo "Du hast 15 Sekunden, um mit crtl-c abzubrechen." + @echo + @sleep 15 + $(AVRDUDE) -p $(PART) $(PROGRAMMER) -u -v -U hfuse:w:0xfe:m + +#------------------- +clean: + rm -f *.o *.map *.out *.hex + +#------------------- diff --git a/85-avr-only-test/analog.c b/85-avr-only-test/analog.c new file mode 100644 index 0000000..9b21ecd --- /dev/null +++ b/85-avr-only-test/analog.c @@ -0,0 +1,34 @@ +#include "analog.h" + +#ifdef ADCSRA + +int analogRead (uint8_t pin){ + int a=1, i=a, j=a; + long int analogwert=0, analogwert1=0, analogwert2=0 ; + + while(j){ + while(i){ + ADCSRA=0x80; // ADC eingeschaltet, kein Prescale + ADMUX=pin; + ADCSRA |=_BV(ADSC); // single conversion mode ein + while (ADCSRA & (1< +int analogRead (uint8_t pin) { + // No ADC on this MCU + abort(); +} + +#endif diff --git a/85-avr-only-test/analog.h b/85-avr-only-test/analog.h new file mode 100644 index 0000000..293c20f --- /dev/null +++ b/85-avr-only-test/analog.h @@ -0,0 +1,12 @@ +#ifndef ANALOG_H +#define ANALOG_H + +/* + * via http://www.sachsendreier.com/msw/projekte/attiny13_analog_bargraph/atiny13_analog_bargraph.html + * Alternative: http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Analoge_Ein-_und_Ausgabe#Nutzung_des_ADC + */ + +#include + +int analogRead(uint8_t pin); +#endif diff --git a/85-avr-only-test/delay.h b/85-avr-only-test/delay.h new file mode 100644 index 0000000..b00cced --- /dev/null +++ b/85-avr-only-test/delay.h @@ -0,0 +1,285 @@ +/* + Copyright (c) 2005, Hans-Juergen Heinrichs + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + + +/* + * delay_x.h + * + * Accurate delays ranging from a single CPU cycle up to + * more than 500 second (e.g. with 8MHz device): + * + * The idea for the functions below was heavily inspired by the + * file which is part of the excellent WinAVR + * distribution. Therefore, thanks to Marek Michalkiewicz and + * Joerg Wunsch. + * + * The idea is to have the GCC preprocessor handle all calculations + * necessary for determining the exact implementation of a delay + * algorithm. The implementation itself is then inlined into the + * user code. + * In this way it is possible to always get the code size optimized + * delay implementation. + * + * !!======================================================!! + * !! Requires compile time constants for the delay !! + * !! Requires compiler optimization !! + * !!======================================================!! + * + */ + +#ifndef _AVR_DELAY_X_H_ +#define _AVR_DELAY_X_H_ 1 + +#include + +#ifndef F_CPU +# warning "Macro F_CPU must be defined" +#endif + + +/* + * + * _ d e l a y _ n s (double __ns) + * _ d e l a y _ u s (double __us) + * _ d e l a y _ m s (double __ms) + * _ d e l a y _ s (double __s) + * + * Perform a very exact delay with a resolution as accurate as a + * single CPU clock (the macro F_CPU is supposed to be defined to a + * constant defining the CPU clock frequency in Hertz). + * + */ +#define _delay_ns(__ns) _delay_cycles( (double)(F_CPU)*((double)__ns)/1.0e9 + 0.5 ) +#define _delay_us(__us) _delay_cycles( (double)(F_CPU)*((double)__us)/1.0e6 + 0.5 ) +#define _delay_ms(__ms) _delay_cycles( (double)(F_CPU)*((double)__ms)/1.0e3 + 0.5 ) +#define _delay_s( __s) _delay_cycles( (double)(F_CPU)*((double)__s )/1.0e0 + 0.5 ) + +/* ==========================================================================*/ + +/* + * Forward declaration for all functions with attribute + * 'always_inline' enforces GCC to inline the code (even + * if it would be better not to do so from optimization + * perspective). + * Without this attribute GCC is free to implement + * inline code or not (using the keyword 'inline' + * alone is not sufficient). + * + */ +static __inline__ void _NOP1( void) __attribute__((always_inline)); +static __inline__ void _NOP2( void) __attribute__((always_inline)); +static __inline__ void _NOP3( void) __attribute__((always_inline)); +static __inline__ void _NOP4( void) __attribute__((always_inline)); +static __inline__ void _NOP5( void) __attribute__((always_inline)); +static __inline__ void _NOP6( void) __attribute__((always_inline)); +static __inline__ void _NOP7( void) __attribute__((always_inline)); +static __inline__ void _NOP8( void) __attribute__((always_inline)); +static __inline__ void _NOP9( void) __attribute__((always_inline)); +static __inline__ void _NOP10(void) __attribute__((always_inline)); +static __inline__ void _NOP11(void) __attribute__((always_inline)); +static __inline__ void _NOP12(void) __attribute__((always_inline)); + +static __inline__ void _delay_loop_3( uint32_t) __attribute__((always_inline)); +static __inline__ void _delay_loop_1_x( uint8_t) __attribute__((always_inline)); +static __inline__ void _delay_loop_2_x(uint16_t) __attribute__((always_inline)); +static __inline__ void _delay_loop_3_x(uint32_t) __attribute__((always_inline)); + +static __inline__ void _delay_cycles(const double) __attribute__((always_inline)); + + +/* + * _ N O P x ( void ) + * + * Code size optimized NOPs - not using any registers + * + * These NOPs will be used for very short delays where + * it is more code efficient than executing loops. + * + */ +static __inline__ void _NOP1 (void) { __asm__ volatile ( "nop " "\n\t" ); } +static __inline__ void _NOP2 (void) { __asm__ volatile ( "rjmp 1f" "\n\t" "1:" "\n\t" ); } +static __inline__ void _NOP3 (void) { __asm__ volatile ( "lpm " "\n\t" ); } +static __inline__ void _NOP4 (void) { _NOP3(); _NOP1(); } +static __inline__ void _NOP5 (void) { _NOP3(); _NOP2(); } +static __inline__ void _NOP6 (void) { _NOP3(); _NOP3(); } +static __inline__ void _NOP7 (void) { _NOP3(); _NOP3(); _NOP1(); } +static __inline__ void _NOP8 (void) { _NOP3(); _NOP3(); _NOP2(); } +static __inline__ void _NOP9 (void) { _NOP3(); _NOP3(); _NOP3(); } +static __inline__ void _NOP10(void) { _NOP3(); _NOP3(); _NOP3(); _NOP1(); } +static __inline__ void _NOP11(void) { _NOP3(); _NOP3(); _NOP3(); _NOP2(); } +static __inline__ void _NOP12(void) { _NOP3(); _NOP3(); _NOP3(); _NOP3(); } + + + +/* + * _ d e l a y _ l o o p _ 3( uint32_t __count ) + * + * This delay loop is not used in the code below: It is + * a supplement to the _delay_loop_1() and _delay_loop_2() + * within standard WinAVR giving a wider + * (32 bit) delay range. + * + */ +static __inline__ void +_delay_loop_3( uint32_t __count ) +{ + __asm__ volatile ( + "1: sbiw %A0,1" "\n\t" + "sbc %C0,__zero_reg__" "\n\t" + "sbc %D0,__zero_reg__" "\n\t" + "brne 1b" + : "=w" (__count) + : "0" (__count) + ); +} + + +/* + * _ d e l a y _ l o o p _ 1 _ x( uint8_t __n ) + * _ d e l a y _ l o o p _ 2 _ x( uint16_t __n ) + * _ d e l a y _ l o o p _ 3 _ x( uint32_t __n ) + * + * These delay loops always have exactly 4(8) cycles per loop. + * They use a 8/16/32 bit register counter respectively. + * + */ +static __inline__ void /* exactly 4 cycles/loop, max 2**8 loops */ +_delay_loop_1_x( uint8_t __n ) +{ /* cycles per loop */ + __asm__ volatile ( /* __n..one zero */ + "1: dec %0" "\n\t" /* 1 1 */ + " breq 2f" "\n\t" /* 1 2 */ + "2: brne 1b" "\n\t" /* 2 1 */ + : "=r" (__n) /* ----- ----- */ + : "0" (__n) /* 4 4 */ + ); +} + +static __inline__ void /* exactly 4 cycles/loop, max 2**16 loops */ +_delay_loop_2_x( uint16_t __n ) +{ /* cycles per loop */ + __asm__ volatile ( /* __n..one zero */ + "1: sbiw %0,1" "\n\t" /* 2 2 */ + " brne 1b " "\n\t" /* 2 1 */ + " nop " "\n\t" /* 1 */ + : "=w" (__n) /* ----- ----- */ + : "0" (__n) /* 4 4 */ + ); +} + +static __inline__ void /* exactly 8 cycles/loop, max 2**32 loops */ +_delay_loop_3_x( uint32_t __n ) +{ /* cycles per loop */ + __asm__ volatile ( /* __n..one zero */ + "1: sbiw %A0,1 " "\n\t" /* 2 2 */ + " sbc %C0,__zero_reg__" "\n\t" /* 1 1 */ + " sbc %D0,__zero_reg__" "\n\t" /* 1 1 */ + " nop " "\n\t" /* 1 1 */ + " breq 2f " "\n\t" /* 1 2 */ + "2: brne 1b " "\n\t" /* 2 1 */ + : "=w" (__n) /* ----- ----- */ + : "0" (__n) /* 8 8 */ + ); +} + + +/* + * + * _ d e l a y _ c y c l e s (double __ticks_d) + * + * Perform an accurate delay of a given number of processor cycles. + * + * All the floating point arithmetic will be handled by the + * GCC Preprocessor and no floating point code will be generated. + * Allthough the parameter __ticks_d is of type 'double' this + * function can be called with any constant integer value, too. + * GCC will handle the casting appropriately. + * + * With an 8 MHz clock e.g., delays ranging from 125 nanoseconds + * up to (2**32-1) * 125ns ~= 536,87 seconds are feasible. + * + */ +static __inline__ void +_delay_cycles(const double __ticks_d) +{ + uint32_t __ticks = (uint32_t)(__ticks_d); + uint32_t __padding; + uint32_t __loops; + + /* + * Special optimization for very + * small delays - not using any register. + */ + if( __ticks <= 12 ) { /* this can be done with 4 opcodes */ + __padding = __ticks; + + /* create a single byte counter */ + } else if( __ticks <= 0x400 ) { + __ticks -= 1; /* caller needs 1 cycle to init counter */ + __loops = __ticks / 4; + __padding = __ticks % 4; + if( __loops != 0 ) + _delay_loop_1_x( (uint8_t)__loops ); + + /* create a two byte counter */ + } else if( __ticks <= 0x40001 ) { + __ticks -= 2; /* caller needs 2 cycles to init counter */ + __loops = __ticks / 4; + __padding = __ticks % 4; + if( __loops != 0 ) + _delay_loop_2_x( (uint16_t)__loops ); + + /* create a four byte counter */ + } else { + __ticks -= 4; /* caller needs 4 cycles to init counter */ + __loops = __ticks / 8; + __padding = __ticks % 8; + if( __loops != 0 ) + _delay_loop_3_x( (uint32_t)__loops ); + } + + if( __padding == 1 ) _NOP1(); + if( __padding == 2 ) _NOP2(); + if( __padding == 3 ) _NOP3(); + if( __padding == 4 ) _NOP4(); + if( __padding == 5 ) _NOP5(); + if( __padding == 6 ) _NOP6(); + if( __padding == 7 ) _NOP7(); + if( __padding == 8 ) _NOP8(); + if( __padding == 9 ) _NOP9(); + if( __padding == 10 ) _NOP10(); + if( __padding == 11 ) _NOP11(); + if( __padding == 12 ) _NOP12(); +} + + +#endif /* _AVR_DELAY_X_H_ */ diff --git a/85-avr-only-test/digital.c b/85-avr-only-test/digital.c new file mode 100644 index 0000000..c261dbb --- /dev/null +++ b/85-avr-only-test/digital.c @@ -0,0 +1,35 @@ +#include "digital.h" +#include + +void pinMode(uint8_t pin, uint8_t mode) { + uint8_t sreg_local = SREG; + cli(); + if(mode) { + DDRB |= _BV(pin); + } + else { + DDRB &= ~_BV(pin); + } + SREG = sreg_local; +} + +void digitalWrite(uint8_t pin, uint8_t val) { + uint8_t sreg_local = SREG; + cli(); + if(val) { + PORTB |= _BV(pin); + } + else { + PORTB &= ~_BV(pin); + } + SREG = sreg_local; +} + +int digitalRead(uint8_t pin) { + if ( PINB & _BV(pin) ) { + return 1; + } + else { + return 0; + } +} diff --git a/85-avr-only-test/digital.h b/85-avr-only-test/digital.h new file mode 100644 index 0000000..7e49041 --- /dev/null +++ b/85-avr-only-test/digital.h @@ -0,0 +1,16 @@ +#ifndef DIGITAL_H +#define DIGITAL_H + +#define INPUT 0 +#define OUTPUT 1 +#define LOW 0 +#define HIGH 1 + +#include + +void pinMode(uint8_t pin, uint8_t mode); +void digitalWrite(uint8_t pin, uint8_t val); +int digitalRead(uint8_t pin); + + +#endif diff --git a/85-avr-only-test/main.c b/85-avr-only-test/main.c new file mode 100755 index 0000000..66974d2 --- /dev/null +++ b/85-avr-only-test/main.c @@ -0,0 +1,26 @@ + +//************************************************************************* +// steffen wrote this stuff for mikrocontrollerspielwiese.de +// have fun! +//************************************************************************* + +#include "delay.h" +#include "digital.h" +#include "analog.h" + + +#define LED 1 + +int main(void){ + pinMode(LED, OUTPUT); + + while (1) { + digitalWrite(LED, HIGH); + _delay_ms(255); + digitalWrite(LED, LOW); + _delay_ms(255); + } + + return 0; +} + diff --git a/85-tinycore-test/Blink.ino b/85-tinycore-test/Blink.ino new file mode 100644 index 0000000..9db4318 --- /dev/null +++ b/85-tinycore-test/Blink.ino @@ -0,0 +1,24 @@ +/* -*-c++-*- + Blink + Turns on an LED on for one second, then off for one second, repeatedly. + This example code is in the public domain. + */ + +void setup() { + // initialize the digital pin as an output. + // Pin 13 has an LED connected on most Arduino boards: + Serial.begin(9600); + Serial.print("Press any key: "); + + pinMode(PB0, OUTPUT); +} + +void loop() { + digitalWrite(13, HIGH); // set the LED on + delay(1000); // wait for a second + digitalWrite(13, LOW); // set the LED off + delay(1000); // wait for a second + if (Serial.available()) { + Serial.println("blinked\n"); + } +} diff --git a/85-tinycore-test/Makefile b/85-tinycore-test/Makefile new file mode 100644 index 0000000..718161a --- /dev/null +++ b/85-tinycore-test/Makefile @@ -0,0 +1,47 @@ +# Arduino Make file. Refer to https://github.com/sudar/Arduino-Makefile + +# attiny841: +# BOARD_TAG = attinyx41 +# BOARD_SUB = 841 +# attiny861: +# BOARD_TAG = attinyx61 +# BOARD_SUB = 861 +# attiny85: +# BOARD_TAG = attinyx5 +# BOARD_SUB = 85 +# attiny84: +# BOARD_TAG = attinyx4 +# BOARD_SUB = 84 + +# Arduino stuff +PROJECT_DIR = $(shell pwd) +BOARD_TAG = attinyx61 +BOARD_SUB = 861 +ARDUINO_DIR = /usr/local/arduino +ARDMK_DIR = /usr/local/arduino/Arduino-Makefile +MONITOR_PORT = /dev/ttyACM0 +ISP_PORT = /dev/ttyACM0 +AVRDUDE = /usr/local/bin/avrdude +ARDUINO_LIB_PATH = $(ARDUINO_DIR)/hardware/ATTinyCore/avr/libraries +ARDUINO_LIBS = +ARDUINO_SKETCHBOOK = . + +# mk stuff +ALTERNATE_CORE = ATTinyCore +F_CPU = 8000000L +MONITOR_BAUDRATE = 115200 +AVRDUDE_ARD_PROGRAMMER = stk500v2 +AVRDUDE_ARD_BAUDRATE = 9600 +AVR_TOOLS_DIR = /usr/local/avr +AVRDUDE_CONF = /usr/local/etc/avrdude.conf + +# compiler stuff +CFLAGS_STD = -std=gnu11 +CXXFLAGS_STD = -std=gnu++11 +CXXFLAGS += -pedantic -Wall -Wextra +CURRENT_DIR = $(shell pwd) + +# keep this! +include $(ARDMK_DIR)/Arduino.mk + + diff --git a/85-tinycore-test/hardware b/85-tinycore-test/hardware new file mode 120000 index 0000000..d34e522 --- /dev/null +++ b/85-tinycore-test/hardware @@ -0,0 +1 @@ +/usr/local/arduino/hardware \ No newline at end of file