From 4afe062d19e5fa71335fa1c889f70270a17a91e4 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Mon, 26 Jun 2023 16:13:35 +0100 Subject: [PATCH] MicroPython: Make DV display us fixed pio/dma. --- drivers/aps6404/aps6404.cpp | 17 +++-- drivers/dv_display/dv_display.cpp | 15 +++-- drivers/dv_display/swd_load.cpp | 106 ++++++++++++++++-------------- 3 files changed, 81 insertions(+), 57 deletions(-) diff --git a/drivers/aps6404/aps6404.cpp b/drivers/aps6404/aps6404.cpp index 3638f19c..83de588b 100644 --- a/drivers/aps6404/aps6404.cpp +++ b/drivers/aps6404/aps6404.cpp @@ -6,6 +6,13 @@ #include "hardware/clocks.h" #include "pico/stdlib.h" #include "aps6404.pio.h" +#ifndef MICROPY_BUILD_TYPE +#define mp_printf(_, ...) printf(__VA_ARGS__); +#else +extern "C" { +#include "py/runtime.h" +} +#endif namespace pimoroni { APS6404::APS6404(uint pin_csn, uint pin_d0, PIO pio) @@ -20,17 +27,19 @@ namespace pimoroni { } pio_prog = &sram_reset_program; + pio_clear_instruction_memory(pio); pio_offset = pio_add_program(pio, &sram_reset_program); - pio_sm = pio_claim_unused_sm(pio, true); + pio_sm = 0; //pio_claim_unused_sm(pio, true); // Claim DMA channels - dma_channel = dma_claim_unused_channel(true); - read_cmd_dma_channel = dma_claim_unused_channel(true); + dma_channel = 0;// dma_claim_unused_channel(true); + read_cmd_dma_channel = 1;// dma_claim_unused_channel(true); } void APS6404::init() { pio_sm_set_enabled(pio, pio_sm, false); - pio_remove_program(pio, pio_prog, pio_offset); + pio_clear_instruction_memory(pio); + //pio_remove_program(pio, pio_prog, pio_offset); pio_prog = &sram_reset_program; pio_offset = pio_add_program(pio, &sram_reset_program); diff --git a/drivers/dv_display/dv_display.cpp b/drivers/dv_display/dv_display.cpp index da729a55..179d5b5d 100644 --- a/drivers/dv_display/dv_display.cpp +++ b/drivers/dv_display/dv_display.cpp @@ -5,6 +5,13 @@ #include #include #include +#ifndef MICROPY_BUILD_TYPE +#define mp_printf(_, ...) printf(__VA_ARGS__); +#else +extern "C" { +#include "py/runtime.h" +} +#endif namespace pimoroni { @@ -43,7 +50,7 @@ namespace pimoroni { } if (res_mode == 0xFF) { - printf("Resolution %dx%d is not supported. Will use 720x480.\n", width, height); + mp_printf(&mp_plat_print, "Resolution %dx%d is not supported. Will use 720x480.\n", width, height); } gpio_init(RAM_SEL); @@ -71,14 +78,14 @@ namespace pimoroni { gpio_put(RAM_SEL, 0); sleep_ms(100); - printf("Start I2C\n"); + mp_printf(&mp_plat_print, "Start I2C\n"); if (res_mode != 0xFF) { i2c.reg_write_uint8(I2C_ADDR, I2C_REG_SET_RES, res_mode); } i2c.reg_write_uint8(I2C_ADDR, I2C_REG_START, 1); - printf("Started\n"); + mp_printf(&mp_plat_print, "Started\n"); } void DVDisplay::flip() { @@ -355,7 +362,7 @@ namespace pimoroni { uint32_t buf[8]; uint addr = 4 * 7; uint line_type = 0x80000000u + ((uint)mode << 28); - printf("Write header, line type %08x\n", line_type); + mp_printf(&mp_plat_print, "Write header, line type %08x\n", line_type); for (int i = 0; i < height; i += 8) { for (int j = 0; j < 8; ++j) { buf[j] = line_type + ((uint32_t)h_repeat << 24) + ((i + j) * width * 6) + base_address; diff --git a/drivers/dv_display/swd_load.cpp b/drivers/dv_display/swd_load.cpp index 458a5d8d..0d6bb5fa 100644 --- a/drivers/dv_display/swd_load.cpp +++ b/drivers/dv_display/swd_load.cpp @@ -2,6 +2,13 @@ #include "stdio.h" #include "swd.pio.h" #include +#ifndef MICROPY_BUILD_TYPE +#define mp_printf(_, ...) printf(__VA_ARGS__); +#else +extern "C" { +#include "py/runtime.h" +} +#endif static uint pio_offset; static uint pio_sm; @@ -67,7 +74,7 @@ static bool read_cmd(uint cmd, uint& data) { pio_sm_put_blocking(pio0, pio_sm, cmd); wait_for_idle(); if (pio0_hw->irq & 0x1) { - printf("Read ID failed\n"); + mp_printf(&mp_plat_print, "Read ID failed\n"); return false; } data = pio_sm_get_blocking(pio0, pio_sm); @@ -89,9 +96,10 @@ static void idle() { static bool connect(bool first = true, uint core = 0) { if (first) { + pio_clear_instruction_memory(pio0); pio_prog = &swd_raw_write_program; pio_offset = pio_add_program(pio0, &swd_raw_write_program); - pio_sm = pio_claim_unused_sm(pio0, true); + pio_sm = 0; //pio_claim_unused_sm(pio0, true); swd_initial_init(pio0, pio_sm, 2, 3); @@ -101,7 +109,7 @@ static bool connect(bool first = true, uint core = 0) { } // Begin transaction: 8 clocks, data low - printf("Begin transaction\n"); + mp_printf(&mp_plat_print, "Begin transaction\n"); pio_sm_put_blocking(pio0, pio_sm, 7); pio_sm_put_blocking(pio0, pio_sm, 0); @@ -110,11 +118,11 @@ static bool connect(bool first = true, uint core = 0) { // 0x6209F392, 0x86852D95, 0xE3DDAFE9, 0x19BC0EA2 // 4 clocks, data low // 0x1A - printf("SWD Mode\n"); + mp_printf(&mp_plat_print, "SWD Mode\n"); pio_sm_put_blocking(pio0, pio_sm, 8-1); pio_sm_put_blocking(pio0, pio_sm, 0xFF); - printf("Tag\n"); + mp_printf(&mp_plat_print, "Tag\n"); pio_sm_put_blocking(pio0, pio_sm, 32*4+4+8-1); pio_sm_put_blocking(pio0, pio_sm, 0x6209F392); pio_sm_put_blocking(pio0, pio_sm, 0x86852D95); @@ -123,12 +131,12 @@ static bool connect(bool first = true, uint core = 0) { pio_sm_put_blocking(pio0, pio_sm, 0x1A0); // Line Reset: 50 high, 8 low - printf("Line Reset\n"); + mp_printf(&mp_plat_print, "Line Reset\n"); pio_sm_put_blocking(pio0, pio_sm, 58-1); pio_sm_put_blocking(pio0, pio_sm, 0xFFFFFFFF); pio_sm_put_blocking(pio0, pio_sm, 0x003FFFF); - printf("Target Select\n"); // Must ignore error response + mp_printf(&mp_plat_print, "Target Select\n"); // Must ignore error response wait_for_idle(); pio_sm_set_enabled(pio0, pio_sm, false); pio_remove_program(pio0, pio_prog, pio_offset); @@ -140,61 +148,61 @@ static bool connect(bool first = true, uint core = 0) { pio_sm_put_blocking(pio0, pio_sm, 0x19); pio_sm_put_blocking(pio0, pio_sm, 0x01002927 | (core << 28)); - printf("Read ID\n"); + mp_printf(&mp_plat_print, "Read ID\n"); uint id; if (!read_cmd(0x25, id)) { - printf("Read ID failed\n"); + mp_printf(&mp_plat_print, "Read ID failed\n"); return false; } - printf("Received ID: %08x\n", id); + mp_printf(&mp_plat_print, "Received ID: %08x\n", id); if (core != 0xf && id != 0x0bc12477) return false; - printf("Abort\n"); + mp_printf(&mp_plat_print, "Abort\n"); if (!write_cmd(0x01, 0x1E)) { - printf("Abort failed\n"); + mp_printf(&mp_plat_print, "Abort failed\n"); return false; } - printf("Select\n"); + mp_printf(&mp_plat_print, "Select\n"); if (!write_cmd(0x31, 0)) { - printf("Select failed\n"); + mp_printf(&mp_plat_print, "Select failed\n"); return false; } - printf("Ctrl/Stat\n"); + mp_printf(&mp_plat_print, "Ctrl/Stat\n"); if (!write_cmd(0x29, 0x50000001)) { - printf("Ctrl power up failed\n"); + mp_printf(&mp_plat_print, "Ctrl power up failed\n"); return false; } uint status; if (!read_cmd(0x0D, status)) { - printf("Read status on power up failed\n"); + mp_printf(&mp_plat_print, "Read status on power up failed\n"); return false; } - printf("Status: %08x\n", status); + mp_printf(&mp_plat_print, "Status: %08x\n", status); if ((status & 0xA0000000) != 0xA0000000) { - printf("Power up not acknowledged\n"); + mp_printf(&mp_plat_print, "Power up not acknowledged\n"); return false; } if (core != 0xf) { - printf("Setup memory access\n"); + mp_printf(&mp_plat_print, "Setup memory access\n"); if (!write_cmd(0x23, 0xA2000052)) { - printf("Memory access setup failed\n"); + mp_printf(&mp_plat_print, "Memory access setup failed\n"); return false; } - printf("Halt CPU\n"); + mp_printf(&mp_plat_print, "Halt CPU\n"); if (!write_reg(0xe000edf0, 0xA05F0003)) { - printf("Halt failed\n"); + mp_printf(&mp_plat_print, "Halt failed\n"); return false; } } else { if (!write_cmd(0x29, 0x00000001)) { - printf("Clear reset failed\n"); + mp_printf(&mp_plat_print, "Clear reset failed\n"); return false; } } @@ -205,14 +213,14 @@ static bool connect(bool first = true, uint core = 0) { } static bool load(uint address, const uint* data, uint len_in_bytes) { - printf("Loading %d bytes at %08x\n", len_in_bytes, address); + mp_printf(&mp_plat_print, "Loading %d bytes at %08x\n", len_in_bytes, address); idle(); constexpr uint BLOCK_SIZE = 1024; uint block_len_in_words = std::min((BLOCK_SIZE - (address & (BLOCK_SIZE - 1))) >> 2, len_in_bytes >> 2); for (uint i = 0; i < len_in_bytes; ) { if (!write_block(address + i, &data[i >> 2], block_len_in_words)) { - printf("Block write failed\n"); + mp_printf(&mp_plat_print, "Block write failed\n"); return false; } i += block_len_in_words << 2; @@ -227,11 +235,11 @@ static bool load(uint address, const uint* data, uint len_in_bytes) { { uint check_data; if (!read_reg(address + j, check_data)) { - printf("Read failed\n"); + mp_printf(&mp_plat_print, "Read failed\n"); return false; } if (check_data != data[j >> 2]) { - printf("Verify failed at %08x, %08x != %08x\n", address + j, check_data, data[j >> 2]); + mp_printf(&mp_plat_print, "Verify failed at %08x, %08x != %08x\n", address + j, check_data, data[j >> 2]); return false; } } @@ -249,18 +257,18 @@ static bool start(uint pc, uint sp) { read_reg(0x0, rom_sp); read_reg(0x4, rom_pc); - printf("Set PC\n"); + mp_printf(&mp_plat_print, "Set PC\n"); if (!write_reg(0xe000edf8, rom_pc) || !write_reg(0xe000edf4, 0x1000F)) { - printf("Failed to set PC\n"); + mp_printf(&mp_plat_print, "Failed to set PC\n"); return false; } - printf("Set SP\n"); + mp_printf(&mp_plat_print, "Set SP\n"); if (!write_reg(0xe000edf8, rom_sp) || !write_reg(0xe000edf4, 0x1000D)) { - printf("Failed to set SP\n"); + mp_printf(&mp_plat_print, "Failed to set SP\n"); return false; } idle(); @@ -268,9 +276,9 @@ static bool start(uint pc, uint sp) { // If a PC has been given, go through watchdog boot sequence to start there if (pc != 0) { uint watchdog_data[4] = {0xb007c0d3, 0x4ff83f2d ^ pc, sp, pc}; - printf("Setup watchdog\n"); + mp_printf(&mp_plat_print, "Setup watchdog\n"); if (!write_block(0x4005801c, watchdog_data, 4)) { - printf("Failed to setup watchdog for reset\n"); + mp_printf(&mp_plat_print, "Failed to setup watchdog for reset\n"); } } @@ -279,24 +287,24 @@ static bool start(uint pc, uint sp) { write_reg(0xe000edf4, 0x0000F); idle(); read_reg(0xe000edf8, data); - printf("PC is %08x\n", data); + mp_printf(&mp_plat_print, "PC is %08x\n", data); for (int i = 0; i < 16; ++i) { write_reg(0xe000edf4, i); idle(); read_reg(0xe000edf8, data); - printf("R%d is %08x\n", i, data); + mp_printf(&mp_plat_print, "R%d is %08x\n", i, data); } for (int i = 0; i < 4; ++i) { read_reg(0x4005801c + 4*i, data); - printf("WD%d is %08x\n", i, data); + mp_printf(&mp_plat_print, "WD%d is %08x\n", i, data); } #endif - printf("Start CPU\n"); + mp_printf(&mp_plat_print, "Start CPU\n"); if (!write_reg(0xe000edf0, 0xA05F0001)) { - printf("Start failed\n"); + mp_printf(&mp_plat_print, "Start failed\n"); return false; } @@ -307,9 +315,9 @@ static bool start(uint pc, uint sp) { sleep_ms(10); connect(false); - printf("Halt CPU\n"); + mp_printf(&mp_plat_print, "Halt CPU\n"); if (!write_reg(0xe000edf0, 0xA05F0003)) { - printf("Halt failed\n"); + mp_printf(&mp_plat_print, "Halt failed\n"); return false; } @@ -317,12 +325,12 @@ static bool start(uint pc, uint sp) { write_reg(0xe000edf4, i); idle(); read_reg(0xe000edf8, data); - printf("R%d is %08x\n", i, data); + mp_printf(&mp_plat_print, "R%d is %08x\n", i, data); } for (int i = 0; i < 4; ++i) { read_reg(0x4005801c + 4*i, data); - printf("WD%d is %08x\n", i, data); + mp_printf(&mp_plat_print, "WD%d is %08x\n", i, data); } #endif @@ -335,25 +343,25 @@ bool swd_load_program(const uint* addresses, const uint** data, const uint* data gpio_disable_pulls(2); gpio_pull_up(3); - printf("Connecting\n"); + mp_printf(&mp_plat_print, "Connecting\n"); bool ok = connect(true, 0xf); - printf("Reset %s\n", ok ? "OK" : "Fail"); + mp_printf(&mp_plat_print, "Reset %s\n", ok ? "OK" : "Fail"); if (!ok) { return false; } ok = connect(false, 0); - printf("Connected core 0 %s\n", ok ? "OK" : "Fail"); + mp_printf(&mp_plat_print, "Connected core 0 %s\n", ok ? "OK" : "Fail"); if (!ok) { return false; } if (use_xip_as_ram) { - printf("Disable XIP\n"); + mp_printf(&mp_plat_print, "Disable XIP\n"); if (!write_reg(0x14000000, 0)) { - printf("Disable XIP failed\n"); + mp_printf(&mp_plat_print, "Disable XIP failed\n"); return false; } } @@ -361,7 +369,7 @@ bool swd_load_program(const uint* addresses, const uint** data, const uint* data for (uint i = 0; i < num_sections; ++i) { if (!load(addresses[i], data[i], data_len_in_bytes[i])) { - printf("Failed to load section %d\n", i); + mp_printf(&mp_plat_print, "Failed to load section %d\n", i); return false; } }