More fixes
This commit is contained in:
parent
77ce276b59
commit
d4b0978d50
8 changed files with 159 additions and 164 deletions
|
|
@ -44,7 +44,6 @@ set_source_files_properties(
|
||||||
|
|
||||||
target_sources(pico_ccid PUBLIC
|
target_sources(pico_ccid PUBLIC
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/usb.c
|
${CMAKE_CURRENT_LIST_DIR}/src/usb/usb.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/usb_descriptors.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/fs/file.c
|
${CMAKE_CURRENT_LIST_DIR}/src/fs/file.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/fs/flash.c
|
${CMAKE_CURRENT_LIST_DIR}/src/fs/flash.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/fs/low_flash.c
|
${CMAKE_CURRENT_LIST_DIR}/src/fs/low_flash.c
|
||||||
|
|
@ -67,4 +66,4 @@ pico_add_extra_outputs(pico_ccid)
|
||||||
|
|
||||||
#target_compile_definitions(pico_ccid PRIVATE MBEDTLS_ECDSA_DETERMINISTIC=1)
|
#target_compile_definitions(pico_ccid PRIVATE MBEDTLS_ECDSA_DETERMINISTIC=1)
|
||||||
|
|
||||||
target_link_libraries(pico_ccid PRIVATE pico_stdlib tinyusb_device tinyusb_board pico_multicore hardware_flash hardware_sync hardware_adc pico_unique_id hardware_rtc)
|
target_link_libraries(pico_ccid PRIVATE pico_stdlib pico_multicore hardware_flash hardware_sync hardware_adc pico_unique_id hardware_rtc)
|
||||||
|
|
|
||||||
|
|
@ -15,20 +15,25 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
// Pico
|
// Pico
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
// For memcpy
|
// For memcpy
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "bsp/board.h"
|
// Include descriptor struct definitions
|
||||||
#include "tusb.h"
|
#include "usb_common.h"
|
||||||
#include "usb_descriptors.h"
|
// USB register definitions from pico-sdk
|
||||||
#include "device/usbd_pvt.h"
|
#include "hardware/regs/usb.h"
|
||||||
|
// USB hardware struct definitions from pico-sdk
|
||||||
|
#include "hardware/structs/usb.h"
|
||||||
|
// For interrupt enable and numbers
|
||||||
|
#include "hardware/irq.h"
|
||||||
|
// For resetting the USB controller
|
||||||
|
#include "hardware/resets.h"
|
||||||
|
|
||||||
#include "pico/multicore.h"
|
#include "pico/multicore.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include "ccid2040.h"
|
#include "ccid2040.h"
|
||||||
|
|
@ -271,105 +276,8 @@ static void ccid_notify_slot_change(struct ccid *c)
|
||||||
|
|
||||||
#define USB_CCID_TIMEOUT (50)
|
#define USB_CCID_TIMEOUT (50)
|
||||||
|
|
||||||
#define GPG_THREAD_TERMINATED 0xffff
|
#define CCID_THREAD_TERMINATED 0xffff
|
||||||
#define GPG_ACK_TIMEOUT 0x6600
|
#define CCID_ACK_TIMEOUT 0x6600
|
||||||
|
|
||||||
static void ccid_init_cb(void) {
|
|
||||||
struct ccid *c = &ccid;
|
|
||||||
TU_LOG1("-------- CCID INIT\r\n");
|
|
||||||
vendord_init();
|
|
||||||
|
|
||||||
//ccid_notify_slot_change(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ccid_reset_cb(uint8_t rhport) {
|
|
||||||
TU_LOG1("-------- CCID RESET\r\n");
|
|
||||||
itf_num = 0;
|
|
||||||
vendord_reset(rhport);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint16_t ccid_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) {
|
|
||||||
uint8_t *itf_vendor = (uint8_t *)malloc(sizeof(uint8_t)*max_len);
|
|
||||||
TU_LOG1("-------- CCID OPEN\r\n");
|
|
||||||
TU_VERIFY(itf_desc->bInterfaceClass == TUSB_CLASS_SMART_CARD && itf_desc->bInterfaceSubClass == 0 && itf_desc->bInterfaceProtocol == 0, 0);
|
|
||||||
|
|
||||||
//vendord_open expects a CLASS_VENDOR interface class
|
|
||||||
memcpy(itf_vendor, itf_desc, sizeof(uint8_t)*max_len);
|
|
||||||
((tusb_desc_interface_t *)itf_vendor)->bInterfaceClass = TUSB_CLASS_VENDOR_SPECIFIC;
|
|
||||||
vendord_open(rhport, (tusb_desc_interface_t *)itf_vendor, max_len);
|
|
||||||
free(itf_vendor);
|
|
||||||
|
|
||||||
uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(struct ccid_class_descriptor) + 2*sizeof(tusb_desc_endpoint_t);
|
|
||||||
TU_VERIFY(max_len >= drv_len, 0);
|
|
||||||
|
|
||||||
itf_num = itf_desc->bInterfaceNumber;
|
|
||||||
return drv_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Support for parameterized reset via vendor interface control request
|
|
||||||
static bool ccid_control_xfer_cb(uint8_t __unused rhport, uint8_t stage, tusb_control_request_t const * request) {
|
|
||||||
// nothing to do with DATA & ACK stage
|
|
||||||
TU_LOG2("-------- CCID CTRL XFER\r\n");
|
|
||||||
if (stage != CONTROL_STAGE_SETUP) return true;
|
|
||||||
|
|
||||||
if (request->wIndex == itf_num)
|
|
||||||
{
|
|
||||||
TU_LOG2("-------- bmRequestType %x, bRequest %x, wValue %x, wLength %x\r\n",request->bmRequestType,request->bRequest, request->wValue, request->wLength);
|
|
||||||
/*
|
|
||||||
#if PICO_STDIO_USB_RESET_INTERFACE_SUPPORT_RESET_TO_BOOTSEL
|
|
||||||
if (request->bRequest == RESET_REQUEST_BOOTSEL) {
|
|
||||||
#ifdef PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED
|
|
||||||
uint gpio_mask = 1u << PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED;
|
|
||||||
#else
|
|
||||||
uint gpio_mask = 0u;
|
|
||||||
#endif
|
|
||||||
#if !PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED
|
|
||||||
if (request->wValue & 0x100) {
|
|
||||||
gpio_mask = 1u << (request->wValue >> 9u);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
reset_usb_boot(gpio_mask, (request->wValue & 0x7f) | PICO_STDIO_USB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK);
|
|
||||||
// does not return, otherwise we'd return true
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PICO_STDIO_USB_RESET_INTERFACE_SUPPORT_RESET_TO_FLASH_BOOT
|
|
||||||
if (request->bRequest == RESET_REQUEST_FLASH) {
|
|
||||||
watchdog_reboot(0, 0, PICO_STDIO_USB_RESET_RESET_TO_FLASH_DELAY_MS);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ccid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
|
|
||||||
//TU_LOG2("------ CALLED XFER_CB\r\n");
|
|
||||||
return vendord_xfer_cb(rhport, ep_addr, result, xferred_bytes);
|
|
||||||
//return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static usbd_class_driver_t const ccid_driver = {
|
|
||||||
#if CFG_TUSB_DEBUG >= 2
|
|
||||||
.name = "CCID",
|
|
||||||
#endif
|
|
||||||
.init = ccid_init_cb,
|
|
||||||
.reset = ccid_reset_cb,
|
|
||||||
.open = ccid_open,
|
|
||||||
.control_xfer_cb = ccid_control_xfer_cb,
|
|
||||||
.xfer_cb = ccid_xfer_cb,
|
|
||||||
.sof = NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
// Implement callback to add our custom driver
|
|
||||||
usbd_class_driver_t const *usbd_app_driver_get_cb(uint8_t *driver_count) {
|
|
||||||
*driver_count = 1;
|
|
||||||
return &ccid_driver;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
|
static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
|
||||||
|
|
||||||
|
|
@ -379,6 +287,44 @@ void led_set_blink(uint32_t mode) {
|
||||||
|
|
||||||
void execute_tasks();
|
void execute_tasks();
|
||||||
|
|
||||||
|
#include "hardware/structs/ioqspi.h"
|
||||||
|
#define BUTTON_STATE_ACTIVE 0
|
||||||
|
|
||||||
|
bool __no_inline_not_in_flash_func(get_bootsel_button)() {
|
||||||
|
const uint CS_PIN_INDEX = 1;
|
||||||
|
|
||||||
|
// Must disable interrupts, as interrupt handlers may be in flash, and we
|
||||||
|
// are about to temporarily disable flash access!
|
||||||
|
uint32_t flags = save_and_disable_interrupts();
|
||||||
|
|
||||||
|
// Set chip select to Hi-Z
|
||||||
|
hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl,
|
||||||
|
GPIO_OVERRIDE_LOW << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB,
|
||||||
|
IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS);
|
||||||
|
|
||||||
|
// Note we can't call into any sleep functions in flash right now
|
||||||
|
for (volatile int i = 0; i < 1000; ++i);
|
||||||
|
|
||||||
|
// The HI GPIO registers in SIO can observe and control the 6 QSPI pins.
|
||||||
|
// Note the button pulls the pin *low* when pressed.
|
||||||
|
bool button_state = (sio_hw->gpio_hi_in & (1u << CS_PIN_INDEX));
|
||||||
|
|
||||||
|
// Need to restore the state of chip select, else we are going to have a
|
||||||
|
// bad time when we return to code in flash!
|
||||||
|
hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl,
|
||||||
|
GPIO_OVERRIDE_NORMAL << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB,
|
||||||
|
IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS);
|
||||||
|
|
||||||
|
restore_interrupts(flags);
|
||||||
|
|
||||||
|
return button_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t board_button_read(void)
|
||||||
|
{
|
||||||
|
return BUTTON_STATE_ACTIVE == get_bootsel_button();
|
||||||
|
}
|
||||||
|
|
||||||
static bool wait_button() {
|
static bool wait_button() {
|
||||||
uint32_t start_button = board_millis();
|
uint32_t start_button = board_millis();
|
||||||
bool timeout = false;
|
bool timeout = false;
|
||||||
|
|
@ -406,12 +352,12 @@ static bool wait_button() {
|
||||||
return timeout;
|
return timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
void usb_tx_enable(const uint8_t *buf, uint32_t len) {
|
void usb_tx_enable(const uint8_t *wbuf, uint32_t len) {
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
if (buf[0] != 0x81)
|
//if (wbuf[0] != 0x81)
|
||||||
DEBUG_PAYLOAD(buf,len);
|
DEBUG_PAYLOAD(wbuf,len);
|
||||||
//DEBUG_PAYLOAD(buf,len);
|
//DEBUG_PAYLOAD(wbuf,len);
|
||||||
tud_vendor_write(buf, len);
|
usb_write(wbuf, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -439,7 +385,7 @@ static const uint8_t ATR_head[] = {
|
||||||
|
|
||||||
/* Send back ATR (Answer To Reset) */
|
/* Send back ATR (Answer To Reset) */
|
||||||
static enum ccid_state ccid_power_on(struct ccid *c) {
|
static enum ccid_state ccid_power_on(struct ccid *c) {
|
||||||
TU_LOG1("!!! CCID POWER ON %d\r\n",c->application);
|
printf("!!! CCID POWER ON %d\r\n",c->application);
|
||||||
uint8_t p[CCID_MSG_HEADER_SIZE+1]; /* >= size of historical_bytes -1 */
|
uint8_t p[CCID_MSG_HEADER_SIZE+1]; /* >= size of historical_bytes -1 */
|
||||||
size_t size_atr = (ccid_atr ? ccid_atr[0] : 0);
|
size_t size_atr = (ccid_atr ? ccid_atr[0] : 0);
|
||||||
if (c->application == 0) {
|
if (c->application == 0) {
|
||||||
|
|
@ -499,8 +445,10 @@ static void ccid_send_status(struct ccid *c) {
|
||||||
/* This is a single packet Bulk-IN transaction */
|
/* This is a single packet Bulk-IN transaction */
|
||||||
c->epi->buf = NULL;
|
c->epi->buf = NULL;
|
||||||
c->epi->tx_done = 1;
|
c->epi->tx_done = 1;
|
||||||
|
|
||||||
|
|
||||||
memcpy(endp1_tx_buf, ccid_reply, CCID_MSG_HEADER_SIZE);
|
memcpy(endp1_tx_buf, ccid_reply, CCID_MSG_HEADER_SIZE);
|
||||||
|
|
||||||
usb_tx_enable(endp1_tx_buf, CCID_MSG_HEADER_SIZE);
|
usb_tx_enable(endp1_tx_buf, CCID_MSG_HEADER_SIZE);
|
||||||
c->tx_busy = 1;
|
c->tx_busy = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -786,7 +734,7 @@ static enum ccid_state ccid_handle_data(struct ccid *c)
|
||||||
{
|
{
|
||||||
enum ccid_state next_state = c->ccid_state;
|
enum ccid_state next_state = c->ccid_state;
|
||||||
|
|
||||||
TU_LOG3("---- CCID STATE %d,msg_type %x,start %d\r\n",c->ccid_state,c->ccid_header.msg_type,CCID_STATE_START);
|
printf("---- CCID STATE %d,msg_type %x,start %d\r\n",c->ccid_state,c->ccid_header.msg_type,CCID_STATE_START);
|
||||||
if (c->err != 0) {
|
if (c->err != 0) {
|
||||||
ccid_reset(c);
|
ccid_reset(c);
|
||||||
ccid_error(c, CCID_OFFSET_DATA_LEN);
|
ccid_error(c, CCID_OFFSET_DATA_LEN);
|
||||||
|
|
@ -952,7 +900,7 @@ static int end_abdata(struct ep_out *epo, size_t orig_len) {
|
||||||
if (orig_len == USB_LL_BUF_SIZE && len < c->ccid_header.data_len)
|
if (orig_len == USB_LL_BUF_SIZE && len < c->ccid_header.data_len)
|
||||||
/* more packet comes */
|
/* more packet comes */
|
||||||
return 1;
|
return 1;
|
||||||
|
printf("!!end_abdata len %d %d\r\n",len,c->ccid_header.data_len);
|
||||||
if (len != c->ccid_header.data_len)
|
if (len != c->ccid_header.data_len)
|
||||||
epo->err = 1;
|
epo->err = 1;
|
||||||
|
|
||||||
|
|
@ -963,7 +911,7 @@ static int end_cmd_apdu_head(struct ep_out *epo, size_t orig_len) {
|
||||||
struct ccid *c = (struct ccid *)epo->priv;
|
struct ccid *c = (struct ccid *)epo->priv;
|
||||||
|
|
||||||
(void)orig_len;
|
(void)orig_len;
|
||||||
|
printf("!!end_cmd_apdu_head len %d %d %d\r\n",epo->cnt,c->ccid_header.data_len,epo->cnt);
|
||||||
if (epo->cnt < 4 || epo->cnt != c->ccid_header.data_len) {
|
if (epo->cnt < 4 || epo->cnt != c->ccid_header.data_len) {
|
||||||
epo->err = 1;
|
epo->err = 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1173,6 +1121,7 @@ static void ccid_rx_ready(uint16_t len) {
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int cont;
|
int cont;
|
||||||
size_t orig_len = len;
|
size_t orig_len = len;
|
||||||
|
printf("epo buf_len %d\r\n",epo->buf_len);
|
||||||
while (epo->err == 0) {
|
while (epo->err == 0) {
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
break;
|
break;
|
||||||
|
|
@ -1257,13 +1206,13 @@ static void ccid_tx_done () {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int usb_event_handle(struct ccid *c) {
|
static int usb_event_handle(struct ccid *c) {
|
||||||
TU_LOG3("!!! tx %d, vendor %d, cfg %d, rx %d\r\n",c->tx_busy,tud_vendor_n_write_available(0),CFG_TUD_VENDOR_TX_BUFSIZE,tud_vendor_available());
|
//printf("!!! tx %d, rx %d\r\n",c->tx_busy,usb_read_available());
|
||||||
if (c->tx_busy == 1 && tud_vendor_n_write_available(0) == CFG_TUD_VENDOR_TX_BUFSIZE) {
|
//if (c->tx_busy == 1 && tud_vendor_n_write_available(0) == CFG_TUD_VENDOR_TX_BUFSIZE) {
|
||||||
|
if (c->tx_busy == 1)
|
||||||
ccid_tx_done ();
|
ccid_tx_done ();
|
||||||
}
|
if (usb_read_available() && c->epo->ready) {
|
||||||
if (tud_vendor_available() && c->epo->ready) {
|
uint32_t count = usb_read(endp1_rx_buf, sizeof(endp1_rx_buf));
|
||||||
uint32_t count = tud_vendor_read(endp1_rx_buf, sizeof(endp1_rx_buf));
|
//if (endp1_rx_buf[0] != 0x65)
|
||||||
if (endp1_rx_buf[0] != 0x65)
|
|
||||||
DEBUG_PAYLOAD(endp1_rx_buf, count);
|
DEBUG_PAYLOAD(endp1_rx_buf, count);
|
||||||
//DEBUG_PAYLOAD(endp1_rx_buf, count);
|
//DEBUG_PAYLOAD(endp1_rx_buf, count);
|
||||||
ccid_rx_ready(count);
|
ccid_rx_ready(count);
|
||||||
|
|
@ -1349,9 +1298,9 @@ void card_thread() {
|
||||||
|
|
||||||
void ccid_task(void) {
|
void ccid_task(void) {
|
||||||
struct ccid *c = &ccid;
|
struct ccid *c = &ccid;
|
||||||
if (tud_vendor_mounted()) {
|
if (usb_is_configured()) {
|
||||||
// connected and there are data available
|
// connected and there are data available
|
||||||
if ((c->epo->ready && tud_vendor_available()) || (tud_vendor_n_write_available(0) == CFG_TUD_VENDOR_TX_BUFSIZE && c->tx_busy == 1)) {
|
if ((c->epo->ready && usb_read_available()) || (c->tx_busy == 1)) {
|
||||||
if (usb_event_handle (c) != 0) {
|
if (usb_event_handle (c) != 0) {
|
||||||
if (c->application) {
|
if (c->application) {
|
||||||
uint32_t flag = EV_EXIT;
|
uint32_t flag = EV_EXIT;
|
||||||
|
|
@ -1369,7 +1318,7 @@ void ccid_task(void) {
|
||||||
uint32_t m = 0x0;
|
uint32_t m = 0x0;
|
||||||
bool has_m = queue_try_remove(&c->ccid_comm, &m);
|
bool has_m = queue_try_remove(&c->ccid_comm, &m);
|
||||||
if (m != 0)
|
if (m != 0)
|
||||||
TU_LOG3("\r\n ------ M = %d\r\n",m);
|
printf("\r\n ------ M = %d\r\n",m);
|
||||||
if (has_m) {
|
if (has_m) {
|
||||||
if (m == EV_CARD_CHANGE) {
|
if (m == EV_CARD_CHANGE) {
|
||||||
if (c->ccid_state == CCID_STATE_NOCARD)
|
if (c->ccid_state == CCID_STATE_NOCARD)
|
||||||
|
|
@ -1393,7 +1342,7 @@ void ccid_task(void) {
|
||||||
else if (m == EV_EXEC_FINISHED) {
|
else if (m == EV_EXEC_FINISHED) {
|
||||||
if (c->ccid_state == CCID_STATE_EXECUTE) {
|
if (c->ccid_state == CCID_STATE_EXECUTE) {
|
||||||
exec_done:
|
exec_done:
|
||||||
if (c->a->sw == GPG_THREAD_TERMINATED) {
|
if (c->a->sw == CCID_THREAD_TERMINATED) {
|
||||||
c->sw1sw2[0] = 0x90;
|
c->sw1sw2[0] = 0x90;
|
||||||
c->sw1sw2[1] = 0x00;
|
c->sw1sw2[1] = 0x00;
|
||||||
c->state = APDU_STATE_RESULT;
|
c->state = APDU_STATE_RESULT;
|
||||||
|
|
@ -1441,9 +1390,7 @@ void ccid_task(void) {
|
||||||
timeout -= MIN(board_millis()-prev_millis,timeout);
|
timeout -= MIN(board_millis()-prev_millis,timeout);
|
||||||
if (timeout == 0) {
|
if (timeout == 0) {
|
||||||
if (c->timeout_cnt == 7 && c->ccid_state == CCID_STATE_ACK_REQUIRED_1) {
|
if (c->timeout_cnt == 7 && c->ccid_state == CCID_STATE_ACK_REQUIRED_1) {
|
||||||
c->a->sw = GPG_ACK_TIMEOUT;
|
c->a->sw = CCID_ACK_TIMEOUT;
|
||||||
c->a->res_apdu_data_len = 0;
|
|
||||||
c->a->sw = GPG_ACK_TIMEOUT;
|
|
||||||
c->a->res_apdu_data_len = 0;
|
c->a->res_apdu_data_len = 0;
|
||||||
|
|
||||||
goto exec_done;
|
goto exec_done;
|
||||||
|
|
@ -1455,10 +1402,6 @@ void ccid_task(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tud_mount_cb() {
|
|
||||||
ccid_prepare_receive (&ccid);
|
|
||||||
}
|
|
||||||
|
|
||||||
void led_blinking_task() {
|
void led_blinking_task() {
|
||||||
#ifdef PICO_DEFAULT_LED_PIN
|
#ifdef PICO_DEFAULT_LED_PIN
|
||||||
static uint32_t start_ms = 0;
|
static uint32_t start_ms = 0;
|
||||||
|
|
@ -1567,7 +1510,7 @@ pico_unique_board_id_t unique_id;
|
||||||
void execute_tasks() {
|
void execute_tasks() {
|
||||||
prev_millis = board_millis();
|
prev_millis = board_millis();
|
||||||
ccid_task();
|
ccid_task();
|
||||||
tud_task(); // tinyusb device task
|
//tud_task(); // tinyusb device task
|
||||||
led_blinking_task();
|
led_blinking_task();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1575,7 +1518,8 @@ int main(void) {
|
||||||
struct apdu *a = &apdu;
|
struct apdu *a = &apdu;
|
||||||
struct ccid *c = &ccid;
|
struct ccid *c = &ccid;
|
||||||
|
|
||||||
board_init();
|
//board_init();
|
||||||
|
stdio_init_all();
|
||||||
|
|
||||||
#ifdef PIMORONI_TINY2040
|
#ifdef PIMORONI_TINY2040
|
||||||
gpio_init(TINY2040_LED_R_PIN);
|
gpio_init(TINY2040_LED_R_PIN);
|
||||||
|
|
@ -1590,11 +1534,10 @@ int main(void) {
|
||||||
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
|
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
led_off_all();
|
led_off_all();
|
||||||
|
|
||||||
tusb_init();
|
usb_init();
|
||||||
|
|
||||||
prepare_ccid();
|
prepare_ccid();
|
||||||
|
|
||||||
|
|
@ -1603,6 +1546,8 @@ int main(void) {
|
||||||
low_flash_init();
|
low_flash_init();
|
||||||
|
|
||||||
init_rtc();
|
init_rtc();
|
||||||
|
|
||||||
|
ccid_prepare_receive(&ccid);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
execute_tasks();
|
execute_tasks();
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,16 @@
|
||||||
#ifndef _CCID2040_H_
|
#ifndef _CCID2040_H_
|
||||||
#define _CCID2040_H_
|
#define _CCID2040_H_
|
||||||
|
|
||||||
#include "ccid.h"
|
|
||||||
#include "tusb.h"
|
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "pico/unique_id.h"
|
#include "pico/unique_id.h"
|
||||||
#include "pico/util/queue.h"
|
#include "pico/util/queue.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "pico/time.h"
|
||||||
|
static inline uint32_t board_millis(void)
|
||||||
|
{
|
||||||
|
return to_ms_since_boot(get_absolute_time());
|
||||||
|
}
|
||||||
|
|
||||||
#define USB_REQ_CCID 0xA1
|
#define USB_REQ_CCID 0xA1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "tusb.h"
|
|
||||||
#include "ccid2040.h"
|
#include "ccid2040.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
extern const uintptr_t end_data_pool;
|
extern const uintptr_t end_data_pool;
|
||||||
extern const uintptr_t start_data_pool;
|
extern const uintptr_t start_data_pool;
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
#include "hardware/flash.h"
|
#include "hardware/flash.h"
|
||||||
#include "ccid2040.h"
|
#include "ccid2040.h"
|
||||||
#include "tusb.h"
|
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,14 @@
|
||||||
#include "hardware/structs/rosc.h"
|
#include "hardware/structs/rosc.h"
|
||||||
#include "hardware/gpio.h"
|
#include "hardware/gpio.h"
|
||||||
#include "hardware/adc.h"
|
#include "hardware/adc.h"
|
||||||
#include "bsp/board.h"
|
|
||||||
#include "pico/unique_id.h"
|
#include "pico/unique_id.h"
|
||||||
|
|
||||||
|
#include "pico/time.h"
|
||||||
|
static inline uint32_t board_millis(void)
|
||||||
|
{
|
||||||
|
return to_ms_since_boot(get_absolute_time());
|
||||||
|
}
|
||||||
|
|
||||||
void adc_start() {
|
void adc_start() {
|
||||||
adc_init();
|
adc_init();
|
||||||
adc_gpio_init(27);
|
adc_gpio_init(27);
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
// For resetting the USB controller
|
// For resetting the USB controller
|
||||||
#include "hardware/resets.h"
|
#include "hardware/resets.h"
|
||||||
|
|
||||||
|
extern void led_blinking_task();
|
||||||
|
|
||||||
// Device descriptors
|
// Device descriptors
|
||||||
|
|
||||||
|
|
@ -327,6 +327,27 @@ void usb_bus_reset(void) {
|
||||||
configured = false;
|
configured = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool usb_is_configured(void) {
|
||||||
|
return configured;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t usb_write(uint8_t *buffer, size_t buffer_size) {
|
||||||
|
struct usb_endpoint_configuration *ep = usb_get_endpoint_configuration(EP2_IN_ADDR);
|
||||||
|
usb_start_transfer(ep, buffer, MIN(buffer_size, 64));
|
||||||
|
return MIN(buffer_size, 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
void usb_init() {
|
||||||
|
usb_device_init();
|
||||||
|
|
||||||
|
// Wait until configured
|
||||||
|
while (!usb_is_configured()) {
|
||||||
|
tight_loop_contents();
|
||||||
|
led_blinking_task();
|
||||||
|
}
|
||||||
|
usb_start_transfer(usb_get_endpoint_configuration(EP1_OUT_ADDR), NULL, 64);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send the requested string descriptor to the host.
|
* @brief Send the requested string descriptor to the host.
|
||||||
*
|
*
|
||||||
|
|
@ -564,30 +585,45 @@ void ep0_out_handler(uint8_t *buf, uint16_t len) {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEBUG_PAYLOAD(p,s) { \
|
|
||||||
printf("Payload %s (%d bytes):\r\n", #p,s);\
|
|
||||||
for (int i = 0; i < s; i += 16) {\
|
|
||||||
printf("%07Xh : ",i+p);\
|
|
||||||
for (int j = 0; j < 16; j++) {\
|
|
||||||
if (j < s-i) printf("%02X ",(p)[i+j]);\
|
|
||||||
else printf(" ");\
|
|
||||||
if (j == 7) printf(" ");\
|
|
||||||
} printf(": "); \
|
|
||||||
for (int j = 0; j < MIN(16,s-i); j++) {\
|
|
||||||
printf("%c",(p)[i+j] == 0x0a || (p)[i+j] == 0x0d ? '\\' : (p)[i+j]);\
|
|
||||||
if (j == 7) printf(" ");\
|
|
||||||
}\
|
|
||||||
printf("\r\n");\
|
|
||||||
} printf("\r\n"); \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Device specific functions
|
// Device specific functions
|
||||||
|
static uint8_t rx_buffer[4096];
|
||||||
|
static uint16_t w_offset = 0, r_offset = 0;
|
||||||
void ep1_out_handler(uint8_t *buf, uint16_t len) {
|
void ep1_out_handler(uint8_t *buf, uint16_t len) {
|
||||||
printf("RX %d bytes from host\n", len);
|
printf("RX %d bytes from host\n", len);
|
||||||
// Send data back to host
|
// Send data back to host
|
||||||
struct usb_endpoint_configuration *ep = usb_get_endpoint_configuration(EP2_IN_ADDR);
|
uint16_t size = MIN(sizeof(rx_buffer)-w_offset,len);
|
||||||
DEBUG_PAYLOAD(buf,len);
|
if (size > 0) {
|
||||||
|
memcpy(rx_buffer+w_offset, buf, size);
|
||||||
|
w_offset += size;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
do {
|
||||||
|
uint16_t size = MIN(sizeof(rx_buffer)-w_offset,len);
|
||||||
|
memcpy(rx_buffer+w_offset, buf, size);
|
||||||
|
len -= size;
|
||||||
|
w_offset += size;
|
||||||
|
if (w_offset == sizeof(rx_buffer))
|
||||||
|
w_offset = 0;
|
||||||
|
buf += size;
|
||||||
|
} while (len > 0);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t usb_read_available() {
|
||||||
|
return w_offset - r_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t usb_read(uint8_t *buffer, size_t buffer_size) {
|
||||||
|
if (w_offset-r_offset > 0) {
|
||||||
|
uint16_t size = MIN(buffer_size, w_offset-r_offset);
|
||||||
|
memcpy(buffer, rx_buffer+r_offset, size);
|
||||||
|
r_offset += size;
|
||||||
|
if (r_offset == w_offset) {
|
||||||
|
r_offset = w_offset = 0;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ep2_in_handler(uint8_t *buf, uint16_t len) {
|
void ep2_in_handler(uint8_t *buf, uint16_t len) {
|
||||||
|
|
@ -595,7 +631,7 @@ void ep2_in_handler(uint8_t *buf, uint16_t len) {
|
||||||
// Get ready to rx again from host
|
// Get ready to rx again from host
|
||||||
usb_start_transfer(usb_get_endpoint_configuration(EP1_OUT_ADDR), NULL, 64);
|
usb_start_transfer(usb_get_endpoint_configuration(EP1_OUT_ADDR), NULL, 64);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
int main(void) {
|
int main(void) {
|
||||||
stdio_init_all();
|
stdio_init_all();
|
||||||
printf("USB Device Low-Level hardware example\n");
|
printf("USB Device Low-Level hardware example\n");
|
||||||
|
|
@ -639,3 +675,4 @@ int main(void) {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
||||||
|
|
@ -315,6 +315,11 @@ static const unsigned char *descriptor_strings[] = {
|
||||||
|
|
||||||
#define USB_REQ_CCID 0xA1
|
#define USB_REQ_CCID 0xA1
|
||||||
|
|
||||||
|
extern uint16_t usb_read(uint8_t *buffer, size_t buffer_size);
|
||||||
|
extern uint16_t usb_read_available();
|
||||||
|
extern uint32_t usb_write(uint8_t *buffer, size_t buffer_size);
|
||||||
|
extern bool usb_is_configured();
|
||||||
|
extern void usb_init();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue