Skip to content

Commit

Permalink
Add atomics example
Browse files Browse the repository at this point in the history
  • Loading branch information
salkinium committed May 20, 2024
1 parent d0558ae commit 80f3d39
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 0 deletions.
54 changes: 54 additions & 0 deletions examples/atomic/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
NAME=vector-test
MCU=atmega328p
F_CPU=16000000ul

PROGRAMMER=arduino
AVRDUDE_FLAGS= -P/dev/ttyUSB0 -b57600

ifeq ($(STD),)
STD=c++20
endif

BUILD_DIR=./build
LIB_DIR=../..
COMMON_DIR=../common

INCLUDES=-I$(COMMON_DIR) -I$(LIB_DIR)/include

SOURCES=$(wildcard *.cpp $(LIB_DIR)/src/*.cc)
VPATH=.:$(LIB_DIR)/src:$(COMMON_DIR)
OBJECTS=$(addprefix $(BUILD_DIR)/,$(notdir $(SOURCES:%=%.o)))

CXXFLAGS=-std=$(STD) -Os -Wno-volatile --param=min-pagesize=0 -Wall -Wextra -pedantic -fno-exceptions -fno-rtti -fno-unwind-tables -fno-threadsafe-statics -Wshadow -Wcast-qual -Wpointer-arith -Wundef -DF_CPU=$(F_CPU)
LDFLAGS=

TARGET=$(BUILD_DIR)/$(NAME)

all: hex size

hex: $(TARGET).hex

$(TARGET).hex: $(TARGET).elf
avr-objcopy -O ihex -j .data -j .text $(TARGET).elf $(TARGET).hex

$(TARGET).elf: $(OBJECTS)
avr-g++ $(LDFLAGS) -mmcu=$(MCU) $(OBJECTS) -o $(TARGET).elf

$(BUILD_DIR)/%.cpp.o: %.cpp
@mkdir -p $(BUILD_DIR)
avr-g++ -c $(CXXFLAGS) -mmcu=$(MCU) $(INCLUDES) $< -o $@

$(BUILD_DIR)/%.cc.o: %.cc
@mkdir -p $(BUILD_DIR)
avr-g++ -c $(CXXFLAGS) -mmcu=$(MCU) $(INCLUDES) $< -o $@

size: $(TARGET).elf
avr-objdump -Pmem-usage $(TARGET).elf

program: $(TARGET).hex
avrdude -p$(MCU) $(AVRDUDE_FLAGS) -c$(PROGRAMMER) -Uflash:w:$(TARGET).hex:a

clean:
rm -rf $(BUILD_DIR)/*.o
rm -rf $(BUILD_DIR)/*.elf
rm -rf $(BUILD_DIR)/*.hex
81 changes: 81 additions & 0 deletions examples/atomic/atomic.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright (c) 2022, Christopher Kormanyos
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#include <atomic>
#include <cstdint>

#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/wdt.h>

static void app_hw_init();

std::atomic<std::uint16_t> sequence;

int main()
{
// Initialize the application hardware. This includes WDT, PORTB.5 and TIMER0.
app_hw_init();

for(;;)
{
// Toggle the LED on portb.5.
PINB = (1U << PORTB5);

sequence++;
}
}

static void app_hw_init()
{
// Initialize the application including WDT, PORTB.5 and TIMER0

// We will now disable the watchdog.
// Service the watchdog just to be sure to avoid pending timeout.
wdt_reset();

// Clear WDRF in MCUSR.
MCUSR &= ~(1U << WDRF);

// Write logical one to WDCE and WDE.
// Keep the old prescaler setting to prevent unintentional time-out.
WDTCSR |= (1U << WDCE) | (1U << WDE);

// Turn off the WDT.
WDTCSR = 0x00;

// We will now initialize PORTB.5 to be used as an LED driver port.
// Set PORTB.5 value to low.
PORTB &= ~(1U << PORTB5);

// Set PORTB.5 direction to output.
DDRB |= (1U << DDB5);

// We will now initialize the TIMER0 clock and interrupt.
// Clear the TIMER0 overflow flag.
TIFR0 = static_cast<std::uint8_t>(1U << TOV0);

// Enable the TIMER0 overflow interrupt.
TIMSK0 = static_cast<std::uint8_t>(1U << TOIE0);

// Set the TIMER0 clock source to f_osc/8 = 2MHz and begin counting.
TCCR0B = static_cast<std::uint8_t>(1U << CS01);

// Enable all interrupts.
sei();
}



ISR(TIMER0_OVF_vect)
{
sequence++;
}

0 comments on commit 80f3d39

Please sign in to comment.