Start trying to build a number transmitter
This commit is contained in:
parent
a78f1ea129
commit
3727225940
37
base/base.h
37
base/base.h
|
@ -3,40 +3,41 @@
|
||||||
#ifndef __BASE_H__
|
#ifndef __BASE_H__
|
||||||
#define __BASE_H__
|
#define __BASE_H__
|
||||||
|
|
||||||
#define PIN_OUT 1
|
#define LINE_OUT 1
|
||||||
#define PIN_IN 0
|
#define LINE_IN 0
|
||||||
|
|
||||||
typedef struct IO_PIN {
|
typedef struct GPIO {
|
||||||
volatile uint8_t *ddr;
|
volatile uint8_t *ddr;
|
||||||
volatile uint8_t *port;
|
volatile uint8_t *port;
|
||||||
|
volatile uint8_t *pin;
|
||||||
uint8_t addr;
|
uint8_t addr;
|
||||||
} io_pin_t;
|
} gpio_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define GPIOA(addr) (io_pin_t){ .ddr = &DDRA, .port = &PORTA, .addr = addr }
|
#define GPIOA(addr) (gpio_t){ .ddr = &DDRA, .port = &PORTA, .addr = addr }
|
||||||
#define GPIOB(addr) (io_pin_t){ .ddr = &DDRB, .port = &PORTB, .addr = addr }
|
#define GPIOB(addr) (gpio_t){ .ddr = &DDRB, .port = &PORTB, .addr = addr }
|
||||||
#define GPIOC(addr) (io_pin_t){ .ddr = &DDRC, .port = &PORTC, .addr = addr }
|
#define GPIOC(addr) (gpio_t){ .ddr = &DDRC, .port = &PORTC, .addr = addr }
|
||||||
#define GPIOD(addr) (io_pin_t){ .ddr = &DDRD, .port = &PORTD, .addr = addr }
|
#define GPIOD(addr) (gpio_t){ .ddr = &DDRD, .port = &PORTD, .addr = addr }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
inline void set_pin_direction(io_pin_t *pin, int direction) {
|
inline void set_line_direction(gpio_t *line, int direction) {
|
||||||
if (direction == PIN_OUT) {
|
if (direction == LINE_OUT) {
|
||||||
*(pin->ddr) |= _BV(pin->addr);
|
*(line->ddr) |= _BV(line->addr);
|
||||||
} else {
|
} else {
|
||||||
*(pin->ddr) &= ~(_BV(pin->addr));
|
*(line->ddr) &= ~(_BV(line->addr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void set_pin(io_pin_t *pin) {
|
inline void set_line(gpio_t *line) {
|
||||||
*(pin->port) |= _BV(pin->addr);
|
*(line->port) |= _BV(line->addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void clear_pin(io_pin_t *pin) {
|
inline void clear_line(gpio_t *line) {
|
||||||
*(pin->port) &= ~(_BV(pin->addr));
|
*(line->port) &= ~(_BV(line->addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int read_pin(io_pin_t *pin) {
|
inline int read_line(gpio_t *line) {
|
||||||
return (*(pin->port) & _BV(pin->addr)) > 0;
|
return (*(line->port) & _BV(line->addr)) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct RNG {
|
typedef struct RNG {
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
name = "morse-tx";
|
name = "morse-tx";
|
||||||
src = ./.;
|
src = ./.;
|
||||||
|
|
||||||
includes = [ "base" "morse" ];
|
includes = [ "base" "spi" "morse" ];
|
||||||
|
|
||||||
MCU = "atmega32u4";
|
MCU = "atmega32u4";
|
||||||
CHIP_SELECT = "AVR_ATmega32u4";
|
CHIP_SELECT = "AVR_ATmega32u4";
|
||||||
|
@ -55,9 +55,10 @@
|
||||||
INCLUDE_DIRS = lib.concatStringsSep " " (map (dir: "-I${src}/${dir}") includes);
|
INCLUDE_DIRS = lib.concatStringsSep " " (map (dir: "-I${src}/${dir}") includes);
|
||||||
|
|
||||||
buildPhase = ''
|
buildPhase = ''
|
||||||
|
${avr.gcc}/bin/avr-gcc ${CFLAGS} ${INCLUDE_DIRS} -o spi.o -c ${src}/spi/spi.c
|
||||||
${avr.gcc}/bin/avr-gcc ${CFLAGS} ${INCLUDE_DIRS} -o morse.o -c ${src}/morse/morse.c
|
${avr.gcc}/bin/avr-gcc ${CFLAGS} ${INCLUDE_DIRS} -o morse.o -c ${src}/morse/morse.c
|
||||||
${avr.gcc}/bin/avr-gcc ${CFLAGS} ${INCLUDE_DIRS} -o main.o -c ${src}/morse_tx/main.c
|
${avr.gcc}/bin/avr-gcc ${CFLAGS} ${INCLUDE_DIRS} -o main.o -c ${src}/morse_tx/main.c
|
||||||
${avr.gcc}/bin/avr-gcc ${CFLAGS} -o main.elf main.o morse.o
|
${avr.gcc}/bin/avr-gcc ${CFLAGS} -o main.elf main.o morse.o spi.o
|
||||||
$OBJCOPY -O ihex main.elf main.hex
|
$OBJCOPY -O ihex main.elf main.hex
|
||||||
'';
|
'';
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
|
|
|
@ -60,7 +60,7 @@ const struct morse_codepoint * morse_lookup(char val) {
|
||||||
return &MORSE[idx];
|
return &MORSE[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_codepoint(io_pin_t *gpio, const struct morse_codepoint *codepoint) {
|
void send_codepoint(gpio_t *gpio, const struct morse_codepoint *codepoint) {
|
||||||
const uint8_t one = 1 << gpio->addr;
|
const uint8_t one = 1 << gpio->addr;
|
||||||
for (size_t i = 0; i < codepoint->length; i++) {
|
for (size_t i = 0; i < codepoint->length; i++) {
|
||||||
*gpio->port = *(gpio->port) | one;
|
*gpio->port = *(gpio->port) | one;
|
||||||
|
@ -75,7 +75,7 @@ void send_codepoint(io_pin_t *gpio, const struct morse_codepoint *codepoint) {
|
||||||
_delay_ms(INTERCHAR * SCALE);
|
_delay_ms(INTERCHAR * SCALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_morse(io_pin_t *gpio, char *message) {
|
void send_morse(gpio_t *gpio, char *message) {
|
||||||
for (size_t i = 0; i < strlen(message); i++) {
|
for (size_t i = 0; i < strlen(message); i++) {
|
||||||
if (message[i] == ' ') {
|
if (message[i] == ' ') {
|
||||||
_delay_ms(INTERWORD * SCALE);
|
_delay_ms(INTERWORD * SCALE);
|
||||||
|
|
|
@ -14,6 +14,6 @@
|
||||||
#define INTERWORD 4
|
#define INTERWORD 4
|
||||||
#define SCALE 100
|
#define SCALE 100
|
||||||
|
|
||||||
void send_morse(io_pin_t *gpio, char *message);
|
void send_morse(gpio_t *gpio, char *message);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,15 +1,89 @@
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
#include <base.h>
|
#include <base.h>
|
||||||
#include <morse.h>
|
#include <spi.h>
|
||||||
|
|
||||||
|
typedef struct RFM {
|
||||||
|
spi_t spi;
|
||||||
|
gpio_t irq;
|
||||||
|
gpio_t reset;
|
||||||
|
} rfm_t;
|
||||||
|
|
||||||
|
void rfm_initialize(rfm_t *rfm) {
|
||||||
|
spi_initialize(&rfm->spi);
|
||||||
|
|
||||||
|
spi_acquire(&rfm->spi);
|
||||||
|
spi_transfer_byte(&rfm->spi, 0x37 | _BV(7));
|
||||||
|
spi_transfer_byte(&rfm->spi, 0);
|
||||||
|
spi_release(&rfm->spi);
|
||||||
|
|
||||||
|
spi_acquire(&rfm->spi);
|
||||||
|
spi_transfer_byte(&rfm->spi, 0x38 | _BV(7));
|
||||||
|
spi_transfer_byte(&rfm->spi, 1);
|
||||||
|
spi_release(&rfm->spi);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rfm_power_off(rfm_t *rfm) {
|
||||||
|
spi_acquire(&rfm->spi);
|
||||||
|
spi_transfer_byte(&rfm->spi, 0x11);
|
||||||
|
spi_transfer_byte(&rfm->spi, 0x00);
|
||||||
|
spi_release(&rfm->spi);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rfm_send_data(rfm_t *rfm, uint8_t *data, size_t length) {
|
||||||
|
/* Go into standby mode */
|
||||||
|
spi_acquire(&rfm->spi);
|
||||||
|
spi_transfer_byte(&rfm->spi, 0x11);
|
||||||
|
spi_transfer_byte(&rfm->spi, 0x01);
|
||||||
|
spi_release(&rfm->spi);
|
||||||
|
|
||||||
|
/* Write data to FIFO */
|
||||||
|
spi_acquire(&rfm->spi);
|
||||||
|
spi_transfer_byte(&rfm->spi, 0x10);
|
||||||
|
for (size_t i = 0; i < length; i++) {
|
||||||
|
spi_transfer_byte(&rfm->spi, data[i]);
|
||||||
|
}
|
||||||
|
spi_release(&rfm->spi);
|
||||||
|
|
||||||
|
/* Go into transmit mode */
|
||||||
|
spi_acquire(&rfm->spi);
|
||||||
|
spi_transfer_byte(&rfm->spi, 0x11);
|
||||||
|
spi_transfer_byte(&rfm->spi, 0x03);
|
||||||
|
spi_release(&rfm->spi);
|
||||||
|
|
||||||
|
/* Return to standby mode */
|
||||||
|
spi_acquire(&rfm->spi);
|
||||||
|
spi_transfer_byte(&rfm->spi, 0x11);
|
||||||
|
spi_transfer_byte(&rfm->spi, 0x01);
|
||||||
|
spi_release(&rfm->spi);
|
||||||
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
// io_pin_t gpio = (io_pin_t){ .ddr = &DDRB, .port = &PORTB, .addr = 7 };
|
spi_t spi = (spi_t){
|
||||||
io_pin_t gpio = (io_pin_t){ .ddr = &DDRB, .port = &PORTB, .addr = 7 };
|
.clock = { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 1 },
|
||||||
set_pin_direction(&gpio, PIN_OUT);
|
.data_out = { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 2 },
|
||||||
|
.data_in = { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 3 },
|
||||||
|
.chip_select = { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 4 },
|
||||||
|
};
|
||||||
|
|
||||||
|
rfm_t rfm = (rfm_t){
|
||||||
|
.spi = spi,
|
||||||
|
.irq = { .ddr = &DDRE, .port = &PORTE, .pin = &PINE, .addr = 6 },
|
||||||
|
.reset = { .ddr = &DDRD, .port = &PORTD, .pin = &PIND, .addr = 4 },
|
||||||
|
};
|
||||||
|
|
||||||
|
gpio_t light = { .ddr = &DDRC, .port = &PORTC, .addr = 7 };
|
||||||
|
|
||||||
|
rfm_initialize(&rfm);
|
||||||
|
|
||||||
|
uint8_t count[1] = { 0 };
|
||||||
while(1) {
|
while(1) {
|
||||||
send_morse(&gpio, "saluton mondo");
|
rfm_send_data(&rfm, count, 1);
|
||||||
_delay_ms(2000);
|
count[0]++;
|
||||||
|
set_line(&light);
|
||||||
|
_delay_ms(50);
|
||||||
|
clear_line(&light);
|
||||||
|
_delay_ms(50);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
39
spi/spi.c
39
spi/spi.c
|
@ -2,35 +2,42 @@
|
||||||
#include <spi.h>
|
#include <spi.h>
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
|
|
||||||
void initialize_spi(spi_t *spi) {
|
void spi_initialize(spi_t *spi) {
|
||||||
set_pin_direction(&spi->clock, PIN_OUT);
|
set_line_direction(&spi->clock, LINE_OUT);
|
||||||
set_pin_direction(&spi->data_out, PIN_OUT);
|
set_line_direction(&spi->data_out, LINE_OUT);
|
||||||
set_pin_direction(&spi->data_in, PIN_IN);
|
set_line_direction(&spi->data_in, LINE_IN);
|
||||||
set_pin_direction(&spi->chip_select, PIN_OUT);
|
set_line_direction(&spi->chip_select, LINE_OUT);
|
||||||
|
|
||||||
|
set_line(&spi->chip_select);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t transfer_byte(spi_t *spi, uint8_t output) {
|
void spi_acquire(spi_t *spi) {
|
||||||
uint8_t input = 0;
|
clear_line(&spi->chip_select);
|
||||||
int input_bit;
|
}
|
||||||
|
|
||||||
set_pin(&spi->chip_select);
|
void spi_release(spi_t *spi) {
|
||||||
|
set_line(&spi->chip_select);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t spi_transfer_byte(spi_t *spi, uint8_t output) {
|
||||||
|
uint8_t input = 0;
|
||||||
|
// int input_bit;
|
||||||
|
|
||||||
for (int i = 7; i >= 0; i--) {
|
for (int i = 7; i >= 0; i--) {
|
||||||
clear_pin(&spi->clock);
|
clear_line(&spi->clock);
|
||||||
if (output & _BV(i)) {
|
if (output & _BV(i)) {
|
||||||
set_pin(&spi->data_out);
|
set_line(&spi->data_out);
|
||||||
} else {
|
} else {
|
||||||
clear_pin(&spi->data_out);
|
clear_line(&spi->data_out);
|
||||||
}
|
}
|
||||||
_delay_us(10);
|
_delay_us(10);
|
||||||
set_pin(&spi->clock);
|
set_line(&spi->clock);
|
||||||
_delay_us(10);
|
_delay_us(10);
|
||||||
//input_bit = read_pin(&spi->data_in);
|
//input_bit = read_line(&spi->data_in);
|
||||||
//input <<= input_bit;
|
//input <<= input_bit;
|
||||||
}
|
}
|
||||||
clear_pin(&spi->clock);
|
clear_line(&spi->clock);
|
||||||
_delay_us(10);
|
_delay_us(10);
|
||||||
clear_pin(&spi->chip_select);
|
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
spi/spi.h
14
spi/spi.h
|
@ -6,13 +6,15 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
typedef struct SPI {
|
typedef struct SPI {
|
||||||
io_pin_t clock;
|
gpio_t clock;
|
||||||
io_pin_t data_out;
|
gpio_t data_out;
|
||||||
io_pin_t data_in;
|
gpio_t data_in;
|
||||||
io_pin_t chip_select;
|
gpio_t chip_select;
|
||||||
} spi_t;
|
} spi_t;
|
||||||
|
|
||||||
void initialize_spi(spi_t *spi);
|
void spi_initialize(spi_t *spi);
|
||||||
uint8_t transfer_byte(spi_t *spi, uint8_t output);
|
void spi_acquire(spi_t *spi);
|
||||||
|
void spi_release(spi_t *spi);
|
||||||
|
uint8_t spi_transfer_byte(spi_t *spi, uint8_t output);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue