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__
|
||||
#define __BASE_H__
|
||||
|
||||
#define PIN_OUT 1
|
||||
#define PIN_IN 0
|
||||
#define LINE_OUT 1
|
||||
#define LINE_IN 0
|
||||
|
||||
typedef struct IO_PIN {
|
||||
typedef struct GPIO {
|
||||
volatile uint8_t *ddr;
|
||||
volatile uint8_t *port;
|
||||
volatile uint8_t *pin;
|
||||
uint8_t addr;
|
||||
} io_pin_t;
|
||||
} gpio_t;
|
||||
|
||||
/*
|
||||
#define GPIOA(addr) (io_pin_t){ .ddr = &DDRA, .port = &PORTA, .addr = addr }
|
||||
#define GPIOB(addr) (io_pin_t){ .ddr = &DDRB, .port = &PORTB, .addr = addr }
|
||||
#define GPIOC(addr) (io_pin_t){ .ddr = &DDRC, .port = &PORTC, .addr = addr }
|
||||
#define GPIOD(addr) (io_pin_t){ .ddr = &DDRD, .port = &PORTD, .addr = addr }
|
||||
#define GPIOA(addr) (gpio_t){ .ddr = &DDRA, .port = &PORTA, .addr = addr }
|
||||
#define GPIOB(addr) (gpio_t){ .ddr = &DDRB, .port = &PORTB, .addr = addr }
|
||||
#define GPIOC(addr) (gpio_t){ .ddr = &DDRC, .port = &PORTC, .addr = addr }
|
||||
#define GPIOD(addr) (gpio_t){ .ddr = &DDRD, .port = &PORTD, .addr = addr }
|
||||
*/
|
||||
|
||||
inline void set_pin_direction(io_pin_t *pin, int direction) {
|
||||
if (direction == PIN_OUT) {
|
||||
*(pin->ddr) |= _BV(pin->addr);
|
||||
inline void set_line_direction(gpio_t *line, int direction) {
|
||||
if (direction == LINE_OUT) {
|
||||
*(line->ddr) |= _BV(line->addr);
|
||||
} else {
|
||||
*(pin->ddr) &= ~(_BV(pin->addr));
|
||||
*(line->ddr) &= ~(_BV(line->addr));
|
||||
}
|
||||
}
|
||||
|
||||
inline void set_pin(io_pin_t *pin) {
|
||||
*(pin->port) |= _BV(pin->addr);
|
||||
inline void set_line(gpio_t *line) {
|
||||
*(line->port) |= _BV(line->addr);
|
||||
}
|
||||
|
||||
inline void clear_pin(io_pin_t *pin) {
|
||||
*(pin->port) &= ~(_BV(pin->addr));
|
||||
inline void clear_line(gpio_t *line) {
|
||||
*(line->port) &= ~(_BV(line->addr));
|
||||
}
|
||||
|
||||
inline int read_pin(io_pin_t *pin) {
|
||||
return (*(pin->port) & _BV(pin->addr)) > 0;
|
||||
inline int read_line(gpio_t *line) {
|
||||
return (*(line->port) & _BV(line->addr)) > 0;
|
||||
}
|
||||
|
||||
typedef struct RNG {
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
name = "morse-tx";
|
||||
src = ./.;
|
||||
|
||||
includes = [ "base" "morse" ];
|
||||
includes = [ "base" "spi" "morse" ];
|
||||
|
||||
MCU = "atmega32u4";
|
||||
CHIP_SELECT = "AVR_ATmega32u4";
|
||||
|
@ -55,9 +55,10 @@
|
|||
INCLUDE_DIRS = lib.concatStringsSep " " (map (dir: "-I${src}/${dir}") includes);
|
||||
|
||||
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 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
|
||||
'';
|
||||
installPhase = ''
|
||||
|
|
|
@ -60,7 +60,7 @@ const struct morse_codepoint * morse_lookup(char val) {
|
|||
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;
|
||||
for (size_t i = 0; i < codepoint->length; i++) {
|
||||
*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);
|
||||
}
|
||||
|
||||
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++) {
|
||||
if (message[i] == ' ') {
|
||||
_delay_ms(INTERWORD * SCALE);
|
||||
|
|
|
@ -14,6 +14,6 @@
|
|||
#define INTERWORD 4
|
||||
#define SCALE 100
|
||||
|
||||
void send_morse(io_pin_t *gpio, char *message);
|
||||
void send_morse(gpio_t *gpio, char *message);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,15 +1,89 @@
|
|||
#include <avr/io.h>
|
||||
#include <util/delay.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) {
|
||||
// io_pin_t gpio = (io_pin_t){ .ddr = &DDRB, .port = &PORTB, .addr = 7 };
|
||||
io_pin_t gpio = (io_pin_t){ .ddr = &DDRB, .port = &PORTB, .addr = 7 };
|
||||
set_pin_direction(&gpio, PIN_OUT);
|
||||
spi_t spi = (spi_t){
|
||||
.clock = { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 1 },
|
||||
.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) {
|
||||
send_morse(&gpio, "saluton mondo");
|
||||
_delay_ms(2000);
|
||||
rfm_send_data(&rfm, count, 1);
|
||||
count[0]++;
|
||||
set_line(&light);
|
||||
_delay_ms(50);
|
||||
clear_line(&light);
|
||||
_delay_ms(50);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
39
spi/spi.c
39
spi/spi.c
|
@ -2,35 +2,42 @@
|
|||
#include <spi.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
void initialize_spi(spi_t *spi) {
|
||||
set_pin_direction(&spi->clock, PIN_OUT);
|
||||
set_pin_direction(&spi->data_out, PIN_OUT);
|
||||
set_pin_direction(&spi->data_in, PIN_IN);
|
||||
set_pin_direction(&spi->chip_select, PIN_OUT);
|
||||
void spi_initialize(spi_t *spi) {
|
||||
set_line_direction(&spi->clock, LINE_OUT);
|
||||
set_line_direction(&spi->data_out, LINE_OUT);
|
||||
set_line_direction(&spi->data_in, LINE_IN);
|
||||
set_line_direction(&spi->chip_select, LINE_OUT);
|
||||
|
||||
set_line(&spi->chip_select);
|
||||
}
|
||||
|
||||
uint8_t transfer_byte(spi_t *spi, uint8_t output) {
|
||||
uint8_t input = 0;
|
||||
int input_bit;
|
||||
void spi_acquire(spi_t *spi) {
|
||||
clear_line(&spi->chip_select);
|
||||
}
|
||||
|
||||
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--) {
|
||||
clear_pin(&spi->clock);
|
||||
clear_line(&spi->clock);
|
||||
if (output & _BV(i)) {
|
||||
set_pin(&spi->data_out);
|
||||
set_line(&spi->data_out);
|
||||
} else {
|
||||
clear_pin(&spi->data_out);
|
||||
clear_line(&spi->data_out);
|
||||
}
|
||||
_delay_us(10);
|
||||
set_pin(&spi->clock);
|
||||
set_line(&spi->clock);
|
||||
_delay_us(10);
|
||||
//input_bit = read_pin(&spi->data_in);
|
||||
//input_bit = read_line(&spi->data_in);
|
||||
//input <<= input_bit;
|
||||
}
|
||||
clear_pin(&spi->clock);
|
||||
clear_line(&spi->clock);
|
||||
_delay_us(10);
|
||||
clear_pin(&spi->chip_select);
|
||||
return input;
|
||||
}
|
||||
|
||||
|
|
14
spi/spi.h
14
spi/spi.h
|
@ -6,13 +6,15 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
typedef struct SPI {
|
||||
io_pin_t clock;
|
||||
io_pin_t data_out;
|
||||
io_pin_t data_in;
|
||||
io_pin_t chip_select;
|
||||
gpio_t clock;
|
||||
gpio_t data_out;
|
||||
gpio_t data_in;
|
||||
gpio_t chip_select;
|
||||
} spi_t;
|
||||
|
||||
void initialize_spi(spi_t *spi);
|
||||
uint8_t transfer_byte(spi_t *spi, uint8_t output);
|
||||
void spi_initialize(spi_t *spi);
|
||||
void spi_acquire(spi_t *spi);
|
||||
void spi_release(spi_t *spi);
|
||||
uint8_t spi_transfer_byte(spi_t *spi, uint8_t output);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue