Hey all.
I am using an AVR ATmega128 processor and would like to send some data using a nRF24L01 module. I haven’t found a libary for this setup but the MIRF is using the ATmega168 and I thought I could port it for the 128 with no succes. I believe it is the registers or pin definitions that is the problem. Could anyone please help me. Does anyone have a link for a suitable libary or could you help me port the MIRF to the 128? I have added a #define AVR_ATmega128.
I have changed the SPI to:
#define PORT_SPI PORTB
#define DDR_SPI DDRB
#define DD_MISO DDB3
#define DD_MOSI DDB2
#define DD_SS DDB0 //CSN
#define DD_SCK DDB1
This is the code of mirf.c so far:
mirf.c
#include “mirf.h”
#include “nRF24L01.h”
#include “spi.h”
#include <avr/io.h>
#include <avr/interrupt.h>
// Defines for setting the MiRF registers for transmitting or receiving mode
#define TX_POWERUP mirf_config_register(CONFIG, mirf_CONFIG | ( (1<<PWR_UP) | (0<<PRIM_RX) ) )
#define RX_POWERUP mirf_config_register(CONFIG, mirf_CONFIG | ( (1<<PWR_UP) | (1<<PRIM_RX) ) )
#define AVR_ATmega128
// Flag which denotes transmitting mode
volatile uint8_t PTX;
void mirf_init()
// Initializes pins ans interrupt to communicate with the MiRF module
// Should be called in the early initializing phase at startup.
{
// Define CSN and CE as Output and set them to default
DDRB |= ((1<<CSN)|(1<<CE));
mirf_CE_lo;
mirf_CSN_hi;
#if defined(AVR_ATmega8)
// Initialize external interrupt 0 (PD2)
MCUCR = ((1<<ISC11)|(0<<ISC10)|(1<<ISC01)|(0<<ISC00)); // Set external interupt on falling edge
GICR = ((0<<INT1)|(1<<INT0)); // Activate INT0
#endif // AVR_ATmega8
#if defined(AVR_ATmega168)
// Initialize external interrupt on port PD6 (PCINT22)
//DDRB &= ~(1<<PD6);
//PCMSK2 = (1<<PCINT22);
//PCICR = (1<<PCIE2);
#endif // AVR_ATmega168
#if defined(AVR_ATmega128)
// Initialize external interrupt on port PD6 (PCINT22)
DDRE &= ~(1<<PE7);
EIMSK = (1<<INT7);
#endif // AVR_ATmega128
// Initialize spi module
spi_init();
}
void mirf_config()
// Sets the important registers in the MiRF module and powers the module
// in receiving mode
{
// Set RF channel
mirf_config_register(RF_CH,mirf_CH);
// Set length of incoming payload
mirf_config_register(RX_PW_P0, mirf_PAYLOAD);
// Start receiver
PTX = 0; // Start in receiving mode
RX_POWERUP; // Power up in receiving mode
mirf_CE_hi; // Listening for pakets
}
void mirf_set_RADDR(uint8_t * adr)
// Sets the receiving address
{
mirf_CE_lo;
mirf_write_register(RX_ADDR_P0,adr,5);
mirf_CE_hi;
}
void mirf_set_TADDR(uint8_t * adr)
// Sets the transmitting address
{
mirf_write_register(TX_ADDR, adr,5);
}
#if defined(AVR_ATmega8)
SIGNAL(SIG_INTERRUPT0)
#endif // AVR_ATmega8
#if defined(AVR_ATmega168)
SIGNAL(SIG_PIN_CHANGE2)
#endif // AVR_ATmega168
#if defined(AVR_ATmega128)
ISR(__vector_default)
#endif // AVR_ATmega128
// Interrupt handler
{
uint8_t status;
// If still in transmitting mode then finish transmission
if (PTX) {
// Read MiRF status
mirf_CSN_lo; // Pull down chip select
status = spi_fast_shift(NOP); // Read status register
mirf_CSN_hi; // Pull up chip select
mirf_CE_lo; // Deactivate transreceiver
RX_POWERUP; // Power up in receiving mode
mirf_CE_hi; // Listening for pakets
PTX = 0; // Set to receiving mode
// Reset status register for further interaction
mirf_config_register(STATUS,(1<<TX_DS)|(1<<MAX_RT)); // Reset status register
}
}
extern uint8_t mirf_data_ready()
// Checks if data is available for reading
{
if (PTX) return 0;
uint8_t status;
// Read MiRF status
mirf_CSN_lo; // Pull down chip select
status = spi_fast_shift(NOP); // Read status register
mirf_CSN_hi; // Pull up chip select
return status & (1<<RX_DR);
}
extern void mirf_get_data(uint8_t * data)
// Reads mirf_PAYLOAD bytes into data array
{
mirf_CSN_lo; // Pull down chip select
spi_fast_shift( R_RX_PAYLOAD ); // Send cmd to read rx payload
spi_transfer_sync(data,data,mirf_PAYLOAD); // Read payload
mirf_CSN_hi; // Pull up chip select
mirf_config_register(STATUS,(1<<RX_DR)); // Reset status register
}
void mirf_config_register(uint8_t reg, uint8_t value)
// Clocks only one byte into the given MiRF register
{
mirf_CSN_lo;
spi_fast_shift(W_REGISTER | (REGISTER_MASK & reg));
spi_fast_shift(value);
mirf_CSN_hi;
}
void mirf_read_register(uint8_t reg, uint8_t * value, uint8_t len)
// Reads an array of bytes from the given start position in the MiRF registers.
{
mirf_CSN_lo;
spi_fast_shift(R_REGISTER | (REGISTER_MASK & reg));
spi_transfer_sync(value,value,len);
mirf_CSN_hi;
}
void mirf_write_register(uint8_t reg, uint8_t * value, uint8_t len)
// Writes an array of bytes into inte the MiRF registers.
{
mirf_CSN_lo;
spi_fast_shift(W_REGISTER | (REGISTER_MASK & reg));
spi_transmit_sync(value,len);
mirf_CSN_hi;
}
void mirf_send(uint8_t * value, uint8_t len)
// Sends a data package to the default address. Be sure to send the correct
// amount of bytes as configured as payload on the receiver.
{
while (PTX) {} // Wait until last paket is send
mirf_CE_lo;
PTX = 1; // Set to transmitter mode
TX_POWERUP; // Power up
mirf_CSN_lo; // Pull down chip select
spi_fast_shift( FLUSH_TX ); // Write cmd to flush tx fifo
mirf_CSN_hi; // Pull up chip select
mirf_CSN_lo; // Pull down chip select
spi_fast_shift( W_TX_PAYLOAD ); // Write cmd to write payload
spi_transmit_sync(value,len); // Write payload
mirf_CSN_hi; // Pull up chip select
mirf_CE_hi; // Start transmission
}