Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
Triss | 425391a3a8 |
|
@ -33,8 +33,8 @@ if(FAMILY STREQUAL "rp2040")
|
|||
family_initialize_project(PROJECT ${CMAKE_CURRENT_LIST_DIR}) # calls pico_sdk_init()
|
||||
#pico_sdk_init()
|
||||
|
||||
#pico_set_program_name(${PROJECT} "${PROJECT}")
|
||||
#pico_set_program_version(${PROJECT} "0.1")
|
||||
#pico_set_program_name(PROJECT "${PROJECT}")
|
||||
#pico_set_program_version(PROJECT "0.1")
|
||||
|
||||
add_executable(${PROJECT})
|
||||
|
||||
|
@ -64,6 +64,8 @@ target_sources(${PROJECT} PUBLIC
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/tempsensor.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/unique.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/cdc_serprog.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/cdc_dynexec.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/dynexec.S
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/vnd_i2ctinyusb.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/rtconf.c
|
||||
|
|
|
@ -19,6 +19,7 @@ enum {
|
|||
#ifdef USE_USBCDC_FOR_STDIO
|
||||
CDC_N_STDIO,
|
||||
#endif
|
||||
CDC_N_DYNEXEC
|
||||
|
||||
CDC_N__NITF
|
||||
};
|
||||
|
@ -28,9 +29,9 @@ enum {
|
|||
|
||||
#define CFG_TUD_HID 1
|
||||
#ifdef USE_USBCDC_FOR_STDIO
|
||||
#define CFG_TUD_CDC 3
|
||||
#define CFG_TUD_CDC 4
|
||||
#else
|
||||
#define CFG_TUD_CDC 2
|
||||
#define CFG_TUD_CDC 3
|
||||
#endif
|
||||
#define CFG_TUD_VENDOR 0
|
||||
|
||||
|
|
12
dmctl.py
12
dmctl.py
|
@ -143,6 +143,14 @@ def main():
|
|||
#do_xfer(1, 1, "/dev/ttyACM1")
|
||||
#do_xfer(1, 0, "/dev/ttyACM1")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
#if __name__ == '__main__':
|
||||
# main()
|
||||
|
||||
with serial.Serial('/dev/ttyACM2', 115200, timeout=1) as ser:
|
||||
regs = [x+0x18 for x in range(8)]
|
||||
ops = [0x1889] # adds r1, r2
|
||||
olen = len(ops)
|
||||
|
||||
ser.write(struct.pack('<IIIIIIII', *regs))
|
||||
ser.write(struct.pack('<I', olen))
|
||||
ser.write(struct.pack('<'+('H'*olen), *ops))
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "tusb.h"
|
||||
|
||||
#include "protocfg.h"
|
||||
|
||||
#include "protos.h"
|
||||
#include "util.h"
|
||||
|
||||
extern uint32_t dynexec_regs[8];
|
||||
uint32_t dynexec_regs[8];
|
||||
extern uint32_t dynexec_codesize;
|
||||
uint32_t dynexec_codesize;
|
||||
extern void* dynexec_code;
|
||||
void* dynexec_code;
|
||||
|
||||
static uint32_t codecap;
|
||||
static uint16_t codestatic[32];
|
||||
|
||||
static uint8_t rx_buf[CFG_TUD_CDC_RX_BUFSIZE];
|
||||
static uint32_t rxavail, rxpos;
|
||||
|
||||
extern void dynexec_exec(void);
|
||||
|
||||
void cdc_dynexec_init(void) {
|
||||
dynexec_codesize = 0;
|
||||
memset(dynexec_regs, 0, sizeof dynexec_regs);
|
||||
|
||||
codecap = 32;
|
||||
dynexec_code = codestatic;
|
||||
}
|
||||
|
||||
static uint8_t read_byte(void) {
|
||||
while (rxavail <= 0) {
|
||||
if (!tud_cdc_n_connected(CDC_N_DYNEXEC) || !tud_cdc_n_available(CDC_N_DYNEXEC)) {
|
||||
thread_yield();
|
||||
continue;
|
||||
}
|
||||
|
||||
rxpos = 0;
|
||||
rxavail = tud_cdc_n_read(CDC_N_DYNEXEC, rx_buf, sizeof rx_buf);
|
||||
|
||||
if (rxavail == 0) thread_yield();
|
||||
}
|
||||
|
||||
uint8_t rv = rx_buf[rxpos];
|
||||
++rxpos;
|
||||
--rxavail;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static uint16_t read_hword(void) {
|
||||
uint16_t r;
|
||||
r = (uint16_t)read_byte();
|
||||
r |= (uint16_t)read_byte() << 8;
|
||||
return r;
|
||||
}
|
||||
static uint32_t read_word(void) {
|
||||
uint32_t r;
|
||||
r = (uint32_t)read_byte();
|
||||
r |= (uint32_t)read_byte() << 8;
|
||||
r |= (uint32_t)read_byte() << 16;
|
||||
r |= (uint32_t)read_byte() << 24;
|
||||
return r;
|
||||
}
|
||||
|
||||
struct dynexec_hdr {
|
||||
uint32_t regs[8];
|
||||
uint32_t codelen;
|
||||
};
|
||||
|
||||
void cdc_dynexec_task(void) {
|
||||
for (int i = 0; i < 8; ++i)
|
||||
dynexec_regs[i] = read_word();
|
||||
dynexec_codesize = read_word() /*+ 3*/;
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
printf("r%d = 0x%08x\n", i, dynexec_regs[i]);
|
||||
printf("codesize = 0x%04x\n", dynexec_codesize);
|
||||
|
||||
while (dynexec_codesize > codecap) {
|
||||
codecap <<= 1;
|
||||
|
||||
if (codecap == 64) {
|
||||
dynexec_code = malloc(codecap*sizeof(uint16_t));
|
||||
} else {
|
||||
dynexec_code = realloc(dynexec_code, codecap*sizeof(uint16_t));
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < dynexec_codesize; ++i) {
|
||||
((uint16_t*)dynexec_code)[2+i] = read_hword();
|
||||
}
|
||||
|
||||
// all little-endian...
|
||||
((uint16_t*)dynexec_code)[0] = 0xbc80; // pop {r7}
|
||||
((uint16_t*)dynexec_code)[1] = 0xb500; // push {lr}
|
||||
((uint16_t*)dynexec_code)[2+dynexec_codesize] = 0xbd00; // pop {pc}
|
||||
|
||||
for (uint32_t i = 0; i < dynexec_codesize+3; ++i) {
|
||||
printf("code[%u] = %04x\n", i, ((uint16_t*)dynexec_code)[i]);
|
||||
}
|
||||
|
||||
printf("exec!\n");
|
||||
dynexec_exec();
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
printf("r%d = 0x%08x\n", i, dynexec_regs[i]);
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
@ vim: set ft=armv5:
|
||||
|
||||
.cpu cortex-m0
|
||||
.thumb
|
||||
|
||||
.extern dynexec_regs
|
||||
.extern dynexec_code
|
||||
|
||||
.section .text.dynexec_exec, "ax", %progbits
|
||||
.type dynexec_exec, %function
|
||||
.thumb_func
|
||||
.global dynexec_exec
|
||||
dynexec_exec:
|
||||
push {r0-r7,lr}
|
||||
|
||||
@ load regs from saved ones
|
||||
ldr r7, =dynexec_regs
|
||||
ldmia r7!, {r0-r6}
|
||||
ldr r7, [r7]
|
||||
push {r7}
|
||||
|
||||
ldr r7, =dynexec_code
|
||||
ldr r7, [r7]
|
||||
add r7, #1 @ bluh
|
||||
blx r7
|
||||
|
||||
@ save regs in saved ones
|
||||
|
||||
push {r7}
|
||||
ldr r7, =dynexec_regs
|
||||
stmia r7!, {r0-r6}
|
||||
pop {r0}
|
||||
str r0, [r7]
|
||||
|
||||
pop {r0-r7,pc}
|
||||
|
||||
.pool
|
||||
|
||||
/*to_exec_code:
|
||||
pop {r7}
|
||||
push {lr}
|
||||
@ TODO
|
||||
pop {pc}*/
|
17
src/main.c
17
src/main.c
|
@ -82,6 +82,18 @@ static void serprog_thread_fn(void) {
|
|||
}
|
||||
#endif
|
||||
|
||||
static cothread_t dynexecthread;
|
||||
static uint8_t dynexecstack[DEFAULT_STACK_SIZE];
|
||||
|
||||
static void dynexec_thread_fn(void) {
|
||||
cdc_dynexec_init();
|
||||
thread_yield();
|
||||
while (1) {
|
||||
cdc_dynexec_task();
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME
|
||||
extern uint32_t co_active_buffer[64];
|
||||
uint32_t co_active_buffer[64];
|
||||
|
@ -114,6 +126,8 @@ int main(void) {
|
|||
serprogthread = co_derive(serprogstack, sizeof serprogstack, serprog_thread_fn);
|
||||
co_switch(serprogthread); // will call cdc_serprog_init() on correct thread
|
||||
#endif
|
||||
dynexecthread = co_derive(dynexecstack, sizeof dynexecstack, dynexec_thread_fn);
|
||||
co_switch(dynexecthread);
|
||||
#ifdef DBOARD_HAS_CMSISDAP
|
||||
DAP_Setup();
|
||||
#endif
|
||||
|
@ -139,6 +153,9 @@ int main(void) {
|
|||
#ifdef DBOARD_HAS_SERPROG
|
||||
co_switch(serprogthread);
|
||||
#endif
|
||||
|
||||
tud_task();
|
||||
co_switch(dynexecthread);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -33,5 +33,8 @@ void itu_init(void);
|
|||
void itu_task(void);
|
||||
#endif
|
||||
|
||||
void dynexec_init(void);
|
||||
void dynexec_task(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -100,6 +100,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
//------------- CLASS -------------//
|
||||
|
||||
#define CFG_TUD_MSC 0
|
||||
#define CFG_TUD_MIDI 0
|
||||
#define CFG_TUD_NET 0
|
||||
|
|
|
@ -57,6 +57,7 @@ enum {
|
|||
STRID_IF_CDC_UART,
|
||||
STRID_IF_CDC_SERPROG,
|
||||
STRID_IF_CDC_STDIO,
|
||||
STRID_IF_CDC_DYNEXEC,
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
|
@ -124,6 +125,8 @@ enum {
|
|||
ITF_NUM_CDC_SERPROG_COM,
|
||||
ITF_NUM_CDC_SERPROG_DATA,
|
||||
#endif
|
||||
ITF_NUM_CDC_DYNEXEC_COM,
|
||||
ITF_NUM_CDC_DYNEXEC_DATA,
|
||||
#ifdef USE_USBCDC_FOR_STDIO
|
||||
ITF_NUM_CDC_STDIO_COM,
|
||||
ITF_NUM_CDC_STDIO_DATA,
|
||||
|
@ -154,6 +157,7 @@ enum {
|
|||
#ifdef USE_USBCDC_FOR_STDIO
|
||||
+ TUD_CDC_DESC_LEN
|
||||
#endif
|
||||
+ TUD_CDC_DESC_LEN
|
||||
};
|
||||
|
||||
#define EPNUM_CDC_UART_OUT 0x02
|
||||
|
@ -163,9 +167,12 @@ enum {
|
|||
#define EPNUM_CDC_SERPROG_OUT 0x05
|
||||
#define EPNUM_CDC_SERPROG_IN 0x85
|
||||
#define EPNUM_CDC_SERPROG_NOTIF 0x86
|
||||
#define EPNUM_CDC_STDIO_OUT 0x07
|
||||
#define EPNUM_CDC_STDIO_IN 0x87
|
||||
#define EPNUM_CDC_STDIO_NOTIF 0x88
|
||||
#define EPNUM_CDC_DYNEXEC_OUT 0x07
|
||||
#define EPNUM_CDC_DYNEXEC_IN 0x87
|
||||
#define EPNUM_CDC_DYNEXEC_NOTIF 0x88
|
||||
#define EPNUM_CDC_STDIO_OUT 0x09
|
||||
#define EPNUM_CDC_STDIO_IN 0x89
|
||||
#define EPNUM_CDC_STDIO_NOTIF 0x8a
|
||||
|
||||
// NOTE: if you modify this table, don't forget to keep tusb_config.h up to date as well!
|
||||
// TODO: maybe add some strings to all these interfaces
|
||||
|
@ -188,6 +195,8 @@ uint8_t const desc_configuration[] = {
|
|||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_SERPROG_COM, STRID_IF_CDC_SERPROG, EPNUM_CDC_SERPROG_NOTIF, 64, EPNUM_CDC_SERPROG_OUT, EPNUM_CDC_SERPROG_IN, 64),
|
||||
#endif
|
||||
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_DYNEXEC_COM, STRID_IF_CDC_DYNEXEC, EPNUM_CDC_DYNEXEC_NOTIF, 64, EPNUM_CDC_DYNEXEC_OUT, EPNUM_CDC_DYNEXEC_IN, 64),
|
||||
|
||||
#ifdef USE_USBCDC_FOR_STDIO
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_STDIO_COM, STRID_IF_CDC_STDIO, EPNUM_CDC_STDIO_NOTIF, 64, EPNUM_CDC_STDIO_OUT, EPNUM_CDC_STDIO_IN, 64),
|
||||
#endif
|
||||
|
@ -218,6 +227,7 @@ char const* string_desc_arr [] = {
|
|||
[STRID_IF_CDC_UART] = "UART CDC interface",
|
||||
[STRID_IF_CDC_SERPROG] = "Serprog CDC interface",
|
||||
[STRID_IF_CDC_STDIO] = "stdio CDC interface (debug)",
|
||||
[STRID_IF_CDC_DYNEXEC] = "Dynamic execution CDC itf",
|
||||
};
|
||||
|
||||
// Invoked when received GET STRING DESCRIPTOR request
|
||||
|
|
Loading…
Reference in New Issue