int HF2::endpointRequest()

in libs/core/hf2.cpp [187:287]


int HF2::endpointRequest()
{
    int sz = recv();

    if (!sz)
        return 0;

    uint32_t tmp;

    if (pkt.serial) {
        // TODO raise some event?
        return 0;
    }

    LOG("HF2 sz=%d CMD=%x", sz, pkt.buf32[0]);

    // one has to be careful dealing with these, as they share memory
    HF2_Command *cmd = &pkt.cmd;
    HF2_Response *resp = &pkt.resp;

    uint32_t cmdId = cmd->command_id;
    resp->tag = cmd->tag;
    resp->status16 = HF2_STATUS_OK;

#define checkDataSize(str, add) usb_assert(sz == 8 + (int)sizeof(cmd->str) + (int)(add))

    gotSomePacket = true;

    switch (cmdId) {
    case HF2_CMD_INFO:
        return sendResponseWithData(uf2_info(), strlen(uf2_info()));

    case HF2_CMD_BININFO:
        resp->bininfo.mode = HF2_MODE_USERSPACE;
        resp->bininfo.flash_page_size = 0;
        resp->bininfo.flash_num_pages = 0;
        resp->bininfo.max_message_size = sizeof(pkt.buf);
        return sendResponse(sizeof(resp->bininfo));

    case HF2_DBG_RESTART:
        *HF2_DBG_MAGIC_PTR = HF2_DBG_MAGIC_START;
        target_reset();
        break;

    case HF2_CMD_RESET_INTO_APP:
        *DBL_TAP_PTR = DBL_TAP_MAGIC_QUICK_BOOT;
        // fall-through
    case HF2_CMD_RESET_INTO_BOOTLOADER:
        target_reset();
        break;

    case HF2_CMD_START_FLASH:
        sendResponse(0);
        hf2_handover(in->ep);
        usb_assert(0); // should not be reached
        break;

    case HF2_CMD_WRITE_WORDS:
        checkDataSize(write_words, cmd->write_words.num_words << 2);
        copy_words((void *)cmd->write_words.target_addr, cmd->write_words.words,
                   cmd->write_words.num_words);
        break;

    case HF2_CMD_READ_WORDS:
        checkDataSize(read_words, 0);
        tmp = cmd->read_words.num_words;
        usb_assert(tmp <= sizeof(pkt.buf) / 4 - 1);
        copy_words(resp->data32, (void *)cmd->read_words.target_addr, tmp);
        return sendResponse(tmp << 2);

    case HF2_CMD_DMESG:
#if DEVICE_DMESG_BUFFER_SIZE > 0
        return sendResponseWithData(codalLogStore.buffer, codalLogStore.ptr);
#else
        break;
#endif

    case HF2_DBG_GET_GLOBAL_STATE: {
        HF2_GLOBAL_STATE_Result gstate = {
            .num_globals = (uint32_t)getNumGlobals(), //
            .globals_addr = (uint32_t)globals,
        };
        return sendResponseWithData(&gstate, sizeof(gstate));
    }

    case HF2_DBG_RESUME:
        globals[0] = (TValue)cmd->data32[0];
        resume = true;
        return sendResponse(0);

    case HF2_DBG_GET_STACK:
        return sendResponseWithData(stackCopy, stackSize);

    default:
        // command not understood
        resp->status16 = HF2_STATUS_INVALID_CMD;
        break;
    }

    return sendResponse(0);
}