hardware timestamp support via mode

This commit is contained in:
Hubert Denkmair 2016-05-13 21:59:31 +02:00
parent 56192e76f6
commit f4f47116cd
6 changed files with 86 additions and 28 deletions

View File

@ -35,7 +35,7 @@ THE SOFTWARE.
#define USBD_CONFIGURATION_STRING_FS (uint8_t*) "gs_usb config"
#define USBD_INTERFACE_STRING_FS (uint8_t*) "gs_usb interface"
#define DFU_INTERFACE_STRING_FS (uint8_t*) "candleLight firmware upgrade interface"
#define USBD_SERIALNUMBER_STRING_FS (uint8_t*) "000000000001"
#define USBD_SERIALNUMBER_STRING_FS (uint8_t*) "000000000002"
#define BOARD_candleLight 1
#define BOARD_cantact 2

View File

@ -38,10 +38,14 @@ THE SOFTWARE.
#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_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_MODE_HW_TIMESTAMP (1<<16)
#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<<16)
#define GS_CAN_FLAG_OVERFLOW 1
#define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */

View File

@ -44,3 +44,5 @@ bool USBD_GS_CAN_CustomInterfaceRequest(USBD_HandleTypeDef *pdev, USBD_SetupReqT
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);

View File

@ -25,6 +25,7 @@ THE SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "stm32f0xx_hal.h"
@ -43,6 +44,7 @@ THE SOFTWARE.
void HAL_MspInit(void);
void SystemClock_Config(void);
static bool send_to_host_or_enqueue(struct gs_host_frame *frame);
static void send_to_host();
can_data_t hCAN;
USBD_HandleTypeDef hUSB;
@ -104,14 +106,7 @@ int main(void)
}
if (USBD_GS_CAN_TxReady(&hUSB)) {
if (queue_size(q_to_host)>0) { // send received message or echo message to host
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);
}
}
send_to_host();
}
if (can_is_rx_pending(&hCAN)) {
@ -207,13 +202,57 @@ void SystemClock_Config(void)
bool send_to_host_or_enqueue(struct gs_host_frame *frame)
{
bool retval = false;
if ( USBD_GS_CAN_SendFrame(&hUSB, frame) == USBD_OK ) {
queue_push_back(q_frame_pool, frame);
retval = true;
} else {
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);
retval = true;
} else {
queue_push_back(q_to_host, frame);
}
return retval;
}
return retval;
}
void send_to_host()
{
uint8_t buf[5*sizeof(struct gs_host_frame)];
struct gs_host_frame *frame;
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);
}
}
}
}

View File

@ -116,17 +116,17 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
/*
* PMA layout
* 0x00 - 0x18 (24 bytes) metadata?
* 0x18 - 0x58 (64 bytes) EP0 OUT
* 0x58 - 0x98 (64 bytes) EP0 IN
* 0x98 - 0xD8 (64 bytes) EP1 IN
* 0xD8 - 0x118 (64 bytes) EP1 OUT (buffer 1)
* 0x118 - 0x158 (64 bytes) EP1 OUT (buffer 2)
* 0x00 - 0x17 (24 bytes) metadata?
* 0x18 - 0x57 (64 bytes) EP0 OUT
* 0x58 - 0x97 (64 bytes) EP0 IN
* 0x98 - 0xD7 (64 bytes) EP1 IN
* 0xD8 - 0x157 (128 bytes) EP1 OUT (buffer 1)
* 0x158 - 0x1D7 (128 bytes) EP1 OUT (buffer 2)
*/
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 24);
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x58);
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x81 , PCD_SNG_BUF, 0x98);
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x02 , PCD_DBL_BUF, 0x00D80118);
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x02 , PCD_DBL_BUF, 0x00D80158);
return USBD_OK;
}

View File

@ -269,13 +269,13 @@ static const struct gs_device_config USBD_GS_CAN_dconf = {
0, // reserved 2
0, // reserved 3
0, // interface count (0=1, 1=2..)
1, // software version
2, // software version
1 // hardware version
};
// bit timing constraints
static const struct gs_device_bt_const USBD_GS_CAN_btconst = {
GS_CAN_FEATURE_LISTEN_ONLY | GS_CAN_FEATURE_LOOP_BACK, // supported features
GS_CAN_FEATURE_LISTEN_ONLY | GS_CAN_FEATURE_LOOP_BACK | GS_CAN_FEATURE_HW_TIMESTAMP, // supported features
48000000, // can timing base clock
1, // tseg1 min
16, // tseg1 max
@ -381,6 +381,8 @@ 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;
can_enable(ch,
(mode->flags & GS_CAN_MODE_LOOP_BACK) != 0,
(mode->flags & GS_CAN_MODE_LISTEN_ONLY) != 0,
@ -619,6 +621,16 @@ uint8_t USBD_GS_CAN_Transmit(USBD_HandleTypeDef *pdev, uint8_t *buf, uint16_t le
}
}
uint8_t USBD_GS_CAN_GetProtocolVersion(USBD_HandleTypeDef *pdev)
{
USBD_GS_CAN_HandleTypeDef *hcan = (USBD_GS_CAN_HandleTypeDef*)pdev->pClassData;
if (hcan->timestamps_enabled) {
return 2;
} else {
return 1;
}
}
uint8_t USBD_GS_CAN_SendFrame(USBD_HandleTypeDef *pdev, struct gs_host_frame *frame)
{
USBD_GS_CAN_HandleTypeDef *hcan = (USBD_GS_CAN_HandleTypeDef*)pdev->pClassData;
@ -650,3 +662,4 @@ bool USBD_GS_CAN_DfuDetachRequested(USBD_HandleTypeDef *pdev)
USBD_GS_CAN_HandleTypeDef *hcan = (USBD_GS_CAN_HandleTypeDef*)pdev->pClassData;
return hcan->dfu_detach_requested;
}