@@ -74,14 +74,20 @@ static bool _done_callback(rmt_channel_handle_t rx_chan,
7474
7575void common_hal_pulseio_pulsein_construct (pulseio_pulsein_obj_t * self , const mcu_pin_obj_t * pin ,
7676 uint16_t maxlen , bool idle_state ) {
77+
78+ // Only use dma when necessary, since dma-rmt might not be available.
79+ // If dma is not available, this will raise an error below.
80+ bool use_dma = maxlen > 128 ;
81+
7782 self -> buffer = (uint16_t * )m_malloc_without_collect (maxlen * sizeof (uint16_t ));
7883 if (self -> buffer == NULL ) {
7984 m_malloc_fail (maxlen * sizeof (uint16_t ));
8085 }
8186 // We add one to the maxlen version to ensure that two symbols at lease are
8287 // captured because we may skip the first portion of a symbol.
83- self -> raw_symbols_size = MIN (64 , maxlen / 2 + 1 ) * sizeof (rmt_symbol_word_t );
84- self -> raw_symbols = (rmt_symbol_word_t * )m_malloc_without_collect (self -> raw_symbols_size );
88+ self -> raw_symbols_size = (maxlen / 2 + 1 ) * sizeof (rmt_symbol_word_t );
89+ // RMT DMA mode cannot access PSRAM -> ensure raw_symbols is in internal ram
90+ self -> raw_symbols = (rmt_symbol_word_t * )port_malloc (self -> raw_symbols_size , use_dma );
8591 if (self -> raw_symbols == NULL ) {
8692 m_free (self -> buffer );
8793 m_malloc_fail (self -> raw_symbols_size );
@@ -109,17 +115,30 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu
109115 .clk_src = RMT_CLK_SRC_DEFAULT ,
110116 // 2 us resolution so we can capture 65ms pulses. The RMT period is only 15 bits.
111117 .resolution_hz = 1000000 / 2 ,
112- .mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL ,
118+ .mem_block_symbols = use_dma ? self -> raw_symbols_size : SOC_RMT_MEM_WORDS_PER_CHANNEL ,
119+ .flags .with_dma = use_dma
113120 };
114- // If we fail here, the buffers allocated above will be garbage collected.
115- CHECK_ESP_RESULT (rmt_new_rx_channel (& config , & self -> channel ));
121+ // If we fail here, the self->buffer will be garbage collected.
122+ esp_err_t result = rmt_new_rx_channel (& config , & self -> channel );
123+ if (result != ESP_OK ) {
124+ port_free (self -> raw_symbols );
125+ if (result == ESP_ERR_NOT_SUPPORTED ) {
126+ mp_raise_ValueError_varg (MP_ERROR_TEXT ("Invalid %q" ), MP_QSTR_maxlen );
127+ } else {
128+ raise_esp_error (result );
129+ }
130+ }
116131
117132 rmt_rx_event_callbacks_t rx_callback = {
118133 .on_recv_done = _done_callback
119134 };
120135 rmt_rx_register_event_callbacks (self -> channel , & rx_callback , self );
121136 rmt_enable (self -> channel );
122- rmt_receive (self -> channel , self -> raw_symbols , self -> raw_symbols_size , & rx_config );
137+ result = rmt_receive (self -> channel , self -> raw_symbols , self -> raw_symbols_size , & rx_config );
138+ if (result != ESP_OK ) {
139+ port_free (self -> raw_symbols );
140+ raise_esp_error (result );
141+ }
123142}
124143
125144bool common_hal_pulseio_pulsein_deinited (pulseio_pulsein_obj_t * self ) {
0 commit comments