K210由于硬件只有一个可以用的SPI,所以想模拟一个。现在是SPI时序有点问题,逻辑分析仪也用上了,发现MISO数据一直是1 ,代码如下:
/*
Change Logs:
Date Author Notes
2022-09-19 xiaoyu first version
*/
#include "board.h"
#if 1
#include <drv_soft_spi.h>
#include <gpiohs.h>
#include <fpioa.h>
#include <sleep.h>
#include "gpio.h"
#define DBG_TAG "softspi"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
static struct k210_soft_spi_config soft_spi_config[] ={
#ifdef BSP_USING_SOFT_SPI
SOFT_SPI_BUS_CONFIG,
#endif
};
#define BSP_USING_SOFT_SPI
#define BSP_SOFT_SPI_CLK_PIN 27
#define BSP_SOFT_SPI_MOSI_PIN 28
#define BSP_SOFT_SPI_MISO_PIN 26
#define RT_USING_SOFT_SPI_CS0
#define RT_USING_SOFT_SPI_CS0_PIN 29
// #define SOFT_SPI_CS (RT_USING_SOFT_SPI_CS0_PIN-FUNC_GPIOHS0)
// #define SOFT_SPI_SCLK (BSP_SOFT_SPI_CLK_PIN-FUNC_GPIOHS0)
// #define SOFT_SPI_MOSI (BSP_SOFT_SPI_MOSI_PIN-FUNC_GPIOHS0)
// #define SOFT_SPI_MISO (BSP_SOFT_SPI_MISO_PIN-FUNC_GPIOHS0)
struct soft_spi_dev
{
struct rt_spi_bus *spi_bus;
};
static struct soft_spi_dev *spi_dev;
static struct k210_soft_spi soft_spi_bus_obj[sizeof(soft_spi_config) / sizeof(soft_spi_config[0])] = {0};
/*设置从设备使能 /
static void soft_spi_cs_enable(int enable)
{
if(enable)
{
gpiohs_set_pin(RT_USING_SOFT_SPI_CS0_PIN,GPIO_PV_LOW);
}
else
{
gpiohs_set_pin(RT_USING_SOFT_SPI_CS0_PIN,GPIO_PV_HIGH);
}
}
static rt_err_t k210_spi_init()
{
fpioa_set_function(RT_USING_SOFT_SPI_CS0_PIN,RT_USING_SOFT_SPI_CS0_PIN + FUNC_GPIOHS0);
fpioa_set_function(BSP_SOFT_SPI_MOSI_PIN,BSP_SOFT_SPI_MOSI_PIN + FUNC_GPIOHS0);
fpioa_set_function(BSP_SOFT_SPI_MISO_PIN,BSP_SOFT_SPI_MISO_PIN + FUNC_GPIOHS0);
fpioa_set_function(BSP_SOFT_SPI_CLK_PIN,BSP_SOFT_SPI_CLK_PIN + FUNC_GPIOHS0);
gpiohs_set_drive_mode(BSP_SOFT_SPI_CLK_PIN, GPIO_DM_OUTPUT);
gpiohs_set_drive_mode(BSP_SOFT_SPI_MOSI_PIN, GPIO_DM_OUTPUT);
gpiohs_set_drive_mode(RT_USING_SOFT_SPI_CS0_PIN, GPIO_DM_OUTPUT);
gpiohs_set_drive_mode(BSP_SOFT_SPI_MISO_PIN,GPIO_DM_INPUT);
gpiohs_set_pin(BSP_SOFT_SPI_CLK_PIN, GPIO_PV_LOW);
gpiohs_set_pin(RT_USING_SOFT_SPI_CS0_PIN, GPIO_PV_HIGH);
return RT_EOK;
}
static inline void spi_delay(uint8_t time)
{
}
void SPI_CLK (int data)
{
if(data == 0)
{
gpiohs_set_pin(BSP_SOFT_SPI_CLK_PIN,GPIO_PV_LOW);
}
else
{
gpiohs_set_pin(BSP_SOFT_SPI_CLK_PIN,GPIO_PV_HIGH);
}
}
void SPI_MOSI (int data)
{
if(data == 0)
{
gpiohs_set_pin(BSP_SOFT_SPI_MOSI_PIN,GPIO_PV_LOW);
}
else
{
gpiohs_set_pin(BSP_SOFT_SPI_MOSI_PIN,GPIO_PV_HIGH);
}
}
int SPI_MISO ()
{
//rt_kprintf("SPI_MISO :%d\n\r", gpiohs_get_pin(BSP_SOFT_SPI_MISO_PIN));
return gpiohs_get_pin(BSP_SOFT_SPI_MISO_PIN);
}
void SPI_Delay()
{
usleep(10);
}
/ 写一个字节 */
static void soft_spi_WriteByte(uint8_t data)
{
uint8_t i = 0;
uint8_t temp = 0;
for(i=0; i<8; i++)
{
temp = ((data&0x80)==0x80)? 1:0;
data = data<<1;
SPI_CLK(0); //CPOL=0
SPI_Delay();
SPI_MOSI(temp);
SPI_Delay();
SPI_CLK(1); //CPHA=0
SPI_Delay();
}
SPI_CLK(0);
}
/* 读写一个字节 */
static uint8_t soft_spi_ReadWriteByte(uint8_t data)
{
uint8_t i = 0;
uint8_t temp = 0;
uint8_t redata = 0xFF;
SPI_Delay();
for(i=0;i<8;i++)
{
if(data & 0x80)
{
SPI_MOSI(1);
}
else
{
SPI_MOSI(0);
}
data <<= 1;
SPI_Delay();
SPI_CLK(1);
redata<<=1;
if(SPI_MISO())
{
redata++;
}
SPI_Delay();
SPI_CLK(0);
// temp = ((data&0x80)==0x80)? 1:0;
// data = data<<1;
// read_data = read_data<<1;
// SPI_CLK(0);
// SPI_Delay();
// SPI_MOSI(temp);
// SPI_Delay();
// SPI_CLK(1);
// SPI_Delay();
// if(SPI_MISO()==1)
// {
// read_data = read_data + 1;
// }
}
return redata;
}
rt_err_t _soft_spi_configure(struct rt_spi_device *dev,struct rt_spi_configuration *cfg)
{
return RT_EOK;
}
/* 模拟 SPI 传输数据 */
rt_uint32_t _soft_spi_xfer(struct rt_spi_device* device, struct rt_spi_message* message)
{
struct rt_spi_configuration * config = &device->config;
rt_uint32_t size = message->length;
/* 设置 CS */
if(message->cs_take)
{
soft_spi_cs_enable(1);
}
const rt_uint8_t * send_ptr = message->send_buf;
rt_uint8_t * recv_ptr = message->recv_buf;
while(size--)
{
rt_uint8_t data = 0xFF;
if(send_ptr != RT_NULL)
{
data = *send_ptr++;
//rt_kprintf("send_ptr:%02x\n",data);
// 发送数据
soft_spi_ReadWriteByte(data);
}
// 接收数据
if(recv_ptr != RT_NULL)
{
// 发送数据
data = soft_spi_ReadWriteByte(data);
*recv_ptr++ = data;
//rt_kprintf("recv_ptr:%02x\n",data);
}
}
/* 设置 release CS */
if(message->cs_release)
{
soft_spi_cs_enable(0);
}
//rt_kprintf("len=%d \n",message->length);
return message->length;
}
static struct rt_spi_ops soft_spi_ops =
{
.configure = _soft_spi_configure,
.xfer = _soft_spi_xfer
};
int rt_soft_spi_bus_register(char *name)
{
int result = RT_EOK;
struct rt_spi_bus *spi_bus = RT_NULL;
if(spi_dev)
{
return RT_EOK;
}
spi_dev = rt_malloc(sizeof(struct soft_spi_dev));
if(!spi_dev)
{
rt_kprintf("[soft spi]:malloc memory for spi_dev failed\n");
result = -RT_ENOMEM;
goto _exit;
}
memset(spi_dev,0,sizeof(struct soft_spi_dev));
spi_bus = rt_malloc(sizeof(struct rt_spi_bus));
if(!spi_bus)
{
rt_kprintf("[soft spi]:malloc memory for spi_bus failed\n");
result = -RT_ENOMEM;
goto _exit;
}
memset(spi_bus,0,sizeof(struct rt_spi_bus));
spi_bus->parent.user_data = spi_dev;
rt_spi_bus_register(spi_bus, name, &soft_spi_ops);
return result;
_exit:
if (spi_dev)
{
rt_free(spi_dev);
spi_dev = RT_NULL;
}
if (spi_bus)
{
rt_free(spi_bus);
spi_bus = RT_NULL;
}
return result;
}
static struct rt_spi_device *soft_spi_device = RT_NULL;
int rt_soft_spi_device_init(void)
{
k210_spi_init();
int result = RT_EOK;
rt_kprintf("[soft spi]:rt_soft_spi_device_init \n");
if(soft_spi_device)
{
return RT_EOK;
}
soft_spi_device = rt_malloc(sizeof(struct rt_spi_device));
if(!soft_spi_device)
{
rt_kprintf("[soft spi]:malloc memory for soft spi_device failed\n");
result = -RT_ENOMEM;
}
memset(soft_spi_device,0,sizeof(struct rt_spi_device));
/* 注册 SPI BUS */
result = rt_soft_spi_bus_register("soft_spi");
if(result != RT_EOK)
{
rt_kprintf("[soft spi]:register soft spi bus error : %d !!!\n",result);
goto _exit;
}
/* 绑定 CS */
result = rt_spi_bus_attach_device(soft_spi_device,"spi188","soft_spi",NULL);
if(result != RT_EOK)
{
rt_kprintf("[soft spi]:attact spi bus error :%d !!!\n",result);
goto _exit;
}
rt_kprintf("[soft spi]:rt_soft_spi_device init ok\n");
return RT_EOK;
_exit:
if(soft_spi_device)
{
rt_free(soft_spi_device);
soft_spi_device = RT_NULL;
}
return result;
}
INIT_APP_EXPORT(rt_soft_spi_device_init);
#endif
/*
Copyright (c) 2006-2018, RT-Thread Development Team
SPDX-License-Identifier: Apache-2.0
Change Logs:
Date Author Notes
*/
#include <rtthread.h>
#ifdef BSP_USING_SDCARD
#if defined(RT_USING_SPI_MSD) && defined(RT_USING_DFS_ELMFAT)
#include <spi_msd.h>
#include <dfs_fs.h>
#define DBG_TAG "sdcard"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
int sd_mount(void)
{
int ret = 0;
ret = msd_init("sd0", "spi188");
if(RT_EOK == ret)
{
if(dfs_mount("sd0", "/", "elm", 0, 0) == 0)
{
LOG_I("Mount /sd0 successfully");
return RT_EOK;
}
else
{
LOG_E("Mount fail !!1");
return -1;
}
}
LOG_E("msd_init fail !!!");
return -2;
}
INIT_APP_EXPORT(sd_mount);
#endif
#endif
自带解析的逻辑分析仪
现在是MISO 一直是0xFF