Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
BaiXuePrincess
rt-thread
提交
763d7456
R
rt-thread
项目概览
BaiXuePrincess
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
763d7456
编写于
7月 26, 2017
作者:
B
Bernard Xiong
提交者:
GitHub
7月 26, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #773 from AubrCool/fix-stm32f10x_spi.drv
[Bsp] stm32f107 spi drv : dma add irq
上级
82359e09
fe16f91c
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
234 addition
and
71 deletion
+234
-71
bsp/stm32f107/drivers/rt_stm32f10x_spi.c
bsp/stm32f107/drivers/rt_stm32f10x_spi.c
+207
-66
bsp/stm32f107/drivers/rt_stm32f10x_spi.h
bsp/stm32f107/drivers/rt_stm32f10x_spi.h
+27
-5
未找到文件。
bsp/stm32f107/drivers/rt_stm32f10x_spi.c
浏览文件 @
763d7456
...
...
@@ -9,35 +9,28 @@ static struct rt_spi_ops stm32_spi_ops =
xfer
};
#ifdef USING_SPI1
static
struct
stm32_spi_bus
stm32_spi_bus_1
;
#endif
/* #ifdef USING_SPI1 */
#ifdef USING_SPI2
static
struct
stm32_spi_bus
stm32_spi_bus_2
;
#endif
/* #ifdef USING_SPI2 */
#ifdef USING_SPI3
static
struct
stm32_spi_bus
stm32_spi_bus_3
;
#endif
/* #ifdef USING_SPI3 */
//------------------ DMA ------------------
#ifdef SPI_USE_DMA
static
uint8_t
dummy
=
0xFF
;
#endif
#endif
/*SPI_USE_DMA*/
#ifdef SPI_USE_DMA
static
void
DMA_Configuration
(
struct
stm32_spi_bus
*
stm32_spi_bus
,
const
void
*
send_addr
,
void
*
recv_addr
,
rt_size_t
size
)
{
DMA_InitTypeDef
DMA_InitStructure
;
DMA_ClearFlag
(
stm32_spi_bus
->
DMA_Channel_RX_FLAG_TC
|
stm32_spi_bus
->
DMA_Channel_RX_FLAG_TE
|
stm32_spi_bus
->
DMA_Channel_TX_FLAG_TC
|
stm32_spi_bus
->
DMA_Channel_TX_FLAG_TE
);
if
(
!
stm32_spi_bus
->
dma
)
{
return
;
}
DMA_ClearFlag
(
stm32_spi_bus
->
dma
->
priv_data
->
DMA_Channel_RX_FLAG_TC
|
stm32_spi_bus
->
dma
->
priv_data
->
DMA_Channel_RX_FLAG_TE
|
stm32_spi_bus
->
dma
->
priv_data
->
DMA_Channel_TX_FLAG_TC
|
stm32_spi_bus
->
dma
->
priv_data
->
DMA_Channel_TX_FLAG_TE
);
/* RX channel configuration */
DMA_Cmd
(
stm32_spi_bus
->
DMA_Channel_RX
,
DISABLE
);
DMA_Cmd
(
stm32_spi_bus
->
dma
->
priv_data
->
DMA_Channel_RX
,
DISABLE
);
DMA_InitStructure
.
DMA_PeripheralBaseAddr
=
(
u32
)(
&
(
stm32_spi_bus
->
SPI
->
DR
));
DMA_InitStructure
.
DMA_DIR
=
DMA_DIR_PeripheralSRC
;
DMA_InitStructure
.
DMA_PeripheralInc
=
DMA_PeripheralInc_Disable
;
...
...
@@ -60,12 +53,13 @@ static void DMA_Configuration(struct stm32_spi_bus * stm32_spi_bus, const void *
DMA_InitStructure
.
DMA_MemoryInc
=
DMA_MemoryInc_Disable
;
}
DMA_Init
(
stm32_spi_bus
->
DMA_Channel_RX
,
&
DMA_InitStructure
);
DMA_Init
(
stm32_spi_bus
->
dma
->
priv_data
->
DMA_Channel_RX
,
&
DMA_InitStructure
);
DMA_Cmd
(
stm32_spi_bus
->
DMA_Channel_RX
,
ENABLE
);
DMA_ITConfig
(
stm32_spi_bus
->
dma
->
priv_data
->
DMA_Channel_RX
,
DMA_IT_TC
,
ENABLE
);
DMA_Cmd
(
stm32_spi_bus
->
dma
->
priv_data
->
DMA_Channel_RX
,
ENABLE
);
/* TX channel configuration */
DMA_Cmd
(
stm32_spi_bus
->
DMA_Channel_TX
,
DISABLE
);
DMA_Cmd
(
stm32_spi_bus
->
dma
->
priv_data
->
DMA_Channel_TX
,
DISABLE
);
DMA_InitStructure
.
DMA_PeripheralBaseAddr
=
(
u32
)(
&
(
stm32_spi_bus
->
SPI
->
DR
));
DMA_InitStructure
.
DMA_DIR
=
DMA_DIR_PeripheralDST
;
DMA_InitStructure
.
DMA_PeripheralInc
=
DMA_PeripheralInc_Disable
;
...
...
@@ -88,18 +82,125 @@ static void DMA_Configuration(struct stm32_spi_bus * stm32_spi_bus, const void *
DMA_InitStructure
.
DMA_MemoryInc
=
DMA_MemoryInc_Disable
;
}
DMA_Init
(
stm32_spi_bus
->
DMA_Channel_TX
,
&
DMA_InitStructure
);
DMA_Init
(
stm32_spi_bus
->
dma
->
priv_data
->
DMA_Channel_TX
,
&
DMA_InitStructure
);
DMA_Cmd
(
stm32_spi_bus
->
DMA_Channel_TX
,
ENABLE
);
DMA_ITConfig
(
stm32_spi_bus
->
dma
->
priv_data
->
DMA_Channel_TX
,
DMA_IT_TC
,
ENABLE
);
DMA_Cmd
(
stm32_spi_bus
->
dma
->
priv_data
->
DMA_Channel_TX
,
ENABLE
);
}
#ifdef SPI1_USING_DMA
static
const
struct
stm32_spi_dma_private
dma1_priv
=
{
DMA1_Channel3
,
DMA1_Channel2
,
DMA1_FLAG_TC3
,
DMA1_FLAG_TE3
,
DMA1_FLAG_TC2
,
DMA1_FLAG_TE2
,
DMA1_Channel3_IRQn
,
DMA1_Channel2_IRQn
,
DMA1_FLAG_GL3
,
DMA1_FLAG_GL2
,
};
static
struct
stm32_spi_dma
dma1
=
{
&
dma1_priv
,
};
void
DMA1_Channel2_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
rt_event_send
(
&
dma1
.
event
,
SPI_DMA_TX_DONE
);
DMA_ClearFlag
(
dma1
.
priv_data
->
tx_gl_flag
);
/* leave interrupt */
rt_interrupt_leave
();
}
void
DMA1_Channel3_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
rt_event_send
(
&
dma1
.
event
,
SPI_DMA_RX_DONE
);
DMA_ClearFlag
(
dma1
.
priv_data
->
rx_gl_flag
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/*SPI1_USING_DMA*/
#ifdef SPI2_USING_DMA
static
const
struct
stm32_spi_dma_private
dma2_priv
=
{
DMA1_Channel5
,
DMA1_Channel5
,
DMA1_FLAG_TC5
,
DMA1_FLAG_TE5
,
DMA1_FLAG_TC4
,
DMA1_FLAG_TE4
,
DMA1_Channel5_IRQn
,
DMA1_Channel4_IRQn
,
DMA1_FLAG_GL5
,
DMA1_FLAG_GL4
,
};
static
struct
stm32_spi_dma
dma2
=
{
&
dma2_priv
,
};
void
DMA1_Channel4_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
rt_event_send
(
&
dma2
.
event
,
SPI_DMA_TX_DONE
);
DMA_ClearFlag
(
dma2
.
tx_gl_flag
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
void
DMA1_Channel5_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
rt_event_send
(
&
dma2
.
event
,
SPI_DMA_RX_DONE
);
DMA_ClearFlag
(
dma2
.
priv_data
->
rx_gl_flag
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/*SPI2_USING_DMA*/
#ifdef SPI3_USING_DMA
static
const
struct
stm32_spi_dma_private
dma3_priv
=
{
DMA2_Channel2
,
DMA2_Channel1
,
DMA2_FLAG_TC2
,
DMA2_FLAG_TE2
,
DMA2_FLAG_TC1
,
DMA2_FLAG_TE1
,
DMA2_Channel2_IRQn
,
DMA2_Channel1_IRQn
,
DMA2_FLAG_GL2
,
DMA2_FLAG_GL1
,
};
static
struct
stm32_spi_dma
dma3
=
{
&
dma3_priv
,
};
void
DMA2_Channel1_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
rt_event_send
(
&
dma3
.
event
,
SPI_DMA_TX_DONE
);
DMA_ClearFlag
(
dma3
.
priv_data
->
tx_gl_flag
);
/* leave interrupt */
rt_interrupt_leave
();
}
void
DMA2_Channel2_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
rt_event_send
(
&
dma3
.
event
,
SPI_DMA_RX_DONE
);
DMA_ClearFlag
(
dma3
.
priv_data
->
rx_gl_flag
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/*SPI3_USING_DMA*/
#endif
/*SPI_USE_DMA*/
rt_inline
uint16_t
get_spi_BaudRatePrescaler
(
rt_uint32_t
max_hz
)
{
uint16_t
SPI_BaudRatePrescaler
;
/* STM32F10x SPI MAX 18Mhz */
if
(
max_hz
>=
SystemCoreClock
/
2
&&
SystemCoreClock
/
2
<=
18
000000
)
if
(
max_hz
>=
SystemCoreClock
/
2
&&
SystemCoreClock
/
2
<=
36
000000
)
{
SPI_BaudRatePrescaler
=
SPI_BaudRatePrescaler_2
;
}
...
...
@@ -208,27 +309,30 @@ static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* mes
rt_uint32_t
size
=
message
->
length
;
/* take CS */
if
(
message
->
cs_take
)
if
(
message
->
cs_take
&&
stm32_spi_cs
)
{
GPIO_ResetBits
(
stm32_spi_cs
->
GPIOx
,
stm32_spi_cs
->
GPIO_Pin
);
}
#ifdef SPI_USE_DMA
if
(
message
->
length
>
32
)
if
(
(
stm32_spi_bus
->
parent
.
parent
.
flag
&
(
RT_DEVICE_FLAG_DMA_RX
|
RT_DEVICE_FLAG_DMA_TX
))
&&
stm32_spi_bus
->
dma
&&
message
->
length
>
32
)
{
if
(
config
->
data_width
<=
8
)
{
rt_uint32_t
ev
=
0
;
DMA_Configuration
(
stm32_spi_bus
,
message
->
send_buf
,
message
->
recv_buf
,
message
->
length
);
SPI_I2S_DMACmd
(
SPI
,
SPI_I2S_DMAReq_Tx
|
SPI_I2S_DMAReq_Rx
,
ENABLE
);
while
(
DMA_GetFlagStatus
(
stm32_spi_bus
->
DMA_Channel_RX_FLAG_TC
)
==
RESET
||
DMA_GetFlagStatus
(
stm32_spi_bus
->
DMA_Channel_TX_FLAG_TC
)
==
RESET
);
rt_event_recv
(
&
stm32_spi_bus
->
dma
->
event
,
SPI_DMA_COMPLETE
,
RT_EVENT_FLAG_AND
|
RT_EVENT_FLAG_CLEAR
,
RT_WAITING_FOREVER
,
&
ev
);
SPI_I2S_DMACmd
(
SPI
,
SPI_I2S_DMAReq_Tx
|
SPI_I2S_DMAReq_Rx
,
DISABLE
);
DMA_ITConfig
(
stm32_spi_bus
->
dma
->
priv_data
->
DMA_Channel_TX
,
DMA_IT_TC
,
DISABLE
);
DMA_ITConfig
(
stm32_spi_bus
->
dma
->
priv_data
->
DMA_Channel_RX
,
DMA_IT_TC
,
DISABLE
);
}
// rt_memcpy(buffer,_spi_flash_buffer,DMA_BUFFER_SIZE);
// buffer += DMA_BUFFER_SIZE;
}
else
#endif
#endif
/*SPI_USE_DMA*/
{
if
(
config
->
data_width
<=
8
)
{
...
...
@@ -293,7 +397,7 @@ static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* mes
}
/* release CS */
if
(
message
->
cs_release
)
if
(
message
->
cs_release
&&
stm32_spi_cs
)
{
GPIO_SetBits
(
stm32_spi_cs
->
GPIOx
,
stm32_spi_cs
->
GPIO_Pin
);
}
...
...
@@ -313,60 +417,97 @@ rt_err_t stm32_spi_register(SPI_TypeDef * SPI,
struct
stm32_spi_bus
*
stm32_spi
,
const
char
*
spi_bus_name
)
{
rt_err_t
res
=
RT_EOK
;
NVIC_InitTypeDef
NVIC_InitStructure
;
RCC_APB2PeriphClockCmd
(
RCC_APB2Periph_AFIO
,
ENABLE
);
rt_uint32_t
flags
=
0
;
if
(
SPI
==
SPI1
)
{
stm32_spi
->
SPI
=
SPI1
;
#ifdef SPI_USE_DMA
/* Enable the DMA1 Clock */
RCC_AHBPeriphClockCmd
(
RCC_AHBPeriph_DMA1
,
ENABLE
);
stm32_spi
->
DMA_Channel_RX
=
DMA1_Channel2
;
stm32_spi
->
DMA_Channel_TX
=
DMA1_Channel3
;
stm32_spi
->
DMA_Channel_RX_FLAG_TC
=
DMA1_FLAG_TC2
;
stm32_spi
->
DMA_Channel_RX_FLAG_TE
=
DMA1_FLAG_TE2
;
stm32_spi
->
DMA_Channel_TX_FLAG_TC
=
DMA1_FLAG_TC3
;
stm32_spi
->
DMA_Channel_TX_FLAG_TE
=
DMA1_FLAG_TE3
;
#endif
#ifdef SPI1_USING_DMA
{
rt_event_init
(
&
dma1
.
event
,
"spi1ev"
,
RT_IPC_FLAG_FIFO
);
stm32_spi
->
dma
=
&
dma1
;
/* rx dma interrupt config */
NVIC_InitStructure
.
NVIC_IRQChannel
=
dma1
.
priv_data
->
tx_irq_ch
;
NVIC_InitStructure
.
NVIC_IRQChannelPreemptionPriority
=
0
;
NVIC_InitStructure
.
NVIC_IRQChannelSubPriority
=
1
;
NVIC_InitStructure
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_Init
(
&
NVIC_InitStructure
);
NVIC_InitStructure
.
NVIC_IRQChannel
=
dma1
.
priv_data
->
rx_irq_ch
;
NVIC_InitStructure
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_Init
(
&
NVIC_InitStructure
);
/* Enable the DMA1 Clock */
RCC_AHBPeriphClockCmd
(
RCC_AHBPeriph_DMA1
,
ENABLE
);
flags
|=
RT_DEVICE_FLAG_DMA_RX
|
RT_DEVICE_FLAG_DMA_TX
;
}
#else
/*!SPI1_USING_DMA*/
stm32_spi
->
dma
=
RT_NULL
;
#endif
/*SPI1_USING_DMA*/
#endif
/*SPI_USE_DMA*/
RCC_APB2PeriphClockCmd
(
RCC_APB2Periph_SPI1
,
ENABLE
);
}
else
if
(
SPI
==
SPI2
)
{
stm32_spi
->
SPI
=
SPI2
;
#ifdef SPI_USE_DMA
/* Enable the DMA1 Clock */
RCC_AHBPeriphClockCmd
(
RCC_AHBPeriph_DMA1
,
ENABLE
);
stm32_spi
->
DMA_Channel_RX
=
DMA1_Channel4
;
stm32_spi
->
DMA_Channel_TX
=
DMA1_Channel5
;
stm32_spi
->
DMA_Channel_RX_FLAG_TC
=
DMA1_FLAG_TC4
;
stm32_spi
->
DMA_Channel_RX_FLAG_TE
=
DMA1_FLAG_TE4
;
stm32_spi
->
DMA_Channel_TX_FLAG_TC
=
DMA1_FLAG_TC5
;
stm32_spi
->
DMA_Channel_TX_FLAG_TE
=
DMA1_FLAG_TE5
;
#endif
#ifdef SPI2_USING_DMA
{
rt_event_init
(
&
dma2
.
event
,
"spi2ev"
,
RT_IPC_FLAG_FIFO
);
stm32_spi
->
dma
=
&
dma2
;
/* rx dma interrupt config */
NVIC_InitStructure
.
NVIC_IRQChannel
=
dma2
.
priv_data
->
tx_irq_ch
;
NVIC_InitStructure
.
NVIC_IRQChannelPreemptionPriority
=
0
;
NVIC_InitStructure
.
NVIC_IRQChannelSubPriority
=
1
;
NVIC_InitStructure
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_Init
(
&
NVIC_InitStructure
);
NVIC_InitStructure
.
NVIC_IRQChannel
=
dma2
.
priv_data
->
rx_irq_ch
;
NVIC_InitStructure
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_Init
(
&
NVIC_InitStructure
);
/* Enable the DMA1 Clock */
RCC_AHBPeriphClockCmd
(
RCC_AHBPeriph_DMA1
,
ENABLE
);
flags
|=
RT_DEVICE_FLAG_DMA_RX
|
RT_DEVICE_FLAG_DMA_TX
;
}
#else
/*!SPI2_USING_DMA*/
stm32_spi
->
dma
=
RT_NULL
;
#endif
/*SPI2_USING_DMA*/
#endif
/*SPI_USE_DMA*/
RCC_APB1PeriphClockCmd
(
RCC_APB1Periph_SPI2
,
ENABLE
);
}
else
if
(
SPI
==
SPI3
)
{
stm32_spi
->
SPI
=
SPI3
;
#ifdef SPI_USE_DMA
/* Enable the DMA2 Clock */
RCC_AHBPeriphClockCmd
(
RCC_AHBPeriph_DMA2
,
ENABLE
);
stm32_spi
->
DMA_Channel_RX
=
DMA2_Channel1
;
stm32_spi
->
DMA_Channel_TX
=
DMA2_Channel2
;
stm32_spi
->
DMA_Channel_RX_FLAG_TC
=
DMA2_FLAG_TC1
;
stm32_spi
->
DMA_Channel_RX_FLAG_TE
=
DMA2_FLAG_TE1
;
stm32_spi
->
DMA_Channel_TX_FLAG_TC
=
DMA2_FLAG_TC2
;
stm32_spi
->
DMA_Channel_TX_FLAG_TE
=
DMA2_FLAG_TE2
;
#endif
#ifdef SPI3_USING_DMA
{
rt_event_init
(
&
dma3
.
event
,
"spi3ev"
,
RT_IPC_FLAG_FIFO
);
stm32_spi
->
dma
=
&
dma3
;
/* rx dma interrupt config */
NVIC_InitStructure
.
NVIC_IRQChannel
=
dma3
.
priv_data
->
tx_irq_ch
;
NVIC_InitStructure
.
NVIC_IRQChannelPreemptionPriority
=
0
;
NVIC_InitStructure
.
NVIC_IRQChannelSubPriority
=
1
;
NVIC_InitStructure
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_Init
(
&
NVIC_InitStructure
);
NVIC_InitStructure
.
NVIC_IRQChannel
=
dma3
.
priv_data
->
rx_irq_ch
;
NVIC_InitStructure
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_Init
(
&
NVIC_InitStructure
);
/* Enable the DMA1 Clock */
RCC_AHBPeriphClockCmd
(
RCC_AHBPeriph_DMA1
,
ENABLE
);
flags
|=
RT_DEVICE_FLAG_DMA_RX
|
RT_DEVICE_FLAG_DMA_TX
;
}
#else
/*!SPI3_USING_DMA*/
stm32_spi
->
dma
=
RT_NULL
;
#endif
/*SPI3_USING_DMA*/
#endif
/*SPI_USE_DMA*/
RCC_APB1PeriphClockCmd
(
RCC_APB1Periph_SPI3
,
ENABLE
);
}
else
{
return
RT_ENOSYS
;
}
res
=
rt_spi_bus_register
(
&
stm32_spi
->
parent
,
spi_bus_name
,
&
stm32_spi_ops
);
stm32_spi
->
parent
.
parent
.
flag
|=
flags
;
return
r
t_spi_bus_register
(
&
stm32_spi
->
parent
,
spi_bus_name
,
&
stm32_spi_ops
)
;
return
r
es
;
}
bsp/stm32f107/drivers/rt_stm32f10x_spi.h
浏览文件 @
763d7456
...
...
@@ -8,19 +8,41 @@
#include "board.h"
//#define SPI_USE_DMA
#if defined(SPI1_USING_DMA) || defined(SPI2_USING_DMA) || defined(SPI3_USING_DMA)
#define SPI_USE_DMA
#endif
/*defined(SPI1_USING_DMA) || defined(SPI2_USING_DMA) || defined(SPI3_USING_DMA)*/
struct
stm32_spi_bus
{
struct
rt_spi_bus
parent
;
SPI_TypeDef
*
SPI
;
#ifdef SPI_USE_DMA
#define SPI_DMA_RX_DONE 0x01
#define SPI_DMA_TX_DONE 0x02
#define SPI_DMA_COMPLETE (SPI_DMA_RX_DONE | SPI_DMA_TX_DONE)
struct
stm32_spi_dma_private
{
DMA_Channel_TypeDef
*
DMA_Channel_TX
;
DMA_Channel_TypeDef
*
DMA_Channel_RX
;
uint32_t
DMA_Channel_TX_FLAG_TC
;
uint32_t
DMA_Channel_TX_FLAG_TE
;
uint32_t
DMA_Channel_RX_FLAG_TC
;
uint32_t
DMA_Channel_RX_FLAG_TE
;
uint8_t
tx_irq_ch
;
uint8_t
rx_irq_ch
;
uint32_t
tx_gl_flag
;
uint32_t
rx_gl_flag
;
};
struct
stm32_spi_dma
{
const
struct
stm32_spi_dma_private
*
priv_data
;
struct
rt_event
event
;
};
#endif
/*SPI_USE_DMA*/
struct
stm32_spi_bus
{
struct
rt_spi_bus
parent
;
SPI_TypeDef
*
SPI
;
#ifdef SPI_USE_DMA
struct
stm32_spi_dma
*
dma
;
#endif
/* SPI_USE_DMA */
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录