Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
9b64d196
Commit
9b64d196
authored
Sep 01, 2016
by
Damien George
Browse files
stmhal/spi: Factor out SPI transfer code to a single function.
parent
3be8b688
Changes
1
Hide whitespace changes
Inline
Side-by-side
stmhal/spi.c
View file @
9b64d196
...
...
@@ -327,6 +327,79 @@ STATIC HAL_StatusTypeDef spi_wait_dma_finished(SPI_HandleTypeDef *spi, uint32_t
return
HAL_OK
;
}
STATIC
void
spi_transfer
(
mp_obj_base_t
*
self_in
,
size_t
src_len
,
const
uint8_t
*
src_buf
,
size_t
dest_len
,
uint8_t
*
dest_buf
,
uint32_t
timeout
)
{
// Note: there seems to be a problem sending 1 byte using DMA the first
// time directly after the SPI/DMA is initialised. The cause of this is
// unknown but we sidestep the issue by using polling for 1 byte transfer.
pyb_spi_obj_t
*
self
=
(
pyb_spi_obj_t
*
)
self_in
;
HAL_StatusTypeDef
status
;
if
(
dest_len
==
0
)
{
// send only
if
(
src_len
==
1
||
query_irq
()
==
IRQ_STATE_DISABLED
)
{
status
=
HAL_SPI_Transmit
(
self
->
spi
,
(
uint8_t
*
)
src_buf
,
src_len
,
timeout
);
}
else
{
DMA_HandleTypeDef
tx_dma
;
dma_init
(
&
tx_dma
,
self
->
tx_dma_descr
,
self
->
spi
);
self
->
spi
->
hdmatx
=
&
tx_dma
;
self
->
spi
->
hdmarx
=
NULL
;
status
=
HAL_SPI_Transmit_DMA
(
self
->
spi
,
(
uint8_t
*
)
src_buf
,
src_len
);
if
(
status
==
HAL_OK
)
{
status
=
spi_wait_dma_finished
(
self
->
spi
,
timeout
);
}
dma_deinit
(
self
->
tx_dma_descr
);
}
}
else
if
(
src_len
==
0
)
{
// receive only
if
(
dest_len
==
1
||
query_irq
()
==
IRQ_STATE_DISABLED
)
{
status
=
HAL_SPI_Receive
(
self
->
spi
,
dest_buf
,
dest_len
,
timeout
);
}
else
{
DMA_HandleTypeDef
tx_dma
,
rx_dma
;
if
(
self
->
spi
->
Init
.
Mode
==
SPI_MODE_MASTER
)
{
// in master mode the HAL actually does a TransmitReceive call
dma_init
(
&
tx_dma
,
self
->
tx_dma_descr
,
self
->
spi
);
self
->
spi
->
hdmatx
=
&
tx_dma
;
}
else
{
self
->
spi
->
hdmatx
=
NULL
;
}
dma_init
(
&
rx_dma
,
self
->
rx_dma_descr
,
self
->
spi
);
self
->
spi
->
hdmarx
=
&
rx_dma
;
status
=
HAL_SPI_Receive_DMA
(
self
->
spi
,
dest_buf
,
dest_len
);
if
(
status
==
HAL_OK
)
{
status
=
spi_wait_dma_finished
(
self
->
spi
,
timeout
);
}
if
(
self
->
spi
->
hdmatx
!=
NULL
)
{
dma_deinit
(
self
->
tx_dma_descr
);
}
dma_deinit
(
self
->
rx_dma_descr
);
}
}
else
{
// send and receive
// requires src_len==dest_len
if
(
src_len
==
1
||
query_irq
()
==
IRQ_STATE_DISABLED
)
{
status
=
HAL_SPI_TransmitReceive
(
self
->
spi
,
(
uint8_t
*
)
src_buf
,
dest_buf
,
src_len
,
timeout
);
}
else
{
DMA_HandleTypeDef
tx_dma
,
rx_dma
;
dma_init
(
&
tx_dma
,
self
->
tx_dma_descr
,
self
->
spi
);
self
->
spi
->
hdmatx
=
&
tx_dma
;
dma_init
(
&
rx_dma
,
self
->
rx_dma_descr
,
self
->
spi
);
self
->
spi
->
hdmarx
=
&
rx_dma
;
status
=
HAL_SPI_TransmitReceive_DMA
(
self
->
spi
,
(
uint8_t
*
)
src_buf
,
dest_buf
,
src_len
);
if
(
status
==
HAL_OK
)
{
status
=
spi_wait_dma_finished
(
self
->
spi
,
timeout
);
}
dma_deinit
(
self
->
tx_dma_descr
);
dma_deinit
(
self
->
rx_dma_descr
);
}
}
if
(
status
!=
HAL_OK
)
{
mp_hal_raise
(
status
);
}
}
/******************************************************************************/
/* Micro Python bindings */
...
...
@@ -556,27 +629,7 @@ STATIC mp_obj_t pyb_spi_send(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
pyb_buf_get_for_send
(
args
[
0
].
u_obj
,
&
bufinfo
,
data
);
// send the data
// Note: there seems to be a problem sending 1 byte using DMA the first
// time directly after the SPI/DMA is initialised. The cause of this is
// unknown but we sidestep the issue by using polling for 1 byte transfer.
HAL_StatusTypeDef
status
;
if
(
bufinfo
.
len
==
1
||
query_irq
()
==
IRQ_STATE_DISABLED
)
{
status
=
HAL_SPI_Transmit
(
self
->
spi
,
bufinfo
.
buf
,
bufinfo
.
len
,
args
[
1
].
u_int
);
}
else
{
DMA_HandleTypeDef
tx_dma
;
dma_init
(
&
tx_dma
,
self
->
tx_dma_descr
,
self
->
spi
);
self
->
spi
->
hdmatx
=
&
tx_dma
;
self
->
spi
->
hdmarx
=
NULL
;
status
=
HAL_SPI_Transmit_DMA
(
self
->
spi
,
bufinfo
.
buf
,
bufinfo
.
len
);
if
(
status
==
HAL_OK
)
{
status
=
spi_wait_dma_finished
(
self
->
spi
,
args
[
1
].
u_int
);
}
dma_deinit
(
self
->
tx_dma_descr
);
}
if
(
status
!=
HAL_OK
)
{
mp_hal_raise
(
status
);
}
spi_transfer
((
mp_obj_base_t
*
)
self
,
bufinfo
.
len
,
bufinfo
.
buf
,
0
,
NULL
,
args
[
1
].
u_int
);
return
mp_const_none
;
}
...
...
@@ -610,34 +663,7 @@ STATIC mp_obj_t pyb_spi_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
mp_obj_t
o_ret
=
pyb_buf_get_for_recv
(
args
[
0
].
u_obj
,
&
vstr
);
// receive the data
HAL_StatusTypeDef
status
;
if
(
vstr
.
len
==
1
||
query_irq
()
==
IRQ_STATE_DISABLED
)
{
status
=
HAL_SPI_Receive
(
self
->
spi
,
(
uint8_t
*
)
vstr
.
buf
,
vstr
.
len
,
args
[
1
].
u_int
);
}
else
{
DMA_HandleTypeDef
tx_dma
,
rx_dma
;
if
(
self
->
spi
->
Init
.
Mode
==
SPI_MODE_MASTER
)
{
// in master mode the HAL actually does a TransmitReceive call
dma_init
(
&
tx_dma
,
self
->
tx_dma_descr
,
self
->
spi
);
self
->
spi
->
hdmatx
=
&
tx_dma
;
}
else
{
self
->
spi
->
hdmatx
=
NULL
;
}
dma_init
(
&
rx_dma
,
self
->
rx_dma_descr
,
self
->
spi
);
self
->
spi
->
hdmarx
=
&
rx_dma
;
status
=
HAL_SPI_Receive_DMA
(
self
->
spi
,
(
uint8_t
*
)
vstr
.
buf
,
vstr
.
len
);
if
(
status
==
HAL_OK
)
{
status
=
spi_wait_dma_finished
(
self
->
spi
,
args
[
1
].
u_int
);
}
if
(
self
->
spi
->
hdmatx
!=
NULL
)
{
dma_deinit
(
self
->
tx_dma_descr
);
}
dma_deinit
(
self
->
rx_dma_descr
);
}
if
(
status
!=
HAL_OK
)
{
mp_hal_raise
(
status
);
}
spi_transfer
((
mp_obj_base_t
*
)
self
,
0
,
NULL
,
vstr
.
len
,
(
uint8_t
*
)
vstr
.
buf
,
args
[
1
].
u_int
);
// return the received data
if
(
o_ret
!=
MP_OBJ_NULL
)
{
...
...
@@ -706,27 +732,8 @@ STATIC mp_obj_t pyb_spi_send_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp
}
}
// send and receive the data
HAL_StatusTypeDef
status
;
if
(
bufinfo_send
.
len
==
1
||
query_irq
()
==
IRQ_STATE_DISABLED
)
{
status
=
HAL_SPI_TransmitReceive
(
self
->
spi
,
bufinfo_send
.
buf
,
bufinfo_recv
.
buf
,
bufinfo_send
.
len
,
args
[
2
].
u_int
);
}
else
{
DMA_HandleTypeDef
tx_dma
,
rx_dma
;
dma_init
(
&
tx_dma
,
self
->
tx_dma_descr
,
self
->
spi
);
self
->
spi
->
hdmatx
=
&
tx_dma
;
dma_init
(
&
rx_dma
,
self
->
rx_dma_descr
,
self
->
spi
);
self
->
spi
->
hdmarx
=
&
rx_dma
;
status
=
HAL_SPI_TransmitReceive_DMA
(
self
->
spi
,
bufinfo_send
.
buf
,
bufinfo_recv
.
buf
,
bufinfo_send
.
len
);
if
(
status
==
HAL_OK
)
{
status
=
spi_wait_dma_finished
(
self
->
spi
,
args
[
2
].
u_int
);
}
dma_deinit
(
self
->
tx_dma_descr
);
dma_deinit
(
self
->
rx_dma_descr
);
}
if
(
status
!=
HAL_OK
)
{
mp_hal_raise
(
status
);
}
// do the transfer
spi_transfer
((
mp_obj_base_t
*
)
self
,
bufinfo_send
.
len
,
bufinfo_send
.
buf
,
bufinfo_recv
.
len
,
bufinfo_recv
.
buf
,
args
[
2
].
u_int
);
// return the received data
if
(
o_ret
!=
MP_OBJ_NULL
)
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment