avr/morse_tx/main.c

90 lines
2.3 KiB
C
Raw Normal View History

#include <avr/io.h>
#include <util/delay.h>
#include <base.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) {
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) {
rfm_send_data(&rfm, count, 1);
count[0]++;
set_line(&light);
_delay_ms(50);
clear_line(&light);
_delay_ms(50);
}
return 0;
}