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__ #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 {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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