Попытка настроить связь между обнаружением stm32f407VG и nrf24l01 через SPI. Похоже, что чтение данных из регистров идет нормально, но есть проблема с записью в них, потому что, не имеет значения, пишу ли я что-то для регистрации или нет, всегда отображаются одинаковые значения, разные для каждого регистра и не 0x00 или 0xFF. Я посмотрел на библиотеку Arduino для nrf24l01, и мои функции регистра чтения / записи выглядят одинаково, поэтому похоже, что проблема в настройке SPI или функциях передачи. Я попытался подключить этот чип к Arduino, и он работал нормально, поэтому чип точно не сломан. Google мало чем помог, потому что на stm32f4 почти нет информации о конфигурации SPI, большая часть информации о серии stm32f1. Любая идея, что там может быть не так?
Файл SPI:
#ifndef SPI_H
#define SPI_H
#include "stm32f4xx.h"
void SPI1_init(void){
RCC->AHB1ENR |= 1;
RCC->APB2ENR |= 0x1000;
GPIOA->MODER &= ~0x0000FC00;
GPIOA->MODER |= 0x0000A800;
GPIOA->OTYPER &= ~0b11100000;
GPIOA->PUPDR &= ~0b1111110000000000;
GPIOA->PUPDR |= 0b0101100000000000;
GPIOA->AFR[0] &= ~0xFFF00000;
GPIOA->AFR[0] |= 0x55500000;
GPIOA->MODER &= ~0x00000300;
GPIOA->MODER |= 0x00000100;
GPIOA->MODER &= ~(3<<6);
GPIOA->MODER |= (1<<6);
SPI1->CR1 = 0x31C;
SPI1->CR2 = 0;
SPI1->CR1 |= 0x40;
}
void SPI1_write(unsigned char data){
while(!(SPI1->SR & SPI_SR_TXE));
//GPIOA->BSRRH = 0x0010;
SPI1->DR = data;
while(!(SPI1->SR & 0x80));
//GPIOA->BSRRL = 0x0010;
}
unsigned char SPI1_read(void){
while(!(SPI1->SR & SPI_SR_RXNE));
//GPIOA->BSRRH = 0x0010;
return SPI1->DR;
//GPIOA->BSRRL = 0x0010;
}
uint8_t SPI_comm(uint8_t data){
while(!(SPI1->SR & SPI_SR_TXE));
//GPIOA->BSRRH = 0x0010;
SPI1->DR = data;
//while(!(SPI1->SR & 0x80));
while(!(SPI1->SR & SPI_SR_RXNE));
data = SPI1->DR;
//GPIOA->BSRRL = 0x0010;
return data;
}
void SPI1_bufWrite(uint8_t * buf, uint8_t size){
for(uint8_t i=0;i<size;i++){
while(!(SPI1->SR & 2));
SPI1->DR = buf[i];
while(!(SPI1->SR & 0x80));
}
}
void SPI1_bufRead(uint8_t * buf, uint8_t size){
for(uint8_t i=0;i<size;i++){
while(!(SPI1->SR & SPI_SR_RXNE));
buf[i]=SPI1->DR;
}
}
#endif
, на случай, если это будет полезно, есть другой файл с функциями CS low / high и функциями nrf24l01:
#ifndef RF24LIB_H
#define RF24LIB_H
#include "spi.h"
#include "rf24.h"
#include "timer.h"
#define TX_ADR_WIDTH 3
#define TX_PLOAD_WIDTH 2
uint8_t TX_ADDRESS[TX_ADR_WIDTH] = {0xb3,0xb4,0x01};
uint8_t RX_BUF[TX_PLOAD_WIDTH] = {0};
void CSN_L(void){
GPIOA->BSRRH = 0x0010;
}
void CSN_H(void){
GPIOA->BSRRL = 0x0010;
}
void CE_L(void){
GPIOA->BSRRH = (1<<3);
}
void CE_H(void){
GPIOA->BSRRL = (1<<3);
}
uint8_t nRF24_ReadReg(uint8_t reg){
CSN_L();
SPI_comm(R_REGISTER|(REGISTER_MASK & reg));
reg = SPI_comm(0xFF);
CSN_H();
return reg;
}
void nRF24_WriteReg(uint8_t reg, uint8_t val){
CSN_L();
SPI1_write(W_REGISTER | ( REGISTER_MASK & reg ));
SPI1_write(val);
CSN_H();
}
uint8_t nRF24_ReadMReg(uint8_t reg, uint8_t * buffer, uint8_t size){
CSN_L();
SPI1_write(R_REGISTER|(REGISTER_MASK®));
for(int i=0;i<size;i++){
SPI1_write(0xff);
}
SPI1_bufRead(buffer, size);
CSN_H();
return reg;
}
uint8_t nRF24_WriteMReg(uint8_t reg, uint8_t * buffer, uint8_t size){
CSN_L();
SPI1_write(W_REGISTER|(REGISTER_MASK®));
delayUs(1);
SPI1_bufWrite(buffer, size);
CSN_H();
return reg;
}
void flush_rx(void){
CSN_L();
SPI_comm(FLUSH_RX);
delayUs(1);
CSN_H();
}
void flush_tx(void){
CSN_L();
SPI_comm(FLUSH_TX);
delayUs(1);
CSN_H();
}
void NRF24L01_RX_Mode(void)
{
uint8_t regval=0x00;
regval = nRF24_ReadReg(CONFIG);
regval |= (1<<PWR_UP)|(1<<PRIM_RX);
nRF24_WriteReg(CONFIG,regval);
CE_L();
delayUs(150);
flush_rx();
flush_tx();
}
void nRF24_ToggleFeatures(void){
CSN_L();
SPI1_write(ACTIVATE);
delayUs(1);
SPI1_write(0x73);
CSN_H();
}
void nRF24_init(void){
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
GPIOD->MODER = 0x55000000;
CE_H();
delayMs(5);
nRF24_WriteReg(CONFIG, 0x0A);
delayMs(5);
nRF24_WriteReg(EN_AA, 0x01);
nRF24_WriteReg(EN_RXADDR, 0x01);
nRF24_WriteReg(SETUP_AW, 0x01);//addr width
nRF24_WriteReg(SETUP_RETR, 0x5F);
nRF24_ToggleFeatures();
nRF24_WriteReg(FEATURE, 0);
nRF24_WriteReg(DYNPD, 0);
nRF24_WriteReg(STATUS, 0x70);
nRF24_WriteReg(RF_CH, 76);
nRF24_WriteReg(RF_SETUP, 0x06);
nRF24_WriteMReg(TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);
nRF24_WriteMReg(RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
nRF24_WriteReg(RX_PW_P0, TX_PLOAD_WIDTH);
NRF24L01_RX_Mode();
GPIOD->ODR = 0xF000;
}
#endif