Browse Source

delay test stuff

main
Triss 8 months ago
parent
commit
3a6ddbc691
  1. 5
      CMakeLists.txt
  2. 42
      src/main.c
  3. 96
      src/test/delay.pio
  4. 439
      src/test/delaytest.c
  5. 8
      src/test/delaytest.h
  6. 127
      src/test/stat.py
  7. 24
      src/tool78/tool78_cmds.c
  8. 5
      test/rl78/test.S

5
CMakeLists.txt

@ -45,6 +45,7 @@ if(FAMILY STREQUAL "rp2040")
${CMAKE_CURRENT_SOURCE_DIR}/src/tool78/tool78_hw_rl78_uart2.c
${CMAKE_CURRENT_SOURCE_DIR}/src/tool78/tool78_cmds.c
${CMAKE_CURRENT_SOURCE_DIR}/src/test/piotest.c
${CMAKE_CURRENT_SOURCE_DIR}/src/test/delaytest.c
)
# Example include
@ -53,6 +54,7 @@ if(FAMILY STREQUAL "rp2040")
${CMAKE_CURRENT_SOURCE_DIR}/src/msp430/
${CMAKE_CURRENT_SOURCE_DIR}/src/swim/
${CMAKE_CURRENT_SOURCE_DIR}/src/tool78/
${CMAKE_CURRENT_SOURCE_DIR}/src/test/
)
# Example defines
@ -60,12 +62,13 @@ if(FAMILY STREQUAL "rp2040")
)
target_link_libraries(${PROJECT} pico_stdlib pico_unique_id
hardware_pio hardware_dma hardware_pwm)
hardware_pio hardware_dma hardware_pwm cmsis_core pico_multicore)
pico_generate_pio_header(${PROJECT} ${CMAKE_CURRENT_SOURCE_DIR}/src/msp430/sbw.pio)
pico_generate_pio_header(${PROJECT} ${CMAKE_CURRENT_SOURCE_DIR}/src/swim/swim.pio)
pico_generate_pio_header(${PROJECT} ${CMAKE_CURRENT_SOURCE_DIR}/src/tool78/tool78.pio)
pico_generate_pio_header(${PROJECT} ${CMAKE_CURRENT_SOURCE_DIR}/src/test/test.pio)
pico_generate_pio_header(${PROJECT} ${CMAKE_CURRENT_SOURCE_DIR}/src/test/delay.pio)
pico_add_extra_outputs(${PROJECT})
else()

42
src/main.c

