freakone | strona domowa

freakone.pl

27 Lipca

Biblioteka RFM73 dla Raspberry PI oraz STM32F303

Zajmuję się ostatnio projektem, w którym wykorzystuję moduły RFM73 do komunikacji. Jako, że kilka dobrych dni męczyłem się, żeby uruchomić komunikację pomiędzy RPi i STMem zamieszczam działające biblioteki pozwalające na uruchomienie modułu radiowego na tych urządzeniach.

Raspberry Pi

RFM podłączony bezpośrednio do pinów RPi.
Raspberry PiRFM73
GPIO 9MISO
GPIO 10MOSI
GPIO 11SCK
GPIO 24CSN
GPIO 7CE
GPIO 25IRQ
Jeśli chcemy podłączyć piny CE, IRQ lub CSN w inny sposób wystarczy zmienić numery portów w pliku rfm73.py

Aby skrypt zadziałał potrzebne nam są biblioteki RPIO oraz SPIdev.

Instalacja RPIO jest bardzo prosta:
sudo apt-get install python-setuptools
sudo easy_install -U RPIO

lub:

git clone https://github.com/metachris/RPIO.git
cd RPIO
sudo python setup.py install
Do działania SPIdev należy posiadać odblokowany sprzętowy moduł SPI. Po wydaniu komendy lsmod na liście powinniśmy zobaczyć wpis spi_bcm2708. Jeśli tak nie jest musimy uaktualnić firmware naszej maliny lub odblokować moduł w pliku /etc/modprobe.d/raspi-blacklsit.conf. Instalacja wygląda następująco:
sudo apt-get update
sudo apt-get install python-dev
mkdir python-spi
cd python-spi
wget https://raw.github.com/doceme/py-spidev/master/setup.py
wget https://raw.github.com/doceme/py-spidev/master/spidev_module.c
sudo python setup.py install

Uruchomienie RFM73 wygląda następująco:
import rfm73
import time

def rfm_interrupt(gpio_id, val):
	status = rfm73.register_read(0x07) #read status reg

	if status & (1 << 6): #rx data
		print "int:", rfm73.receive()
	if status & (1 << 4): #max_rt
		print "packet not sent"
	rfm73.register_write(0x07, status) #clear int flags


rfm73.init(rfm_interrupt)
rfm73.init_banks()
rfm73.receive_mode()

while 1:
	time.sleep(0.1)


STM32F303
Całość została uruchomiona na płytce ewaluacyjnej STM32F3Discovery.
STM32RFM73
PB14MISO
PB15MOSI
PB13SCK
PB12CSN
PB11CE
PB1IRQ

Uruchomienie modułu:
#include <stm32f30x.h>
#include "rfm73.h"
void clocks_init()
{
	//HSE i zegar na 72MHz
	RCC->CR = RCC_CR_HSION;
	while(!(RCC->CR & RCC_CR_HSIRDY)){};
	FLASH->ACR |= FLASH_ACR_LATENCY_0;
	RCC->CFGR = (RCC_CFGR_PLLMULL9 | RCC_CFGR_PPRE1_DIV2 | RCC_CFGR_PLLSRC_HSI_Div2);
	RCC->CR |= RCC_CR_PLLON;
	while(!(RCC->CR & RCC_CR_PLLRDY)){};
	RCC->CFGR |= RCC_CFGR_SW_PLL;
	while(!(RCC->CFGR & RCC_CFGR_SWS_PLL));

	RCC->AHBENR |= RCC_AHBENR_GPIOEEN;
	GPIOE->MODER |= GPIO_MODER_MODER8_0 | GPIO_MODER_MODER9_0;
	GPIOE->ODR |= GPIO_ODR_8;
		
	RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
	GPIOB->MODER &= ~GPIO_MODER_MODER1;
	//GPIOB->PUPDR |= GPIO_PUPDR_PUPDR1_0;
	GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR1;
		
		
	RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;	
	SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI1_PB;
	EXTI->FTSR |= EXTI_FTSR_TR1;
	EXTI->IMR |= EXTI_IMR_MR1;	
	NVIC_EnableIRQ(EXTI1_IRQn);
	

	
}

unsigned char length = 0;
unsigned char rx_buf[32];

void EXTI1_IRQHandler(void){
  
	uint8_t status = rfm73_register_read(RFM73_REG_STATUS);
	if(status & (1 << 6)) //RX data
	{
			rfm73_receive(rx_buf, &length);
	}
	
	if(status & (1 << 4)) //max_rt
	{
		//packet not sent
	}
	
	rfm73_register_write(RFM73_REG_STATUS, status); //clear ints
	
	EXTI->PR |= EXTI_PR_PR1;	
	GPIOE->ODR ^= GPIO_ODR_8;
	
	
}
int main(void)
{
	clocks_init();
	rfm73_init();


	if(rfm73_is_present())
			GPIOE->ODR |= GPIO_ODR_9;
	
	rfm73_mode_transmit();

	rfm73_transmit_message("asd",3);
    while(1)
    {
	     
    }
}

Zarówno biblioteka na STM32 jak i na Raspberry Pi wykorzystuje przerwania do obsługi komunikacji przychodzącej. Biblioteki są dostępne na moim koncie GitHub.