aboutsummaryrefslogtreecommitdiffstats
path: root/src/app
diff options
context:
space:
mode:
Diffstat (limited to 'src/app')
-rw-r--r--src/app/Makefile107
-rw-r--r--src/app/README.md10
-rw-r--r--src/app/build/.gitignore4
-rw-r--r--src/app/delay.h9
-rw-r--r--src/app/main.c121
5 files changed, 251 insertions, 0 deletions
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 <util/delay.h>
+
+#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 <stdio.h>
+#include <avr/pgmspace.h>
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#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;
+}
+