@ -13,6 +13,7 @@
#include "tool78_cmds.h"
void piotest(void);
void delaytest(void);
/*static uint16_t DATA_text[0x24] = {
0xc232,0x43c2,0x0000,0x4031,0x02fe,0x40f2,0x00ff,0x002a,0x40b2,0x5a10,0x0120,
@ -29,7 +30,7 @@ static uint16_t DATA_vectors[0x10] = {
static uint16_t dumpmem_ram[256>>1];
static uint16_t dumpmem_flash[8192>>1];*/
static uint8_t DATA_test_rom[256] = { // RL78
/*static uint8_t DATA_test_rom[256] = { // RL78
0xce, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@ -50,9 +51,20 @@ static uint8_t DATA_test_rom[256] = { // RL78
0x71, 0x38, 0x23, 0xff, 0x71, 0x38, 0x33, 0x00, 0x71, 0x68, 0x77, 0x00, 0x71,
0x38, 0x53, 0x00, 0xd7, 0x71, 0x30, 0x03, 0xff, 0x00, 0x00, 0x71, 0x38, 0x03,
0xff, 0xef, 0xf4, 0xd7, 0xd7, 0xff, 0xff, 0xff, 0xff
};*/
static uint8_t shellcode_test[] = {
/*0x71,0x38,0x23,0xff, // clr1 !0xfff23.3
//0x71,0x38,0x33,0x00, // clr1 !0xf0033.3
//0x71,0x68,0x77,0x00, // clr1 !0xf0077.6
//0x71,0x38,0x53,0x00, // clr1 !0xf0053.3
0x71,0x30,0x03,0xff, // set1 !0xfff03.3*/
0x51, 0x61, // mov a, #97
0xfc, 0xa1, 0xff, 0x0e, // call !!effa1
0xd7, // ret
};
static void test_sbw(void) {
gpio_init(PINOUT_SBW_TCK);
gpio_set_function(PINOUT_SBW_TCK, GPIO_FUNC_SIO);
@ -247,13 +259,37 @@ static void tool78_ocdtest() {
uint16_t ver=0;
enum tool78_stat st = tool78_init_ocd(&tool78_hw_rl78_uart1, &ver, passwd);
printf("result: 0x%02x ver=%04x\n", st, ver);
// hw addr len data
st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0x07e0,
sizeof(shellcode_test), shellcode_test);
printf("write res 0x%02x\n", st);
uint8_t shbuf[sizeof(shellcode_test)];
memset(shbuf, 0, sizeof shbuf);
st = tool78_ocd_read(&tool78_hw_rl78_uart1, 0x07e0,
sizeof(shellcode_test), shbuf);
printf("read res 0x%02x\n", st);
for (size_t i = 0; i < sizeof shellcode_test; ++i)
printf("%02x ", shbuf[i]);
printf("%c", '\n');
st = tool78_ocd_exec(&tool78_hw_rl78_uart1);
printf("exec res 0x%02x\n", st);
uint8_t stuff[16];
int rr = tool78_hw_rl78_uart1.recv(1, stuff, 1000);
printf("rr=%d\n", rr);
if (rr == 1) printf("0x%02x %c\n", stuff[0], stuff[0]);
st = tool78_ocd_version(&tool78_hw_rl78_uart1, &ver);
printf("ver res 0x%02x %04x\n", st, ver);
}
int main() {
stdio_init_all();
//tool78_testtest();
tool78_prototest();
//tool78_prototest();
//tool78_ocdtest();
//piotest();
delaytest();
return 0;
}

96
src/test/delay.pio

@ -0,0 +1,96 @@
.program delayt1
_start:
wait 1 pin 0
irq set 0
.program delayt2
_start:
pull
set pins, 1 [31]
nop [31]
set pins, 0
.program delayt3
_start:
wait irq 0
set pins, 1 [31]
nop [31]
set pins, 0
% c-sdk {
#include <hardware/clocks.h>
static inline void delayt1_program_init(PIO pio, uint sm, uint offset,
uint pin, bool en) {
pio_gpio_init(pio, pin);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, false);
pio_sm_config c = delayt1_program_get_default_config(offset);
sm_config_set_in_pins(&c, pin);
sm_config_set_clkdiv(&c, 1);
pio_sm_init(pio, sm, offset, &c);
pio->input_sync_bypass = (1u<<pin);
pio_sm_set_enabled(pio, sm, en);
}
static inline void delayt1_wait_irqflag(PIO pio) {
while (!(pio->irq & (1<<0))) ;
}
static inline void delayt1_ack_irqflag(PIO pio) {
hw_set_bits(&pio->irq, (1<<0));
}
static inline void delayt1_irq_enable(PIO pio) {
pio_set_irq1_source_enabled(pio, pis_interrupt0, true);
}
static inline void delayt2_program_init(PIO pio, uint sm, uint offset,
uint pin, bool en) {
pio_gpio_init(pio, pin);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
pio_sm_config c = delayt2_program_get_default_config(offset);
sm_config_set_out_pins(&c, pin, 1);
sm_config_set_set_pins(&c, pin, 1);
sm_config_set_clkdiv(&c, 1);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, en);
}
static inline void delayt2_put(PIO pio, uint sm, uint v) {
pio->txf[sm] = v;
}
static inline void delayt3_program_init(PIO pio, uint sm, uint offset,
uint pin, bool en) {
pio_gpio_init(pio, pin);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
pio_sm_config c = delayt3_program_get_default_config(offset);
sm_config_set_out_pins(&c, pin, 1);
sm_config_set_set_pins(&c, pin, 1);
sm_config_set_clkdiv(&c, 1);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, en);
}
static inline void delayt3_put(PIO pio) {
hw_set_bits(&pio->irq_force, (1<<0));
}
%}

439
src/test/delaytest.c

