Skip to content

Commit

Permalink
Add terminating resistor support
Browse files Browse the repository at this point in the history
The mcba_usb kernel driver in linux has support for configurable terminating
resistors. This patch adds similar support to this firmware which the
gs_usb USB driver would then activate via the netlink interface.

Signed-off-by: Daniel Trevitz <daniel.trevitz@wika.com>
  • Loading branch information
Daniel-Trevitz committed Sep 19, 2022
1 parent c19f3a1 commit e6b51fa
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 2 deletions.
5 changes: 5 additions & 0 deletions include/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,11 @@ THE SOFTWARE.
#define USB_Pin_DM GPIO_PIN_11
#define USB_Pin_DP GPIO_PIN_12

#define PIN_TERM_GPIO_Port GPIOB
#define PIN_TERM_Pin GPIO_PIN_3
#define PIN_TERM_Mode GPIO_MODE_OUTPUT_PP
#define PIN_TERM_Active_High 1

#else
#error please define BOARD
#endif
11 changes: 11 additions & 0 deletions include/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,14 @@ THE SOFTWARE.
#pragma once

void gpio_init(void);


enum terminator_status {
term_unsupported = -1,
term_inactive,
term_active
};

enum terminator_status set_term(unsigned int channel, enum terminator_status state);

enum terminator_status get_term(unsigned int channel);
3 changes: 3 additions & 0 deletions include/gs_usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ THE SOFTWARE.
* GS_USB_BREQ_BT_CONST_EXT and struct gs_device_bt_const_extended
*/
#define GS_CAN_FEATURE_BT_CONST_EXT (1<<10)
#define GS_CAN_FEATURE_TERMINATION (1<<11)

#define GS_CAN_FLAG_OVERFLOW (1<<0)
#define GS_CAN_FLAG_FD (1<<1) /* is a CAN-FD frame */
Expand Down Expand Up @@ -163,6 +164,8 @@ enum gs_usb_breq {
GS_USB_BREQ_SET_USER_ID,
GS_USB_BREQ_DATA_BITTIMING,
GS_USB_BREQ_BT_CONST_EXT,
GS_USB_BREQ_SET_TERMINATION,
GS_USB_BREQ_GET_TERMINATION,
};

enum gs_can_mode {
Expand Down
61 changes: 61 additions & 0 deletions src/gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ THE SOFTWARE.
*/

#include "config.h"
#include "gpio.h"
#include "hal_include.h"

// must run before can_init
Expand Down Expand Up @@ -70,6 +71,19 @@ void gpio_init(void)
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LEDTX_GPIO_Port, &GPIO_InitStruct);

#ifdef PIN_TERM_Pin
#if (PIN_TERM_Active_High == 1)
HAL_GPIO_WritePin(PIN_TERM_GPIO_Port, PIN_TERM_Pin, GPIO_PIN_RESET);
#else
HAL_GPIO_WritePin(PIN_TERM_GPIO_Port, PIN_TERM_Pin, GPIO_PIN_SET);
#endif
GPIO_InitStruct.Pin = PIN_TERM_Pin;
GPIO_InitStruct.Mode = PIN_TERM_Mode;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(PIN_TERM_GPIO_Port, &GPIO_InitStruct);
#endif

#if defined(BOARD_cannette)
HAL_GPIO_WritePin(nCANSTBY_Port, nCANSTBY_Pin, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = nCANSTBY_Pin;
Expand Down Expand Up @@ -104,3 +118,50 @@ void gpio_init(void)
HAL_GPIO_Init(USB_GPIO_Port, &GPIO_InitStruct);
#endif
}

#ifdef PIN_TERM_Pin
static int term_state = 0;

enum terminator_status set_term(unsigned int channel, enum terminator_status state)
{
// TODO add support for multiple channels
if (state == term_active) {
term_state |= 1 << channel;
} else {
term_state &= ~(1 << channel);
}

#if (PIN_TERM_Active_High == 1)
#define TERM_ON GPIO_PIN_SET
#define TERM_OFF GPIO_PIN_RESET
#else
#define TERM_ON GPIO_PIN_RESET
#define TERM_OFF GPIO_PIN_SET
#endif

HAL_GPIO_WritePin(PIN_TERM_GPIO_Port, PIN_TERM_Pin, state ? TERM_ON : TERM_OFF);

return state;
}

