From 9f32dfdb31d37ce1413fa24d1095690ce7ca030b Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sat, 9 Apr 2022 13:48:35 +0200 Subject: Add src/app for attiny --- src/app/Makefile | 107 +++++++++++++++++++++++++++++++++++++++++ src/app/README.md | 10 ++++ src/app/build/.gitignore | 4 ++ src/app/delay.h | 9 ++++ src/app/main.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 251 insertions(+) create mode 100644 src/app/Makefile create mode 100644 src/app/README.md create mode 100644 src/app/build/.gitignore create mode 100644 src/app/delay.h create mode 100644 src/app/main.c diff --git a/src/app/Makefile b/src/app/Makefile new file mode 100644 index 0000000..8fe6809 --- /dev/null +++ b/src/app/Makefile @@ -0,0 +1,107 @@ +# Location of build tools +CC=avr-gcc +OBJCOPY=avr-objcopy +SIZE=avr-size +AVRDUDE=avrdude +AVRDUDE_FLAGS=-B 100kHz + +# Modify this to the device name of the UART used for AVRDUDE +AVRDUDE_DEV=usb +PROG = dragon_isp + +# Modify this to the CPU you are using +PART=attiny25 +AVRDUDE_PART=t25 + +# Cpu frequency +# is 3.579545MHz / 8 = 447443.125 +#F_CPU=447443UL +F_CPU="(3579545UL/8)" + +# Directory for built objects +BUILD_DIR=build + +# Port/application object files +APP_NAME = app + +# Application object files +APP_OBJECTS = main.o + +# Library object files to build and use +LIB_OBJECTS = +LIB_ASM_OBJECTS = +LIB_DIR = ../lib + +# Collection of built objects +ALL_OBJECTS = $(LIB_OBJECTS) $(LIB_ASM_OBJECTS) $(APP_OBJECTS) +BUILT_OBJECTS = $(patsubst %,$(BUILD_DIR)/%,$(ALL_OBJECTS)) + +# Target application filenames (.elf and .hex) for each application object +APP_ELF = $(APP_NAME).elf +APP_HEX = $(APP_NAME).hex + +# Search build/output directory for dependencies +vpath %.o ./$(BUILD_DIR) +vpath %.elf ./$(BUILD_DIR) +vpath %.hex ./$(BUILD_DIR) + +# GCC flags +CFLAGS=-g -mmcu=$(PART) -O1 -Wall -Werror -DF_CPU=$(F_CPU) +INCLUDES=-I. -I$(LIB_DIR) + + +################# +# Build targets # +################# + +# All applications +all: $(BUILD_DIR) $(APP_HEX) Makefile + +# Make build/output directory +$(BUILD_DIR): + mkdir $(BUILD_DIR) + +# Application HEX files +$(APP_HEX): %.hex: %.elf + @echo Building $@ + $(OBJCOPY) -j .text -j .data -O ihex $(BUILD_DIR)/$< $(BUILD_DIR)/$@ + +# Application ELF files +$(APP_ELF): %.elf: $(LIB_OBJECTS) $(LIB_ASM_OBJECTS) $(APP_OBJECTS) + $(CC) $(CFLAGS) $(BUILT_OBJECTS) --output $(BUILD_DIR)/$@ -Wl,-Map,$(BUILD_DIR)/$(basename $@).map + +# Application objects builder +$(APP_OBJECTS): %.o: %.c + $(CC) -c $(CFLAGS) $(INCLUDES) $< -o $(BUILD_DIR)/$(notdir $@) + +# Application C objects builder +$(LIB_OBJECTS): %.o: $(LIB_DIR)/%.c + $(CC) -c $(CFLAGS) $(INCLUDES) $< -o $(BUILD_DIR)/$(notdir $@) + +# Application asm objects builder +$(LIB_ASM_OBJECTS): %.o: $(LIB_DIR)/%.s + $(CC) -c $(CFLAGS) -x assembler-with-cpp $(INCLUDES) $< -o $(BUILD_DIR)/$(notdir $@) + +# .lst file builder +%.lst: %.c + $(CC) $(CFLAGS) $(INCLUDES) -Wa,-al $< > $@ + +# Clean +clean: + rm -f *.o *.elf *.map *.hex *.bin *.lst + rm -rf doxygen-avr + rm -rf build + +# Send to device +program: $(APP_HEX) + $(SIZE) -C $(BUILD_DIR)/$(APP_ELF) + $(AVRDUDE) $(AVRDUDE_FLAGS) -c $(PROG) -P $(AVRDUDE_DEV) -p $(AVRDUDE_PART) -U flash:w:$(BUILD_DIR)/$(APP_HEX) -v + +fuse: + $(AVRDUDE) $(AVRDUDE_FLAGS) -c $(PROG) -P $(AVRDUDE_DEV) -p $(AVRDUDE_PART) -U lfuse:w:0x60:m -U hfuse:w:0xdc:m -U efuse:w:0xff:m -v + +interactive: + $(AVRDUDE) $(AVRDUDE_FLAGS) -c $(PROG) -P $(AVRDUDE_DEV) -p $(AVRDUDE_PART) -t -v + +doxygen: + doxygen ./Doxyfile diff --git a/src/app/README.md b/src/app/README.md new file mode 100644 index 0000000..9683e00 --- /dev/null +++ b/src/app/README.md @@ -0,0 +1,10 @@ +app +=== + +On startup, configure ADF4002 with + +- R counter = 400 +- N counter = 1080 + + f_VCO = N ⋅ f_REF / R + 27 = 1080 ⋅ 10 / 400 diff --git a/src/app/build/.gitignore b/src/app/build/.gitignore new file mode 100644 index 0000000..1e22b08 --- /dev/null +++ b/src/app/build/.gitignore @@ -0,0 +1,4 @@ +app.elf* +app.hex +app.map +main.o diff --git a/src/app/delay.h b/src/app/delay.h new file mode 100644 index 0000000..af92a4f --- /dev/null +++ b/src/app/delay.h @@ -0,0 +1,9 @@ +#ifndef __DELAY_INT_H +#define __DELAY_INT_H + +#include + +#define delay_us(us) _delay_us(us) +#define delay_ms(ms) _delay_ms(ms) + +#endif diff --git a/src/app/main.c b/src/app/main.c new file mode 100644 index 0000000..6fe7cd7 --- /dev/null +++ b/src/app/main.c @@ -0,0 +1,121 @@ +#include +#include +#include +#include +#include "delay.h" + +/* Definitions for pins */ +#define PORTB_PLL_MUXOUT (1 << 0) +#define PORTB_PLL_LE (1 << 4) +#define PORTB_PLL_DATA (1 << 3) +#define PORTB_PLL_CLK (1 << 2) + +void set_pin(int pin, int high) +{ + if (high) { + PORTB |= pin; + } + else + { + PORTB &= ~pin; + } +} + +void shift_out(uint8_t value) +{ + for (uint8_t i = 0; i < 8; i++) { + set_pin(PORTB_PLL_DATA, !!(value & (1 << (7 - i)))); + + set_pin(PORTB_PLL_CLK, 1); + set_pin(PORTB_PLL_CLK, 0); + } +} + +void write_adf4002(uint32_t value) +{ + set_pin(PORTB_PLL_LE, 0); + shift_out((value & 0x00FF0000) >> 16); + shift_out((value & 0x0000FF00) >> 8); + shift_out(value & 0x000000FF); + set_pin(PORTB_PLL_LE, 1); +} + +volatile uint8_t systick; /* Timer (100Hz increment) */ +volatile uint32_t seconds; + +/* 200Hz timer interrupt */ +ISR(TIM0_COMPA_vect) +{ + systick++; + if (systick == 20) { + systick = 0; + seconds += 1; + } +} + +static int inittimer(void) +{ + /* Start 200Hz system timer */ + TCCR0B |= (1 << WGM01); // Configure timer for CTC mode + TIMSK |= (1 << OCIE0A); // enable compare match A interrupt + OCR0A = (uint8_t)(F_CPU / 64 / 50); // Set CTC compare value to 50ms + TCCR0B |= ((1 << CS00) | (1 << CS01)); // Start timer at Fcpu/64 + + // Enable interrupts + sei(); + + return 0; +} + + +int main(void) +{ + systick = 0; + seconds = 0; + + /* Configure GPIO */ + PORTB = PORTB_PLL_LE; + DDRB = PORTB_PLL_CLK | PORTB_PLL_LE | PORTB_PLL_DATA; + + /* initialise timer interrupt */ + inittimer(); + + delay_ms(120); + + // See README.md + const uint32_t r_counter = 400; + const uint32_t n_counter = 1080; + const uint32_t ldp = 1; // 5 consecutive cycles of phase delay less than 15ns before lock det + const uint32_t cpi = 3; // I_CP = 2.5mA + const uint32_t pd_polarity = 1; // positive + const uint32_t muxout = 1; // lock detect, active high + + const uint32_t refernce_counter_latch = (ldp << 20) | (r_counter << 2) | 0; + const uint32_t n_counter_latch = (n_counter << 8) | 1; + const uint32_t function_latch = (cpi << 18) | (cpi << 15) | (pd_polarity << 7) | (muxout << 4) | 2; + const uint32_t init_latch = (cpi << 18) | (cpi << 15) | (pd_polarity << 7) | (muxout << 4) | 3; + + // ADF4002 Datasheet Page 16 + // Device Programming After Initial Statup + // Initialisation Latch Method + write_adf4002(init_latch); + write_adf4002(function_latch); + write_adf4002(refernce_counter_latch); + write_adf4002(n_counter_latch); + + while (1) { + /* + // We actually dont use the timer, but the code is kept around as a reference. + const uint32_t second = seconds % 60uL; + const uint32_t minute = seconds / 60uL; + + if ((PINB & PORTB_PLL_MUXOUT) == 0) { + delay_ms(600); + } + */ + delay_ms(1000); + } + + return 0; +} + -- cgit v1.2.3