@ -0,0 +1,439 @@
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <RP2040.h>
#include <system_RP2040.h>
#include <core_cm0plus.h>
#include <hardware/structs/iobank0.h>
#include <hardware/clocks.h>
#include <hardware/gpio.h>
#include <hardware/irq.h>
#include <hardware/vreg.h>
#include <pico/multicore.h>
#include <pico/platform.h>
#include <pico/stdlib.h>
#include "delaytest.h"
#include "delay.pio.h"
enum test {
test_gpio_busyloop,
test_gpio_irq_handle,
test_gpio_irq_wfi,
test_pio_if_busyloop,
test_pio_if_irq_handle,
test_pio_if_irq_wfi,
test_pio_fifo,
test_pio_irq,
test_core0_mem,
test_core0_fifo_busyloop,
test_core0_fifo_irq_handle,
test_core0_fifo_irq_wfi,
test_core0_wfe,
test__num
};
#define PIN_HIGH 8
#define PIN_TRIG_IN 9
#define PIN_TRIG_OUT 10
#define PIN_CORE0_TRG 15
typedef void (*test_fn)(void);
static volatile uint32_t shvar = 0;
__attribute__((__section__(".scratch_y.core1_init")))
static void core1_init(void);
__attribute__((__section__(".scratch_y.core1_irq")))
static void core1_irq(void) {
sio_hw->gpio_set = 1<<PIN_TRIG_OUT;
busy_wait_us_32(100);
sio_hw->gpio_clr = 1<<PIN_TRIG_OUT;
const int irq = SIO_IRQ_PROC1;
const int gpio = PIN_TRIG_IN;
const int event = GPIO_IRQ_EDGE_RISE;
// acknowledge all IRQs
irq_set_enabled(irq, false);
iobank0_hw->intr[gpio>>3] = event << 4*(gpio&7);
delayt1_ack_irqflag(pio0);
multicore_fifo_drain();
multicore_fifo_clear_irq();
irq_set_enabled(irq, true);
}
__attribute__((__section__(".scratch_y.t_gpio_busyloop")))
static void t_gpio_busyloop(void) {
core1_init();
while (true) {
// ldr; tst; beq.n loop
while (!(sio_hw->gpio_in & (1<<PIN_TRIG_IN))) ;
sio_hw->gpio_set = 1<<PIN_TRIG_OUT;
busy_wait_us_32(100);
sio_hw->gpio_clr = 1<<PIN_TRIG_OUT;
}
}
__attribute__((__section__(".scratch_y.t_gpio_irq_handle")))
static void t_gpio_irq_handle(void) {
core1_init();
const int gpio = PIN_TRIG_IN;
const int irq = IO_IRQ_BANK0;
const int event = GPIO_IRQ_EDGE_RISE;
irq_set_enabled(irq, false);
iobank0_hw->intr[gpio>>3] = event << 4*(gpio&7); // acknowledge irq
irq_set_priority(irq, PICO_HIGHEST_IRQ_PRIORITY);
hw_set_bits(&iobank0_hw->proc1_irq_ctrl.inte[gpio>>3], event << 4*(gpio&7));
irq_set_exclusive_handler(irq, core1_irq);
irq_set_enabled(irq, true);
while (true) ;
}
__attribute__((__section__(".scratch_y.t_gpio_irq_wfi")))
static void t_gpio_irq_wfi(void) {
core1_init();
const int gpio = PIN_TRIG_IN;
const int irq = IO_IRQ_BANK0;
const int event = GPIO_IRQ_EDGE_RISE;
irq_set_enabled(irq, false);
iobank0_hw->intr[gpio>>3] = event << 4*(gpio&7); // acknowledge irq
irq_set_priority(irq, PICO_HIGHEST_IRQ_PRIORITY);
hw_set_bits(&iobank0_hw->proc1_irq_ctrl.inte[gpio>>3], event << 4*(gpio&7));
// only enable in ^, hope wfi works w/o doing a PendSV
//irq_set_exclusive_handler(irq, core1_irq);
__disable_irq();
irq_set_enabled(irq, true);
while (true) {
__WFI();
sio_hw->gpio_set = 1<<PIN_TRIG_OUT;
irq_set_enabled(irq, false);
iobank0_hw->intr[gpio>>3] = event << 4*(gpio&7); // acknowledge irq
busy_wait_us_32(100);
irq_set_enabled(irq, true);
sio_hw->gpio_clr = 1<<PIN_TRIG_OUT;
}
}
__attribute__((__section__(".scratch_y.t_pio_if_busyloop")))
static void t_pio_if_busyloop(void) {
uint off = pio_add_program(pio0, &delayt1_program);
delayt1_program_init(pio0, 0, off, PIN_TRIG_IN, true);
while (true) {
delayt1_wait_irqflag(pio0);
sio_hw->gpio_set = 1<<PIN_TRIG_OUT;
delayt1_ack_irqflag(pio0);
busy_wait_us_32(100);
sio_hw->gpio_clr = 1<<PIN_TRIG_OUT;
}
}
__attribute__((__section__(".scratch_y.t_pio_if_irq_handle")))
static void t_pio_if_irq_handle(void) {
uint off = pio_add_program(pio0, &delayt1_program);
delayt1_program_init(pio0, 0, off, PIN_TRIG_IN, true);
const int irq = PIO0_IRQ_1;
irq_set_enabled(irq, false);
delayt1_ack_irqflag(pio0);
irq_set_priority(irq, PICO_HIGHEST_IRQ_PRIORITY);
delayt1_irq_enable(pio0);
irq_set_exclusive_handler(irq, core1_irq);
irq_set_enabled(irq, true);
while (true) ;
}
__attribute__((__section__(".scratch_y.t_pio_if_irq_wfi")))
static void t_pio_if_irq_wfi(void) {
uint off = pio_add_program(pio0, &delayt1_program);
delayt1_program_init(pio0, 0, off, PIN_TRIG_IN, true);
const int irq = PIO0_IRQ_1;
irq_set_enabled(irq, false);
delayt1_ack_irqflag(pio0);
irq_set_priority(irq, PICO_HIGHEST_IRQ_PRIORITY);
delayt1_irq_enable(pio0);
//irq_set_exclusive_handler(irq, core1_irq);
__disable_irq();
irq_set_enabled(irq, true);
while (true) {
__WFI();
sio_hw->gpio_set = 1<<PIN_TRIG_OUT;
irq_set_enabled(irq, false);
delayt1_ack_irqflag(pio0);
busy_wait_us_32(100);
irq_set_enabled(irq, true);
sio_hw->gpio_clr = 1<<PIN_TRIG_OUT;
}
}
__attribute__((__section__(".scratch_y.t_pio_fifo")))
static void t_pio_fifo(void) {
uint off = pio_add_program(pio0, &delayt2_program);
delayt2_program_init(pio0, 0, off, PIN_TRIG_OUT, true);
const int gpio = PIN_TRIG_IN;
const int irq = IO_IRQ_BANK0;
const int event = GPIO_IRQ_EDGE_RISE;
irq_set_enabled(irq, false);
iobank0_hw->intr[gpio>>3] = event << 4*(gpio&7); // acknowledge irq
irq_set_priority(irq, PICO_HIGHEST_IRQ_PRIORITY);
hw_set_bits(&iobank0_hw->proc1_irq_ctrl.inte[gpio>>3], event << 4*(gpio&7));
__disable_irq();
irq_set_enabled(irq, true);
while (true) {
__WFI();
delayt2_put(pio0, 0, 1);
//sio_hw->gpio_set = 1<<PIN_TRIG_OUT;
irq_set_enabled(irq, false);
iobank0_hw->intr[gpio>>3] = event << 4*(gpio&7); // acknowledge irq
busy_wait_us_32(100);
irq_set_enabled(irq, true);
//sio_hw->gpio_clr = 1<<PIN_TRIG_OUT;
}
}
__attribute__((__section__(".scratch_y.t_pio_irq")))
static void t_pio_irq(void) {
uint off = pio_add_program(pio0, &delayt3_program);
delayt3_program_init(pio0, 0, off, PIN_TRIG_OUT, true);
const int gpio = PIN_TRIG_IN;
const int irq = IO_IRQ_BANK0;
const int event = GPIO_IRQ_EDGE_RISE;
irq_set_enabled(irq, false);
iobank0_hw->intr[gpio>>3] = event << 4*(gpio&7); // acknowledge irq
irq_set_priority(irq, PICO_HIGHEST_IRQ_PRIORITY);
hw_set_bits(&iobank0_hw->proc1_irq_ctrl.inte[gpio>>3], event << 4*(gpio&7));
__disable_irq();
irq_set_enabled(irq, true);
while (true) {
__WFI();
delayt3_put(pio0);
//sio_hw->gpio_set = 1<<PIN_TRIG_OUT;
irq_set_enabled(irq, false);
iobank0_hw->intr[gpio>>3] = event << 4*(gpio&7); // acknowledge irq
busy_wait_us_32(100);
irq_set_enabled(irq, true);
//sio_hw->gpio_clr = 1<<PIN_TRIG_OUT;
}
}
__attribute__((__section__(".scratch_y.t_core0_mem")))
static void t_core0_mem(void) {
while (true) {
while (!shvar) ;
sio_hw->gpio_set = 1<<PIN_TRIG_OUT;
busy_wait_us_32(100);
shvar = 0;
sio_hw->gpio_clr = 1<<PIN_TRIG_OUT;
}
}
__attribute__((__section__(".scratch_y.t_core0_wfe")))
static void t_core0_wfe(void) {
while (true) {
__WFE();
sio_hw->gpio_set = 1<<PIN_TRIG_OUT;
busy_wait_us_32(100);
shvar = 0;
sio_hw->gpio_clr = 1<<PIN_TRIG_OUT;
}
}
__attribute__((__section__(".scratch_y.t_core0_fifo_busyloop")))
static void t_core0_fifo_busyloop(void) {
while (true) {
while (!multicore_fifo_rvalid()) ;
sio_hw->gpio_set = 1<<PIN_TRIG_OUT;
busy_wait_us_32(100);
multicore_fifo_drain();
sio_hw->gpio_clr = 1<<PIN_TRIG_OUT;
}
}
__attribute__((__section__(".scratch_y.t_core0_fifo_irq_handle")))
static void t_core0_fifo_irq_handle(void) {
const int irq = SIO_IRQ_PROC1;
irq_set_enabled(irq, false);
multicore_fifo_clear_irq();
irq_set_priority(irq, PICO_HIGHEST_IRQ_PRIORITY);
delayt1_irq_enable(pio0);
irq_set_exclusive_handler(irq, core1_irq);
irq_set_enabled(irq, true);
while (true) ;
}
__attribute__((__section__(".scratch_y.t_core0_fifo_irq_wfi")))
static void t_core0_fifo_irq_wfi(void) {
const int irq = SIO_IRQ_PROC1;
irq_set_enabled(irq, false);
multicore_fifo_clear_irq();
irq_set_priority(irq, PICO_HIGHEST_IRQ_PRIORITY);
delayt1_irq_enable(pio0);
//irq_set_exclusive_handler(irq, core1_irq);
__disable_irq();
irq_set_enabled(irq, true);
while (true) {
__WFI();
sio_hw->gpio_set = 1<<PIN_TRIG_OUT;
irq_set_enabled(irq, false);
multicore_fifo_drain();
multicore_fifo_clear_irq();
busy_wait_us_32(100);
irq_set_enabled(irq, true);
sio_hw->gpio_clr = 1<<PIN_TRIG_OUT;
}
}
static test_fn tests[] = {
// delays: (units are ns, 40ns=1cyc@25MHz, so 200ns=5cyc)
// 300 400 400 320 260 380 320 300 360 300
// 320 320 400 280 300 400 360 260 280 280
// 360 340 360 300 300 380 380 280 300 340
//(240 300 340 360 360 300 400 300 260 380
// 360 320 260 260 340 380 260 360 340 340)
[test_gpio_busyloop] = t_gpio_busyloop,
// 1520 1520 1520 1500 1500 1500 1520 1520 1500 1500
// 1500 1480 1500 1500 1520 1500 1500 1500 1500 1520
[test_gpio_irq_handle] = t_gpio_irq_handle,
// 360 380 380 380 380 380 380 380 380 360
//(380 360 380 400 380 380 380 380 380 380
// 420 400 400 400 360 380 400 380 400 380)
[test_gpio_irq_wfi] = t_gpio_irq_wfi,
// these depend on the PIO SM wake insn resuming and then setting the irq
// flag, which has a 2 cycle delay in total (but basically no variance)
// 660 500 580 540 280 540 680 640 660 540
// 620 520 540 540 540 540 600 560 500 480
// 520 600 600 520 620 480 600 640 600 620
// 620 660 580 680 660 620 560 480 580 540
[test_pio_if_busyloop] = t_pio_if_busyloop,
// 1380 1460 1480 1480 1460 1360 1400 1460 1480 1480
// 1400 1460 1440 1360 1460 1460 1460 1440 1380 1500
[test_pio_if_irq_handle] = t_pio_if_irq_handle,
// 560 540 560 560 520 580 540 540 540 560
// 560 0 540 540 560 540 560 560 560 560 580
//(540 560 220 560 540 560 560 540 540 540
// 560 560 540 520 540 560 540 540 560 520)
[test_pio_if_irq_wfi] = t_pio_if_irq_wfi,
// 500 500 520 520 500 520 520 500 520 520
// 520 520 500 500 520 520 480 480 500 500
[test_pio_fifo] = t_pio_fifo,
// 520 500 500 500 500 500 500 500 520 520
// 500 500 520 500 500 500 500 500 500 500
[test_pio_irq ] = t_pio_irq,
// these depend on core0 using a GPIO trigger using WFI, so this is a bit
// more complicated. N_obsv = N_gpio_irq_wfi + N_core0
// => x_core0 = x_obsv - x_gpio_irq_wfi
// => σ_core0 = sqrt(σ²_obsv - σ²_gpio_irq_wfi)
// 740 660 680 640 580 640 740 660 700 640
// 660 580 720 680 740 620 620 660 640 660
[test_core0_mem] = t_core0_mem,
// 520 540 540 540 560 560 540 520 560 540
// 540 560 520 540 540 520 560 540 560 540
[test_core0_wfe] = t_core0_wfe,
// 740 640 700 620 600 720 660 660 600 720
// 560 660 600 680 660 580 740 560 700 700
[test_core0_fifo_busyloop] = t_core0_fifo_busyloop,
// 1460 1480 1500 1480 1520 1500 1540 1520 1500 1500
// 1540 1520 1520 1520 1520 1500 1540 1500 1500 1520
[test_core0_fifo_irq_handle] = t_core0_fifo_irq_handle,
// 780 760 800 800 780 800 780 780 780 800
// 800 760 800 800 800 820 780 780 800 780
[test_core0_fifo_irq_wfi] = t_core0_fifo_irq_wfi,
[test__num] = NULL,
};
__attribute__((__section__(".scratch_y.core1_init")))
static void core1_init(void) {
SCB->SCR &= ~SCB_SCR_SEVONPEND_Msk;
// TODO: IRQ stuff?
// TODO: * set core1 irq as used irqs
}
__attribute__((__section__(".scratch_x.delaytest")))
void delaytest(void) {
vreg_set_voltage(VREG_VOLTAGE_1_15);
set_sys_clock_khz(25*1000, true);
gpio_set_function(PIN_HIGH , GPIO_FUNC_SIO);
gpio_set_function(PIN_TRIG_IN , GPIO_FUNC_SIO);
gpio_set_function(PIN_TRIG_OUT , GPIO_FUNC_SIO);
gpio_set_function(PIN_CORE0_TRG, GPIO_FUNC_SIO);
gpio_set_dir(PIN_HIGH , GPIO_OUT);
gpio_set_dir(PIN_TRIG_IN , GPIO_IN );
gpio_set_dir(PIN_TRIG_OUT , GPIO_OUT);
gpio_set_dir(PIN_CORE0_TRG, GPIO_IN );
gpio_put(PIN_HIGH, true);
gpio_put(PIN_TRIG_OUT, false);
SCB->SCR &= ~SCB_SCR_SEVONPEND_Msk;
const enum test t = test_pio_fifo;
if (t <= test_core0_mem || t >= test_core0_wfe)
__disable_irq();
multicore_launch_core1(tests[t]);
if (t >= test_core0_mem && t <= test_core0_wfe) {
const int gpio = PIN_TRIG_IN;
const int irq = IO_IRQ_BANK0;
const int event = GPIO_IRQ_EDGE_RISE;
irq_set_enabled(irq, false);
iobank0_hw->intr[gpio>>3] = event << 4*(gpio&7); // acknowledge irq
irq_set_priority(irq, PICO_HIGHEST_IRQ_PRIORITY);
hw_set_bits(&iobank0_hw->proc0_irq_ctrl.inte[gpio>>3], event << 4*(gpio&7));
__disable_irq();
irq_set_enabled(irq, true);
while (true) {
__WFI();
sio_hw->fifo_wr = 1;//__SEV();//shvar = 1;//
irq_set_enabled(irq, false);
iobank0_hw->intr[gpio>>3] = event << 4*(gpio&7); // acknowledge irq
busy_wait_us_32(100);
irq_set_enabled(irq, true);
}
} else while (true) ;
}

