@@ -117,6 +117,9 @@ fn convert_rgb_channel_to_pulses(
117
117
118
118
/// Function to calculate the required RMT buffer size for a given number of LEDs when using
119
119
/// the blocking API.
120
+ ///
121
+ /// This buffer size is calculated for the synchronous API provided by the [SmartLedsAdapter].
122
+ /// [buffer_size_async] should be used for the asynchronous API.
120
123
pub const fn buffer_size ( num_leds : usize ) -> usize {
121
124
// 1 additional pulse for the end delimiter
122
125
num_leds * RMT_RAM_ONE_LED + 1
@@ -225,104 +228,96 @@ where
225
228
}
226
229
227
230
/// Support for asynchronous and non-blocking use of the RMT peripheral to drive smart LEDs.
228
- pub mod asynch {
229
- use super :: * ;
230
- use esp_hal:: {
231
- clock:: Clocks ,
232
- gpio:: OutputPin ,
233
- peripheral:: Peripheral ,
234
- rmt:: { TxChannelAsync , TxChannelCreatorAsync } ,
235
- } ;
236
231
237
- /// Function to calculate the required RMT buffer size for a given number of LEDs when using
238
- /// the asynchronous API.
239
- pub const fn buffer_size ( num_leds : usize ) -> usize {
240
- // 1 byte end delimiter for each transfer.
241
- num_leds * ( RMT_RAM_ONE_LED + 1 )
242
- }
232
+ /// Function to calculate the required RMT buffer size for a given number of LEDs when using
233
+ /// the asynchronous API. This buffer size is calculated for the asynchronous API provided by the
234
+ /// [SmartLedsAdapterAsync]. [buffer_size] should be used for the synchronous API.
235
+ pub const fn buffer_size_async ( num_leds : usize ) -> usize {
236
+ // 1 byte end delimiter for each transfer.
237
+ num_leds * ( RMT_RAM_ONE_LED + 1 )
238
+ }
243
239
244
- /// Adapter taking an RMT channel and a specific pin and providing RGB LED
245
- /// interaction functionality.
246
- pub struct SmartLedAdapterAsync < Tx , const BUFFER_SIZE : usize > {
247
- channel : Tx ,
240
+ /// Adapter taking an RMT channel and a specific pin and providing RGB LED
241
+ /// interaction functionality.
242
+ pub struct SmartLedsAdapterAsync < Tx , const BUFFER_SIZE : usize > {
243
+ channel : Tx ,
244
+ rmt_buffer : [ u32 ; BUFFER_SIZE ] ,
245
+ pulses : ( u32 , u32 ) ,
246
+ }
247
+
248
+ impl < ' d , Tx : TxChannelAsync , const BUFFER_SIZE : usize > SmartLedsAdapterAsync < Tx , BUFFER_SIZE > {
249
+ /// Create a new adapter object that drives the pin using the RMT channel.
250
+ pub fn new < C , O > (
251
+ channel : C ,
252
+ pin : impl Peripheral < P = O > + ' d ,
248
253
rmt_buffer : [ u32 ; BUFFER_SIZE ] ,
249
- pulses : ( u32 , u32 ) ,
250
- }
254
+ ) -> SmartLedsAdapterAsync < Tx , BUFFER_SIZE >
255
+ where
256
+ O : OutputPin + ' d ,
257
+ C : TxChannelCreatorAsync < ' d , Tx , O > ,
258
+ {
259
+ let channel = channel. configure ( pin, led_config ( ) ) . unwrap ( ) ;
251
260
252
- impl < ' d , Tx : TxChannelAsync , const BUFFER_SIZE : usize > SmartLedAdapterAsync < Tx , BUFFER_SIZE > {
253
- /// Create a new adapter object that drives the pin using the RMT channel.
254
- pub fn new < C , O > (
255
- channel : C ,
256
- pin : impl Peripheral < P = O > + ' d ,
257
- rmt_buffer : [ u32 ; BUFFER_SIZE ] ,
258
- ) -> SmartLedAdapterAsync < Tx , BUFFER_SIZE >
259
- where
260
- O : OutputPin + ' d ,
261
- C : TxChannelCreatorAsync < ' d , Tx , O > ,
262
- {
263
- let channel = channel. configure ( pin, led_config ( ) ) . unwrap ( ) ;
264
-
265
- // Assume the RMT peripheral is set up to use the APB clock
266
- let src_clock = Clocks :: get ( ) . apb_clock . to_MHz ( ) ;
267
-
268
- Self {
269
- channel,
270
- rmt_buffer,
271
- pulses : led_pulses_for_clock ( src_clock) ,
272
- }
273
- }
261
+ // Assume the RMT peripheral is set up to use the APB clock
262
+ let src_clock = Clocks :: get ( ) . apb_clock . to_MHz ( ) ;
274
263
275
- fn prepare_rmt_buffer < I : Into < RGB8 > > (
276
- & mut self ,
277
- iterator : impl IntoIterator < Item = I > ,
278
- ) -> Result < ( ) , LedAdapterError > {
279
- // We always start from the beginning of the buffer
280
- let mut seq_iter = self . rmt_buffer . iter_mut ( ) ;
281
-
282
- // Add all converted iterator items to the buffer.
283
- // This will result in an `BufferSizeExceeded` error in case
284
- // the iterator provides more elements than the buffer can take.
285
- for item in iterator {
286
- Self :: convert_rgb_to_pulse ( item. into ( ) , & mut seq_iter, self . pulses ) ?;
287
- }
288
- Ok ( ( ) )
264
+ Self {
265
+ channel,
266
+ rmt_buffer,
267
+ pulses : led_pulses_for_clock ( src_clock) ,
289
268
}
269
+ }
290
270
291
- /// Converts a RGB value to the correspodnign pulse value.
292
- fn convert_rgb_to_pulse (
293
- value : RGB8 ,
294
- mut_iter : & mut IterMut < u32 > ,
295
- pulses : ( u32 , u32 ) ,
296
- ) -> Result < ( ) , LedAdapterError > {
297
- convert_rgb_to_pulses ( value, mut_iter, pulses) ?;
298
- * mut_iter. next ( ) . ok_or ( LedAdapterError :: BufferSizeExceeded ) ? = 0 ;
271
+ fn prepare_rmt_buffer < I : Into < RGB8 > > (
272
+ & mut self ,
273
+ iterator : impl IntoIterator < Item = I > ,
274
+ ) -> Result < ( ) , LedAdapterError > {
275
+ // We always start from the beginning of the buffer
276
+ let mut seq_iter = self . rmt_buffer . iter_mut ( ) ;
299
277
300
- Ok ( ( ) )
278
+ // Add all converted iterator items to the buffer.
279
+ // This will result in an `BufferSizeExceeded` error in case
280
+ // the iterator provides more elements than the buffer can take.
281
+ for item in iterator {
282
+ Self :: convert_rgb_to_pulse ( item. into ( ) , & mut seq_iter, self . pulses ) ?;
301
283
}
284
+ Ok ( ( ) )
285
+ }
286
+
287
+ /// Converts a RGB value to the correspodnign pulse value.
288
+ fn convert_rgb_to_pulse (
289
+ value : RGB8 ,
290
+ mut_iter : & mut IterMut < u32 > ,
291
+ pulses : ( u32 , u32 ) ,
292
+ ) -> Result < ( ) , LedAdapterError > {
293
+ convert_rgb_to_pulses ( value, mut_iter, pulses) ?;
294
+ * mut_iter. next ( ) . ok_or ( LedAdapterError :: BufferSizeExceeded ) ? = 0 ;
295
+
296
+ Ok ( ( ) )
302
297
}
298
+ }
299
+
300
+ impl < Tx : TxChannelAsync , const BUFFER_SIZE : usize > SmartLedsWriteAsync
301
+ for SmartLedsAdapterAsync < Tx , BUFFER_SIZE >
302
+ {
303
+ type Error = LedAdapterError ;
304
+ type Color = RGB8 ;
303
305
304
- impl < Tx : TxChannelAsync , const BUFFER_SIZE : usize > SmartLedsWriteAsync
305
- for SmartLedAdapterAsync < Tx , BUFFER_SIZE >
306
+ /// Convert all RGB8 items of the iterator to the RMT format and
307
+ /// add them to internal buffer, then start perform all asynchronous operations based on
308
+ /// that buffer.
309
+ async fn write < T , I > ( & mut self , iterator : T ) -> Result < ( ) , Self :: Error >
310
+ where
311
+ T : IntoIterator < Item = I > ,
312
+ I : Into < Self :: Color > ,
306
313
{
307
- type Error = LedAdapterError ;
308
- type Color = RGB8 ;
309
-
310
- /// Convert all RGB8 items of the iterator to the RMT format and
311
- /// add them to internal buffer, then start perform all asynchronous operations based on
312
- /// that buffer.
313
- async fn write < T , I > ( & mut self , iterator : T ) -> Result < ( ) , Self :: Error >
314
- where
315
- T : IntoIterator < Item = I > ,
316
- I : Into < Self :: Color > ,
317
- {
318
- self . prepare_rmt_buffer ( iterator) ?;
319
- for chunk in self . rmt_buffer . chunks ( RMT_RAM_ONE_LED + 1 ) {
320
- self . channel
321
- . transmit ( chunk)
322
- . await
323
- . map_err ( LedAdapterError :: TransmissionError ) ?;
324
- }
325
- Ok ( ( ) )
314
+ self . prepare_rmt_buffer ( iterator) ?;
315
+ for chunk in self . rmt_buffer . chunks ( RMT_RAM_ONE_LED + 1 ) {
316
+ self . channel
317
+ . transmit ( chunk)
318
+ . await
319
+ . map_err ( LedAdapterError :: TransmissionError ) ?;
326
320
}
321
+ Ok ( ( ) )
327
322
}
328
323
}
0 commit comments