MicroPython: Make DV display us fixed pio/dma.

dv_stick
Phil Howard 2023-06-26 16:13:35 +01:00
rodzic 3bc215074c
commit 4afe062d19
3 zmienionych plików z 81 dodań i 57 usunięć

Wyświetl plik

@ -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);

Wyświetl plik

@ -5,6 +5,13 @@
#include <cstdlib>
#include <math.h>
#include <string.h>
#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;

Wyświetl plik

@ -2,6 +2,13 @@
#include "stdio.h"
#include "swd.pio.h"
#include <algorithm>
#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;
}
}