Skip to content

Commit b128f18

Browse files
committed
switch to single single dma channel, fix some bugs
1 parent 33d6d55 commit b128f18

File tree

3 files changed

+54
-46
lines changed

3 files changed

+54
-46
lines changed

ports/raspberrypi/bindings/rp2pio/StateMachine.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,9 @@ STATIC mp_obj_t rp2pio_statemachine_start_continuous_write(size_t n_args, const
482482

483483
ok = common_hal_rp2pio_statemachine_start_continuous_write(self, args[ARG_buffer].u_obj, ((uint8_t *)bufinfo.buf) + start, length, stride_in_bytes);
484484
}
485+
if (mp_hal_is_interrupted()) {
486+
return mp_const_none;
487+
}
485488
if (!ok) {
486489
mp_raise_OSError(MP_EIO);
487490
}
@@ -495,6 +498,9 @@ MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_start_continuous_write_obj, 2, rp
495498
STATIC mp_obj_t rp2pio_statemachine_obj_end_continuous_write(mp_obj_t self_in) {
496499
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in);
497500
bool ok = common_hal_rp2pio_statemachine_end_continuous_write(self);
501+
if (mp_hal_is_interrupted()) {
502+
return mp_const_none;
503+
}
498504
if (!ok) {
499505
mp_raise_OSError(MP_EIO);
500506
}

ports/raspberrypi/common-hal/rp2pio/StateMachine.c

Lines changed: 48 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ STATIC bool _never_reset[NUM_PIOS][NUM_PIO_STATE_MACHINES];
5353

5454
STATIC uint32_t _current_pins[NUM_PIOS];
5555
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)
5662

5763
STATIC PIO pio_instances[2] = {pio0, pio1};
5864
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
7278
}
7379
}
7480

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+
7596
STATIC void _reset_statemachine(PIO pio, uint8_t sm, bool leave_pins) {
7697
uint8_t pio_index = pio_get_index(pio);
98+
rp2pio_statemachine_clear_dma(pio_index, sm);
7799
uint32_t program_id = _current_program_id[pio_index][sm];
78100
if (program_id == 0) {
79101
return;
@@ -333,7 +355,7 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
333355
self->sm_config = c;
334356

335357
// no DMA allocated
336-
self->dma_channel[0] = self->dma_channel[1] = NO_DMA_CHANNEL;
358+
SM_DMA_CLEAR_CHANNEL(pio_index, state_machine);
337359

338360
pio_sm_init(self->pio, self->state_machine, program_offset, &c);
339361
common_hal_rp2pio_statemachine_run(self, init, init_len);
@@ -858,7 +880,10 @@ uint8_t rp2pio_statemachine_program_offset(rp2pio_statemachine_obj_t *self) {
858880
#define HERE(fmt, ...) (mp_printf(&mp_plat_print, "%s: %d: " fmt "\n", __FILE__, __LINE__,##__VA_ARGS__))
859881

860882
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) {
862887
HERE("updating channel pending=%d\n", self->pending_set_data);
863888
while (self->pending_set_data) {
864889
RUN_BACKGROUND_TASKS;
@@ -881,19 +906,15 @@ bool common_hal_rp2pio_statemachine_start_continuous_write(rp2pio_statemachine_o
881906

882907
common_hal_rp2pio_statemachine_end_continuous_write(self);
883908

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;
896914
}
915+
HERE("got channel %d", channel);
916+
917+
SM_DMA_SET_CHANNEL(pio_index, sm, channel);
897918

898919
volatile uint8_t *tx_destination = (volatile uint8_t *)&self->pio->txf[self->state_machine];
899920

@@ -909,37 +930,31 @@ bool common_hal_rp2pio_statemachine_start_continuous_write(rp2pio_statemachine_o
909930
self->next_buffer = data;
910931
self->next_size = len / stride_in_bytes;
911932

912-
c = dma_channel_get_default_config(self->dma_channel[0]);
933+
c = dma_channel_get_default_config(channel);
913934
channel_config_set_transfer_data_size(&c, _stride_to_dma_size(stride_in_bytes));
914935
channel_config_set_dreq(&c, self->tx_dreq);
915936
channel_config_set_read_increment(&c, true);
916937
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,
919939
tx_destination,
920940
data,
921941
len / stride_in_bytes,
922942
false);
943+
HERE("OK let's go");
923944

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;
934948
irq_set_mask_enabled(1 << DMA_IRQ_0, true);
949+
dma_start_channel_mask(1u << channel);
950+
common_hal_mcu_enable_interrupts();
935951

936-
HERE("OK let's go");
937-
dma_start_channel_mask(1u << self->dma_channel[0]);
952+
HERE("mark");
938953
return true;
939954
}
940955

941956
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 " : "",
943958
self->next_size, self->next_buffer);
944959

945960
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
949964
}
950965

951966
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);
967970
return true;
968971
}

ports/raspberrypi/common-hal/rp2pio/StateMachine.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ typedef struct {
5959
uint8_t buf_obj_idx;
6060
const uint8_t *next_buffer;
6161
size_t next_size;
62-
int dma_channel[2];
6362
mp_obj_t buf_objs[2];
6463
int continuous_stride_in_bytes;
6564
volatile int pending_set_data;

0 commit comments

Comments
 (0)