diff --git a/firmware/Makefile b/firmware/Makefile index ee09faf..1b45219 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -1,11 +1,11 @@ -AVRMCU ?= atmega8 +AVRMCU ?= atmega328p F_CPU ?= 16000000 -ISPPORT ?= /dev/kaboard +ISPPORT ?= /dev/ttyUSB0 VERSION = 0.1 -HEADERS = include/twi.h include/si5351.h include/wspr.h -SRC = main.c twi.c si5351.c wspr.c +HEADERS = include/twi.h include/uart.h include/si5351.h include/wspr.h include/ov7670.h +SRC = main.c twi.c uart.c si5351.c wspr.c ov7670.c TARGET = cube-kl OBJDIR = bin diff --git a/firmware/include/ov7670.h b/firmware/include/ov7670.h new file mode 100644 index 0000000..b577599 --- /dev/null +++ b/firmware/include/ov7670.h @@ -0,0 +1,82 @@ +#ifndef __ov7670_H__ +#define __ov7670_H__ __ov7670_H__ + +#include + +#include +#include + +void ov7670_init(void); + +static inline uint8_t ov7670_vsync(void) { + return (PINC & (1 << PC0)) != 0; +} + +static inline void ov7670_wait_vsync(void) { + while(ov7670_vsync()); // Wait until low + while(!ov7670_vsync()); // Wait until high +} + +static inline void ov7670_set_rst(void) { + PORTD |= (1 << PD3); +} + +static inline void ov7670_unset_rst(void) { + PORTD &= ~(1 << PD3); +} + +static inline void ov7670_set_wrst(void) { + PORTC |= (1 << PC3); +} + +static inline void ov7670_unset_wrst(void) { + PORTC &= ~(1 << PC3); +} + +static inline void ov7670_toggle_wrst(void) { + ov7670_set_wrst(); + _delay_us(5); + ov7670_unset_wrst(); +} + +static inline void ov7670_set_rrst(void) { + PORTC |= (1 << PC2); +} + +static inline void ov7670_unset_rrst(void) { + PORTC &= ~(1 << PC2); +} + +static inline void ov7670_toggle_rrst(void) { + ov7670_set_rrst(); + _delay_us(5); + ov7670_unset_rrst(); +} + +static inline void ov7670_set_we(void) { + PORTC |= (1 << PC1); +} + +static inline void ov7670_unset_we(void) { + PORTC &= ~(1 << PC1); +} + +static inline void ov7670_set_rck(void) { + PORTB |= (1 << PB5); +} + +static inline void ov7670_unset_rck(void) { + PORTB &= ~(1 << PB5); +} + +static inline void ov7670_toggle_rck(void) { + ov7670_set_rck(); + _delay_us(5); + ov7670_unset_rck(); +} + +static inline uint8_t ov7670_read_bits(void) { + return (PINB & 0x0F) | (PIND & 0xF0); +} + +#endif diff --git a/firmware/include/uart.h b/firmware/include/uart.h new file mode 100644 index 0000000..0038270 --- /dev/null +++ b/firmware/include/uart.h @@ -0,0 +1,58 @@ +#ifndef UART_H_ +#define UART_H_ UART_H_ + +#include +#include +#include + +#include + + +//#define BAUD 76800UL // baudrate +#define BAUD 115200UL +#define UART_TIMEOUT 100 // Timeout in ms + +// 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) + +#if ((BAUD_ERROR<950) || (BAUD_ERROR>1050)) // Make sure your UBRR_VAL will work + #error Baudrate error is bigger then 1% ! +#endif + +extern uint8_t uart_timed_out; + +void uart_init(void); +uint8_t uart_getc_timeout(void); +uint8_t uart_get_line(char buffer[], uint8_t maxlen); + + +static inline void uart_putc(uint8_t data) { + UDR0 = data; // write byte to data register + while (!(UCSR0A & (1<< UDRE0))); // waiting for the uart to finish transmission + UCSR0A |= (1 << UDRE0); +} + +static inline void uart_puts(char *data) { + uint8_t i; + for(i = 0; i < strlen(data); i++) { + uart_putc(data[i]); + } +} + +static inline uint8_t uart_getc(void) { + while (!(UCSR0A & (1< #include "twi.h" +#include "uart.h" #include "si5351.h" #include "wspr.h" +#include "ov7670.h" int main(void) { twi_init(); + uart_init(); - si5351_init(25000000, 800000000, 500000000); - si5351_ms_set_source(SI5351_MS0, SI5351_PLLA); + ov7670_init(); + //while(1) { + ov7670_wait_vsync(); + ov7670_toggle_wrst(); + ov7670_unset_we(); - //si5351_ms_set_freq(SI5351_MS0, 7040100); - //si5351_ms_enable_output(SI5351_MS0); - //si5351_ms_write_params(SI5351_MS0, WSPR_SYMBOLS[3]); + ov7670_wait_vsync(); + ov7670_set_we(); + ov7670_toggle_rrst(); - uint8_t wspr_buffer[WSPR_LENGTH]; + for(uint16_t y = 0; y < 480; y++) { + for(uint16_t x = 0; x < 640; x++) { + ov7670_toggle_rck(); + uint8_t bits = ov7670_read_bits(); + uart_putc(bits); + } + } - wspr_encode("DL1SSK", "JN39", 27, wspr_buffer); - wspr_transmit(SI5351_MS0, wspr_buffer); + uart_puts("Done"); + //} while(1); } diff --git a/firmware/ov7670.c b/firmware/ov7670.c new file mode 100644 index 0000000..540a4d2 --- /dev/null +++ b/firmware/ov7670.c @@ -0,0 +1,23 @@ +#include "ov7670.h" + + +void ov7670_init(void) { + // WRST, RRST, WE + DDRC |= (1 << PC3) | (1 << PC2) | (1 << PC1); + // VSYNC + DDRC &= ~(1 << PC0); + // RCK + DDRB |= (1 << PB5); + // RST + DDRD |= (1 << PD3); + + // Lower nibble of 8bit data, input + DDRB &= ~0x0F; + // Upper nibble of 8bit data, input + DDRD &= ~0xF0; + + // Reset should be high + ov7670_set_rst(); + // Write enable should be high + ov7670_set_we(); +} diff --git a/firmware/uart.c b/firmware/uart.c new file mode 100644 index 0000000..8a1c2fc --- /dev/null +++ b/firmware/uart.c @@ -0,0 +1,68 @@ +#include "uart.h" + +uint8_t uart_timed_out = 0; + +void uart_init(void) { + UBRR0H = UBRR_VAL >> 8; //Setting baudrate + UBRR0L = UBRR_VAL & 0xFF; + + UCSR0B |= (1< 0)) { + if(delays == 0) { + retries--; + } + delays = (delays + 1) % 250; + _delay_us(4); + } + + if(retries > 0) { + uart_timed_out = 0; + return UDR0; + } + + uart_timed_out = 1; + return 0; +} + +uint8_t uart_get_line(char buffer[], uint8_t maxlen) { + char t = 0; + uint8_t pos = 0; + buffer[0] = 0; + + //maxlen needs to be at least big enough for one character + null byte. + if(maxlen < 2) { + return 0; + } + + uart_clear_time_out(); + + while(pos < maxlen && t != '\n' && !uart_has_timed_out()) { + t = uart_getc_timeout(); + buffer[pos] = t; + pos++; + } + + // We passed the loop at least once, so pos can not be 0 + if(buffer[pos-1] != '\n') { + return 0; + } + buffer[pos-1] = 0; + return 1; +}