diff options
| -rw-r--r-- | openpcd/firmware/Makefile | 1 | ||||
| -rw-r--r-- | openpcd/firmware/src/main_dumbreader.c | 132 | ||||
| -rw-r--r-- | openpcd/firmware/src/usb_handler.c | 148 | ||||
| -rw-r--r-- | openpcd/firmware/src/usb_handler.h | 6 | 
4 files changed, 158 insertions, 129 deletions
| 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 <errno.h> -#include <string.h>  #include <include/lib_AT91SAM7.h>  #include <include/openpcd.h>  #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 <sys/types.h> +#include <errno.h> +#include <string.h> + +#include <openpcd.h> + +#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 | 
