Merge pull request #7 from mbehensky/master

Thank you very much for your great contribution, will happily merge it :-)
I definitely should put more interest in the candleLight windows support, I guess.
This commit is contained in:
Hubert Denkmair 2017-11-27 21:31:26 +01:00 committed by GitHub
commit 53b4b915af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 102 additions and 72 deletions

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
*.o
*.d
*.bin
*.asmo
*.elf
*~

View File

@ -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

View File

@ -33,6 +33,16 @@ THE SOFTWARE.
#include <can.h>
#include <gs_usb.h>
/* 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);

View File

@ -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(!frame)
return;
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; i<num_msgs; i++) {
frame = queue_pop_front(q_to_host);
memcpy(&buf[i*sizeof(struct gs_host_frame)], frame, sizeof(struct gs_host_frame));
queue_push_back(q_frame_pool, frame);
}
USBD_GS_CAN_Transmit(&hUSB, buf, num_msgs * sizeof(struct gs_host_frame));
} else {
struct gs_host_frame *frame = queue_pop_front(q_to_host);
if (USBD_GS_CAN_SendFrame(&hUSB, frame) == USBD_OK) {
queue_push_back(q_frame_pool, frame);
} else {
queue_push_front(q_to_host, frame);
}
}
if (USBD_GS_CAN_SendFrame(&hUSB, frame) == USBD_OK) {
queue_push_back(q_frame_pool, frame);
} else {
queue_push_front(q_to_host, frame);
}
}

View File

@ -37,14 +37,6 @@ THE SOFTWARE.
#include "timer.h"
#include "flash.h"
#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
typedef struct {
uint8_t ep0_buf[CAN_CMD_PACKET_SIZE];
@ -56,7 +48,7 @@ typedef struct {
queue_t *q_frame_pool;
queue_t *q_from_host;
struct gs_host_frame *from_host_buf;
struct gs_host_frame *from_host_buf;
can_data_t *channels[NUM_CAN_CHANNEL];
@ -70,6 +62,8 @@ typedef struct {
bool timestamps_enabled;
uint32_t sof_timestamp_us;
bool pad_pkts_to_max_pkt_size;
} USBD_GS_CAN_HandleTypeDef __attribute__ ((aligned (4)));
static uint8_t USBD_GS_CAN_Start(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
@ -280,7 +274,8 @@ static const struct gs_device_bt_const USBD_GS_CAN_btconst = {
| GS_CAN_FEATURE_LOOP_BACK
| GS_CAN_FEATURE_HW_TIMESTAMP
| GS_CAN_FEATURE_IDENTIFY
| GS_CAN_FEATURE_USER_ID,
| GS_CAN_FEATURE_USER_ID
| GS_CAN_FEATURE_PAD_PKTS_TO_MAX_PKT_SIZE,
48000000, // can timing base clock
1, // tseg1 min
16, // tseg1 max
@ -303,6 +298,8 @@ uint8_t USBD_GS_CAN_Init(USBD_HandleTypeDef *pdev, queue_t *q_frame_pool, queue_
hcan->q_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)