之前,我把SPI的片選在Cubemx中配置成了SPI_NSS。
現在我給它改為了GPIO_OUTPUT. 同時參考了別人的類似的一個操作無線模塊(采用SPI設備驅動)的例子程序(清楚了RTT的系統API的調用流程)。
年初第一天上班,有空回過頭來看這個問題,就成功解決了。
------Sx1278.h-----------------------------------------------------------------------------------------------------
#ifndef __SX1278_H__
#define __SX1278_H__
#include "drv_gpio.h"
struct spi_sx1278_device
{
struct rt_device sx1278_device;
struct rt_spi_device * rt_spi_device;
struct rt_mutex lock;
void * user_data;
};
typedef struct spi_sx1278_device * rt_spi_sx1278_device_t;
// 引腳定義
#define Sx1278_IRQ_PIN GET_PIN(C, 8)
#define Sx1278_nCS_PIN GET_PIN(B, 12)
#define Sx1278_RST_PIN GET_PIN(C, 9)
// 引腳狀態
#define ST_SX1278_IRQ() rt_pin_read(Sx1278_IRQ_PIN)
// 引腳輸出
#define SX1278_SPI_NCS_H() rt_pin_write(Sx1278_nCS_PIN, PIN_HIGH);
#define SX1278_SPI_NCS_L() rt_pin_write(Sx1278_nCS_PIN, PIN_LOW);
#define SX1278_SPI_RST_H() rt_pin_write(Sx1278_RST_PIN, PIN_HIGH);
#define SX1278_SPI_RST_L() rt_pin_write(Sx1278_RST_PIN, PIN_LOW);
typedef rt_uint8_t u8;
typedef rt_uint16_t u16;
typedef rt_uint32_t u32;
void test(void);
#endif
------Sx1278.c-----------------------------------------------------------------------------------------------------
#include "board.h"
#include "drv_spi.h"
#include "Sx1278.h"
#define SPI_BUS_NAME "spi2"
#define SPI_SX1278_DEVICE_NAME "spi20"
void hdr_callback(void *args)// 回調函數
{
char *a = args; // 獲取參數
rt_kprintf("KEY_PIN down! %s\n",a);
}
//struct stm32_hw_spi_cs
//{
// rt_uint32_t pin;
//}; 不自己定義了,新的STM32 BSP 的drv_spi.h 有如下定義
// drv_spi.h 內定義:
//struct stm32_hw_spi_cs
//{
// GPIO_TypeDef* GPIOx;
// uint16_t GPIO_Pin;
//};
static struct stm32_hw_spi_cs spi_cs; /* SPI設備CS片選引腳 */
static struct spi_sx1278_device spi_sx1278_device;
#define CS_PIN 28 // Sx1278_nCS_PIN
static u8 SX1278_spiReadWriteByte(const u8 Sdata)
{
u8 Rdata[13] = {0};
// rt_pin_write(CS_PIN, PIN_LOW); /* 先 低電平 */
// rt_spi_send_then_recv第一個形參:struct rt_spi_device *device;
rt_spi_send_then_recv( spi_sx1278_device.rt_spi_device, &Sdata, (rt_size_t)1, Rdata, (rt_size_t)1);
// rt_spi_send(spi_sx1278_device.rt_spi_device, &Sdata, 1);
return Rdata[0];
}
int rt_hw_spi2_config(const char * spi_device_name) // 這里填的就是"spi20"為參數。這里應該直接直接命名參數為const char * device name
{ // spi_device_name是spi總線設備的意思, 對應的是"spi2"總線。
rt_err_t res;
struct rt_spi_device * rt_spi_device;
rt_pin_mode(CS_PIN, PIN_MODE_OUTPUT);
// 這個不用根據SPI設備名字 來 查找 設備
//res = rt_spi_bus_attach_device(spi_sx1278_device.rt_spi_device, SPI_SX1278_DEVICE_NAME, SPI_BUS_NAME, (void*)&spi_cs);
spi_cs.GPIOx = GPIOB;
spi_cs.GPIO_Pin = GPIO_PIN_12;
// 這個要根據SPI設備名字 來 查找 設備 功能1: 把spi20掛到spi2上
res = rt_hw_spi_device_attach(SPI_BUS_NAME, SPI_SX1278_DEVICE_NAME, spi_cs.GPIOx, spi_cs.GPIO_Pin);
if( res == RT_EOK )
{
rt_kprintf("\n rt_hw_spi_device_attach(), OK! \r\n");
}
rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
spi_sx1278_device.rt_spi_device = rt_spi_device;
if(spi_sx1278_device.rt_spi_device == RT_NULL)
rt_kprintf("\n Wrong ! \r\n");
/* config spi */
{
struct rt_spi_configuration cfg;
cfg.data_width = 8;
cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
cfg.max_hz = 1 * 1000 *1000; /* 20M,SPI max 42MHz,ssd1351 4-wire spi */
res = rt_spi_configure(spi_sx1278_device.rt_spi_device, &cfg);
if( res == RT_EOK )
{
rt_kprintf("\n rt_spi_configure(), OK! \r\n");
}
}
return RT_EOK;
}
rt_err_t rt_hw_SX1278_config(const char * sx1278_device_name, const char * spi_device_name)
{
rt_hw_spi2_config(sx1278_device_name);
return RT_EOK;
}
static int rt_hw_SX1278_init(void)
{
// rt_hw_SX1278_config( "spi2", "spi20"); 參數填寫錯誤
rt_hw_SX1278_config( "spi20", "spi2"); // 參數填寫正確
// SX1278 部分
// IO 方向
rt_pin_mode(Sx1278_IRQ_PIN, PIN_MODE_INPUT_PULLUP);
rt_pin_mode(Sx1278_RST_PIN, PIN_MODE_OUTPUT);
// SX1278中斷
rt_pin_attach_irq(Sx1278_IRQ_PIN, PIN_IRQ_MODE_FALLING, hdr_callback, (void*)"CallBack args"); // 綁定中斷,下降沿模式,回調函數
rt_pin_irq_enable(Sx1278_IRQ_PIN, PIN_IRQ_DISABLE); // PIN_IRQ_DISABLE、PIN_IRQ_ENABLE
// IO初值設置
rt_pin_write(Sx1278_nCS_PIN, PIN_HIGH);
rt_pin_write(Sx1278_RST_PIN, PIN_HIGH);
return 0;
}
INIT_PREV_EXPORT(rt_hw_SX1278_init); /* 使用RT-Thread的組件自動初始化機制 */
u8 WirelessInit(u8 channel, u8 pa)
{
u8 result=0;
// SX1278_DisableInt();
// SX1278_SetLoRaPA(pa);
// SX1278_Init(channel); // 初始化
//
// sG_RfState = ST_RF_RECE; // 接收狀態
//
// SX1278_EnableInt();
return result;
}
void Delay_1ms(u8 x)
{
//rt_thread_mdelay(x);
rt_thread_delay(x);
}
void SX1278_Reset(void)
{
static int sPowerUpFlag=1;
SX1278_SPI_RST_H();
Delay_1ms(2);
SX1278_SPI_RST_L(); // 至少100us
Delay_1ms(2);
SX1278_SPI_RST_H(); // 至少5ms
if(sPowerUpFlag)
{
sPowerUpFlag = 0;
Delay_1ms(12); // 第一次上電,延時時間長一點
}
else
{
Delay_1ms(7);
}
}
static u8 SX1278Read(u8 adr)
{
u8 tmp;
SX1278_SPI_NCS_L();
SX1278_spiReadWriteByte(adr); // Send address first
tmp = SX1278_spiReadWriteByte(0xFF);
SX1278_SPI_NCS_H();
return tmp;
}
void test(void)
{
u8 TempReg;
u8 timeOutCnt=0;
SX1278_Reset(); rt_thread_mdelay(500);
while(1)
{
TempReg = SX1278Read(0x06);
//rt_kprintf("Hard SPI TempReg = %d \r\n", TempReg);
rt_thread_delay(50);
}
}