8
src/test/delaytest.h

@ -0,0 +1,8 @@
#ifndef DELAYTEST_H_
#define DELAYTEST_H_
void delaytest(void);
#endif

127
src/test/stat.py

@ -0,0 +1,127 @@
#!/usr/bin/env python3
from math import *
pio_reference = ("PIO reference\t", 1, None, [2*40])
test_gpio_busyloop = ("GPIO busyloop\t", 40, None, [ # N=40
300, 400, 400, 320, 260, 380, 320, 300, 360, 300,
320, 320, 400, 280, 300, 400, 360, 260, 280, 280,
360, 340, 360, 300, 300, 380, 380, 280, 300, 340,
300, 400, 400, 320, 260, 380, 320, 300, 360, 300,
320, 320, 400, 280, 300, 400, 360, 260, 280, 280,
360, 340, 360, 300, 300, 380, 380, 280, 300, 340,
240, 300, 340, 360, 360, 300, 400, 300, 260, 380,
360, 320, 260, 260, 340, 380, 260, 360, 340, 340,
])
test_gpio_irq_handle = ("GPIO IRQ handler", 20, None, [ # N=20
1520, 1520, 1520, 1500, 1500, 1500, 1520, 1520, 1500, 1500,
1500, 1480, 1500, 1500, 1520, 1500, 1500, 1500, 1500, 1520,
])
test_gpio_irq_wfi = ("GPIO IRQ WFI\t", 30, None, [ # N=30
360, 380, 380, 380, 380, 380, 380, 380, 380, 360,
360, 380, 380, 380, 380, 380, 380, 380, 380, 360,
380, 360, 380, 400, 380, 380, 380, 380, 380, 380,
420, 400, 400, 400, 360, 380, 400, 380, 400, 380,
])
test_pio_if_busyloop = ("PIO IrqFlag busyloop", 40, 0, [ # N=40
660, 500, 580, 540, 280, 540, 680, 640, 660, 540,
620, 520, 540, 540, 540, 540, 600, 560, 500, 480,
520, 600, 600, 520, 620, 480, 600, 640, 600, 620,
620, 660, 580, 680, 660, 620, 560, 480, 580, 540,
])
test_pio_if_irq_handle = ("PIO IrqFlag IRQ handler", 20, 0, [ # N=20
1380, 1460, 1480, 1480, 1460, 1360, 1400, 1460, 1480, 1480,
1400, 1460, 1440, 1360, 1460, 1460, 1460, 1440, 1380, 1500,
])
test_pio_if_irq_wfi = ("PIO IrqFlag IRQ WFI", 39, 0, [ # N=39 ; has weird outliers (0 and 220 cyc)
560, 540, 560, 560, 520, 580, 540, 540, 540, 560,
560, 580, 540, 540, 560, 540, 560, 560, 560, 560,
540, 560, 560, 540, 560, 560, 540, 540, 540,
560, 560, 540, 520, 540, 560, 540, 540, 560, 520,
])
test_pio_fifo = ("PIO CPU FIFO->SM", 20, 3, [
500, 500, 520, 520, 500, 520, 520, 500, 520, 520,
520, 520, 500, 500, 520, 520, 480, 480, 500, 500,
])
test_pio_irq = ("PIO CPU IRQ->SM\t", 20, 3, [
520, 500, 500, 500, 500, 500, 500, 500, 520, 520,
500, 500, 520, 500, 500, 500, 500, 500, 500, 500,
])
test_core0_mem = ("core0 memory busyloop", 20, 3, [ # N=20
740, 660, 680, 640, 580, 640, 740, 660, 700, 640,
660, 580, 720, 680, 740, 620, 620, 660, 640, 660,
])
test_core0_wfe = ("core0 SEV/WFE\t", 20, 3, [ # N=20
520, 540, 540, 540, 560, 560, 540, 520, 560, 540,
540, 560, 520, 540, 540, 520, 560, 540, 560, 540,
])
test_core0_fifo_busyloop = ("core0 FIFO busyloop", 20, 3, [ # N=20
740, 640, 700, 620, 600, 720, 660, 660, 600, 720,
560, 660, 600, 680, 660, 580, 740, 560, 700, 700,
])
test_core0_fifo_irq_handle = ("core0 FIFO IRQ handler", 20, 3, [ # N=20
1460, 1480, 1500, 1480, 1520, 1500, 1540, 1520, 1500, 1500,
1540, 1520, 1520, 1520, 1520, 1500, 1540, 1500, 1500, 1520,
])
test_core0_fifo_irq_wfi = ("core0 FIFO IRQ WFI", 20, 3, [ # N=20
780, 760, 800, 800, 780, 800, 780, 780, 780, 800,
800, 760, 800, 800, 800, 820, 780, 780, 800, 780,
])
all_stats = [
pio_reference,
test_gpio_busyloop,
test_gpio_irq_handle,
test_gpio_irq_wfi,
test_pio_if_busyloop,
test_pio_if_irq_handle,
test_pio_if_irq_wfi,
test_pio_fifo,
test_pio_irq,
test_core0_mem,
test_core0_wfe,
test_core0_fifo_busyloop,
test_core0_fifo_irq_handle,
test_core0_fifo_irq_wfi,
]
def calc_avg(data): return sum(data)/len(data)
def calc_var(data, avg=None):
if avg is None: avg = calc_avg(data)
return sum((x-avg)**2 for x in data) / len(data)
refs = {}
i = 0
for name, Nnom, ref, data in all_stats:
avg = calc_avg(data)
var = calc_var(data, avg)
refs[i] = (avg, var); i=i+1
Aavg, Avar = avg, var
if ref is not None:
Ravg, Rvar = refs[ref]
avg = avg - Ravg
var = var - Rvar
if i != 1:
#print("%s\tN=%2d x=%04.2f σ=%2.2f" % (name, Nnom, Aavg, sqrt(Avar)))
str_avg = "%04.2f" % avg
str_avg = ' '*(7-len(str_avg)) + str_avg
if var < 0:
str_dev = "0 (Var orig=%.2f; Var other=%.2f)" % (Avar, Rvar)
else:
str_dev = "%02.2f" % sqrt(var)
str_dev = ' '*(5-len(str_dev)) + str_dev
print("%s\tN=%2d x=%s σ=%s" % (name, Nnom, str_avg, str_dev))

