@@ -496,6 +496,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_write_obj, 2, rp2pio_statemachine
496
496
//| once: Optional[ReadableBuffer] = None,
497
497
//| *,
498
498
//| loop: Optional[ReadableBuffer] = None,
499
+ //| loop2: Optional[ReadableBuffer] = None,
499
500
//| swap: bool = False,
500
501
//| ) -> None:
501
502
//| """Write data to the TX fifo in the background, with optional looping.
@@ -504,7 +505,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_write_obj, 2, rp2pio_statemachine
504
505
//| This means that any ``once`` or ``loop`` buffer will be written at least once.
505
506
//| Then the ``once`` and/or ``loop`` buffers are queued. and the function returns.
506
507
//| The ``once`` buffer (if specified) will be written just once.
507
- //| Finally, the ``loop`` buffer (if specified) will continue being looped indefinitely.
508
+ //| Finally, the ``loop`` and/or ``loop2`` buffer (if specified) will continue being looped indefinitely. If both ``loop`` and ``loop2`` are specified, they will alternate .
508
509
//|
509
510
//| Writes to the FIFO will match the input buffer's element size. For example, bytearray elements
510
511
//| will perform 8 bit writes to the PIO FIFO. The RP2040's memory bus will duplicate the value into
@@ -531,14 +532,15 @@ MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_write_obj, 2, rp2pio_statemachine
531
532
//|
532
533
//| :param ~Optional[circuitpython_typing.ReadableBuffer] once: Data to be written once
533
534
//| :param ~Optional[circuitpython_typing.ReadableBuffer] loop: Data to be written repeatedly
535
+ //| :param ~Optional[circuitpython_typing.ReadableBuffer] loop2: Data to be written repeatedly
534
536
//| :param bool swap: For 2- and 4-byte elements, swap (reverse) the byte order
535
537
//| """
536
538
//| ...
537
539
538
- static void fill_buf_info (sm_buf_info * info , mp_obj_t obj , size_t * stride_in_bytes ) {
540
+ static void fill_buf_info (sm_buf_info * info , mp_obj_t obj , size_t * stride_in_bytes , mp_uint_t direction ) {
539
541
if (obj != mp_const_none ) {
540
542
info -> obj = obj ;
541
- mp_get_buffer_raise (obj , & info -> info , MP_BUFFER_READ );
543
+ mp_get_buffer_raise (obj , & info -> info , direction );
542
544
size_t stride = mp_binary_get_size ('@' , info -> info .typecode , NULL );
543
545
if (stride > 4 ) {
544
546
mp_raise_ValueError (MP_ERROR_TEXT ("Buffer elements must be 4 bytes long or less" ));
@@ -553,27 +555,29 @@ static void fill_buf_info(sm_buf_info *info, mp_obj_t obj, size_t *stride_in_byt
553
555
}
554
556
555
557
static mp_obj_t rp2pio_statemachine_background_write (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
556
- enum { ARG_once , ARG_loop , ARG_swap };
558
+ enum { ARG_once , ARG_loop , ARG_loop2 , ARG_swap };
557
559
static const mp_arg_t allowed_args [] = {
558
560
{ MP_QSTR_once , MP_ARG_OBJ , {.u_obj = mp_const_none } },
559
561
{ MP_QSTR_loop , MP_ARG_OBJ | MP_ARG_KW_ONLY , {.u_obj = mp_const_none } },
560
- { MP_QSTR_swap , MP_ARG_KW_ONLY | MP_ARG_BOOL , {.u_bool = false} },
562
+ { MP_QSTR_loop2 , MP_ARG_OBJ | MP_ARG_KW_ONLY , {.u_obj = mp_const_none } },
563
+ { MP_QSTR_swap , MP_ARG_KW_ONLY | MP_ARG_BOOL , {.u_bool = false} },
561
564
};
562
565
rp2pio_statemachine_obj_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
563
566
check_for_deinit (self );
564
567
mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
565
568
mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
566
569
567
- sm_buf_info once_info ;
568
- sm_buf_info loop_info ;
569
570
size_t stride_in_bytes = 0 ;
570
- fill_buf_info (& once_info , args [ARG_once ].u_obj , & stride_in_bytes );
571
- fill_buf_info (& loop_info , args [ARG_loop ].u_obj , & stride_in_bytes );
571
+
572
+ fill_buf_info (& self -> once_write_buf_info , args [ARG_once ].u_obj , & stride_in_bytes , MP_BUFFER_READ );
573
+ fill_buf_info (& self -> loop_write_buf_info , args [ARG_loop ].u_obj , & stride_in_bytes , MP_BUFFER_READ );
574
+ fill_buf_info (& self -> loop2_write_buf_info , args [ARG_loop2 ].u_obj , & stride_in_bytes , MP_BUFFER_READ );
575
+
572
576
if (!stride_in_bytes ) {
573
577
return mp_const_none ;
574
578
}
575
579
576
- bool ok = common_hal_rp2pio_statemachine_background_write (self , & once_info , & loop_info , stride_in_bytes , args [ARG_swap ].u_bool );
580
+ bool ok = common_hal_rp2pio_statemachine_background_write (self , stride_in_bytes , args [ARG_swap ].u_bool );
577
581
578
582
if (mp_hal_is_interrupted ()) {
579
583
return mp_const_none ;
@@ -602,6 +606,7 @@ static mp_obj_t rp2pio_statemachine_obj_stop_background_write(mp_obj_t self_in)
602
606
}
603
607
MP_DEFINE_CONST_FUN_OBJ_1 (rp2pio_statemachine_stop_background_write_obj , rp2pio_statemachine_obj_stop_background_write );
604
608
609
+
605
610
//| writing: bool
606
611
//| """Returns True if a background write is in progress"""
607
612
static mp_obj_t rp2pio_statemachine_obj_get_writing (mp_obj_t self_in ) {
@@ -613,18 +618,147 @@ MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_writing_obj, rp2pio_statemachi
613
618
MP_PROPERTY_GETTER (rp2pio_statemachine_writing_obj ,
614
619
(mp_obj_t )& rp2pio_statemachine_get_writing_obj );
615
620
621
+ //| pending_write: int
616
622
//| pending: int
617
623
//| """Returns the number of pending buffers for background writing.
618
624
//|
619
- //| If the number is 0, then a `StateMachine.background_write` call will not block."""
620
- static mp_obj_t rp2pio_statemachine_obj_get_pending (mp_obj_t self_in ) {
625
+ //| If the number is 0, then a `StateMachine.background_write` call will not block.
626
+ //| Note that `pending` is a deprecated alias for `pending_write` and will be removed
627
+ //| in a future version of CircuitPython."""
628
+
629
+
630
+ static mp_obj_t rp2pio_statemachine_obj_get_pending_write (mp_obj_t self_in ) {
621
631
rp2pio_statemachine_obj_t * self = MP_OBJ_TO_PTR (self_in );
622
- return mp_obj_new_int (common_hal_rp2pio_statemachine_get_pending (self ));
632
+ return mp_obj_new_int (common_hal_rp2pio_statemachine_get_pending_write (self ));
623
633
}
624
- MP_DEFINE_CONST_FUN_OBJ_1 (rp2pio_statemachine_get_pending_obj , rp2pio_statemachine_obj_get_pending );
634
+ MP_DEFINE_CONST_FUN_OBJ_1 (rp2pio_statemachine_get_pending_write_obj , rp2pio_statemachine_obj_get_pending_write );
625
635
626
636
MP_PROPERTY_GETTER (rp2pio_statemachine_pending_obj ,
627
- (mp_obj_t )& rp2pio_statemachine_get_pending_obj );
637
+ (mp_obj_t )& rp2pio_statemachine_get_pending_write_obj );
638
+
639
+ MP_PROPERTY_GETTER (rp2pio_statemachine_pending_write_obj ,
640
+ (mp_obj_t )& rp2pio_statemachine_get_pending_write_obj );
641
+
642
+
643
+ // =================================================================================================================================
644
+
645
+ //| def background_read(
646
+ //| self,
647
+ //| once: Optional[WriteableBuffer] = None,
648
+ //| *,
649
+ //| loop: Optional[WriteableBuffer] = None,
650
+ //| loop2: Optional[WriteableBuffer] = None,
651
+ //| swap: bool = False,
652
+ //| ) -> None:
653
+ //| """Read data from the RX fifo in the background, with optional looping.
654
+ //|
655
+ //| First, if any previous ``once`` or ``loop`` buffer has not been started, this function blocks until they have been started.
656
+ //| This means that any ``once`` or ``loop`` buffer will be read at least once.
657
+ //| Then the ``once`` and/or ``loop`` buffers are queued. and the function returns.
658
+ //| The ``once`` buffer (if specified) will be read just once.
659
+ //| Finally, the ``loop`` and/or ``loop2`` buffer (if specified) will continue being read indefinitely. If both ``loop`` and ``loop2`` are specified, they will alternate.
660
+ //|
661
+ //| Reads from the FIFO will match the input buffer's element size. For example, bytearray elements
662
+ //| will perform 8 bit reads from the PIO FIFO. The RP2040's memory bus will duplicate the value into
663
+ //| the other byte positions. So, pulling more data in the PIO assembly will read the duplicated values.
664
+ //|
665
+ //| To perform 16 or 32 bits reads from the FIFO use an `array.array` with a type code of the desired
666
+ //| size, or use `memoryview.cast` to change the interpretation of an
667
+ //| existing buffer. To receive just part of a larger buffer, slice a `memoryview`
668
+ //| of it.
669
+ //|
670
+ //| Most use cases will probably only use one of ``once`` or ``loop``.
671
+ //|
672
+ //| Having neither ``once`` nor ``loop`` terminates an existing
673
+ //| background looping read after exactly a whole loop. This is in contrast to
674
+ //| `stop_background_read`, which interrupts an ongoing DMA operation.
675
+ //|
676
+ //| :param ~Optional[circuitpython_typing.WriteableBuffer] once: Data to be read once
677
+ //| :param ~Optional[circuitpython_typing.WriteableBuffer] loop: Data to be read repeatedly
678
+ //| :param ~Optional[circuitpython_typing.WriteableBuffer] loop2: Data to be read repeatedly
679
+ //| :param bool swap: For 2- and 4-byte elements, swap (reverse) the byte order
680
+ //| """
681
+ //| ...
682
+
683
+
684
+ static mp_obj_t rp2pio_statemachine_background_read (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
685
+ enum { ARG_once , ARG_loop , ARG_loop2 , ARG_swap };
686
+ static const mp_arg_t allowed_args [] = {
687
+ { MP_QSTR_once , MP_ARG_OBJ , {.u_obj = mp_const_none } },
688
+ { MP_QSTR_loop , MP_ARG_OBJ | MP_ARG_KW_ONLY , {.u_obj = mp_const_none } },
689
+ { MP_QSTR_loop2 , MP_ARG_OBJ | MP_ARG_KW_ONLY , {.u_obj = mp_const_none } },
690
+ { MP_QSTR_swap , MP_ARG_KW_ONLY | MP_ARG_BOOL , {.u_bool = false} },
691
+ };
692
+ rp2pio_statemachine_obj_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
693
+ check_for_deinit (self );
694
+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
695
+ mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
696
+
697
+ size_t stride_in_bytes = 0 ;
698
+
699
+ fill_buf_info (& self -> once_read_buf_info , args [ARG_once ].u_obj , & stride_in_bytes , MP_BUFFER_WRITE );
700
+ fill_buf_info (& self -> loop_read_buf_info , args [ARG_loop ].u_obj , & stride_in_bytes , MP_BUFFER_WRITE );
701
+ fill_buf_info (& self -> loop2_read_buf_info , args [ARG_loop2 ].u_obj , & stride_in_bytes , MP_BUFFER_WRITE );
702
+
703
+ if (!stride_in_bytes ) {
704
+ return mp_const_none ;
705
+ }
706
+
707
+ bool ok = common_hal_rp2pio_statemachine_background_read (self , stride_in_bytes , args [ARG_swap ].u_bool );
708
+
709
+ if (mp_hal_is_interrupted ()) {
710
+ return mp_const_none ;
711
+ }
712
+ if (!ok ) {
713
+ mp_raise_OSError (MP_EIO );
714
+ }
715
+ return mp_const_none ;
716
+ }
717
+ MP_DEFINE_CONST_FUN_OBJ_KW (rp2pio_statemachine_background_read_obj , 1 , rp2pio_statemachine_background_read );
718
+
719
+ //| def stop_background_read(self) -> None:
720
+ //| """Immediately stop a background read, if one is in progress. Any
721
+ //| DMA in progress is halted, but items already in the RX FIFO are not
722
+ //| affected."""
723
+ static mp_obj_t rp2pio_statemachine_obj_stop_background_read (mp_obj_t self_in ) {
724
+ rp2pio_statemachine_obj_t * self = MP_OBJ_TO_PTR (self_in );
725
+ bool ok = common_hal_rp2pio_statemachine_stop_background_read (self );
726
+ if (mp_hal_is_interrupted ()) {
727
+ return mp_const_none ;
728
+ }
729
+ if (!ok ) {
730
+ mp_raise_OSError (MP_EIO );
731
+ }
732
+ return mp_const_none ;
733
+ }
734
+ MP_DEFINE_CONST_FUN_OBJ_1 (rp2pio_statemachine_stop_background_read_obj , rp2pio_statemachine_obj_stop_background_read );
735
+
736
+ //| reading: bool
737
+ //| """Returns True if a background read is in progress"""
738
+ static mp_obj_t rp2pio_statemachine_obj_get_reading (mp_obj_t self_in ) {
739
+ rp2pio_statemachine_obj_t * self = MP_OBJ_TO_PTR (self_in );
740
+ return mp_obj_new_bool (common_hal_rp2pio_statemachine_get_reading (self ));
741
+ }
742
+ MP_DEFINE_CONST_FUN_OBJ_1 (rp2pio_statemachine_get_reading_obj , rp2pio_statemachine_obj_get_reading );
743
+
744
+ MP_PROPERTY_GETTER (rp2pio_statemachine_reading_obj ,
745
+ (mp_obj_t )& rp2pio_statemachine_get_reading_obj );
746
+
747
+ //| pending_read: int
748
+ //| """Returns the number of pending buffers for background reading.
749
+ //|
750
+ //| If the number is 0, then a `StateMachine.background_read` call will not block."""
751
+ static mp_obj_t rp2pio_statemachine_obj_get_pending_read (mp_obj_t self_in ) {
752
+ rp2pio_statemachine_obj_t * self = MP_OBJ_TO_PTR (self_in );
753
+ return mp_obj_new_int (common_hal_rp2pio_statemachine_get_pending_read (self ));
754
+ }
755
+ MP_DEFINE_CONST_FUN_OBJ_1 (rp2pio_statemachine_get_pending_read_obj , rp2pio_statemachine_obj_get_pending_read );
756
+
757
+ MP_PROPERTY_GETTER (rp2pio_statemachine_pending_read_obj ,
758
+ (mp_obj_t )& rp2pio_statemachine_get_pending_read_obj );
759
+
760
+
761
+ // =================================================================================================================================
628
762
629
763
//| def readinto(
630
764
//| self,
@@ -924,6 +1058,42 @@ MP_PROPERTY_GETTER(rp2pio_statemachine_rxfifo_obj,
924
1058
(mp_obj_t )& rp2pio_statemachine_get_rxfifo_obj );
925
1059
926
1060
1061
+ //| last_read: array.array
1062
+ //| """Returns the buffer most recently filled by background reads.
1063
+ //|
1064
+ //| This property is self-clearing -- once read, subsequent reads
1065
+ //| will return a zero-length buffer until the background read buffer
1066
+ //| changes or restarts.
1067
+ //| """
1068
+ static mp_obj_t rp2pio_statemachine_obj_get_last_read (mp_obj_t self_in ) {
1069
+ rp2pio_statemachine_obj_t * self = MP_OBJ_TO_PTR (self_in );
1070
+ check_for_deinit (self );
1071
+ return common_hal_rp2pio_statemachine_get_last_read (self );
1072
+ }
1073
+ MP_DEFINE_CONST_FUN_OBJ_1 (rp2pio_statemachine_get_last_read_obj , rp2pio_statemachine_obj_get_last_read );
1074
+
1075
+ MP_PROPERTY_GETTER (rp2pio_statemachine_last_read_obj ,
1076
+ (mp_obj_t )& rp2pio_statemachine_get_last_read_obj );
1077
+
1078
+
1079
+ //| last_write: array.array
1080
+ //| """Returns the buffer most recently emptied by background writes.
1081
+ //|
1082
+ //| This property is self-clearing -- once read, subsequent reads
1083
+ //| will return a zero-length buffer until the background write buffer
1084
+ //| changes or restarts.
1085
+ //| """
1086
+ //|
1087
+ static mp_obj_t rp2pio_statemachine_obj_get_last_write (mp_obj_t self_in ) {
1088
+ rp2pio_statemachine_obj_t * self = MP_OBJ_TO_PTR (self_in );
1089
+ check_for_deinit (self );
1090
+ return common_hal_rp2pio_statemachine_get_last_write (self );
1091
+ }
1092
+ MP_DEFINE_CONST_FUN_OBJ_1 (rp2pio_statemachine_get_last_write_obj , rp2pio_statemachine_obj_get_last_write );
1093
+
1094
+ MP_PROPERTY_GETTER (rp2pio_statemachine_last_write_obj ,
1095
+ (mp_obj_t )& rp2pio_statemachine_get_last_write_obj );
1096
+
927
1097
static const mp_rom_map_elem_t rp2pio_statemachine_locals_dict_table [] = {
928
1098
{ MP_ROM_QSTR (MP_QSTR_deinit ), MP_ROM_PTR (& rp2pio_statemachine_deinit_obj ) },
929
1099
{ MP_ROM_QSTR (MP_QSTR___enter__ ), MP_ROM_PTR (& default___enter___obj ) },
@@ -938,10 +1108,17 @@ static const mp_rom_map_elem_t rp2pio_statemachine_locals_dict_table[] = {
938
1108
{ MP_ROM_QSTR (MP_QSTR_readinto ), MP_ROM_PTR (& rp2pio_statemachine_readinto_obj ) },
939
1109
{ MP_ROM_QSTR (MP_QSTR_write ), MP_ROM_PTR (& rp2pio_statemachine_write_obj ) },
940
1110
{ MP_ROM_QSTR (MP_QSTR_write_readinto ), MP_ROM_PTR (& rp2pio_statemachine_write_readinto_obj ) },
1111
+
941
1112
{ MP_ROM_QSTR (MP_QSTR_background_write ), MP_ROM_PTR (& rp2pio_statemachine_background_write_obj ) },
942
1113
{ MP_ROM_QSTR (MP_QSTR_stop_background_write ), MP_ROM_PTR (& rp2pio_statemachine_stop_background_write_obj ) },
943
1114
{ MP_ROM_QSTR (MP_QSTR_writing ), MP_ROM_PTR (& rp2pio_statemachine_writing_obj ) },
944
- { MP_ROM_QSTR (MP_QSTR_pending ), MP_ROM_PTR (& rp2pio_statemachine_pending_obj ) },
1115
+ { MP_ROM_QSTR (MP_QSTR_pending ), MP_ROM_PTR (& rp2pio_statemachine_pending_write_obj ) },
1116
+ { MP_ROM_QSTR (MP_QSTR_pending_write ), MP_ROM_PTR (& rp2pio_statemachine_pending_write_obj ) },
1117
+
1118
+ { MP_ROM_QSTR (MP_QSTR_background_read ), MP_ROM_PTR (& rp2pio_statemachine_background_read_obj ) },
1119
+ { MP_ROM_QSTR (MP_QSTR_stop_background_read ), MP_ROM_PTR (& rp2pio_statemachine_stop_background_read_obj ) },
1120
+ { MP_ROM_QSTR (MP_QSTR_reading ), MP_ROM_PTR (& rp2pio_statemachine_reading_obj ) },
1121
+ { MP_ROM_QSTR (MP_QSTR_pending_read ), MP_ROM_PTR (& rp2pio_statemachine_pending_read_obj ) },
945
1122
946
1123
{ MP_ROM_QSTR (MP_QSTR_frequency ), MP_ROM_PTR (& rp2pio_statemachine_frequency_obj ) },
947
1124
{ MP_ROM_QSTR (MP_QSTR_rxstall ), MP_ROM_PTR (& rp2pio_statemachine_rxstall_obj ) },
@@ -952,6 +1129,10 @@ static const mp_rom_map_elem_t rp2pio_statemachine_locals_dict_table[] = {
952
1129
{ MP_ROM_QSTR (MP_QSTR_pc ), MP_ROM_PTR (& rp2pio_statemachine_pc_obj ) },
953
1130
954
1131
{ MP_ROM_QSTR (MP_QSTR_rxfifo ), MP_ROM_PTR (& rp2pio_statemachine_rxfifo_obj ) },
1132
+
1133
+ { MP_ROM_QSTR (MP_QSTR_last_read ), MP_ROM_PTR (& rp2pio_statemachine_last_read_obj ) },
1134
+ { MP_ROM_QSTR (MP_QSTR_last_write ), MP_ROM_PTR (& rp2pio_statemachine_last_write_obj ) },
1135
+
955
1136
};
956
1137
static MP_DEFINE_CONST_DICT (rp2pio_statemachine_locals_dict , rp2pio_statemachine_locals_dict_table ) ;
957
1138
0 commit comments