mirror of
https://github.com/candle-usb/candleLight_fw.git
synced 2025-01-14 05:42:53 +08:00
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:
commit
53b4b915af
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
*.o
|
||||
*.d
|
||||
*.bin
|
||||
*.asmo
|
||||
*.elf
|
||||
*~
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
55
src/main.c
55
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; 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(!frame)
|
||||
return;
|
||||
|
||||
if (USBD_GS_CAN_SendFrame(&hUSB, frame) == USBD_OK) {
|
||||
queue_push_back(q_frame_pool, frame);
|
||||
} else {
|
||||
queue_push_front(q_to_host, frame);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user