24
src/tool78/tool78_cmds.c

@ -813,13 +813,17 @@ int tool78_ocd_read(struct tool78_hw* hw, uint16_t off, uint8_t len,
hdr[3] = len;
int rr = hw->send(sizeof hdr, hdr, -1);
rr = hw->recv(1, &hdr[2], 1000);
// last byte of header sent echoed back
if (rr != 1 || hdr[2] != hdr[3]) return -2;
rr = hw->recv(len, data, 1000*len);
printf("ocd read %d\n", rr);
//printf("ocd read %d\n", rr);
return (rr == len) ? 0 : -1;
}
int tool78_ocd_write(struct tool78_hw* hw, uint16_t addr, uint8_t len,
const uint8_t* data) {
if (len == 0) return -1;
busy_wait_ms(1);
uint8_t hdr[4];
@ -831,21 +835,23 @@ int tool78_ocd_write(struct tool78_hw* hw, uint16_t addr, uint8_t len,
int rr = hw->send(sizeof hdr, hdr, -1);
rr = hw->send(len, data, -1);
rr = hw->recv(1, hdr, 1000*len);
if (rr != 1) return -1;
return (hdr[0] == tool78ocd_cmd_write) ? 0 : -2;
// last data byte echoed back
rr = hw->recv(2, hdr, 1000*len);
if (rr != 2) return -1;
///printf("ocd write 0x%02x\n", hdr[1]);
return (hdr[1] == tool78ocd_cmd_write) ? 0 : -2;
}
int tool78_ocd_exec(struct tool78_hw* hw) {
busy_wait_ms(1);
uint8_t hdr[1];
uint8_t hdr[2];
hdr[0] = tool78ocd_cmd_exec;
int rr = hw->send(sizeof hdr, hdr, -1);
int rr = hw->send(1, hdr, -1);
rr = hw->recv(1, hdr, 1000);
if (rr != 1) return -1;
rr = hw->recv(2, hdr, 1000);
if (rr != 1 && rr != 2) return -1;
printf("h[0]=0x%02x, h[1]=0x%02x\n", hdr[0], hdr[1]);
return (hdr[0] == tool78ocd_cmd_exec) ? 0 : -2;
}

5
test/rl78/test.S

@ -10,6 +10,11 @@ ch2&3: TxD1,RxD1
.global _start
_start:
mov a, #'a'
call !!0xeffa1
ret
call !hw_init
call !port_init

Loading…
Cancel
Save