enum terminator_status get_term(unsigned int channel)
{
return !!(term_state & (1 << channel));
}

#else

enum terminator_status set_term(unsigned int channel, enum terminator_status state)
{
(void)state;
(void)channel;
return term_unsupported;
}

enum terminator_status get_term(unsigned int channel)
{
(void)channel;
return term_unsupported;
}

#endif
30 changes: 28 additions & 2 deletions src/usbd_gs_can.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ THE SOFTWARE.
#include "usbd_ioreq.h"
#include "gs_usb.h"
#include "can.h"
#include "gpio.h"
#include "timer.h"
#include "flash.h"

Expand Down Expand Up @@ -272,7 +273,11 @@ static const struct gs_device_bt_const USBD_GS_CAN_btconst = {
| GS_CAN_FEATURE_HW_TIMESTAMP
| GS_CAN_FEATURE_IDENTIFY
| GS_CAN_FEATURE_USER_ID
| GS_CAN_FEATURE_PAD_PKTS_TO_MAX_PKT_SIZE,
| GS_CAN_FEATURE_PAD_PKTS_TO_MAX_PKT_SIZE
#ifdef PIN_TERM_Pin
| GS_CAN_FEATURE_TERMINATION
#endif
,
CAN_CLOCK_SPEED, // can timing base clock
1, // tseg1 min
16, // tseg1 max
Expand Down Expand Up @@ -383,6 +388,12 @@ static uint8_t USBD_GS_CAN_EP0_RxReady(USBD_HandleTypeDef *pdev) {
}
break;

case GS_USB_BREQ_SET_TERMINATION:
memcpy(&param_u32, hcan->ep0_buf, sizeof(param_u32));
if (set_term(req->wValue, param_u32) == term_unsupported)
USBD_CtlError(pdev, req);
break;

case GS_USB_BREQ_SET_USER_ID:
memcpy(&param_u32, hcan->ep0_buf, sizeof(param_u32));
if (flash_set_user_id(req->wValue, param_u32)) {
Expand Down Expand Up @@ -468,6 +479,7 @@ static uint8_t USBD_GS_CAN_DFU_Request(USBD_HandleTypeDef *pdev, USBD_SetupReqTy
static uint8_t USBD_GS_CAN_Config_Request(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_GS_CAN_HandleTypeDef *hcan = (USBD_GS_CAN_HandleTypeDef*) pdev->pClassData;
enum terminator_status term_state;
uint32_t d32;

switch (req->bRequest) {
Expand All @@ -477,10 +489,24 @@ static uint8_t USBD_GS_CAN_Config_Request(USBD_HandleTypeDef *pdev, USBD_SetupRe
case GS_USB_BREQ_BITTIMING:
case GS_USB_BREQ_IDENTIFY:
case GS_USB_BREQ_SET_USER_ID:
case GS_USB_BREQ_SET_TERMINATION:
hcan->last_setup_request = *req;
USBD_CtlPrepareRx(pdev, hcan->ep0_buf, req->wLength);
break;

case GS_USB_BREQ_GET_TERMINATION:
term_state = get_term(req->wValue);

if(term_state == term_unsupported) {
USBD_CtlError(pdev, req);
} else {
d32 = (uint32_t)term_state;
memcpy(hcan->ep0_buf, &d32, sizeof(d32));
USBD_CtlSendData(pdev, hcan->ep0_buf, req->wLength);
}

break;

case GS_USB_BREQ_DEVICE_CONFIG:
memcpy(hcan->ep0_buf, &USBD_GS_CAN_dconf, sizeof(USBD_GS_CAN_dconf));
USBD_CtlSendData(pdev, hcan->ep0_buf, req->wLength);
Expand Down Expand Up @@ -738,7 +764,7 @@ void USBD_GS_CAN_SuspendCallback(USBD_HandleTypeDef *pdev)

if(hcan != NULL && hcan->leds != NULL)
led_set_mode(hcan->leds, led_mode_off);

is_usb_suspend_cb = true;
}

Expand Down

0 comments on commit e6b51fa

Please sign in to comment.