@@ -53,6 +53,12 @@ STATIC bool _never_reset[NUM_PIOS][NUM_PIO_STATE_MACHINES];
53
53
54
54
STATIC uint32_t _current_pins [NUM_PIOS ];
55
55
STATIC uint32_t _current_sm_pins [NUM_PIOS ][NUM_PIO_STATE_MACHINES ];
56
+ STATIC int8_t _sm_dma_plus_one [NUM_PIOS ][NUM_PIO_STATE_MACHINES ];
57
+
58
+ #define SM_DMA_ALLOCATED (pio_index , sm ) (_sm_dma_plus_one[(pio_index)][(sm)] != 0)
59
+ #define SM_DMA_GET_CHANNEL (pio_index , sm ) (_sm_dma_plus_one[(pio_index)][(sm)] - 1)
60
+ #define SM_DMA_CLEAR_CHANNEL (pio_index , sm ) (_sm_dma_plus_one[(pio_index)][(sm)] = 0)
61
+ #define SM_DMA_SET_CHANNEL (pio_isntance , sm , channel ) (_sm_dma_plus_one[(pio_index)][(sm)] = (channel) + 1)
56
62
57
63
STATIC PIO pio_instances [2 ] = {pio0 , pio1 };
58
64
typedef void (* interrupt_handler_type )(void * );
@@ -72,8 +78,24 @@ static void rp2pio_statemachine_set_pull(uint32_t pull_pin_up, uint32_t pull_pin
72
78
}
73
79
}
74
80
81
+ STATIC void rp2pio_statemachine_clear_dma (int pio_index , int sm ) {
82
+ if (SM_DMA_ALLOCATED (pio_index , sm )) {
83
+ int channel = SM_DMA_GET_CHANNEL (pio_index , sm );
84
+ uint32_t channel_mask = 1u << channel ;
85
+ dma_hw -> inte0 &= ~channel_mask ;
86
+ if (!dma_hw -> inte0 ) {
87
+ irq_set_mask_enabled (1 << DMA_IRQ_0 , false);
88
+ }
89
+ MP_STATE_PORT (continuous_pio )[channel ] = NULL ;
90
+ dma_channel_abort (channel );
91
+ dma_channel_unclaim (channel );
92
+ }
93
+ SM_DMA_CLEAR_CHANNEL (pio_index , sm );
94
+ }
95
+
75
96
STATIC void _reset_statemachine (PIO pio , uint8_t sm , bool leave_pins ) {
76
97
uint8_t pio_index = pio_get_index (pio );
98
+ rp2pio_statemachine_clear_dma (pio_index , sm );
77
99
uint32_t program_id = _current_program_id [pio_index ][sm ];
78
100
if (program_id == 0 ) {
79
101
return ;
@@ -333,7 +355,7 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
333
355
self -> sm_config = c ;
334
356
335
357
// no DMA allocated
336
- self -> dma_channel [ 0 ] = self -> dma_channel [ 1 ] = NO_DMA_CHANNEL ;
358
+ SM_DMA_CLEAR_CHANNEL ( pio_index , state_machine ) ;
337
359
338
360
pio_sm_init (self -> pio , self -> state_machine , program_offset , & c );
339
361
common_hal_rp2pio_statemachine_run (self , init , init_len );
@@ -858,7 +880,10 @@ uint8_t rp2pio_statemachine_program_offset(rp2pio_statemachine_obj_t *self) {
858
880
#define HERE (fmt , ...) (mp_printf(&mp_plat_print, "%s: %d: " fmt "\n", __FILE__, __LINE__,##__VA_ARGS__))
859
881
860
882
bool common_hal_rp2pio_statemachine_start_continuous_write (rp2pio_statemachine_obj_t * self , mp_obj_t buf_obj , const uint8_t * data , size_t len , uint8_t stride_in_bytes ) {
861
- if (self -> dma_channel [0 ] != NO_DMA_CHANNEL && stride_in_bytes == self -> continuous_stride_in_bytes ) {
883
+ uint8_t pio_index = pio_get_index (self -> pio );
884
+ uint8_t sm = self -> state_machine ;
885
+
886
+ if (SM_DMA_ALLOCATED (pio_index , sm ) && stride_in_bytes == self -> continuous_stride_in_bytes ) {
862
887
HERE ("updating channel pending=%d\n" , self -> pending_set_data );
863
888
while (self -> pending_set_data ) {
864
889
RUN_BACKGROUND_TASKS ;
@@ -881,19 +906,15 @@ bool common_hal_rp2pio_statemachine_start_continuous_write(rp2pio_statemachine_o
881
906
882
907
common_hal_rp2pio_statemachine_end_continuous_write (self );
883
908
884
- for (int i = 0 ; i < 2 ; i ++ ) {
885
- HERE ("allocating channel %d" , i );
886
- if (self -> dma_channel [i ] == -1 ) {
887
- self -> dma_channel [i ] = dma_claim_unused_channel (false);
888
- HERE ("got channel %d" , self -> dma_channel [i ]);
889
- MP_STATE_PORT (continuous_pio )[self -> dma_channel [i ]] = self ;
890
- }
891
- if (self -> dma_channel [i ] == -1 ) {
892
- HERE ("allocating channel %d failed" , i );
893
- (void )common_hal_rp2pio_statemachine_end_continuous_write (self );
894
- return false;
895
- }
909
+ HERE ("allocating dma channel" );
910
+ int channel = dma_claim_unused_channel (false);
911
+ if (channel == -1 ) {
912
+ HERE ("allocating DMA channel failed" );
913
+ return false;
896
914
}
915
+ HERE ("got channel %d" , channel );
916
+
917
+ SM_DMA_SET_CHANNEL (pio_index , sm , channel );
897
918
898
919
volatile uint8_t * tx_destination = (volatile uint8_t * )& self -> pio -> txf [self -> state_machine ];
899
920
@@ -909,37 +930,31 @@ bool common_hal_rp2pio_statemachine_start_continuous_write(rp2pio_statemachine_o
909
930
self -> next_buffer = data ;
910
931
self -> next_size = len / stride_in_bytes ;
911
932
912
- c = dma_channel_get_default_config (self -> dma_channel [ 0 ] );
933
+ c = dma_channel_get_default_config (channel );
913
934
channel_config_set_transfer_data_size (& c , _stride_to_dma_size (stride_in_bytes ));
914
935
channel_config_set_dreq (& c , self -> tx_dreq );
915
936
channel_config_set_read_increment (& c , true);
916
937
channel_config_set_write_increment (& c , false);
917
- // channel_config_set_chain_to(&c, self->dma_channel[1]);
918
- dma_channel_configure (self -> dma_channel [0 ], & c ,
938
+ dma_channel_configure (channel , & c ,
919
939
tx_destination ,
920
940
data ,
921
941
len / stride_in_bytes ,
922
942
false);
943
+ HERE ("OK let's go" );
923
944
924
- #if 0
925
- channel_config_set_chain_to (& c , self -> dma_channel [0 ]);
926
- dma_channel_configure (self -> dma_channel [1 ], & c ,
927
- tx_destination ,
928
- data ,
929
- len / stride_in_bytes ,
930
- false);
931
- #endif
932
-
933
- dma_hw -> inte0 |= (1 << self -> dma_channel [0 ]) | (1 << self -> dma_channel [1 ]);
945
+ common_hal_mcu_disable_interrupts ();
946
+ MP_STATE_PORT (continuous_pio )[channel ] = self ;
947
+ dma_hw -> inte0 |= 1u << channel ;
934
948
irq_set_mask_enabled (1 << DMA_IRQ_0 , true);
949
+ dma_start_channel_mask (1u << channel );
950
+ common_hal_mcu_enable_interrupts ();
935
951
936
- HERE ("OK let's go" );
937
- dma_start_channel_mask (1u << self -> dma_channel [0 ]);
952
+ HERE ("mark" );
938
953
return true;
939
954
}
940
955
941
956
void rp2pio_statemachine_dma_complete (rp2pio_statemachine_obj_t * self , int channel ) {
942
- HERE ("dma complete[%d] pending set data=%d busy=%d,%d %d@%p" , channel , self -> pending_set_data , dma_channel_is_busy (self -> dma_channel [ 0 ]), dma_channel_is_busy ( self -> dma_channel [ 1 ]) ,
957
+ HERE ("dma complete[%d] pending set data=%d %sbusy %d@%p" , channel , self -> pending_set_data , dma_channel_is_busy (channel ) ? "not " : "" ,
943
958
self -> next_size , self -> next_buffer );
944
959
945
960
dma_channel_set_read_addr (channel , self -> next_buffer , false);
@@ -949,20 +964,8 @@ void rp2pio_statemachine_dma_complete(rp2pio_statemachine_obj_t *self, int chann
949
964
}
950
965
951
966
bool common_hal_rp2pio_statemachine_end_continuous_write (rp2pio_statemachine_obj_t * self ) {
952
- for (int i = 0 ; i < 2 ; i ++ ) {
953
- if (self -> dma_channel [i ] == NO_DMA_CHANNEL ) {
954
- continue ;
955
- }
956
- int channel = self -> dma_channel [i ];
957
- uint32_t channel_mask = 1u << channel ;
958
- dma_hw -> inte0 &= ~channel_mask ;
959
- if (!dma_hw -> inte0 ) {
960
- irq_set_mask_enabled (1 << DMA_IRQ_0 , false);
961
- }
962
- MP_STATE_PORT (continuous_pio )[channel ] = NULL ;
963
- dma_channel_abort (channel );
964
- dma_channel_unclaim (channel );
965
- self -> dma_channel [i ] = NO_DMA_CHANNEL ;
966
- }
967
+ uint8_t pio_index = pio_get_index (self -> pio );
968
+ uint8_t sm = self -> state_machine ;
969
+ rp2pio_statemachine_clear_dma (pio_index , sm );
967
970
return true;
968
971
}
0 commit comments