121 lines
3.4 KiB
C
121 lines
3.4 KiB
C
|
/*
|
||
|
Copyright 2022, Savanni D'Gerinel <savanni@luminescent-dreams.com>
|
||
|
|
||
|
This file is part of Savanni's AVR library.
|
||
|
|
||
|
Lumeto is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||
|
|
||
|
Lumeto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License along with Lumeto. If not, see <https://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
|
||
|
#include <rfm.h>
|
||
|
|
||
|
void rfm_write(rfm_t *rfm, uint8_t reg, uint8_t *data, size_t length) {
|
||
|
spi_acquire(&rfm->spi);
|
||
|
spi_transfer_byte(&rfm->spi, _BV(7) | reg);
|
||
|
for (size_t i = 0; i < length; i++) {
|
||
|
spi_transfer_byte(&rfm->spi, data[i]);
|
||
|
}
|
||
|
spi_release(&rfm->spi);
|
||
|
}
|
||
|
|
||
|
void rfm_read(rfm_t *rfm, uint8_t reg, uint8_t *data, size_t length) {
|
||
|
spi_acquire(&rfm->spi);
|
||
|
spi_transfer_byte(&rfm->spi, reg);
|
||
|
for (size_t i = 0; i < length; i++) {
|
||
|
data[i] = spi_transfer_byte(&rfm->spi, 0);
|
||
|
}
|
||
|
spi_release(&rfm->spi);
|
||
|
}
|
||
|
|
||
|
void rfm_initialize(rfm_t *rfm) {
|
||
|
spi_initialize(&rfm->spi);
|
||
|
}
|
||
|
|
||
|
void rfm_packet_format(rfm_t *rfm, packet_format_e format, size_t length) {
|
||
|
switch (format) {
|
||
|
case unlimited:
|
||
|
rfm_write(rfm, 0x37, (uint8_t [1]){ 0 }, 1);
|
||
|
rfm_write(rfm, 0x38, (uint8_t [1]){ 0 }, 1);
|
||
|
break;
|
||
|
case fixed:
|
||
|
rfm_write(rfm, 0x37, (uint8_t [1]){ 0 }, 1);
|
||
|
rfm_write(rfm, 0x38, (uint8_t [1]){ length }, 1);
|
||
|
break;
|
||
|
case variable:
|
||
|
rfm_write(rfm, 0x37, (uint8_t [1]){ _BV(7) }, 1);
|
||
|
rfm_write(rfm, 0x38, (uint8_t [1]){ 0 }, 1);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uint8_t rfm_temperature(rfm_t *rfm) {
|
||
|
uint8_t ready = 0;
|
||
|
uint8_t temp;
|
||
|
rfm_write(rfm, 0x4e, (uint8_t [1]){ _BV(3) }, 1);
|
||
|
_delay_ms(1);
|
||
|
|
||
|
uint8_t i = 0;
|
||
|
while (!(ready & _BV(2)) && i < 10) {
|
||
|
rfm_read(rfm, 0x4e, &ready, 1);
|
||
|
i++;
|
||
|
_delay_us(100);
|
||
|
}
|
||
|
|
||
|
rfm_read(rfm, 0x4f, &temp, 1);
|
||
|
|
||
|
return temp;
|
||
|
}
|
||
|
|
||
|
uint8_t rfm_mode(rfm_t *rfm) {
|
||
|
uint8_t mode_flag;
|
||
|
rfm_read(rfm, 0x01, &mode_flag, 1);
|
||
|
return mode_flag;
|
||
|
}
|
||
|
|
||
|
uint8_t rfm_status(rfm_t *rfm) {
|
||
|
uint8_t status_flag;
|
||
|
rfm_read(rfm, 0x28, &status_flag, 1);
|
||
|
return status_flag;
|
||
|
}
|
||
|
|
||
|
void rfm_listen(rfm_t *rfm) {
|
||
|
rfm_write(rfm, 0x01, (uint8_t [1]){ _BV(6) }, 1);
|
||
|
_delay_ms(100);
|
||
|
}
|
||
|
|
||
|
uint32_t rfm_frequency(rfm_t *rfm) {
|
||
|
uint8_t frequency_bytes[3];
|
||
|
uint32_t frequency;
|
||
|
rfm_read(rfm, 0x07, &frequency_bytes[2], 1);
|
||
|
rfm_read(rfm, 0x08, &frequency_bytes[1], 1);
|
||
|
rfm_read(rfm, 0x09, &frequency_bytes[0], 1);
|
||
|
|
||
|
frequency = frequency_bytes[2];
|
||
|
frequency = frequency << 8;
|
||
|
frequency += frequency_bytes[1];
|
||
|
frequency = frequency << 8;
|
||
|
frequency += frequency_bytes[0];
|
||
|
return frequency * 61;
|
||
|
}
|
||
|
|
||
|
uint8_t rfm_set_mode(rfm_t *rfm, mode_e mode) {
|
||
|
uint8_t mode_flags;
|
||
|
rfm_read(rfm, 0x01, &mode_flags, 1);
|
||
|
mode_flags = mode_flags & 0b11100011;
|
||
|
/*
|
||
|
mode_flags += (mode << 2);
|
||
|
rfm_write(rfm, 0x01, &mode_flags, 1);
|
||
|
*/
|
||
|
return mode_flags;
|
||
|
}
|
||
|
|
||
|
uint8_t rfm_irq_1(rfm_t *rfm) {
|
||
|
uint8_t irq;
|
||
|
rfm_read(rfm, 0x27, &irq, 1);
|
||
|
return irq;
|
||
|
}
|