commit 7b50230314da52043b02883f6e23bbe2ffc5b890 Author: sebastian laptop Date: Thu Oct 6 14:53:21 2011 +0200 Initial commit diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7df1ac4 --- /dev/null +++ b/Makefile @@ -0,0 +1,80 @@ +# +# Makefile +# Created on: Sep 28, 2011 +# Author: sebastian +# +# This file is part of the RingLock-library for Atmel AVR MCUS. +# +# RingLock 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. +# +# RingLock 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 RingLock. If not, see . +# +# Copyright Sebastian Schumb (sebastian_at_sebastians-site_de) 2011 +# + + +SRC = main.c include/ringlock.c +TARGET = ringlock-$(AVRMCU)-$(LOCKROLE) +OBJDIR = bin/$(AVRMCU)-$(LOCKROLE) + +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + +OBJ = $(SRC:%.c=$(OBJDIR)/%.o) + +CFLAGS = -Os -Wall -Wstrict-prototypes +CFLAGS += -fshort-enums -fpack-struct -funsigned-char -funsigned-bitfields +CFLAGS += -mmcu=$(AVRMCU) -DF_CPU=$(F_CPU)UL +ifeq "$(LOCKROLE)" "master" +CFLAGS += -DRL_MASTER +endif + +all: start $(OBJDIR)/$(TARGET).hex size + @echo "Done !" + +start: + @echo " _____ _ _ _" + @echo "| ___ (_) | | | |" + @echo "| |_/ /_ _ __ __ _| | ___ ___| | __" + @echo "| /| | '_ \ / _\` | | / _ \ / __| |/ /" + @echo "| |\ \| | | | | (_| | |____| (_) | (__| < " + @echo "\_| \_|_|_| |_|\__, \_____/ \___/ \___|_|\_\\" + @echo " __/ |" + @echo " |___/" + @echo + @echo "Software based token passing mutex for AVR microcontrollers" + @echo + @echo ":: Building for $(AVRMCU)" + @echo ":: Role is $(LOCKROLE)" + @echo ":: MCU operating frequency is $(F_CPU)Hz" + +$(OBJDIR)/%.o : %.c + @mkdir -p $$(dirname $@) + $(CC) $(CFLAGS) -c $< -o $@ + + +$(OBJDIR)/$(TARGET).elf : $(OBJ) + $(CC) $(CFLAGS) $+ -o $@ + +$(OBJDIR)/$(TARGET).hex : $(OBJDIR)/$(TARGET).elf + $(OBJCOPY) -O ihex $< $@ + + +size : $(OBJDIR)/$(TARGET).elf + @echo + @$(SIZE) $(OBJDIR)/$(TARGET).hex + @echo + +clean : + @rm -rf $(OBJDIR) diff --git a/include/ringlock.c b/include/ringlock.c new file mode 100644 index 0000000..a1d1f79 --- /dev/null +++ b/include/ringlock.c @@ -0,0 +1,72 @@ +/* + * ringlock.c + * + * Created on: Sep 28, 2011 + * Author: sebastian + * + * This file is part of the RingLock-library for Atmel AVR MCUS. + * + * RingLock 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. + * + * RingLock 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 RingLock. If not, see . + * + * Copyright Sebastian Schumb (sebastian_at_sebastians-site_de) 2011 + */ + + +#include "ringlock.h" + + +void rl_init(void) { + + //Setting up pin to pass on the token + RL_OUT_DDR |= (1 << RL_OUT); + RL_OUT_PORT &= ~(1 << RL_OUT); + + //Setting up the interrupt use to receive the token + RL_INT_DDR &= ~(1 << RL_INT_PIN); + RL_INT_CONFIG |= RL_INT_CBITS; + RL_INT_ENABLE |= (1 << RL_INT_EBITS); + + rl_request_token = 0; + +#ifdef RL_MASTER + rl_have_token = 1; //Master haz the token + + rl_to_setup(); //Fire up the timer + rl_to_start(); +#else + rl_have_token = 0; +#endif +} + +/* + * Interrupt used for getting the token and timeout + */ +ISR(RL_INT) { + rl_have_token = 1; + if(!rl_request_token) { + rl_release_lock(); + } + else { + rl_request_token = 0; + } +#ifdef RL_MASTER + rl_to_reset(); // reset the timeout +#endif + +} + +#ifdef RL_MASTER +ISR(RL_TO_INT, ISR_ALIASOF(RL_INT)); // if we have a timeout, + // we just pretend to have the token +#endif diff --git a/include/ringlock.h b/include/ringlock.h new file mode 100644 index 0000000..d4abd45 --- /dev/null +++ b/include/ringlock.h @@ -0,0 +1,151 @@ +/* + * ringlock.h + * + * Created on: Sep 28, 2011 + * Author: sebastian + * + * This file is part of the RingLock-library for Atmel AVR MCUS. + * + * RingLock 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. + * + * RingLock 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 RingLock. If not, see . + * + * Copyright Sebastian Schumb (sebastian_at_sebastians-site_de) 2011 + */ + +#ifndef RINGLOCK_H_ +#define RINGLOCK_H_ RINGLOCK_H_ + +#include +#include +#include + +#ifdef __AVR_ATmega32__ + +/* + * Config for the Port that passes the token on + */ +#define RL_OUT_PORT PORTD // Port used for passing the token, +#define RL_OUT_DDR DDRD // DDRD for that port +#define RL_OUT PD5 // and the pin we want to use + +/* + * Config for the external interrupt + */ +#define RL_INT_DDR DDRD // DDR +#define RL_INT_PIN PIN2 // and the Pin used for the interrupt +#define RL_INT INT0_vect // The timer interrupt +#define RL_INT_CONFIG MCUCR // Interrupt config register +#define RL_INT_CBITS ((1 << ISC00) | (1 << ISC01)) // bits to set in this register +#define RL_INT_ENABLE GICR // Global Interrupt Register +#define RL_INT_EBITS INT0 // Bit that enables the interrupt + +/* + * Timer config + * The master has a timeout timer, just in case a token gets lost, + * or you have a controller with messed up code in the ring ... + */ +#define RL_TO_TIME 10 //timeout in milliseconds +#define RL_TO_INT TIMER0_COMP_vect //timer interrupt +/* + * You can't use the config register and bits approach from above for timers, + * e.g. some mcus split TCCR in two registers. + * Therefore I cheated a little and used static inline functions, + * to make the timers configurable. + */ + +// function called to setup the timer +static inline void rl_to_setup(void) { + TCCR0 |= (1 << WGM01); + TIMSK |= (1 << OCIE0); + OCR0 = ((RL_TO_TIME * F_CPU/1000) / 1024); //1024 is prescaler +} + +// function called to start the timer +static inline void rl_to_start(void) { + TCCR0 |= (1<. + * + * Copyright Sebastian Schumb (sebastian_at_sebastians-site_de) 2011 + */ + +#include +#include + +#include "include/ringlock.h" + +#define BAUD 9600UL // baudrate + +// Some calculations ... +#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // rounding magic +#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Real baudrate +#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Error in 0,1% + +#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010)) // Make sure your UBRR_VAL will work + #error Baudrate error is bigger then 1% ! +#endif + + + +int main(void) { + + rl_init(); + + UBRRH = UBRR_VAL >> 8; //Setting baudrate + UBRRL = UBRR_VAL & 0xFF; + + UCSRB |= (1<