Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
M
micropython
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
card10
micropython
Commits
9de67732
Commit
9de67732
authored
10 years ago
by
Damien George
Browse files
Options
Downloads
Patches
Plain Diff
stmhal: Make SPI bus use DMA for transfers.
Uses DMA if interrupts are enabled, polling if they are disabled.
parent
d4f80f58
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
stmhal/spi.c
+214
-70
214 additions, 70 deletions
stmhal/spi.c
with
214 additions
and
70 deletions
stmhal/spi.c
+
214
−
70
View file @
9de67732
...
@@ -33,6 +33,7 @@
...
@@ -33,6 +33,7 @@
#include
"qstr.h"
#include
"qstr.h"
#include
"obj.h"
#include
"obj.h"
#include
"runtime.h"
#include
"runtime.h"
#include
"irq.h"
#include
"pin.h"
#include
"pin.h"
#include
"genhdr/pins.h"
#include
"genhdr/pins.h"
#include
"bufhelper.h"
#include
"bufhelper.h"
...
@@ -71,6 +72,60 @@ SPI_HandleTypeDef SPIHandle2 = {.Instance = NULL};
...
@@ -71,6 +72,60 @@ SPI_HandleTypeDef SPIHandle2 = {.Instance = NULL};
SPI_HandleTypeDef
SPIHandle3
=
{.
Instance
=
NULL
};
SPI_HandleTypeDef
SPIHandle3
=
{.
Instance
=
NULL
};
#endif
#endif
// Possible DMA configurations for SPI busses:
// SPI1_RX: DMA2_Stream0.CHANNEL_3 or DMA2_Stream2.CHANNEL_3
// SPI1_TX: DMA2_Stream3.CHANNEL_3 or DMA2_Stream5.CHANNEL_3
// SPI2_RX: DMA1_Stream3.CHANNEL_0
// SPI2_TX: DMA1_Stream4.CHANNEL_0
// SPI3_RX: DMA1_Stream0.CHANNEL_0 or DMA1_Stream2.CHANNEL_0
// SPI3_TX: DMA1_Stream5.CHANNEL_0 or DMA1_Stream7.CHANNEL_0
#define SPI1_DMA_CLK_ENABLE __DMA2_CLK_ENABLE
#define SPI1_RX_DMA_STREAM (DMA2_Stream2)
#define SPI1_TX_DMA_STREAM (DMA2_Stream5)
#define SPI1_DMA_CHANNEL (DMA_CHANNEL_3)
#define SPI1_RX_DMA_IRQN (DMA2_Stream2_IRQn)
#define SPI1_TX_DMA_IRQN (DMA2_Stream5_IRQn)
#define SPI1_RX_DMA_IRQ_HANDLER DMA2_Stream2_IRQHandler
#define SPI1_TX_DMA_IRQ_HANDLER DMA2_Stream5_IRQHandler
#define SPI2_DMA_CLK_ENABLE __DMA1_CLK_ENABLE
#define SPI2_RX_DMA_STREAM (DMA1_Stream3)
#define SPI2_TX_DMA_STREAM (DMA1_Stream4)
#define SPI2_DMA_CHANNEL (DMA_CHANNEL_0)
#define SPI2_RX_DMA_IRQN (DMA1_Stream3_IRQn)
#define SPI2_TX_DMA_IRQN (DMA1_Stream4_IRQn)
#define SPI2_RX_DMA_IRQ_HANDLER DMA1_Stream3_IRQHandler
#define SPI2_TX_DMA_IRQ_HANDLER DMA1_Stream4_IRQHandler
#define SPI3_DMA_CLK_ENABLE __DMA1_CLK_ENABLE
#define SPI3_RX_DMA_STREAM (DMA1_Stream2)
#define SPI3_TX_DMA_STREAM (DMA1_Stream7)
#define SPI3_DMA_CHANNEL (DMA_CHANNEL_0)
#define SPI3_RX_DMA_IRQN (DMA1_Stream2_IRQn)
#define SPI3_TX_DMA_IRQN (DMA1_Stream7_IRQn)
#define SPI3_RX_DMA_IRQ_HANDLER DMA1_Stream2_IRQHandler
#define SPI3_TX_DMA_IRQ_HANDLER DMA1_Stream7_IRQHandler
#if MICROPY_HW_ENABLE_SPI1
STATIC
DMA_HandleTypeDef
spi1_rx_dma_handle
;
STATIC
DMA_HandleTypeDef
spi1_tx_dma_handle
;
void
SPI1_RX_DMA_IRQ_HANDLER
(
void
)
{
HAL_DMA_IRQHandler
(
&
spi1_rx_dma_handle
);
}
void
SPI1_TX_DMA_IRQ_HANDLER
(
void
)
{
HAL_DMA_IRQHandler
(
&
spi1_tx_dma_handle
);
}
#endif
STATIC
DMA_HandleTypeDef
spi2_rx_dma_handle
;
STATIC
DMA_HandleTypeDef
spi2_tx_dma_handle
;
void
SPI2_RX_DMA_IRQ_HANDLER
(
void
)
{
HAL_DMA_IRQHandler
(
&
spi2_rx_dma_handle
);
}
void
SPI2_TX_DMA_IRQ_HANDLER
(
void
)
{
HAL_DMA_IRQHandler
(
&
spi2_tx_dma_handle
);
}
#if MICROPY_HW_ENABLE_SPI3
STATIC
DMA_HandleTypeDef
spi3_rx_dma_handle
;
STATIC
DMA_HandleTypeDef
spi3_tx_dma_handle
;
void
SPI3_RX_DMA_IRQ_HANDLER
(
void
)
{
HAL_DMA_IRQHandler
(
&
spi3_rx_dma_handle
);
}
void
SPI3_TX_DMA_IRQ_HANDLER
(
void
)
{
HAL_DMA_IRQHandler
(
&
spi3_tx_dma_handle
);
}
#endif
void
spi_init0
(
void
)
{
void
spi_init0
(
void
)
{
// reset the SPI handles
// reset the SPI handles
#if MICROPY_HW_ENABLE_SPI1
#if MICROPY_HW_ENABLE_SPI1
...
@@ -93,6 +148,9 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
...
@@ -93,6 +148,9 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
GPIO_InitStructure
.
Speed
=
GPIO_SPEED_FAST
;
GPIO_InitStructure
.
Speed
=
GPIO_SPEED_FAST
;
GPIO_InitStructure
.
Pull
=
spi
->
Init
.
CLKPolarity
==
SPI_POLARITY_LOW
?
GPIO_PULLDOWN
:
GPIO_PULLUP
;
GPIO_InitStructure
.
Pull
=
spi
->
Init
.
CLKPolarity
==
SPI_POLARITY_LOW
?
GPIO_PULLDOWN
:
GPIO_PULLUP
;
DMA_HandleTypeDef
*
rx_dma
,
*
tx_dma
;
IRQn_Type
rx_dma_irqn
,
tx_dma_irqn
;
const
pin_obj_t
*
pins
[
4
];
const
pin_obj_t
*
pins
[
4
];
if
(
0
)
{
if
(
0
)
{
#if MICROPY_HW_ENABLE_SPI1
#if MICROPY_HW_ENABLE_SPI1
...
@@ -105,6 +163,15 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
...
@@ -105,6 +163,15 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
GPIO_InitStructure
.
Alternate
=
GPIO_AF5_SPI1
;
GPIO_InitStructure
.
Alternate
=
GPIO_AF5_SPI1
;
// enable the SPI clock
// enable the SPI clock
__SPI1_CLK_ENABLE
();
__SPI1_CLK_ENABLE
();
// configure DMA
SPI1_DMA_CLK_ENABLE
();
spi1_rx_dma_handle
.
Instance
=
SPI1_RX_DMA_STREAM
;
spi1_rx_dma_handle
.
Init
.
Channel
=
SPI1_DMA_CHANNEL
;
spi1_tx_dma_handle
.
Instance
=
SPI1_TX_DMA_STREAM
;
rx_dma
=
&
spi1_rx_dma_handle
;
tx_dma
=
&
spi1_tx_dma_handle
;
rx_dma_irqn
=
SPI1_RX_DMA_IRQN
;
tx_dma_irqn
=
SPI1_TX_DMA_IRQN
;
#endif
#endif
}
else
if
(
spi
->
Instance
==
SPI2
)
{
}
else
if
(
spi
->
Instance
==
SPI2
)
{
// Y-skin: Y5=PB12=SPI2_NSS, Y6=PB13=SPI2_SCK, Y7=PB14=SPI2_MISO, Y8=PB15=SPI2_MOSI
// Y-skin: Y5=PB12=SPI2_NSS, Y6=PB13=SPI2_SCK, Y7=PB14=SPI2_MISO, Y8=PB15=SPI2_MOSI
...
@@ -115,6 +182,15 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
...
@@ -115,6 +182,15 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
GPIO_InitStructure
.
Alternate
=
GPIO_AF5_SPI2
;
GPIO_InitStructure
.
Alternate
=
GPIO_AF5_SPI2
;
// enable the SPI clock
// enable the SPI clock
__SPI2_CLK_ENABLE
();
__SPI2_CLK_ENABLE
();
// configure DMA
SPI2_DMA_CLK_ENABLE
();
spi2_rx_dma_handle
.
Instance
=
SPI2_RX_DMA_STREAM
;
spi2_rx_dma_handle
.
Init
.
Channel
=
SPI2_DMA_CHANNEL
;
spi2_tx_dma_handle
.
Instance
=
SPI2_TX_DMA_STREAM
;
rx_dma
=
&
spi2_rx_dma_handle
;
tx_dma
=
&
spi2_tx_dma_handle
;
rx_dma_irqn
=
SPI2_RX_DMA_IRQN
;
tx_dma_irqn
=
SPI2_TX_DMA_IRQN
;
#if MICROPY_HW_ENABLE_SPI3
#if MICROPY_HW_ENABLE_SPI3
}
else
if
(
spi
->
Instance
==
SPI3
)
{
}
else
if
(
spi
->
Instance
==
SPI3
)
{
pins
[
0
]
=
&
pin_A4
;
pins
[
0
]
=
&
pin_A4
;
...
@@ -124,6 +200,15 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
...
@@ -124,6 +200,15 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
GPIO_InitStructure
.
Alternate
=
GPIO_AF6_SPI3
;
GPIO_InitStructure
.
Alternate
=
GPIO_AF6_SPI3
;
// enable the SPI clock
// enable the SPI clock
__SPI3_CLK_ENABLE
();
__SPI3_CLK_ENABLE
();
// configure DMA
SPI3_DMA_CLK_ENABLE
();
spi3_rx_dma_handle
.
Instance
=
SPI3_RX_DMA_STREAM
;
spi3_rx_dma_handle
.
Init
.
Channel
=
SPI3_DMA_CHANNEL
;
spi3_tx_dma_handle
.
Instance
=
SPI3_TX_DMA_STREAM
;
rx_dma
=
&
spi3_rx_dma_handle
;
tx_dma
=
&
spi3_tx_dma_handle
;
rx_dma_irqn
=
SPI3_RX_DMA_IRQN
;
tx_dma_irqn
=
SPI3_TX_DMA_IRQN
;
#endif
#endif
}
else
{
}
else
{
// SPI does not exist for this board (shouldn't get here, should be checked by caller)
// SPI does not exist for this board (shouldn't get here, should be checked by caller)
...
@@ -143,6 +228,37 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
...
@@ -143,6 +228,37 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
printf
(
"OSError: HAL_SPI_Init failed
\n
"
);
printf
(
"OSError: HAL_SPI_Init failed
\n
"
);
return
;
return
;
}
}
// configure DMA
rx_dma
->
Init
.
Direction
=
DMA_PERIPH_TO_MEMORY
;
rx_dma
->
Init
.
PeriphInc
=
DMA_PINC_DISABLE
;
rx_dma
->
Init
.
MemInc
=
DMA_MINC_ENABLE
;
rx_dma
->
Init
.
PeriphDataAlignment
=
DMA_PDATAALIGN_BYTE
;
rx_dma
->
Init
.
MemDataAlignment
=
DMA_MDATAALIGN_BYTE
;
rx_dma
->
Init
.
Mode
=
DMA_NORMAL
;
rx_dma
->
Init
.
Priority
=
DMA_PRIORITY_LOW
;
rx_dma
->
Init
.
FIFOMode
=
DMA_FIFOMODE_DISABLE
;
rx_dma
->
Init
.
FIFOThreshold
=
DMA_FIFO_THRESHOLD_FULL
;
rx_dma
->
Init
.
MemBurst
=
DMA_MBURST_INC4
;
rx_dma
->
Init
.
PeriphBurst
=
DMA_PBURST_INC4
;
tx_dma
->
Init
=
rx_dma
->
Init
;
// copy rx settings
tx_dma
->
Init
.
Direction
=
DMA_MEMORY_TO_PERIPH
;
__HAL_LINKDMA
(
spi
,
hdmarx
,
*
rx_dma
);
HAL_DMA_DeInit
(
rx_dma
);
HAL_DMA_Init
(
rx_dma
);
__HAL_LINKDMA
(
spi
,
hdmatx
,
*
tx_dma
);
HAL_DMA_DeInit
(
tx_dma
);
HAL_DMA_Init
(
tx_dma
);
// Enable the relevant IRQs.
HAL_NVIC_SetPriority
(
rx_dma_irqn
,
6
,
0
);
HAL_NVIC_EnableIRQ
(
rx_dma_irqn
);
HAL_NVIC_SetPriority
(
tx_dma_irqn
,
6
,
0
);
HAL_NVIC_EnableIRQ
(
tx_dma_irqn
);
}
}
void
spi_deinit
(
SPI_HandleTypeDef
*
spi
)
{
void
spi_deinit
(
SPI_HandleTypeDef
*
spi
)
{
...
@@ -167,6 +283,17 @@ void spi_deinit(SPI_HandleTypeDef *spi) {
...
@@ -167,6 +283,17 @@ void spi_deinit(SPI_HandleTypeDef *spi) {
}
}
}
}
STATIC
HAL_StatusTypeDef
spi_wait_dma_finished
(
SPI_HandleTypeDef
*
spi
,
uint32_t
timeout
)
{
uint32_t
start
=
HAL_GetTick
();
while
(
HAL_SPI_GetState
(
spi
)
!=
HAL_SPI_STATE_READY
)
{
if
(
HAL_GetTick
()
-
start
>=
timeout
)
{
return
HAL_TIMEOUT
;
}
__WFI
();
}
return
HAL_OK
;
}
/******************************************************************************/
/******************************************************************************/
/* Micro Python bindings */
/* Micro Python bindings */
...
@@ -238,7 +365,8 @@ STATIC void pyb_spi_print(void (*print)(void *env, const char *fmt, ...), void *
...
@@ -238,7 +365,8 @@ STATIC void pyb_spi_print(void (*print)(void *env, const char *fmt, ...), void *
///
///
/// - `mode` must be either `SPI.MASTER` or `SPI.SLAVE`.
/// - `mode` must be either `SPI.MASTER` or `SPI.SLAVE`.
/// - `baudrate` is the SCK clock rate (only sensible for a master).
/// - `baudrate` is the SCK clock rate (only sensible for a master).
STATIC
const
mp_arg_t
pyb_spi_init_args
[]
=
{
STATIC
mp_obj_t
pyb_spi_init_helper
(
const
pyb_spi_obj_t
*
self
,
mp_uint_t
n_args
,
const
mp_obj_t
*
pos_args
,
mp_map_t
*
kw_args
)
{
static
const
mp_arg_t
allowed_args
[]
=
{
{
MP_QSTR_mode
,
MP_ARG_REQUIRED
|
MP_ARG_INT
,
{.
u_int
=
0
}
},
{
MP_QSTR_mode
,
MP_ARG_REQUIRED
|
MP_ARG_INT
,
{.
u_int
=
0
}
},
{
MP_QSTR_baudrate
,
MP_ARG_INT
,
{.
u_int
=
328125
}
},
{
MP_QSTR_baudrate
,
MP_ARG_INT
,
{.
u_int
=
328125
}
},
{
MP_QSTR_polarity
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
1
}
},
{
MP_QSTR_polarity
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
1
}
},
...
@@ -250,16 +378,14 @@ STATIC const mp_arg_t pyb_spi_init_args[] = {
...
@@ -250,16 +378,14 @@ STATIC const mp_arg_t pyb_spi_init_args[] = {
{
MP_QSTR_ti
,
MP_ARG_KW_ONLY
|
MP_ARG_BOOL
,
{.
u_bool
=
false
}
},
{
MP_QSTR_ti
,
MP_ARG_KW_ONLY
|
MP_ARG_BOOL
,
{.
u_bool
=
false
}
},
{
MP_QSTR_crc
,
MP_ARG_KW_ONLY
|
MP_ARG_OBJ
,
{.
u_obj
=
mp_const_none
}
},
{
MP_QSTR_crc
,
MP_ARG_KW_ONLY
|
MP_ARG_OBJ
,
{.
u_obj
=
mp_const_none
}
},
};
};
#define PYB_SPI_INIT_NUM_ARGS MP_ARRAY_SIZE(pyb_spi_init_args)
STATIC
mp_obj_t
pyb_spi_init_helper
(
const
pyb_spi_obj_t
*
self
,
mp_uint_t
n_args
,
const
mp_obj_t
*
args
,
mp_map_t
*
kw_args
)
{
// parse args
// parse args
mp_arg_val_t
vals
[
PYB_SPI_INIT_NUM_ARGS
];
mp_arg_val_t
args
[
MP_ARRAY_SIZE
(
allowed_args
)
];
mp_arg_parse_all
(
n_args
,
args
,
kw_args
,
PYB_SPI_INIT_NUM_ARGS
,
pyb_spi_init
_args
,
val
s
);
mp_arg_parse_all
(
n_args
,
pos_
args
,
kw_args
,
MP_ARRAY_SIZE
(
allowed_args
),
allowed
_args
,
arg
s
);
// set the SPI configuration values
// set the SPI configuration values
SPI_InitTypeDef
*
init
=
&
self
->
spi
->
Init
;
SPI_InitTypeDef
*
init
=
&
self
->
spi
->
Init
;
init
->
Mode
=
val
s
[
0
].
u_int
;
init
->
Mode
=
arg
s
[
0
].
u_int
;
// compute the baudrate prescaler from the requested baudrate
// compute the baudrate prescaler from the requested baudrate
// select a prescaler that yields at most the requested baudrate
// select a prescaler that yields at most the requested baudrate
...
@@ -271,7 +397,7 @@ STATIC mp_obj_t pyb_spi_init_helper(const pyb_spi_obj_t *self, mp_uint_t n_args,
...
@@ -271,7 +397,7 @@ STATIC mp_obj_t pyb_spi_init_helper(const pyb_spi_obj_t *self, mp_uint_t n_args,
// SPI2 and SPI3 are on APB1
// SPI2 and SPI3 are on APB1
spi_clock
=
HAL_RCC_GetPCLK1Freq
();
spi_clock
=
HAL_RCC_GetPCLK1Freq
();
}
}
uint
br_prescale
=
spi_clock
/
val
s
[
1
].
u_int
;
uint
br_prescale
=
spi_clock
/
arg
s
[
1
].
u_int
;
if
(
br_prescale
<=
2
)
{
init
->
BaudRatePrescaler
=
SPI_BAUDRATEPRESCALER_2
;
}
if
(
br_prescale
<=
2
)
{
init
->
BaudRatePrescaler
=
SPI_BAUDRATEPRESCALER_2
;
}
else
if
(
br_prescale
<=
4
)
{
init
->
BaudRatePrescaler
=
SPI_BAUDRATEPRESCALER_4
;
}
else
if
(
br_prescale
<=
4
)
{
init
->
BaudRatePrescaler
=
SPI_BAUDRATEPRESCALER_4
;
}
else
if
(
br_prescale
<=
8
)
{
init
->
BaudRatePrescaler
=
SPI_BAUDRATEPRESCALER_8
;
}
else
if
(
br_prescale
<=
8
)
{
init
->
BaudRatePrescaler
=
SPI_BAUDRATEPRESCALER_8
;
}
...
@@ -281,19 +407,19 @@ STATIC mp_obj_t pyb_spi_init_helper(const pyb_spi_obj_t *self, mp_uint_t n_args,
...
@@ -281,19 +407,19 @@ STATIC mp_obj_t pyb_spi_init_helper(const pyb_spi_obj_t *self, mp_uint_t n_args,
else
if
(
br_prescale
<=
128
)
{
init
->
BaudRatePrescaler
=
SPI_BAUDRATEPRESCALER_128
;
}
else
if
(
br_prescale
<=
128
)
{
init
->
BaudRatePrescaler
=
SPI_BAUDRATEPRESCALER_128
;
}
else
{
init
->
BaudRatePrescaler
=
SPI_BAUDRATEPRESCALER_256
;
}
else
{
init
->
BaudRatePrescaler
=
SPI_BAUDRATEPRESCALER_256
;
}
init
->
CLKPolarity
=
val
s
[
2
].
u_int
==
0
?
SPI_POLARITY_LOW
:
SPI_POLARITY_HIGH
;
init
->
CLKPolarity
=
arg
s
[
2
].
u_int
==
0
?
SPI_POLARITY_LOW
:
SPI_POLARITY_HIGH
;
init
->
CLKPhase
=
val
s
[
3
].
u_int
==
0
?
SPI_PHASE_1EDGE
:
SPI_PHASE_2EDGE
;
init
->
CLKPhase
=
arg
s
[
3
].
u_int
==
0
?
SPI_PHASE_1EDGE
:
SPI_PHASE_2EDGE
;
init
->
Direction
=
val
s
[
4
].
u_int
;
init
->
Direction
=
arg
s
[
4
].
u_int
;
init
->
DataSize
=
(
val
s
[
5
].
u_int
==
16
)
?
SPI_DATASIZE_16BIT
:
SPI_DATASIZE_8BIT
;
init
->
DataSize
=
(
arg
s
[
5
].
u_int
==
16
)
?
SPI_DATASIZE_16BIT
:
SPI_DATASIZE_8BIT
;
init
->
NSS
=
val
s
[
6
].
u_int
;
init
->
NSS
=
arg
s
[
6
].
u_int
;
init
->
FirstBit
=
val
s
[
7
].
u_int
;
init
->
FirstBit
=
arg
s
[
7
].
u_int
;
init
->
TIMode
=
val
s
[
8
].
u_bool
?
SPI_TIMODE_ENABLED
:
SPI_TIMODE_DISABLED
;
init
->
TIMode
=
arg
s
[
8
].
u_bool
?
SPI_TIMODE_ENABLED
:
SPI_TIMODE_DISABLED
;
if
(
val
s
[
9
].
u_obj
==
mp_const_none
)
{
if
(
arg
s
[
9
].
u_obj
==
mp_const_none
)
{
init
->
CRCCalculation
=
SPI_CRCCALCULATION_DISABLED
;
init
->
CRCCalculation
=
SPI_CRCCALCULATION_DISABLED
;
init
->
CRCPolynomial
=
0
;
init
->
CRCPolynomial
=
0
;
}
else
{
}
else
{
init
->
CRCCalculation
=
SPI_CRCCALCULATION_ENABLED
;
init
->
CRCCalculation
=
SPI_CRCCALCULATION_ENABLED
;
init
->
CRCPolynomial
=
mp_obj_get_int
(
val
s
[
9
].
u_obj
);
init
->
CRCPolynomial
=
mp_obj_get_int
(
arg
s
[
9
].
u_obj
);
}
}
// init the SPI bus
// init the SPI bus
...
@@ -363,28 +489,34 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_spi_deinit_obj, pyb_spi_deinit);
...
@@ -363,28 +489,34 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_spi_deinit_obj, pyb_spi_deinit);
/// - `timeout` is the timeout in milliseconds to wait for the send.
/// - `timeout` is the timeout in milliseconds to wait for the send.
///
///
/// Return value: `None`.
/// Return value: `None`.
STATIC
const
mp_arg_t
pyb_spi_send_args
[]
=
{
STATIC
mp_obj_t
pyb_spi_send
(
mp_uint_t
n_args
,
const
mp_obj_t
*
pos_args
,
mp_map_t
*
kw_args
)
{
// TODO assumes transmission size is 8-bits wide
static
const
mp_arg_t
allowed_args
[]
=
{
{
MP_QSTR_send
,
MP_ARG_REQUIRED
|
MP_ARG_OBJ
,
{.
u_obj
=
MP_OBJ_NULL
}
},
{
MP_QSTR_send
,
MP_ARG_REQUIRED
|
MP_ARG_OBJ
,
{.
u_obj
=
MP_OBJ_NULL
}
},
{
MP_QSTR_timeout
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
5000
}
},
{
MP_QSTR_timeout
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
5000
}
},
};
};
#define PYB_SPI_SEND_NUM_ARGS MP_ARRAY_SIZE(pyb_spi_send_args)
STATIC
mp_obj_t
pyb_spi_send
(
mp_uint_t
n_args
,
const
mp_obj_t
*
args
,
mp_map_t
*
kw_args
)
{
// TODO assumes transmission size is 8-bits wide
pyb_spi_obj_t
*
self
=
args
[
0
];
// parse args
// parse args
mp_arg_val_t
vals
[
PYB_SPI_SEND_NUM_ARGS
];
pyb_spi_obj_t
*
self
=
pos_args
[
0
];
mp_arg_parse_all
(
n_args
-
1
,
args
+
1
,
kw_args
,
PYB_SPI_SEND_NUM_ARGS
,
pyb_spi_send_args
,
vals
);
mp_arg_val_t
args
[
MP_ARRAY_SIZE
(
allowed_args
)];
mp_arg_parse_all
(
n_args
-
1
,
pos_args
+
1
,
kw_args
,
MP_ARRAY_SIZE
(
allowed_args
),
allowed_args
,
args
);
// get the buffer to send from
// get the buffer to send from
mp_buffer_info_t
bufinfo
;
mp_buffer_info_t
bufinfo
;
uint8_t
data
[
1
];
uint8_t
data
[
1
];
pyb_buf_get_for_send
(
val
s
[
0
].
u_obj
,
&
bufinfo
,
data
);
pyb_buf_get_for_send
(
arg
s
[
0
].
u_obj
,
&
bufinfo
,
data
);
// send the data
// send the data
HAL_StatusTypeDef
status
=
HAL_SPI_Transmit
(
self
->
spi
,
bufinfo
.
buf
,
bufinfo
.
len
,
vals
[
1
].
u_int
);
HAL_StatusTypeDef
status
;
if
(
query_irq
()
==
IRQ_STATE_DISABLED
)
{
status
=
HAL_SPI_Transmit
(
self
->
spi
,
bufinfo
.
buf
,
bufinfo
.
len
,
args
[
1
].
u_int
);
}
else
{
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
);
}
}
if
(
status
!=
HAL_OK
)
{
if
(
status
!=
HAL_OK
)
{
mp_hal_raise
(
status
);
mp_hal_raise
(
status
);
...
@@ -404,27 +536,33 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_send_obj, 1, pyb_spi_send);
...
@@ -404,27 +536,33 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_send_obj, 1, pyb_spi_send);
///
///
/// Return value: if `recv` is an integer then a new buffer of the bytes received,
/// Return value: if `recv` is an integer then a new buffer of the bytes received,
/// otherwise the same buffer that was passed in to `recv`.
/// otherwise the same buffer that was passed in to `recv`.
STATIC
const
mp_arg_t
pyb_spi_recv_args
[]
=
{
STATIC
mp_obj_t
pyb_spi_recv
(
mp_uint_t
n_args
,
const
mp_obj_t
*
pos_args
,
mp_map_t
*
kw_args
)
{
// TODO assumes transmission size is 8-bits wide
static
const
mp_arg_t
allowed_args
[]
=
{
{
MP_QSTR_recv
,
MP_ARG_REQUIRED
|
MP_ARG_OBJ
,
{.
u_obj
=
MP_OBJ_NULL
}
},
{
MP_QSTR_recv
,
MP_ARG_REQUIRED
|
MP_ARG_OBJ
,
{.
u_obj
=
MP_OBJ_NULL
}
},
{
MP_QSTR_timeout
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
5000
}
},
{
MP_QSTR_timeout
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
5000
}
},
};
};
#define PYB_SPI_RECV_NUM_ARGS MP_ARRAY_SIZE(pyb_spi_recv_args)
STATIC
mp_obj_t
pyb_spi_recv
(
mp_uint_t
n_args
,
const
mp_obj_t
*
args
,
mp_map_t
*
kw_args
)
{
// TODO assumes transmission size is 8-bits wide
pyb_spi_obj_t
*
self
=
args
[
0
];
// parse args
// parse args
mp_arg_val_t
vals
[
PYB_SPI_RECV_NUM_ARGS
];
pyb_spi_obj_t
*
self
=
pos_args
[
0
];
mp_arg_parse_all
(
n_args
-
1
,
args
+
1
,
kw_args
,
PYB_SPI_RECV_NUM_ARGS
,
pyb_spi_recv_args
,
vals
);
mp_arg_val_t
args
[
MP_ARRAY_SIZE
(
allowed_args
)];
mp_arg_parse_all
(
n_args
-
1
,
pos_args
+
1
,
kw_args
,
MP_ARRAY_SIZE
(
allowed_args
),
allowed_args
,
args
);
// get the buffer to receive into
// get the buffer to receive into
mp_buffer_info_t
bufinfo
;
mp_buffer_info_t
bufinfo
;
mp_obj_t
o_ret
=
pyb_buf_get_for_recv
(
val
s
[
0
].
u_obj
,
&
bufinfo
);
mp_obj_t
o_ret
=
pyb_buf_get_for_recv
(
arg
s
[
0
].
u_obj
,
&
bufinfo
);
// receive the data
// receive the data
HAL_StatusTypeDef
status
=
HAL_SPI_Receive
(
self
->
spi
,
bufinfo
.
buf
,
bufinfo
.
len
,
vals
[
1
].
u_int
);
HAL_StatusTypeDef
status
;
if
(
query_irq
()
==
IRQ_STATE_DISABLED
)
{
status
=
HAL_SPI_Receive
(
self
->
spi
,
bufinfo
.
buf
,
bufinfo
.
len
,
args
[
1
].
u_int
);
}
else
{
status
=
HAL_SPI_Receive_DMA
(
self
->
spi
,
bufinfo
.
buf
,
bufinfo
.
len
);
if
(
status
==
HAL_OK
)
{
status
=
spi_wait_dma_finished
(
self
->
spi
,
args
[
1
].
u_int
);
}
}
if
(
status
!=
HAL_OK
)
{
if
(
status
!=
HAL_OK
)
{
mp_hal_raise
(
status
);
mp_hal_raise
(
status
);
...
@@ -432,7 +570,7 @@ STATIC mp_obj_t pyb_spi_recv(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *k
...
@@ -432,7 +570,7 @@ STATIC mp_obj_t pyb_spi_recv(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *k
// return the received data
// return the received data
if
(
o_ret
==
MP_OBJ_NULL
)
{
if
(
o_ret
==
MP_OBJ_NULL
)
{
return
val
s
[
0
].
u_obj
;
return
arg
s
[
0
].
u_obj
;
}
else
{
}
else
{
return
mp_obj_str_builder_end
(
o_ret
);
return
mp_obj_str_builder_end
(
o_ret
);
}
}
...
@@ -450,21 +588,19 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_recv_obj, 1, pyb_spi_recv);
...
@@ -450,21 +588,19 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_recv_obj, 1, pyb_spi_recv);
/// - `timeout` is the timeout in milliseconds to wait for the receive.
/// - `timeout` is the timeout in milliseconds to wait for the receive.
///
///
/// Return value: the buffer with the received bytes.
/// Return value: the buffer with the received bytes.
STATIC
const
mp_arg_t
pyb_spi_send_recv_args
[]
=
{
STATIC
mp_obj_t
pyb_spi_send_recv
(
mp_uint_t
n_args
,
const
mp_obj_t
*
pos_args
,
mp_map_t
*
kw_args
)
{
// TODO assumes transmission size is 8-bits wide
static
const
mp_arg_t
allowed_args
[]
=
{
{
MP_QSTR_send
,
MP_ARG_REQUIRED
|
MP_ARG_OBJ
,
{.
u_obj
=
MP_OBJ_NULL
}
},
{
MP_QSTR_send
,
MP_ARG_REQUIRED
|
MP_ARG_OBJ
,
{.
u_obj
=
MP_OBJ_NULL
}
},
{
MP_QSTR_recv
,
MP_ARG_OBJ
,
{.
u_obj
=
MP_OBJ_NULL
}
},
{
MP_QSTR_recv
,
MP_ARG_OBJ
,
{.
u_obj
=
MP_OBJ_NULL
}
},
{
MP_QSTR_timeout
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
5000
}
},
{
MP_QSTR_timeout
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
5000
}
},
};
};
#define PYB_SPI_SEND_RECV_NUM_ARGS MP_ARRAY_SIZE(pyb_spi_send_recv_args)
STATIC
mp_obj_t
pyb_spi_send_recv
(
mp_uint_t
n_args
,
const
mp_obj_t
*
args
,
mp_map_t
*
kw_args
)
{
// TODO assumes transmission size is 8-bits wide
pyb_spi_obj_t
*
self
=
args
[
0
];
// parse args
// parse args
mp_arg_val_t
vals
[
PYB_SPI_SEND_RECV_NUM_ARGS
];
pyb_spi_obj_t
*
self
=
pos_args
[
0
];
mp_arg_parse_all
(
n_args
-
1
,
args
+
1
,
kw_args
,
PYB_SPI_SEND_RECV_NUM_ARGS
,
pyb_spi_send_recv_args
,
vals
);
mp_arg_val_t
args
[
MP_ARRAY_SIZE
(
allowed_args
)];
mp_arg_parse_all
(
n_args
-
1
,
pos_args
+
1
,
kw_args
,
MP_ARRAY_SIZE
(
allowed_args
),
allowed_args
,
args
);
// get buffers to send from/receive to
// get buffers to send from/receive to
mp_buffer_info_t
bufinfo_send
;
mp_buffer_info_t
bufinfo_send
;
...
@@ -472,24 +608,24 @@ STATIC mp_obj_t pyb_spi_send_recv(mp_uint_t n_args, const mp_obj_t *args, mp_map
...
@@ -472,24 +608,24 @@ STATIC mp_obj_t pyb_spi_send_recv(mp_uint_t n_args, const mp_obj_t *args, mp_map
mp_buffer_info_t
bufinfo_recv
;
mp_buffer_info_t
bufinfo_recv
;
mp_obj_t
o_ret
;
mp_obj_t
o_ret
;
if
(
val
s
[
0
].
u_obj
==
val
s
[
1
].
u_obj
)
{
if
(
arg
s
[
0
].
u_obj
==
arg
s
[
1
].
u_obj
)
{
// same object for send and receive, it must be a r/w buffer
// same object for send and receive, it must be a r/w buffer
mp_get_buffer_raise
(
val
s
[
0
].
u_obj
,
&
bufinfo_send
,
MP_BUFFER_RW
);
mp_get_buffer_raise
(
arg
s
[
0
].
u_obj
,
&
bufinfo_send
,
MP_BUFFER_RW
);
bufinfo_recv
=
bufinfo_send
;
bufinfo_recv
=
bufinfo_send
;
o_ret
=
MP_OBJ_NULL
;
o_ret
=
MP_OBJ_NULL
;
}
else
{
}
else
{
// get the buffer to send from
// get the buffer to send from
pyb_buf_get_for_send
(
val
s
[
0
].
u_obj
,
&
bufinfo_send
,
data_send
);
pyb_buf_get_for_send
(
arg
s
[
0
].
u_obj
,
&
bufinfo_send
,
data_send
);
// get the buffer to receive into
// get the buffer to receive into
if
(
val
s
[
1
].
u_obj
==
MP_OBJ_NULL
)
{
if
(
arg
s
[
1
].
u_obj
==
MP_OBJ_NULL
)
{
// only send argument given, so create a fresh buffer of the send length
// only send argument given, so create a fresh buffer of the send length
bufinfo_recv
.
len
=
bufinfo_send
.
len
;
bufinfo_recv
.
len
=
bufinfo_send
.
len
;
bufinfo_recv
.
typecode
=
'B'
;
bufinfo_recv
.
typecode
=
'B'
;
o_ret
=
mp_obj_str_builder_start
(
&
mp_type_bytes
,
bufinfo_recv
.
len
,
(
byte
**
)
&
bufinfo_recv
.
buf
);
o_ret
=
mp_obj_str_builder_start
(
&
mp_type_bytes
,
bufinfo_recv
.
len
,
(
byte
**
)
&
bufinfo_recv
.
buf
);
}
else
{
}
else
{
// recv argument given
// recv argument given
mp_get_buffer_raise
(
val
s
[
1
].
u_obj
,
&
bufinfo_recv
,
MP_BUFFER_WRITE
);
mp_get_buffer_raise
(
arg
s
[
1
].
u_obj
,
&
bufinfo_recv
,
MP_BUFFER_WRITE
);
if
(
bufinfo_recv
.
len
!=
bufinfo_send
.
len
)
{
if
(
bufinfo_recv
.
len
!=
bufinfo_send
.
len
)
{
nlr_raise
(
mp_obj_new_exception_msg
(
&
mp_type_ValueError
,
"recv must be same length as send"
));
nlr_raise
(
mp_obj_new_exception_msg
(
&
mp_type_ValueError
,
"recv must be same length as send"
));
}
}
...
@@ -498,7 +634,15 @@ STATIC mp_obj_t pyb_spi_send_recv(mp_uint_t n_args, const mp_obj_t *args, mp_map
...
@@ -498,7 +634,15 @@ STATIC mp_obj_t pyb_spi_send_recv(mp_uint_t n_args, const mp_obj_t *args, mp_map
}
}
// send and receive the data
// send and receive the data
HAL_StatusTypeDef
status
=
HAL_SPI_TransmitReceive
(
self
->
spi
,
bufinfo_send
.
buf
,
bufinfo_recv
.
buf
,
bufinfo_send
.
len
,
vals
[
2
].
u_int
);
HAL_StatusTypeDef
status
;
if
(
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
{
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
);
}
}
if
(
status
!=
HAL_OK
)
{
if
(
status
!=
HAL_OK
)
{
mp_hal_raise
(
status
);
mp_hal_raise
(
status
);
...
@@ -506,7 +650,7 @@ STATIC mp_obj_t pyb_spi_send_recv(mp_uint_t n_args, const mp_obj_t *args, mp_map
...
@@ -506,7 +650,7 @@ STATIC mp_obj_t pyb_spi_send_recv(mp_uint_t n_args, const mp_obj_t *args, mp_map
// return the received data
// return the received data
if
(
o_ret
==
MP_OBJ_NULL
)
{
if
(
o_ret
==
MP_OBJ_NULL
)
{
return
val
s
[
1
].
u_obj
;
return
arg
s
[
1
].
u_obj
;
}
else
{
}
else
{
return
mp_obj_str_builder_end
(
o_ret
);
return
mp_obj_str_builder_end
(
o_ret
);
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
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!
Save comment
Cancel
Please
register
or
sign in
to comment