From 14055f6e670862ee5aa204d70654e75226d523c3 Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@6dc7ffe9-61d6-0310-9af1-9938baff3ed1> Date: Tue, 8 Aug 2006 17:19:09 +0000 Subject: split usb handling from dumbreader main program git-svn-id: https://svn.openpcd.org:2342/trunk@83 6dc7ffe9-61d6-0310-9af1-9938baff3ed1 --- openpcd/firmware/Makefile | 1 + openpcd/firmware/src/main_dumbreader.c | 132 +---------------------------- openpcd/firmware/src/usb_handler.c | 148 +++++++++++++++++++++++++++++++++ openpcd/firmware/src/usb_handler.h | 6 ++ 4 files changed, 158 insertions(+), 129 deletions(-) create mode 100644 openpcd/firmware/src/usb_handler.c create mode 100644 openpcd/firmware/src/usb_handler.h diff --git a/openpcd/firmware/Makefile b/openpcd/firmware/Makefile index 531342a..f9bc515 100644 --- a/openpcd/firmware/Makefile +++ b/openpcd/firmware/Makefile @@ -75,6 +75,7 @@ SRC = SRCARM = lib/lib_AT91SAM7.c src/pcd_enumerate.c src/fifo.c src/dbgu.c \ src/led.c src/rc632.c src/rc632_highlevel.c src/req_ctx.c \ src/trigger.c src/main.c src/syscalls.c src/pwm.c src/tc.c \ + src/usb_handler.c \ src/$(TARGET).c src/start/Cstartup_SAM7.c SRCARM += src/rfid_layer2_iso14443a.c diff --git a/openpcd/firmware/src/main_dumbreader.c b/openpcd/firmware/src/main_dumbreader.c index 0447ca2..54d7819 100644 --- a/openpcd/firmware/src/main_dumbreader.c +++ b/openpcd/firmware/src/main_dumbreader.c @@ -1,131 +1,14 @@ #include -#include #include #include #include "dbgu.h" #include "rc632.h" #include "led.h" #include "pcd_enumerate.h" +#include "usb_handler.h" #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]; - struct openpcd_hdr *pih = (struct openpcd_hdr *) &rctx->tx.data[0]; - u_int16_t len = rctx->rx.tot_len; - - DEBUGP("usb_in "); - - if (len < sizeof(*poh)) - return -EINVAL; - - memcpy(pih, poh, sizeof(*poh)); - rctx->tx.tot_len = sizeof(*poh); - - switch (poh->cmd) { - case OPENPCD_CMD_READ_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: - { - 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); - break; - case OPENPCD_CMD_WRITE_FIFO: - DEBUGP("WRITE FIFO(len=%u) ", poh->len); - if (len - sizeof(*poh) < poh->len) - return -EINVAL; - rc632_fifo_write(RAH, poh->len, poh->data, 0); - break; - case OPENPCD_CMD_READ_VFIFO: - DEBUGP("READ VFIFO "); - DEBUGP("NOT IMPLEMENTED YET "); - goto respond; - break; - case OPENPCD_CMD_WRITE_VFIFO: - DEBUGP("WRITE VFIFO "); - DEBUGP("NOT IMPLEMENTED YET "); - break; - case OPENPCD_CMD_REG_BITS_CLEAR: - DEBUGP("CLEAR BITS "); - pih->val = rc632_clear_bits(RAH, poh->reg, poh->val); - break; - case OPENPCD_CMD_REG_BITS_SET: - DEBUGP("SET BITS "); - pih->val = rc632_set_bits(RAH, poh->reg, poh->val); - break; - case OPENPCD_CMD_SET_LED: - 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; - } - 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(); @@ -150,24 +33,15 @@ void _main_func(void) 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); - - } + /* next we deal with incoming reqyests from USB EP1 (OUT) */ + usb_in_process(); rc632_unthrottle(); - udp_unthrottle(); } diff --git a/openpcd/firmware/src/usb_handler.c b/openpcd/firmware/src/usb_handler.c new file mode 100644 index 0000000..dc5632e --- /dev/null +++ b/openpcd/firmware/src/usb_handler.c @@ -0,0 +1,148 @@ +/* OpenPCD USB handler - handle incoming USB requests on OUT pipe + * (C) 2006 by Harald Welte + */ + +#include +#include +#include + +#include + +#include "pcd_enumerate.h" +#include "openpcd.h" +#include "rc632.h" +#include "led.h" +#include "dbgu.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]; + struct openpcd_hdr *pih = (struct openpcd_hdr *) &rctx->tx.data[0]; + u_int16_t len = rctx->rx.tot_len; + + DEBUGP("usb_in "); + + if (len < sizeof(*poh)) + return -EINVAL; + + memcpy(pih, poh, sizeof(*poh)); + rctx->tx.tot_len = sizeof(*poh); + + switch (poh->cmd) { + case OPENPCD_CMD_READ_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: + { + 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); + break; + case OPENPCD_CMD_WRITE_FIFO: + DEBUGP("WRITE FIFO(len=%u) ", poh->len); + if (len - sizeof(*poh) < poh->len) + return -EINVAL; + rc632_fifo_write(RAH, poh->len, poh->data, 0); + break; + case OPENPCD_CMD_READ_VFIFO: + DEBUGP("READ VFIFO "); + DEBUGP("NOT IMPLEMENTED YET "); + goto respond; + break; + case OPENPCD_CMD_WRITE_VFIFO: + DEBUGP("WRITE VFIFO "); + DEBUGP("NOT IMPLEMENTED YET "); + break; + case OPENPCD_CMD_REG_BITS_CLEAR: + DEBUGP("CLEAR BITS "); + pih->val = rc632_clear_bits(RAH, poh->reg, poh->val); + break; + case OPENPCD_CMD_REG_BITS_SET: + DEBUGP("SET BITS "); + pih->val = rc632_set_bits(RAH, poh->reg, poh->val); + break; + case OPENPCD_CMD_SET_LED: + 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: + /* FIXME: add a method how other firmware modules can + * register callback functions for additional commands */ + DEBUGP("UNKNOWN "); + return -EINVAL; + break; + } + 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 usb_in_process(void) +{ + struct req_ctx *rctx; + + 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); + } + udp_unthrottle(); +} + diff --git a/openpcd/firmware/src/usb_handler.h b/openpcd/firmware/src/usb_handler.h new file mode 100644 index 0000000..a09b447 --- /dev/null +++ b/openpcd/firmware/src/usb_handler.h @@ -0,0 +1,6 @@ +#ifndef _USB_HANDLER_H +#define _USB_HANDLER_H + +extern void usb_in_process(void); + +#endif -- cgit v1.2.3