Initial commit
This commit is contained in:
commit
7b50230314
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# 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)
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Copyright Sebastian Schumb (sebastian_at_sebastians-site_de) 2011
|
||||
*/
|
||||
|
||||
#ifndef RINGLOCK_H_
|
||||
#define RINGLOCK_H_ RINGLOCK_H_
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#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<<CS00) | (1<<CS02);
|
||||
}
|
||||
|
||||
// function called to reset the timer
|
||||
static inline void rl_to_reset(void) {
|
||||
TCCR0 &= ~((1<<CS00) | (1<<CS02));
|
||||
TCNT0 = 0;
|
||||
rl_to_start();
|
||||
}
|
||||
|
||||
|
||||
#elif defined __AVR_ATmega8__
|
||||
|
||||
/*
|
||||
* Config for the Port that passes the token on
|
||||
* Explanation see above ...
|
||||
*/
|
||||
#define RL_OUT_PORT PORTD
|
||||
#define RL_OUT_DDR DDRD
|
||||
#define RL_OUT PD0
|
||||
|
||||
/*
|
||||
* Config for the external interrupt
|
||||
* Explanation see above ...
|
||||
*/
|
||||
#define RL_INT_DDR DDRD
|
||||
#define RL_INT_PIN PD2
|
||||
#define RL_INT INT0_vect
|
||||
#define RL_INT_CONFIG MCUCR
|
||||
#define RL_INT_CBITS ((1 << ISC00) | (1 << ISC01))
|
||||
#define RL_INT_ENABLE GICR
|
||||
#define RL_INT_EBITS INT0
|
||||
|
||||
/*
|
||||
* TODO: Add timer config here ;)
|
||||
*/
|
||||
|
||||
|
||||
#else
|
||||
#error "MCU is not supported. Please add it to ringlock.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Config ends here
|
||||
*/
|
||||
|
||||
volatile uint8_t rl_request_token; // set if the controller should keep the token
|
||||
volatile uint8_t rl_have_token; // set if the controller has the token
|
||||
|
||||
/*
|
||||
* Functions for manipulation the token
|
||||
* The next two functions might seem necessary,
|
||||
* but we don't want people fiddling with the flags directly.
|
||||
*/
|
||||
static inline void rl_request_lock(void) {
|
||||
rl_request_token = 1;
|
||||
}
|
||||
|
||||
static inline uint8_t rl_have_lock(void) {
|
||||
return rl_have_token;
|
||||
}
|
||||
|
||||
|
||||
static inline void rl_release_lock(void) { // used to release the token
|
||||
if(rl_have_token) { // make sure we have the token
|
||||
rl_have_token = 0;
|
||||
RL_OUT_PORT |= (1 << RL_OUT);
|
||||
_delay_us(1); // give the signal time to raise
|
||||
RL_OUT_PORT &= ~(1 << RL_OUT);
|
||||
}
|
||||
}
|
||||
|
||||
void rl_init(void);
|
||||
|
||||
|
||||
#endif /* RINGLOCK_H_ */
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* main.c
|
||||
*
|
||||
* Created on: Sep 28, 2011
|
||||
* Author: sebastian
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Copyright Sebastian Schumb (sebastian_at_sebastians-site_de) 2011
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#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<<TXEN); // UART TX
|
||||
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // Asynchronous 8N1
|
||||
|
||||
|
||||
sei();
|
||||
|
||||
while(1) {
|
||||
|
||||
rl_request_lock(); // Request a log
|
||||
while(!rl_have_lock()); // Wait for it
|
||||
while (!(UCSRA & (1<<UDRE))); // Make sure the uart is ready to go
|
||||
#ifdef RL_MASTER
|
||||
UDR = 'A'; // Master send A
|
||||
#else
|
||||
UDR = 'B'; // Slave send B
|
||||
#endif
|
||||
while (!(UCSRA & (1<< TXC))); // waiting for the uart to finish transmission
|
||||
UCSRA |= (1 << TXC); // resetting the TXC bit
|
||||
_delay_us(250); // We need to make sure, that no other mcu
|
||||
// is sending during our stop bit.
|
||||
rl_release_lock(); // Stop bit is over, the other can talk.
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue