diff options
Diffstat (limited to 'openpcd/firmware/src/main_dumbreader.c')
-rw-r--r-- | openpcd/firmware/src/main_dumbreader.c | 99 |
1 files changed, 86 insertions, 13 deletions
diff --git a/openpcd/firmware/src/main_dumbreader.c b/openpcd/firmware/src/main_dumbreader.c index e59b4b6..0447ca2 100644 --- a/openpcd/firmware/src/main_dumbreader.c +++ b/openpcd/firmware/src/main_dumbreader.c @@ -9,6 +9,8 @@ #include "openpcd.h" #include "main.h" +#define MAX_PAYLOAD_LEN (64 - sizeof(struct openpcd_hdr)) + static int usb_in(struct req_ctx *rctx) { struct openpcd_hdr *poh = (struct openpcd_hdr *) &rctx->rx.data[0]; @@ -20,21 +22,57 @@ static int usb_in(struct req_ctx *rctx) if (len < sizeof(*poh)) return -EINVAL; - //data_len = ntohs(poh->len); - memcpy(pih, poh, sizeof(*poh)); rctx->tx.tot_len = sizeof(*poh); switch (poh->cmd) { case OPENPCD_CMD_READ_REG: - DEBUGP("READ REG(0x%02x) ", poh->reg); rc632_reg_read(RAH, poh->reg, &pih->val); + DEBUGP("READ REG(0x%02x)=0x%02x ", poh->reg, pih->val); + goto respond; break; case OPENPCD_CMD_READ_FIFO: - DEBUGP("READ FIFO(len=%u) ", poh->val); - rc632_fifo_read(RAH, poh->val, pih->data); - rctx->tx.tot_len += pih->len; + { + u_int16_t tot_len = poh->val, remain_len; + if (tot_len > MAX_PAYLOAD_LEN) { + pih->len = MAX_PAYLOAD_LEN; + remain_len -= pih->len; + rc632_fifo_read(RAH, pih->len, pih->data); + rctx->tx.tot_len += pih->len; + DEBUGP("READ FIFO(len=%u)=%s ", pih->len, + hexdump(pih->data, poh->val)); + req_ctx_set_state(rctx, RCTX_STATE_UDP_EP2_PENDING); + udp_refill_ep(2, rctx); + + /* get and initialize second rctx */ + rctx = req_ctx_find_get(RCTX_STATE_FREE, + RCTX_STATE_MAIN_PROCESSING); + if (!rctx) { + DEBUGPCRF("FATAL_NO_RCTX!!!\n"); + break; + } + poh = (struct openpcd_hdr *) &rctx->rx.data[0]; + pih = (struct openpcd_hdr *) &rctx->tx.data[0]; + memcpy(pih, poh, sizeof(*poh)); + rctx->tx.tot_len = sizeof(*poh); + + pih->len = remain_len; + rc632_fifo_read(RAH, pih->len, pih->data); + rctx->tx.tot_len += pih->len; + DEBUGP("READ FIFO(len=%u)=%s ", pih->len, + hexdump(pih->data, poh->val)); + /* don't set state of second rctx, main function + * body will do this after switch statement */ + } else { + pih->len = poh->val; + rc632_fifo_read(RAH, poh->val, pih->data); + rctx->tx.tot_len += pih->len; + DEBUGP("READ FIFO(len=%u)=%s ", poh->val, + hexdump(pih->data, poh->val)); + } + goto respond; break; + } case OPENPCD_CMD_WRITE_REG: DEBUGP("WRITE_REG(0x%02x, 0x%02x) ", poh->reg, poh->val); rc632_reg_write(RAH, poh->reg, poh->val); @@ -48,6 +86,7 @@ static int usb_in(struct req_ctx *rctx) case OPENPCD_CMD_READ_VFIFO: DEBUGP("READ VFIFO "); DEBUGP("NOT IMPLEMENTED YET "); + goto respond; break; case OPENPCD_CMD_WRITE_VFIFO: DEBUGP("WRITE VFIFO "); @@ -65,20 +104,33 @@ static int usb_in(struct req_ctx *rctx) DEBUGP("SET LED(%u,%u) ", poh->reg, poh->val); led_switch(poh->reg, poh->val); break; + case OPENPCD_CMD_DUMP_REGS: + DEBUGP("DUMP REGS "); + DEBUGP("NOT IMPLEMENTED YET "); + goto respond; + break; default: + DEBUGP("UNKNOWN "); return -EINVAL; + break; } - DEBUGPCRF("calling UDP_Write"); - AT91F_UDP_Write(0, &rctx->tx.data[0], rctx->tx.tot_len); - DEBUGPCRF("usb_in: returning to main"); - + req_ctx_put(rctx); return 0; + +respond: + req_ctx_set_state(rctx, RCTX_STATE_UDP_EP2_PENDING); + /* FIXME: we could try to send this immediately */ + udp_refill_ep(2, rctx); + DEBUGPCR(""); + + return 1; } void _init_func(void) { rc632_init(); udp_init(); + rc632_test(RAH); } int _main_dbgu(char key) @@ -90,11 +142,32 @@ void _main_func(void) { struct req_ctx *rctx; - for (rctx = req_ctx_find_busy(); rctx; - rctx = req_ctx_find_busy()) { + /* first we try to get rid of pending to-be-sent stuff */ + while (rctx = req_ctx_find_get(RCTX_STATE_UDP_EP3_PENDING, + RCTX_STATE_UDP_EP3_BUSY)) { + DEBUGPCRF("EP3_BUSY for ctx %u", req_ctx_num(rctx)); + if (udp_refill_ep(3, rctx) < 0) + req_ctx_set_state(rctx, RCTX_STATE_UDP_EP3_PENDING); + } + +#if 0 + while (rctx = req_ctx_find_get(RCTX_STATE_UDP_EP2_PENDING, + RCTX_STATE_UDP_EP2_BUSY)) { + DEBUGPCRF("EP2_BUSY for ctx %u", req_ctx_num(rctx)); + if (udp_refill_ep(2, rctx) < 0) + req_ctx_set_state(rctx, RCTX_STATE_UDP_EP2_PENDING); + } +#endif + + /* next we deal with incoming reqyests from USB EP1 */ + while (rctx = req_ctx_find_get(RCTX_STATE_UDP_RCV_DONE, + RCTX_STATE_MAIN_PROCESSING)) { DEBUGPCRF("found used ctx %u: len=%u", req_ctx_num(rctx), rctx->rx.tot_len); usb_in(rctx); - req_ctx_put(rctx); + } + + rc632_unthrottle(); + udp_unthrottle(); } |