Start trying to build a number transmitter

i2c
Savanni D'Gerinel 2022-06-20 14:52:29 -04:00
parent a78f1ea129
commit 3727225940
7 changed files with 136 additions and 51 deletions

View File

@ -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 {

View File

@ -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 = ''

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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