miniAVRfreeRTOS icon indicating copy to clipboard operation
miniAVRfreeRTOS copied to clipboard

NRF24L SPI library?

Open colesnicov opened this issue 4 years ago • 0 comments

Hello. I will try your implementation of this great RTOS to get the library to work with NRF24L01 but the library doesn't work for me. Without using RTOS everything is fine but does not work with RTOS. Would you have any advice? My sender code looks like this:

#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

#include <avr/io.h>
#include <avr/interrupt.h>

/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include "timers.h"

extern "C" {
#include "nrf24l01-mnemonics.h"
#include "nrf24l01.h"
}

TimerHandle_t xAutoReloadTimer;

unsigned int uiAutoReloadTimerPeriod = pdMS_TO_TICKS(1000);

void taskTransmit(void *p);

void vAutoReloadTimerFunction(TimerHandle_t xTimer);

extern "C" int main(void) {

	xTaskCreate(taskTransmit, (const char*) "--", 256, NULL, 3, NULL); // */

	xAutoReloadTimer = xTimerCreate("AutoReloadTimer", uiAutoReloadTimerPeriod,
	pdTRUE, 0, vAutoReloadTimerFunction);

	xTimerReset(xAutoReloadTimer, 0);

	vTaskStartScheduler();

}

nRF24L01* setup_rf(void);

volatile bool rf_interrupt = false;
volatile bool send_message = false;

void taskTransmit(void *p) {
	uint8_t to_address[5] = { 0x01, 0x01, 0x01, 0x01, 0x01 };
	bool on = false;

	nRF24L01 *rf = setup_rf();

	while (true) {
		if (rf_interrupt) {
			rf_interrupt = false;
			int success = nRF24L01_transmit_success(rf);
			if (success != 0)
				nRF24L01_flush_transmit_message(rf);
		}

		if (send_message) {
			send_message = false;
			on = !on;
			nRF24L01Message msg;
			if (on)
				memcpy(msg.data, "ON", 3);
			else
				memcpy(msg.data, "OFF", 4);
			msg.length = strlen((char*) msg.data) + 1;
			nRF24L01_transmit(rf, to_address, &msg);
		}
		portYIELD();
	}

}

nRF24L01* setup_rf(void) {
	nRF24L01 *rf = nRF24L01_init();
	rf->ss.port = &PORTB;
	rf->ss.pin = PB2;
	rf->ce.port = &PORTB;
	rf->ce.pin = PB1;
	rf->sck.port = &PORTB;
	rf->sck.pin = PB5;
	rf->mosi.port = &PORTB;
	rf->mosi.pin = PB3;
	rf->miso.port = &PORTB;
	rf->miso.pin = PB4;
	// interrupt on falling edge of INT0 (PD2)
	EICRA |= _BV(ISC01);
	EIMSK |= _BV(INT0);
	nRF24L01_begin(rf);
	return rf;
}

ISR(INT0_vect) {
	rf_interrupt = true;
}

void vAutoReloadTimerFunction(TimerHandle_t xTimer) {
	send_message = true;
	uiAutoReloadTimerPeriod += pdMS_TO_TICKS(1000);
	xTimerChangePeriod(xTimer, uiAutoReloadTimerPeriod, 0);
}


I used FreeRTOS program timer instead of TIMER1. And receiver code:

#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

extern "C" {
#include <nrf24l01-mnemonics.h>
#include "nrf24l01.h"
}

nRF24L01* setup_rf(void);
void process_message(char *message);
inline void prepare_led_pin(void);
inline void set_led_high(void);
inline void set_led_low(void);

volatile bool rf_interrupt = false;

void taskR(void *v) {
	uint8_t address[5] = { 0x01, 0x01, 0x01, 0x01, 0x01 };
	prepare_led_pin();
	sei();
	nRF24L01 *rf = setup_rf();
	nRF24L01_listen(rf, 0, address);
	uint8_t addr[5];
	nRF24L01_read_register(rf, CONFIG, addr, 1);

	while (true) {
		if (rf_interrupt) {
			rf_interrupt = false;
			while (nRF24L01_data_received(rf)) {
				nRF24L01Message msg;
				nRF24L01_read_received_data(rf, &msg);
				process_message((char*) msg.data);
			}

			nRF24L01_listen(rf, 0, address);
		}
	}

}

nRF24L01* setup_rf(void) {
	nRF24L01 *rf = nRF24L01_init();
	rf->ss.port = &PORTB;
	rf->ss.pin = PB2;
	rf->ce.port = &PORTB;
	rf->ce.pin = PB1;
	rf->sck.port = &PORTB;
	rf->sck.pin = PB5;
	rf->mosi.port = &PORTB;
	rf->mosi.pin = PB3;
	rf->miso.port = &PORTB;
	rf->miso.pin = PB4;
	// interrupt on falling edge of INT0 (PD2)
	EICRA |= _BV(ISC01);
	EIMSK |= _BV(INT0);
	nRF24L01_begin(rf);
	return rf;
}

void process_message(char *message) {
	if (strcmp(message, "ON") == 0)
		set_led_high();
	else if (strcmp(message, "OFF") == 0)
		set_led_low();
}

inline void prepare_led_pin(void) {
	DDRB |= _BV(PB0);
	PORTB &= ~_BV(PB0);
}

inline void set_led_high(void) {
	PORTB |= _BV(PB0);
}

inline void set_led_low(void) {
	PORTB &= ~_BV(PB0);
}

// nRF24L01 interrupt
ISR(INT0_vect) {
	rf_interrupt = true;
}

extern "C" int main(void) {

	xTaskCreate(taskR, (const char*) "--", 256, NULL, 3, NULL);

	vTaskStartScheduler();

}

Unfortunately, it doesn't work for me. I'm not so good at programming to fix it. Can't you give me some advice? Thank you for any advice. Regards...

colesnicov avatar Mar 31 '20 18:03 colesnicov