I'm trying to interface a 433MHz RFM69 module with an atmega328p. Datasheet for the RF module can be found here.
I connected the SPI pins from the atmega328p to the corresponding pins on the RF module via a 5V to 3.3V logic level converter. The 5V side of the converter is powered by the VCC pin of the atmega328p. The 3.3V side of the logic level converter is powered by the same VCC pin drawn via a LD1117 voltage regulator.
The atmega328p is connected to a 16MHz crystal oscillator.
Below is my code. I'm trying to set the RFM's register at 0x01 (operation mode) to 0x04, which is supposed to be the default value anyway (page 63 of the datasheet). In my main function, I write this value, and try to read it back. But I keep getting value 0 from my read_reg()
.
I'm using this implementation as a reference, but I still can't get it to work. Any help is much appreciated!
Also, one other question I have is, in my read_reg(), I read SPDR after I raise SS. Is this okay? Or should I read SPDR while SS is low, and then raise it? I tried the latter as well, but that didn't resolve my problem with the RFM69 module.
#include
#include
#include
#include
#include "serial.h"
#define SPI_SS PB2
#define SPI_SCK PB5
#define SPI_MISO PB4
#define SPI_MOSI PB3
#define SPI_DDR DDRB
#define SPI_PORT PORTB
static inline uint8_t read_reg(uint8_t reg)
{
SPI_PORT &= ~(1 << SPI_SS);
SPDR = reg | 0x7F;
while (!(SPSR & (1 << SPIF)))
;
SPDR = 0;
while (!(SPSR & (1 << SPIF)))
;
SPI_PORT |= (1 << SPI_SS);
return SPDR;
}
static inline void write_reg(uint8_t reg, uint8_t val)
{
SPI_PORT &= ~(1 << SPI_SS);
SPDR = reg | 0x80;
while (!(SPSR & (1 << SPIF)))
;
SPDR = val;
while (!(SPSR & (1 << SPIF)))
;
SPI_PORT |= (1 << SPI_SS);
}
static inline void radio_init(void)
{
SPI_DDR |= (1 << SPI_SS) | (1 << SPI_SCK) | (1 << SPI_MOSI);
SPI_PORT |= (1 << SPI_SS);
SPCR |= (1 << SPE) | (1 << MSTR);
}
int main(void)
{
uint8_t val;
char buf[5];
serial_init();
radio_init();
for (;;) {
write_reg(0x01, 0x04);
val = read_reg(0x01);
serial_write_line(itoa(val, buf, 16));
_delay_ms(2000);
}
return 0;
}