spi的通信方式和协议我之前已经写过了,这里不再多写了。最近在研究rtthread,里面有硬件spi,最近因为项目需要用io口来模拟spi,但是网上能找到的资料不多,所以自己研究了一下,搞出来两套写法,一套是基于rtthread封装好的spi-bit-ops这个文件中的函数来注册一个软件spi。另一种就是纯自己手搓出来的。两套我都测试过了,都可以用,但是频率差了好多。下面简单贴一下基于rtthread已经给出的RT_USING_SPI_BITOPS这个宏定义来写。
struct at32_soft_spi_config
{
rt_uint8_t clk;
rt_uint8_t miso;
rt_uint8_t mosi;
const char *bus_name;
};
/* at32 sspi dirver class */
struct at32_sspi
{
struct rt_spi_bus spi_bus;
struct rt_spi_configuration config;
struct rt_spi_bit_ops ops;
};
#ifdef BSP_USING_SSPI
#define SSPI_BUS_CONFIG \
{
\
.clk = BSP_SSPI_CLK_PIN, \
.miso = BSP_SSPI_MISO_PIN, \
.mosi = BSP_SSPI_MOSI_PIN, \
.bus_name = "sspi", \
}
#endif
static const struct at32_soft_spi_config soft_spi_config[] =
{
#ifdef BSP_USING_SSPI
SSPI_BUS_CONFIG,
#endif
};
static struct at32_sspi sspi_obj[sizeof(soft_spi_config) / sizeof(soft_spi_config[0])];
static void at32_sspi_gpio_init(struct at32_sspi *sspi)
{
struct at32_soft_spi_config *cfg = (struct at32_soft_spi_config *)sspi->ops.data;
rt_pin_mode(cfg->clk, PIN_MODE_OUTPUT);
rt_pin_mode(cfg->mosi, PIN_MODE_OUTPUT);
rt_pin_mode(cfg->miso, PIN_MODE_INPUT);
// rt_pin_write(cfg->clk, PIN_LOW);
// rt_pin_write(cfg->mosi, PIN_LOW);
// rt_pin_write(cfg->miso, PIN_LOW);
}
static void sspi_tog_sclk(void *data)
{
struct at32_soft_spi_config *cfg = (struct at32_soft_spi_config *)data;
if (rt_pin_read(cfg->clk) == SET)
{
rt_pin_write(cfg->clk, PIN_LOW);
}
else
{
rt_pin_write(cfg->clk, PIN_HIGH);
}
}
static void sspi_set_sclk(void *data, rt_int32_t state)
{
struct at32_soft_spi_config *cfg = (struct at32_soft_spi_config *)data;
rt_pin_write(cfg->clk, state);
// if (state)
// {
// rt_pin_write(cfg->clk, PIN_HIGH);
// }
// else
// {
// rt_pin_write(cfg->clk, PIN_LOW);
// }
}
static void sspi_set_mosi(void *data, rt_int32_t state)
{
struct at32_soft_spi_config *cfg = (struct at32_soft_spi_config *