HUB75 Prevent stuck row on soft reset

TODO:

* Move this into drivers/ for C++ use too.
* Display still goes mighty weird sometimes!
This commit is contained in:
Phil Howard 2021-11-22 15:22:04 +00:00
parent 0e8c1228af
commit 66d25d2e9c
3 changed files with 43 additions and 21 deletions

View File

@ -55,6 +55,7 @@ void Hub75_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind
/***** Destructor ******/
mp_obj_t Hub75___del__(mp_obj_t self_in) {
_Hub75_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Hub75_obj_t);
self->hub75->stop(dma_complete);
delete self->hub75;
return mp_const_none;
}
@ -130,7 +131,7 @@ mp_obj_t Hub75_start(mp_obj_t self_in) {
mp_obj_t Hub75_stop(mp_obj_t self_in) {
_Hub75_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Hub75_obj_t);
self->hub75->stop();
self->hub75->stop(dma_complete);
return mp_const_none;
}

View File

@ -69,6 +69,18 @@ void Hub75::start(irq_handler_t handler) {
FM6126A_write_register(0b0000001000000000, 13);
if(handler) {
dma_channel = 0;
if(pio_sm_is_claimed(pio, sm_data) || pio_sm_is_claimed(pio, sm_row)) {
irq_set_enabled(pio_get_dreq(pio, sm_data, true), false);
pio_sm_set_enabled(pio, sm_data, false);
pio_sm_unclaim(pio, sm_data);
pio_sm_set_enabled(pio, sm_row, false);
pio_sm_unclaim(pio, sm_row);
pio_clear_instruction_memory(pio);
}
pio_sm_claim(pio, sm_data);
pio_sm_claim(pio, sm_row);
@ -77,7 +89,15 @@ void Hub75::start(irq_handler_t handler) {
hub75_data_rgb888_program_init(pio, sm_data, data_prog_offs, DATA_BASE_PIN, CLK_PIN);
hub75_row_program_init(pio, sm_row, row_prog_offs, ROWSEL_BASE_PIN, ROWSEL_N_PINS, STROBE_PIN);
dma_channel = 0;
if(dma_channel_is_claimed(dma_channel)) {
irq_set_enabled(DMA_IRQ_0, false);
dma_channel_set_irq0_enabled(dma_channel, false);
irq_set_enabled(pio_get_dreq(pio, sm_data, true), false);
irq_remove_handler(DMA_IRQ_0, handler);
dma_channel_wait_for_finish_blocking(dma_channel);
dma_channel_unclaim(dma_channel);
}
dma_channel_claim(dma_channel);
dma_channel_config config = dma_channel_get_default_config(dma_channel);
channel_config_set_transfer_data_size(&config, DMA_SIZE_32);
@ -101,33 +121,35 @@ void Hub75::start(irq_handler_t handler) {
}
}
void Hub75::stop() {
void Hub75::stop(irq_handler_t handler) {
running = false;
// stop and release the dma channel
irq_set_enabled(DMA_IRQ_0, false);
dma_channel_set_irq0_enabled(dma_channel, false);
irq_set_enabled(pio_get_dreq(pio, sm_data, true), false);
//irq_remove_handler(DMA_IRQ_0, dma_complete);
if(dma_channel_is_claimed(dma_channel)) {
// stop and release the dma channel
irq_set_enabled(DMA_IRQ_0, false);
dma_channel_set_irq0_enabled(dma_channel, false);
irq_set_enabled(pio_get_dreq(pio, sm_data, true), false);
irq_remove_handler(DMA_IRQ_0, handler);
dma_channel_wait_for_finish_blocking(dma_channel);
dma_channel_unclaim(dma_channel);
dma_channel_wait_for_finish_blocking(dma_channel);
dma_channel_unclaim(dma_channel);
}
hub75_wait_tx_stall(pio, sm_row);
// release the pio and sm
pio_sm_unclaim(pio, sm_data);
pio_sm_unclaim(pio, sm_row);
pio_clear_instruction_memory(pio);
pio_sm_restart(pio, sm_data);
pio_sm_restart(pio, sm_row);
pio_sm_set_enabled(pio, sm_data, false);
pio_sm_set_enabled(pio, sm_row, false);
// release the pio and sm
if(pio_sm_is_claimed(pio, sm_data)) pio_sm_unclaim(pio, sm_data);
if(pio_sm_is_claimed(pio, sm_data)) pio_sm_unclaim(pio, sm_row);
pio_clear_instruction_memory(pio);
gpio_put(pin_stb, !STB_POLARITY);
gpio_put(pin_oe, !OE_POLARITY);
//gpio_put(pin_stb, !STB_POLARITY);
}
Hub75::~Hub75() {
stop();
}
void Hub75::clear() {
@ -193,7 +215,7 @@ void Hub75::dma_complete() {
dma_channel_acknowledge_irq0(dma_channel);
// SM is finished when it stalls on empty TX FIFO (or, y'know, DMA callback)
//hub75_wait_tx_stall(pio, sm_data);
// hub75_wait_tx_stall(pio, sm_data);
// Check that previous OEn pulse is finished, else things WILL get out of sequence
hub75_wait_tx_stall(pio, sm_row);
@ -214,6 +236,5 @@ void Hub75::dma_complete() {
}
dma_channel_set_trans_count(dma_channel, width * 4, false);
//dma_channel_set_read_addr(dma_channel, dma_buffer, true);
dma_channel_set_read_addr(dma_channel, &back_buffer[row * width * 2], true);
}

View File

@ -116,7 +116,7 @@ class Hub75 {
void display_update();
void clear();
void start(irq_handler_t handler);
void stop();
void stop(irq_handler_t handler);
void flip();
void dma_complete();
};