Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/build_all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
matrix:
spice: [RAMNV1]
conf: [Release, Debug]
cubeide_docker_tag: ["7.0", "15.0"]
cubeide_docker_tag: ["15.0"]

runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -73,6 +73,10 @@ jobs:
variant: gsusb
enable: "ENABLE_GSUSB"
disable: "ENABLE_CDC"
- ecu: TARGET_ECUA
variant: gsusb-fdcan
enable: "ENABLE_GSUSB ENABLE_GSUSB_CANFD"
disable: "ENABLE_CDC"
- ecu: TARGET_ECUA
variant: no_uds
enable: ""
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ hardware/V1_revC/0_ramn/fp-info-cache
firmware/RAMNV1/Core/Inc/ramn_screen_template.h
firmware/RAMNV1/Core/Src/ramn_screen_template.c
firmware/RAMNV1/RAMNV1 Debug.launch
workspace/
2 changes: 2 additions & 0 deletions firmware/RAMNV1/.cproject
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
</tool>
<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.1566503351" name="MCU GCC Linker" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker">
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.script.1815547934" name="Linker Script (-T)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.script" value="${workspace_loc:/${ProjName}/STM32L552CETX_FLASH.ld}" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.otherflags.1815547935" name="Other flags" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.otherflags" value="-Wl,--no-warn-rwx-segments" valueType="string"/>
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input.130960903" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
Expand Down Expand Up @@ -161,6 +162,7 @@
</tool>
<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.62359485" name="MCU GCC Linker" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker">
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.script.877762017" name="Linker Script (-T)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.script" value="${workspace_loc:/${ProjName}/STM32L552CETX_FLASH.ld}" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.otherflags.877762018" name="Other flags" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.otherflags" value="-Wl,--no-warn-rwx-segments" valueType="string"/>
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input.1439787846" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
Expand Down
11 changes: 9 additions & 2 deletions firmware/RAMNV1/Core/Inc/ramn_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,15 @@

// Enable this flag to enable the candlelight interface (gs_usb drivers)
// Current implementation is experimental:
// - Error frames are not reported
// - CAN-FD is not supported
// - Due to clock differences, bit timings are not respected (but equivalent baudrates are used)
// Try increasing _Min_Stack_Size if you run into issues
//#define ENABLE_GSUSB

// Enable this flag to enable CAN-FD support in the gs_usb interface.
// When enabled, FD frames (up to 64 bytes) with BRS and ESI flags are supported.
// Requires ENABLE_GSUSB to be defined.
//#define ENABLE_GSUSB_CANFD

#ifndef ENABLE_GSUSB
#define USBD_VID 0x483
#define USBD_PID 0x5740
Expand Down Expand Up @@ -400,6 +403,10 @@
#error Cannot activate GSUSB without enabling USB
#endif

#if defined(ENABLE_GSUSB_CANFD) && !defined(ENABLE_GSUSB)
#error Cannot activate GSUSB_CANFD without enabling GSUSB
#endif

