1
+ use core:: ops:: Deref ;
1
2
use core:: ptr;
2
3
3
4
use nb;
@@ -72,41 +73,71 @@ spi_pins! {
72
73
}
73
74
}
74
75
76
+ macro_rules! spi {
77
+ ( $( $SPI: ident: ( $spi: ident, $spiXen: ident, $spiXrst: ident, $apbrstr: ident, $apbenr: ident) , ) +) => {
78
+ $(
79
+ use crate :: stm32:: $SPI;
80
+ impl <SCKPIN , MISOPIN , MOSIPIN > Spi <SPI1 , SCKPIN , MISOPIN , MOSIPIN > {
81
+ pub fn $spi<F >(
82
+ spi: $SPI,
83
+ pins: ( SCKPIN , MISOPIN , MOSIPIN ) ,
84
+ mode: Mode ,
85
+ speed: F ,
86
+ clocks: Clocks ,
87
+ ) -> Self
88
+ where
89
+ SCKPIN : SckPin <$SPI>,
90
+ MISOPIN : MisoPin <$SPI>,
91
+ MOSIPIN : MosiPin <$SPI>,
92
+ F : Into <Hertz >,
93
+ {
94
+ // NOTE(unsafe) This executes only during initialisation
95
+ let rcc = unsafe { & ( * RCC :: ptr( ) ) } ;
96
+
97
+ /* Enable clock for SPI1 */
98
+ rcc. $apbenr. modify( |_, w| w. $spiXen( ) . set_bit( ) ) ;
99
+
100
+ /* Reset SPI1 */
101
+ rcc. $apbrstr. modify( |_, w| w. $spiXrst( ) . set_bit( ) ) ;
102
+ rcc. $apbrstr. modify( |_, w| w. $spiXrst( ) . clear_bit( ) ) ;
103
+ Spi { spi, pins } . spi_init( mode, speed, clocks)
104
+ }
105
+ }
106
+ ) +
107
+ }
108
+ }
75
109
#[ cfg( any( feature = "stm32f042" , feature = "stm32f030" ) ) ]
76
- impl < SCKPIN , MISOPIN , MOSIPIN > Spi < SPI1 , SCKPIN , MISOPIN , MOSIPIN > {
77
- pub fn spi1 < F > (
78
- spi : SPI1 ,
79
- pins : ( SCKPIN , MISOPIN , MOSIPIN ) ,
80
- mode : Mode ,
81
- speed : F ,
82
- clocks : Clocks ,
83
- ) -> Self
110
+ spi ! {
111
+ SPI1 : ( spi1, spi1en, spi1rst, apb2enr, apb2rstr) ,
112
+ }
113
+ #[ cfg( any( feature = "stm32f030x8" , feature = "stm32f030xc" ) ) ]
114
+ spi ! {
115
+ SPI2 : ( spi2, spi2en, spi2rst, apb1enr, apb1rstr) ,
116
+ }
117
+
118
+ // It's s needed for the impls, but rustc doesn't recognize that
119
+ #[ allow( dead_code) ]
120
+ type SpiRegisterBlock = stm32:: spi1:: RegisterBlock ;
121
+
122
+ impl < SPI , SCKPIN , MISOPIN , MOSIPIN > Spi < SPI , SCKPIN , MISOPIN , MOSIPIN >
123
+ where
124
+ SPI : Deref < Target = SpiRegisterBlock > ,
125
+ {
126
+ fn spi_init < F > ( self : Self , mode : Mode , speed : F , clocks : Clocks ) -> Self
84
127
where
85
- SCKPIN : SckPin < SPI1 > ,
86
- MISOPIN : MisoPin < SPI1 > ,
87
- MOSIPIN : MosiPin < SPI1 > ,
88
128
F : Into < Hertz > ,
89
129
{
90
- // NOTE(unsafe) This executes only during initialisation
91
- let rcc = unsafe { & ( * RCC :: ptr ( ) ) } ;
92
-
93
- /* Enable clock for SPI1 */
94
- rcc. apb2enr . modify ( |_, w| w. spi1en ( ) . set_bit ( ) ) ;
95
-
96
- /* Reset SPI1 */
97
- rcc. apb2rstr . modify ( |_, w| w. spi1rst ( ) . set_bit ( ) ) ;
98
- rcc. apb2rstr . modify ( |_, w| w. spi1rst ( ) . clear_bit ( ) ) ;
99
-
100
130
/* Make sure the SPI unit is disabled so we can configure it */
101
- spi. cr1 . modify ( |_, w| w. spe ( ) . clear_bit ( ) ) ;
131
+ self . spi . cr1 . modify ( |_, w| w. spe ( ) . clear_bit ( ) ) ;
102
132
103
133
// FRXTH: 8-bit threshold on RX FIFO
104
134
// DS: 8-bit data size
105
135
// SSOE: cleared to disable SS output
106
136
//
107
137
// NOTE(unsafe): DS reserved bit patterns are 0b0000, 0b0001, and 0b0010. 0b0111 is valid
108
138
// (reference manual, pp 804)
109
- spi. cr2
139
+ self . spi
140
+ . cr2
110
141
. write ( |w| unsafe { w. frxth ( ) . set_bit ( ) . ds ( ) . bits ( 0b0111 ) . ssoe ( ) . clear_bit ( ) } ) ;
111
142
112
143
let br = match clocks. pclk ( ) . 0 / speed. into ( ) . 0 {
@@ -128,7 +159,7 @@ impl<SCKPIN, MISOPIN, MOSIPIN> Spi<SPI1, SCKPIN, MISOPIN, MOSIPIN> {
128
159
// dff: 8 bit frames
129
160
// bidimode: 2-line unidirectional
130
161
// spe: enable the SPI bus
131
- spi. cr1 . write ( |w| unsafe {
162
+ self . spi . cr1 . write ( |w| unsafe {
132
163
w. cpha ( )
133
164
. bit ( mode. phase == Phase :: CaptureOnSecondTransition )
134
165
. cpol ( )
@@ -151,17 +182,17 @@ impl<SCKPIN, MISOPIN, MOSIPIN> Spi<SPI1, SCKPIN, MISOPIN, MOSIPIN> {
151
182
. set_bit ( )
152
183
} ) ;
153
184
154
- Spi { spi , pins }
185
+ self
155
186
}
156
-
157
- pub fn release ( self ) -> ( SPI1 , ( SCKPIN , MISOPIN , MOSIPIN ) ) {
187
+ pub fn release ( self ) -> ( SPI , ( SCKPIN , MISOPIN , MOSIPIN ) ) {
158
188
( self . spi , self . pins )
159
189
}
160
190
}
161
191
162
- #[ cfg( any( feature = "stm32f042" , feature = "stm32f030" ) ) ]
163
- impl < SCKPIN , MISOPIN , MOSIPIN > :: embedded_hal:: spi:: FullDuplex < u8 >
164
- for Spi < SPI1 , SCKPIN , MISOPIN , MOSIPIN >
192
+ impl < SPI , SCKPIN , MISOPIN , MOSIPIN > :: embedded_hal:: spi:: FullDuplex < u8 >
193
+ for Spi < SPI , SCKPIN , MISOPIN , MOSIPIN >
194
+ where
195
+ SPI : Deref < Target = SpiRegisterBlock > ,
165
196
{
166
197
type Error = Error ;
167
198
@@ -202,13 +233,15 @@ impl<SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::spi::FullDuplex<u8>
202
233
}
203
234
}
204
235
205
- #[ cfg( any( feature = "stm32f042" , feature = "stm32f030" ) ) ]
206
- impl < SCKPIN , MISOPIN , MOSIPIN > :: embedded_hal:: blocking:: spi:: transfer:: Default < u8 >
207
- for Spi < SPI1 , SCKPIN , MISOPIN , MOSIPIN >
236
+ impl < SPI , SCKPIN , MISOPIN , MOSIPIN > :: embedded_hal:: blocking:: spi:: transfer:: Default < u8 >
237
+ for Spi < SPI , SCKPIN , MISOPIN , MOSIPIN >
238
+ where
239
+ SPI : Deref < Target = SpiRegisterBlock > ,
208
240
{
209
241
}
210
- #[ cfg( any( feature = "stm32f042" , feature = "stm32f030" ) ) ]
211
- impl < SCKPIN , MISOPIN , MOSIPIN > :: embedded_hal:: blocking:: spi:: write:: Default < u8 >
212
- for Spi < SPI1 , SCKPIN , MISOPIN , MOSIPIN >
242
+ impl < SPI , SCKPIN , MISOPIN , MOSIPIN > :: embedded_hal:: blocking:: spi:: write:: Default < u8 >
243
+ for Spi < SPI , SCKPIN , MISOPIN , MOSIPIN >
244
+ where
245
+ SPI : Deref < Target = SpiRegisterBlock > ,
213
246
{
214
247
}
0 commit comments