From 68aaa2c78d0ec5af95c2a424cfb087246d532de7 Mon Sep 17 00:00:00 2001 From: Max Behensky Date: Tue, 14 Nov 2017 08:14:22 -0800 Subject: [PATCH 1/2] Ignore built files --- .gitignore | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..69bb4ea --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*.o +*.d +*.bin +*.asmo +*.elf +*~ + From 46b01339f5eeab1157d0aa6f6e9c853b440f30a8 Mon Sep 17 00:00:00 2001 From: Max Behensky Date: Tue, 14 Nov 2017 12:10:44 -0800 Subject: [PATCH 2/2] Add new mode to pad output usb packets to max packet size for better WinUSB performance --- include/gs_usb.h | 30 ++++++++++-------- include/usbd_gs_can.h | 11 +++++++ src/main.c | 55 +++++++++++---------------------- src/usbd_gs_can.c | 71 ++++++++++++++++++++++++++++++------------- 4 files changed, 95 insertions(+), 72 deletions(-) diff --git a/include/gs_usb.h b/include/gs_usb.h index 3c7f79f..1d6b765 100644 --- a/include/gs_usb.h +++ b/include/gs_usb.h @@ -33,20 +33,24 @@ THE SOFTWARE. #define GSUSB_ENDPOINT_OUT 0x02 -#define GS_CAN_MODE_NORMAL 0 -#define GS_CAN_MODE_LISTEN_ONLY (1<<0) -#define GS_CAN_MODE_LOOP_BACK (1<<1) -#define GS_CAN_MODE_TRIPLE_SAMPLE (1<<2) -#define GS_CAN_MODE_ONE_SHOT (1<<3) -#define GS_CAN_MODE_HW_TIMESTAMP (1<<4) +#define GS_CAN_MODE_NORMAL 0 +#define GS_CAN_MODE_LISTEN_ONLY (1<<0) +#define GS_CAN_MODE_LOOP_BACK (1<<1) +#define GS_CAN_MODE_TRIPLE_SAMPLE (1<<2) +#define GS_CAN_MODE_ONE_SHOT (1<<3) +#define GS_CAN_MODE_HW_TIMESTAMP (1<<4) -#define GS_CAN_FEATURE_LISTEN_ONLY (1<<0) -#define GS_CAN_FEATURE_LOOP_BACK (1<<1) -#define GS_CAN_FEATURE_TRIPLE_SAMPLE (1<<2) -#define GS_CAN_FEATURE_ONE_SHOT (1<<3) -#define GS_CAN_FEATURE_HW_TIMESTAMP (1<<4) -#define GS_CAN_FEATURE_IDENTIFY (1<<5) -#define GS_CAN_FEATURE_USER_ID (1<<6) +#define GS_CAN_MODE_PAD_PKTS_TO_MAX_PKT_SIZE (1<<7) + +#define GS_CAN_FEATURE_LISTEN_ONLY (1<<0) +#define GS_CAN_FEATURE_LOOP_BACK (1<<1) +#define GS_CAN_FEATURE_TRIPLE_SAMPLE (1<<2) +#define GS_CAN_FEATURE_ONE_SHOT (1<<3) +#define GS_CAN_FEATURE_HW_TIMESTAMP (1<<4) +#define GS_CAN_FEATURE_IDENTIFY (1<<5) +#define GS_CAN_FEATURE_USER_ID (1<<6) + +#define GS_CAN_FEATURE_PAD_PKTS_TO_MAX_PKT_SIZE (1<<7) #define GS_CAN_FLAG_OVERFLOW 1 diff --git a/include/usbd_gs_can.h b/include/usbd_gs_can.h index ec02142..cc60207 100644 --- a/include/usbd_gs_can.h +++ b/include/usbd_gs_can.h @@ -33,6 +33,16 @@ THE SOFTWARE. #include #include +/* Define these here so they can be referenced in other files */ + +#define CAN_DATA_MAX_PACKET_SIZE 32 /* Endpoint IN & OUT Packet size */ +#define CAN_CMD_PACKET_SIZE 64 /* Control Endpoint Packet size */ +#define USB_CAN_CONFIG_DESC_SIZ 50 +#define NUM_CAN_CHANNEL 1 +#define USBD_GS_CAN_VENDOR_CODE 0x20 +#define DFU_INTERFACE_NUM 1 +#define DFU_INTERFACE_STR_INDEX 0xE0 + extern USBD_ClassTypeDef USBD_GS_CAN; uint8_t USBD_GS_CAN_Init(USBD_HandleTypeDef *pdev, queue_t *q_frame_pool, queue_t *q_from_host, led_data_t *leds); @@ -46,3 +56,4 @@ bool USBD_GS_CAN_DfuDetachRequested(USBD_HandleTypeDef *pdev); uint8_t USBD_GS_CAN_SendFrame(USBD_HandleTypeDef *pdev, struct gs_host_frame *frame); uint8_t USBD_GS_CAN_Transmit(USBD_HandleTypeDef *pdev, uint8_t *buf, uint16_t len); uint8_t USBD_GS_CAN_GetProtocolVersion(USBD_HandleTypeDef *pdev); +uint8_t USBD_GS_CAN_GetPadPacketsToMaxPacketSize(USBD_HandleTypeDef *pdev); diff --git a/src/main.c b/src/main.c index 8edaa3f..75fba21 100644 --- a/src/main.c +++ b/src/main.c @@ -55,6 +55,9 @@ queue_t *q_frame_pool; queue_t *q_from_host; queue_t *q_to_host; +uint32_t received_count=0; + + int main(void) { uint32_t last_can_error_status = 0; @@ -95,18 +98,17 @@ int main(void) #endif while (1) { - - struct gs_host_frame *frame = queue_pop_front(q_from_host); if (frame != 0) { // send can message from host if (can_send(&hCAN, frame)) { - frame->timestamp_us = timer_get(); + // Echo sent frame back to host + frame->timestamp_us = timer_get(); send_to_host_or_enqueue(frame); + led_indicate_trx(&hLED, led_2); } else { queue_push_front(q_from_host, frame); // retry later } - } if (USBD_GS_CAN_TxReady(&hUSB)) { @@ -116,12 +118,14 @@ int main(void) if (can_is_rx_pending(&hCAN)) { struct gs_host_frame *frame = queue_pop_front(q_frame_pool); if ((frame != 0) && can_receive(&hCAN, frame)) { + received_count++; frame->timestamp_us = timer_get(); frame->echo_id = 0xFFFFFFFF; // not a echo frame frame->channel = 0; frame->flags = 0; frame->reserved = 0; + send_to_host_or_enqueue(frame); led_indicate_trx(&hLED, led_1); @@ -154,7 +158,6 @@ int main(void) } } - } void HAL_MspInit(void) @@ -207,12 +210,10 @@ void SystemClock_Config(void) bool send_to_host_or_enqueue(struct gs_host_frame *frame) { if (USBD_GS_CAN_GetProtocolVersion(&hUSB) == 2) { - queue_push_back(q_to_host, frame); return true; } else { - bool retval = false; if ( USBD_GS_CAN_SendFrame(&hUSB, frame) == USBD_OK ) { queue_push_back(q_frame_pool, frame); @@ -221,42 +222,20 @@ bool send_to_host_or_enqueue(struct gs_host_frame *frame) queue_push_back(q_to_host, frame); } return retval; - } } void send_to_host() { - uint8_t buf[5*sizeof(struct gs_host_frame)]; - struct gs_host_frame *frame; + struct gs_host_frame *frame = queue_pop_front(q_to_host); - unsigned num_msgs = queue_size(q_to_host); - - if (num_msgs>0) { // send received message or echo message to host - - if (USBD_GS_CAN_GetProtocolVersion(&hUSB) == 2) { - - if (num_msgs>1) { - num_msgs = 1; - } - - for (unsigned i=0; iq_from_host = q_from_host; hcan->leds = leds; pdev->pClassData = hcan; + hcan->from_host_buf = NULL; + ret = USBD_OK; } else { pdev->pClassData = 0; @@ -319,10 +316,10 @@ static uint8_t USBD_GS_CAN_Start(USBD_HandleTypeDef *pdev, uint8_t cfgidx) uint8_t ret = USBD_FAIL; if (pdev->pClassData) { - USBD_GS_CAN_HandleTypeDef *hcan = (USBD_GS_CAN_HandleTypeDef*) pdev->pClassData; + USBD_GS_CAN_HandleTypeDef *hcan = (USBD_GS_CAN_HandleTypeDef*) pdev->pClassData; USBD_LL_OpenEP(pdev, GSUSB_ENDPOINT_IN, USBD_EP_TYPE_BULK, CAN_DATA_MAX_PACKET_SIZE); USBD_LL_OpenEP(pdev, GSUSB_ENDPOINT_OUT, USBD_EP_TYPE_BULK, CAN_DATA_MAX_PACKET_SIZE); - hcan->from_host_buf = queue_pop_front(hcan->q_frame_pool); + hcan->from_host_buf = queue_pop_front(hcan->q_frame_pool); USBD_GS_CAN_PrepareReceive(pdev); ret = USBD_OK; } else { @@ -411,6 +408,7 @@ static uint8_t USBD_GS_CAN_EP0_RxReady(USBD_HandleTypeDef *pdev) { } else if (mode->mode == GS_CAN_MODE_START) { hcan->timestamps_enabled = (mode->flags & GS_CAN_MODE_HW_TIMESTAMP) != 0; + hcan->pad_pkts_to_max_pkt_size = (mode->flags & GS_CAN_MODE_PAD_PKTS_TO_MAX_PKT_SIZE) != 0; can_enable(ch, (mode->flags & GS_CAN_MODE_LOOP_BACK) != 0, @@ -618,12 +616,17 @@ static uint8_t USBD_GS_CAN_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) { uint32_t rxlen = USBD_LL_GetRxDataSize(pdev, epnum); if (rxlen >= (sizeof(struct gs_host_frame)-4)) { - queue_push_back_i(hcan->q_from_host, hcan->from_host_buf); - hcan->from_host_buf = queue_pop_front_i(hcan->q_frame_pool); - if (hcan->from_host_buf==0) { - // TODO handle buffers full condition - how? + struct gs_host_frame *frame = queue_pop_front_i(hcan->q_frame_pool); + if(frame){ + queue_push_back_i(hcan->q_from_host, hcan->from_host_buf); + hcan->from_host_buf = frame; + + retval = USBD_OK; + } + else{ + // Discard current packet from host if we have no place + // to put the next one } - retval = USBD_OK; } USBD_GS_CAN_PrepareReceive(pdev); return retval; @@ -638,7 +641,7 @@ static uint8_t *USBD_GS_CAN_GetCfgDesc(uint16_t *len) inline uint8_t USBD_GS_CAN_PrepareReceive(USBD_HandleTypeDef *pdev) { USBD_GS_CAN_HandleTypeDef *hcan = (USBD_GS_CAN_HandleTypeDef*)pdev->pClassData; - return USBD_LL_PrepareReceive(pdev, GSUSB_ENDPOINT_OUT, (uint8_t*)hcan->from_host_buf, sizeof(struct gs_host_frame)); + return USBD_LL_PrepareReceive(pdev, GSUSB_ENDPOINT_OUT, (uint8_t*)hcan->from_host_buf, sizeof(*hcan->from_host_buf)); } bool USBD_GS_CAN_TxReady(USBD_HandleTypeDef *pdev) @@ -669,12 +672,38 @@ uint8_t USBD_GS_CAN_GetProtocolVersion(USBD_HandleTypeDef *pdev) } } -uint8_t USBD_GS_CAN_SendFrame(USBD_HandleTypeDef *pdev, struct gs_host_frame *frame) +uint8_t USBD_GS_CAN_GetPadPacketsToMaxPacketSize(USBD_HandleTypeDef *pdev) { + USBD_GS_CAN_HandleTypeDef *hcan = (USBD_GS_CAN_HandleTypeDef*)pdev->pClassData; + return hcan->pad_pkts_to_max_pkt_size; +} + +uint8_t USBD_GS_CAN_SendFrame(USBD_HandleTypeDef *pdev, struct gs_host_frame *frame) +{ + uint8_t buf[CAN_DATA_MAX_PACKET_SIZE],*send_addr; + USBD_GS_CAN_HandleTypeDef *hcan = (USBD_GS_CAN_HandleTypeDef*)pdev->pClassData; size_t len = sizeof(struct gs_host_frame); - if (!hcan->timestamps_enabled) { len -= 4; } - return USBD_GS_CAN_Transmit(pdev, (uint8_t*)frame, len); + + if (!hcan->timestamps_enabled) + len -= 4; + + send_addr = (uint8_t *)frame; + + if(hcan->pad_pkts_to_max_pkt_size){ + // When talking to WinUSB it seems to help a lot if the + // size of packet you send equals the max packet size. + // In this mode, fill packets out to max packet size and + // then send. + memcpy(buf, frame, len); + + // zero rest of buffer + memset(buf + len, 0, sizeof(buf) - len); + send_addr = buf; + len = sizeof(buf); + } + + return USBD_GS_CAN_Transmit(pdev, send_addr, len); } uint8_t *USBD_GS_CAN_GetStrDesc(USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length)