#if defined(ENABLE_USB) && !defined(ENABLE_CDC) && !defined(ENABLE_GSUSB)
#error At least one USB interface must be active if you enable USB
#endif
Expand Down
3 changes: 3 additions & 0 deletions firmware/RAMNV1/Core/Inc/ramn_gsusb.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ RAMN_Result_t RAMN_GSUSB_ProcessRX(FDCAN_RxHeaderTypeDef *canRxHeader, uint8_t *
// Forward a USB message to CAN
RAMN_Result_t RAMN_GSUSB_ProcessTX(FDCAN_TxHeaderTypeDef *canTxHeader, uint8_t *canRxData);

// Send a CAN error frame to USB
RAMN_Result_t RAMN_GSUSB_SendErrorFrame(const FDCAN_ProtocolStatusTypeDef *protocolStatus, const FDCAN_ErrorCountersTypeDef *errorCount, uint32_t err);

#endif

#endif /* INC_RAMN_GSUSB_H_ */
28 changes: 21 additions & 7 deletions firmware/RAMNV1/Core/Src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1867,7 +1867,6 @@ void RAMN_ErrorTaskFunc(void *argument)
{
/* USER CODE BEGIN RAMN_ErrorTaskFunc */
/* Infinite loop */
//TODO: report Errors to GS_USB
FDCAN_ErrorCountersTypeDef errorCount;
FDCAN_ProtocolStatusTypeDef protocolStatus;
RAMN_FDCAN_Status_t gw_freeze;
Expand Down Expand Up @@ -1904,6 +1903,13 @@ void RAMN_ErrorTaskFunc(void *argument)
if(err & HAL_FDCAN_ERROR_PROTOCOL_DATA) RAMN_FDCAN_Status.slcanFlags |= SLCAN_FLAG_BUS_ERROR;
#endif

#ifdef ENABLE_GSUSB
if(RAMN_USB_Config.gsusbOpened && GSUSB_IsConnected((USBD_HandleTypeDef*)hpcd_USB_FS.pData))
{
RAMN_GSUSB_SendErrorFrame(&protocolStatus, &errorCount, err);
}
#endif

#if defined(AUTO_RECOVER_BUSOFF)
if (protocolStatus.BusOff != 0U)
{
Expand Down Expand Up @@ -2287,10 +2293,7 @@ void RAMN_RxTask2Func(void *argument)
else
{

// TODO implement CAN-FD

//recvFrame->echo_id
//recvFrame.flags
//recvFrame.reserved


Expand All @@ -2302,9 +2305,20 @@ void RAMN_RxTask2Func(void *argument)
if (recvFrame->can_id & CAN_EFF_FLAG) CANTxHeader.IdType = FDCAN_EXTENDED_ID;
else CANTxHeader.IdType = FDCAN_STANDARD_ID;

CANTxHeader.BitRateSwitch = FDCAN_BRS_OFF;
CANTxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
CANTxHeader.FDFormat = FDCAN_CLASSIC_CAN;
#ifdef ENABLE_GSUSB_CANFD
if (recvFrame->flags & GS_CAN_FLAG_FD)
{
CANTxHeader.FDFormat = FDCAN_FD_CAN;
CANTxHeader.BitRateSwitch = (recvFrame->flags & GS_CAN_FLAG_BRS) ? FDCAN_BRS_ON : FDCAN_BRS_OFF;
CANTxHeader.ErrorStateIndicator = (recvFrame->flags & GS_CAN_FLAG_ESI) ? FDCAN_ESI_PASSIVE : FDCAN_ESI_ACTIVE;
}
else
#endif
{
CANTxHeader.FDFormat = FDCAN_CLASSIC_CAN;
CANTxHeader.BitRateSwitch = FDCAN_BRS_OFF;
CANTxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
}
CANTxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;

//CANTxHeader.MessageMarker = 0U;
Expand Down
126 changes: 106 additions & 20 deletions firmware/RAMNV1/Core/Src/ramn_gsusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,6 @@ RAMN_Result_t RAMN_GSUSB_ProcessRX(FDCAN_RxHeaderTypeDef *canRxHeader, uint8_t *
qret = xQueueReceive(RAMN_GSUSB_PoolQueueHandle, &frameData, portMAX_DELAY);
if (qret == pdPASS)
{
// Does not support CAN FD yet
if(canRxHeader->FDFormat == FDCAN_FD_CAN)
{
#ifdef HANG_ON_ERRORS
Error_Handler();
#endif
return RAMN_ERROR;
}

frameData->can_id = canRxHeader->Identifier;
if (canRxHeader->IdType != FDCAN_STANDARD_ID) frameData->can_id |= CAN_EFF_FLAG;
if (canRxHeader->RxFrameType != FDCAN_DATA_FRAME) frameData->can_id |= CAN_RTR_FLAG;
Expand All @@ -49,7 +40,20 @@ RAMN_Result_t RAMN_GSUSB_ProcessRX(FDCAN_RxHeaderTypeDef *canRxHeader, uint8_t *
frameData->can_dlc = canRxHeader->DataLength;
frameData->timestamp_us = (xTaskGetTickCount() * (1000000 /*us per sec*/ / configTICK_RATE_HZ) );

if (!(frameData->can_id & CAN_RTR_FLAG)) RAMN_memcpy(frameData->data, canRxData, frameData->can_dlc);
#ifdef ENABLE_GSUSB_CANFD
if (canRxHeader->FDFormat == FDCAN_FD_CAN)
{
frameData->flags |= GS_CAN_FLAG_FD;
if (canRxHeader->BitRateSwitch == FDCAN_BRS_ON) frameData->flags |= GS_CAN_FLAG_BRS;
if (canRxHeader->ErrorStateIndicator == FDCAN_ESI_PASSIVE) frameData->flags |= GS_CAN_FLAG_ESI;
}
#endif

if (!(frameData->can_id & CAN_RTR_FLAG))
{
uint8_t actual = FDCAN_ConvertToActual(frameData->can_dlc);
RAMN_memcpy(frameData->data, canRxData, actual);
}

// Send to task
qret = xQueueSendToBack(RAMN_GSUSB_SendQueueHandle, &frameData, CAN_QUEUE_TIMEOUT);
Expand All @@ -75,21 +79,25 @@ RAMN_Result_t RAMN_GSUSB_ProcessTX(FDCAN_TxHeaderTypeDef *canTxHeader, uint8_t *
qret = xQueueReceive(RAMN_GSUSB_PoolQueueHandle, &frameData, CAN_QUEUE_TIMEOUT);
if (qret == pdPASS)
{
// Does not support CAN FD yet
if(canTxHeader->FDFormat == FDCAN_FD_CAN)
{
#ifdef HANG_ON_ERRORS
Error_Handler();
#endif
return RAMN_ERROR;
}

frameData->can_id = canTxHeader->Identifier;
frameData->echo_id = 0xFFFFFFFF;
frameData->channel = 0;
frameData->flags = 0;
frameData->can_dlc = canTxHeader->DataLength;
frameData->timestamp_us = 0; // timestamps are ignored on send
RAMN_memcpy(frameData->data, canRxData, frameData->can_dlc);

#ifdef ENABLE_GSUSB_CANFD
if (canTxHeader->FDFormat == FDCAN_FD_CAN)
{
frameData->flags |= GS_CAN_FLAG_FD;
if (canTxHeader->BitRateSwitch == FDCAN_BRS_ON) frameData->flags |= GS_CAN_FLAG_BRS;
}
#endif

{
uint8_t actual = FDCAN_ConvertToActual(frameData->can_dlc);
RAMN_memcpy(frameData->data, canRxData, actual);
}

// Send to task
qret = xQueueSendToBack(RAMN_GSUSB_SendQueueHandle, &frameData, CAN_QUEUE_TIMEOUT);
Expand All @@ -103,4 +111,82 @@ RAMN_Result_t RAMN_GSUSB_ProcessTX(FDCAN_TxHeaderTypeDef *canTxHeader, uint8_t *
return ret;
}

RAMN_Result_t RAMN_GSUSB_SendErrorFrame(const FDCAN_ProtocolStatusTypeDef *protocolStatus, const FDCAN_ErrorCountersTypeDef *errorCount, uint32_t err)
{
BaseType_t qret;
struct gs_host_frame *frameData;

// Get frame data pointer from pool queue (non-blocking)
qret = xQueueReceive(RAMN_GSUSB_PoolQueueHandle, &frameData, 0);
if (qret != pdPASS) return RAMN_ERROR;

frameData->echo_id = 0xFFFFFFFF;
frameData->can_id = CAN_ERR_FLAG;
frameData->can_dlc = CAN_ERR_DLC;
frameData->channel = 0;
frameData->flags = 0;
frameData->reserved = 0;
frameData->timestamp_us = (xTaskGetTickCount() * (1000000U / configTICK_RATE_HZ));
RAMN_memset(frameData->data, 0, CAN_ERR_DLC);

// Bus off
if (protocolStatus->BusOff != 0U)
{
frameData->can_id |= CAN_ERR_BUSOFF;
}

// Controller error state
if ((protocolStatus->ErrorPassive != 0U) || (protocolStatus->Warning != 0U))
{
frameData->can_id |= CAN_ERR_CRTL;
if (protocolStatus->Warning != 0U)
{
if (errorCount->TxErrorCnt >= 96U) frameData->data[1] |= CAN_ERR_CRTL_TX_WARNING;
if (errorCount->RxErrorCnt >= 96U) frameData->data[1] |= CAN_ERR_CRTL_RX_WARNING;
}
if (protocolStatus->ErrorPassive != 0U)
{
if (errorCount->TxErrorCnt >= 128U) frameData->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
if (errorCount->RxErrorPassive != 0U) frameData->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
}
}

// Protocol errors
if ((err & (HAL_FDCAN_ERROR_PROTOCOL_ARBT | HAL_FDCAN_ERROR_PROTOCOL_DATA)) != 0U)
{
uint32_t lec = protocolStatus->LastErrorCode;
frameData->can_id |= CAN_ERR_BUSERROR;
if ((lec != FDCAN_PROTOCOL_ERROR_NONE) && (lec != FDCAN_PROTOCOL_ERROR_NO_CHANGE))
{
frameData->can_id |= CAN_ERR_PROT;
switch (lec)
{
case FDCAN_PROTOCOL_ERROR_STUFF: frameData->data[2] = CAN_ERR_PROT_STUFF; break;
case FDCAN_PROTOCOL_ERROR_FORM: frameData->data[2] = CAN_ERR_PROT_FORM; break;
case FDCAN_PROTOCOL_ERROR_ACK: frameData->can_id |= CAN_ERR_ACK; break;
case FDCAN_PROTOCOL_ERROR_BIT1: frameData->data[2] = CAN_ERR_PROT_BIT1; break;
case FDCAN_PROTOCOL_ERROR_BIT0: frameData->data[2] = CAN_ERR_PROT_BIT0; break;
case FDCAN_PROTOCOL_ERROR_CRC: frameData->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; break;
default: frameData->data[2] = CAN_ERR_PROT_UNSPEC; break;
}
}
}

// Only send if there is actual error info
if (frameData->can_id == CAN_ERR_FLAG)
{
xQueueSendToBack(RAMN_GSUSB_PoolQueueHandle, &frameData, portMAX_DELAY);
return RAMN_OK;
}

qret = xQueueSendToBack(RAMN_GSUSB_SendQueueHandle, &frameData, 0);
if (qret != pdPASS)
{
xQueueSendToBack(RAMN_GSUSB_PoolQueueHandle, &frameData, portMAX_DELAY);
return RAMN_ERROR;
}

return RAMN_OK;
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
* Public functions *
*==============================================================================*/

#ifdef ENABLE_CDC
static void cdc_init(USBD_HandleTypeDef *pdev, uint8_t index)
{
if(index == 0)
Expand Down Expand Up @@ -61,6 +62,7 @@ static void cdc_init(USBD_HandleTypeDef *pdev, uint8_t index)
((USBD_Composite_HandleTypeDef *)pdev->pClassData)->RxState[0] = 0U;
}
}
#endif

/**
* @brief USBD_CDC_Init
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ void breq_set_mode(USBD_GS_CAN_HandleTypeDef *hcan, USBD_SetupReqTypedef *req)
}
else if (mode->mode == GS_CAN_MODE_START)
{
#ifdef ENABLE_GSUSB_CANFD
hcan->enable_fdcan = (mode->flags & GS_CAN_MODE_FD) != 0;
#else
hcan->enable_fdcan = 0;
#endif
FDCAN_InitQueues(hcan);
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;
Expand Down Expand Up @@ -121,6 +126,7 @@ void breq_set_bittiming(USBD_GS_CAN_HandleTypeDef *hcan, USBD_SetupReqTypedef *r
*/
void breq_set_data_bittiming(USBD_GS_CAN_HandleTypeDef *hcan, USBD_SetupReqTypedef *req)
{
#ifdef ENABLE_GSUSB_CANFD
struct gs_device_bittiming *timing;

timing = (struct gs_device_bittiming *)hcan->ep0_buf;
Expand All @@ -133,6 +139,7 @@ void breq_set_data_bittiming(USBD_GS_CAN_HandleTypeDef *hcan, USBD_SetupReqTyped
);

hcan->enable_fdcan = 1;
#endif
}

#endif
Loading