bulk write implemented but not yet tested. bulk read improved
This commit is contained in:
@@ -646,9 +646,12 @@ uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum)
|
|||||||
|
|
||||||
if(pdev->pClassData2 != NULL)
|
if(pdev->pClassData2 != NULL)
|
||||||
{
|
{
|
||||||
|
if (epnum == CDC_IN_EP) {
|
||||||
hcdc->TxState = 0;
|
hcdc->TxState = 0;
|
||||||
USBD_CDC_TransmitDone(pdev);
|
USBD_CDC_TransmitDone(pdev);
|
||||||
|
} else if (epnum == CDC_CMD_EP) {
|
||||||
|
// command EP send done
|
||||||
|
}
|
||||||
|
|
||||||
return USBD_OK;
|
return USBD_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,9 @@
|
|||||||
#include "task_sched.h"
|
#include "task_sched.h"
|
||||||
#include "TinyFrame.h"
|
#include "TinyFrame.h"
|
||||||
|
|
||||||
|
#define BULK_LST_TIMEOUT_MS 200
|
||||||
|
#define BULKREAD_MAX_CHUNK 512 // this is a static buffer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Supported message types (TF_TYPE)
|
* Supported message types (TF_TYPE)
|
||||||
*/
|
*/
|
||||||
@@ -38,6 +41,7 @@ extern TinyFrame *comm;
|
|||||||
// Must be after the enum because it's used in the header file.
|
// Must be after the enum because it's used in the header file.
|
||||||
#include "msg_responses.h"
|
#include "msg_responses.h"
|
||||||
#include "msg_bulkread.h"
|
#include "msg_bulkread.h"
|
||||||
|
#include "msg_bulkwrite.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize TinyFrame and set up listeners
|
* Initialize TinyFrame and set up listeners
|
||||||
|
|||||||
+17
-19
@@ -30,40 +30,38 @@ static TF_Result bulkread_lst(TinyFrame *tf, TF_Msg *msg)
|
|||||||
|
|
||||||
if (msg->type == MSG_BULK_ABORT) {
|
if (msg->type == MSG_BULK_ABORT) {
|
||||||
goto close;
|
goto close;
|
||||||
} else if (msg->type == MSG_BULK_READ_POLL) {
|
}
|
||||||
|
else if (msg->type == MSG_BULK_READ_POLL) {
|
||||||
|
// find how much data the reader wants
|
||||||
PayloadParser pp = pp_start(msg->data, msg->len, NULL);
|
PayloadParser pp = pp_start(msg->data, msg->len, NULL);
|
||||||
uint32_t chunk = pp_u32(&pp);
|
uint32_t chunk = pp_u32(&pp);
|
||||||
|
|
||||||
// if past len, say we're done and close
|
|
||||||
if (bulk->offset >= bulk->len) {
|
|
||||||
TF_ClearMsg(msg);
|
|
||||||
msg->frame_id = bulk->frame_id;
|
|
||||||
msg->type = MSG_BULK_END;
|
|
||||||
TF_Respond(tf, msg);
|
|
||||||
goto close;
|
|
||||||
}
|
|
||||||
|
|
||||||
chunk = MIN(chunk, bulk->len - bulk->offset);
|
chunk = MIN(chunk, bulk->len - bulk->offset);
|
||||||
chunk = MIN(chunk, BULKREAD_MAX_CHUNK);
|
chunk = MIN(chunk, BULKREAD_MAX_CHUNK);
|
||||||
|
|
||||||
|
// load data into the buffer
|
||||||
bulk->read(bulk, chunk, bulkread_buffer);
|
bulk->read(bulk, chunk, bulkread_buffer);
|
||||||
|
|
||||||
TF_ClearMsg(msg);
|
bool last = (bulk->offset + chunk >= bulk->len);
|
||||||
msg->frame_id = bulk->frame_id;
|
|
||||||
msg->type = MSG_BULK_DATA;
|
TF_Msg resp;
|
||||||
msg->data = bulkread_buffer;
|
TF_ClearMsg(&resp);
|
||||||
msg->len = (TF_LEN) chunk;
|
resp.frame_id = bulk->frame_id;
|
||||||
TF_Respond(tf, msg);
|
resp.type = (last ? MSG_BULK_END : MSG_BULK_DATA); // the last chunk has the END type
|
||||||
|
resp.data = bulkread_buffer;
|
||||||
|
resp.len = (TF_LEN) chunk;
|
||||||
|
TF_Respond(tf, &resp);
|
||||||
|
|
||||||
|
if (last) goto close;
|
||||||
|
|
||||||
// advance the position pointer
|
// advance the position pointer
|
||||||
bulk->offset += chunk;
|
bulk->offset += chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg->userdata = bulk; // We must put it back
|
|
||||||
return TF_RENEW;
|
return TF_RENEW;
|
||||||
|
|
||||||
close:
|
close:
|
||||||
if (msg->userdata) {
|
if (bulk) {
|
||||||
// Ask user to free the bulk and userdata
|
// Ask user to free the bulk and userdata
|
||||||
bulk->read(bulk, 0, NULL);
|
bulk->read(bulk, 0, NULL);
|
||||||
msg->userdata = NULL;
|
msg->userdata = NULL;
|
||||||
|
|||||||
@@ -11,11 +11,6 @@
|
|||||||
|
|
||||||
#include <TinyFrame.h>
|
#include <TinyFrame.h>
|
||||||
|
|
||||||
|
|
||||||
#define BULK_LST_TIMEOUT_MS 200
|
|
||||||
|
|
||||||
#define BULKREAD_MAX_CHUNK 512 // this is a static buffer
|
|
||||||
|
|
||||||
typedef struct bulk_read BulkRead;
|
typedef struct bulk_read BulkRead;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
//
|
||||||
|
// Created by MightyPork on 2017/12/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
|
||||||
|
#include <TinyFrame.h>
|
||||||
|
|
||||||
|
#include "messages.h"
|
||||||
|
#include "utils/payload_parser.h"
|
||||||
|
#include "utils/payload_builder.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TF listener for the bulk write transaction
|
||||||
|
*/
|
||||||
|
static TF_Result bulkwrite_lst(TinyFrame *tf, TF_Msg *msg)
|
||||||
|
{
|
||||||
|
struct bulk_write *bulk = msg->userdata;
|
||||||
|
|
||||||
|
// this is a final call before timeout, to clean up
|
||||||
|
if (msg->data == NULL) {
|
||||||
|
dbg("Bulk rx lst cleanup\r\n");
|
||||||
|
goto close;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_param(NULL != bulk);
|
||||||
|
|
||||||
|
if (msg->type == MSG_BULK_ABORT) {
|
||||||
|
goto close;
|
||||||
|
}
|
||||||
|
else if (msg->type == MSG_BULK_DATA || msg->type == MSG_BULK_END) {
|
||||||
|
// if past len, say we're done and close
|
||||||
|
if (bulk->offset >= bulk->len) {
|
||||||
|
com_respond_err(bulk->frame_id, "WRITE OVERRUN");
|
||||||
|
goto close;
|
||||||
|
}
|
||||||
|
|
||||||
|
bulk->write(bulk, msg->data, msg->len);
|
||||||
|
|
||||||
|
// Return SUCCESS
|
||||||
|
com_respond_ok(msg->frame_id);
|
||||||
|
|
||||||
|
// advance the position pointer (can be used by the write callback)
|
||||||
|
bulk->offset += msg->len;
|
||||||
|
|
||||||
|
if (msg->type == MSG_BULK_END) {
|
||||||
|
// this was the last chunk
|
||||||
|
goto close;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TF_RENEW;
|
||||||
|
|
||||||
|
close:
|
||||||
|
if (bulk) {
|
||||||
|
// Ask user to free the bulk and userdata
|
||||||
|
bulk->write(bulk, NULL, 0);
|
||||||
|
msg->userdata = NULL;
|
||||||
|
}
|
||||||
|
return TF_CLOSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Start the bulk write flow */
|
||||||
|
void bulkwrite_start(TinyFrame *tf, struct bulk_write *bulk)
|
||||||
|
{
|
||||||
|
assert_param(bulk);
|
||||||
|
assert_param(bulk->len);
|
||||||
|
assert_param(bulk->write);
|
||||||
|
|
||||||
|
bulk->offset = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
uint8_t buf[8];
|
||||||
|
PayloadBuilder pb = pb_start(buf, 4, NULL);
|
||||||
|
pb_u32(&pb, bulk->len);
|
||||||
|
pb_u32(&pb, TF_MAX_PAYLOAD_RX);
|
||||||
|
|
||||||
|
// We use userdata1 to hold a reference to the bulk transfer
|
||||||
|
TF_Msg msg = {
|
||||||
|
.type = MSG_BULK_WRITE_OFFER,
|
||||||
|
.frame_id = bulk->frame_id,
|
||||||
|
.is_response = true, // this ensures the frame_id is not re-generated
|
||||||
|
.data = buf,
|
||||||
|
.len = (TF_LEN) pb_length(&pb),
|
||||||
|
.userdata = bulk,
|
||||||
|
};
|
||||||
|
|
||||||
|
TF_Query(tf, &msg, bulkwrite_lst, BULK_LST_TIMEOUT_MS);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
//
|
||||||
|
// Created by MightyPork on 2017/12/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef GEX_F072_MSG_BULKWRITE_H
|
||||||
|
#define GEX_F072_MSG_BULKWRITE_H
|
||||||
|
|
||||||
|
#include <TinyFrame.h>
|
||||||
|
|
||||||
|
typedef struct bulk_write BulkWrite;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of the bulk-write listener. Offset within the data can be retrieved from bulk->offset.
|
||||||
|
*
|
||||||
|
* If buffer is NULL, this is the last call and the bulk struct must be freed if it was allocated.
|
||||||
|
*
|
||||||
|
* @param bulk - a data object passed to the bulkwrite_start() function.
|
||||||
|
* @param chunk - destination buffer to fill with the data. NULL if bulk should be freed.
|
||||||
|
* @param len - size of the chunk to write
|
||||||
|
*/
|
||||||
|
typedef void (*bulkwrite_data_cb)(BulkWrite *bulk, const uint8_t *chunk, uint32_t len);
|
||||||
|
|
||||||
|
/** Bulk read structure */
|
||||||
|
struct bulk_write {
|
||||||
|
TF_ID frame_id; //!< ID of the requesting frame, used for the entire bulk read session
|
||||||
|
bulkwrite_data_cb write; //!< Write callback
|
||||||
|
uint32_t len; //!< Total data length
|
||||||
|
void *userdata; //!< A place for arbitrary userdata
|
||||||
|
|
||||||
|
uint32_t offset; //!< Internal offset counter, will be set to 0 on start.
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a bulk write session
|
||||||
|
* @param tf - tinyframe instance
|
||||||
|
* @param bulk - bulk write config structure (malloc'd or static)
|
||||||
|
*/
|
||||||
|
void bulkwrite_start(TinyFrame *tf, struct bulk_write *bulk);
|
||||||
|
|
||||||
|
|
||||||
|
#endif //GEX_F072_MSG_BULKWRITE_H
|
||||||
Reference in New Issue
Block a user