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