mirror of
https://github.com/candle-usb/candleLight_fw.git
synced 2025-01-28 06:02:52 +08:00
implement can settings
This commit is contained in:
parent
48bbbbb254
commit
b52e20ecb6
8
include/can.h
Normal file
8
include/can.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "stm32f0xx_hal.h"
|
||||||
|
|
||||||
|
void can_set_bittiming(CAN_HandleTypeDef *hcan, uint16_t brp, uint8_t phase_seg1, uint8_t phase_seg2, uint8_t sjw);
|
||||||
|
void can_enable(CAN_HandleTypeDef *hcan, bool loop_back, bool listen_only, bool one_shot, bool triple_sample);
|
||||||
|
void can_disable(CAN_HandleTypeDef *hcan);
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
extern USBD_ClassTypeDef USBD_GS_CAN;
|
extern USBD_ClassTypeDef USBD_GS_CAN;
|
||||||
|
|
||||||
|
void USBD_GS_CAN_SetChannel(USBD_HandleTypeDef *pdev, uint8_t channel, CAN_HandleTypeDef* handle);
|
||||||
|
|
||||||
void USBD_GS_CAN_SendFrameToHost(
|
void USBD_GS_CAN_SendFrameToHost(
|
||||||
USBD_HandleTypeDef *pdev,
|
USBD_HandleTypeDef *pdev,
|
||||||
uint32_t echo_id,
|
uint32_t echo_id,
|
||||||
|
44
src/can.c
Normal file
44
src/can.c
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#include "can.h"
|
||||||
|
|
||||||
|
void can_set_bittiming(CAN_HandleTypeDef *hcan, uint16_t brp, uint8_t phase_seg1, uint8_t phase_seg2, uint8_t sjw)
|
||||||
|
{
|
||||||
|
HAL_CAN_DeInit(hcan);
|
||||||
|
|
||||||
|
hcan->Init.Prescaler = brp;
|
||||||
|
|
||||||
|
if ((phase_seg1>0) && (phase_seg1<17)) {
|
||||||
|
hcan->Init.BS1 = (phase_seg1-1)<<16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((phase_seg2>0) && (phase_seg2<9)) {
|
||||||
|
hcan->Init.BS2 = (phase_seg2-1)<<20;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((sjw>0) && (sjw<5)) {
|
||||||
|
hcan->Init.SJW = (sjw-1)<<24;
|
||||||
|
}
|
||||||
|
|
||||||
|
HAL_CAN_Init(hcan);
|
||||||
|
}
|
||||||
|
|
||||||
|
void can_enable(CAN_HandleTypeDef *hcan, bool loop_back, bool listen_only, bool one_shot, bool triple_sample)
|
||||||
|
{
|
||||||
|
hcan->Init.Mode = 0;
|
||||||
|
if (loop_back) {
|
||||||
|
hcan->Init.Mode |= CAN_MODE_LOOPBACK;
|
||||||
|
}
|
||||||
|
if (listen_only) {
|
||||||
|
hcan->Init.Mode |= CAN_MODE_SILENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
hcan->Init.NART = one_shot ? ENABLE : DISABLE;
|
||||||
|
|
||||||
|
// tripple sample not supported on bxCAN
|
||||||
|
|
||||||
|
HAL_CAN_Init(hcan);
|
||||||
|
}
|
||||||
|
|
||||||
|
void can_disable(CAN_HandleTypeDef *hcan)
|
||||||
|
{
|
||||||
|
HAL_CAN_DeInit(hcan);
|
||||||
|
}
|
@ -74,6 +74,7 @@ int main(void)
|
|||||||
|
|
||||||
USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);
|
USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);
|
||||||
USBD_RegisterClass(&hUsbDeviceFS, &USBD_GS_CAN);
|
USBD_RegisterClass(&hUsbDeviceFS, &USBD_GS_CAN);
|
||||||
|
USBD_GS_CAN_SetChannel(&hUsbDeviceFS, 0, &hcan);
|
||||||
USBD_Start(&hUsbDeviceFS);
|
USBD_Start(&hUsbDeviceFS);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -1,27 +1,31 @@
|
|||||||
#include "usbd_gs_can.h"
|
#include "usbd_gs_can.h"
|
||||||
|
|
||||||
|
#include "stm32f0xx_hal.h"
|
||||||
#include "usbd_desc.h"
|
#include "usbd_desc.h"
|
||||||
#include "usbd_ctlreq.h"
|
#include "usbd_ctlreq.h"
|
||||||
#include "usbd_ioreq.h"
|
#include "usbd_ioreq.h"
|
||||||
#include "gs_usb.h"
|
#include "gs_usb.h"
|
||||||
|
#include "can.h"
|
||||||
|
|
||||||
#define CAN_DATA_MAX_PACKET_SIZE 32 /* Endpoint IN & OUT Packet size */
|
#define CAN_DATA_MAX_PACKET_SIZE 32 /* Endpoint IN & OUT Packet size */
|
||||||
#define CAN_CMD_PACKET_SIZE 64 /* Control Endpoint Packet size */
|
#define CAN_CMD_PACKET_SIZE 64 /* Control Endpoint Packet size */
|
||||||
#define USB_CAN_CONFIG_DESC_SIZ 32
|
#define USB_CAN_CONFIG_DESC_SIZ 32
|
||||||
|
#define NUM_CAN_CHANNEL 1
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
__IO uint32_t TxState;
|
__IO uint32_t TxState;
|
||||||
|
|
||||||
uint8_t req_bRequest;
|
uint8_t req_bRequest;
|
||||||
uint8_t req_wLength;
|
uint16_t req_wLength;
|
||||||
|
uint16_t req_wValue;
|
||||||
|
|
||||||
uint8_t ep0_buf[CAN_CMD_PACKET_SIZE];
|
uint8_t ep0_buf[CAN_CMD_PACKET_SIZE];
|
||||||
uint8_t ep_out_buf[CAN_DATA_MAX_PACKET_SIZE];
|
uint8_t ep_out_buf[CAN_DATA_MAX_PACKET_SIZE];
|
||||||
uint8_t ep_in_buf[CAN_DATA_MAX_PACKET_SIZE];
|
uint8_t ep_in_buf[CAN_DATA_MAX_PACKET_SIZE];
|
||||||
|
|
||||||
struct gs_host_config host_config;
|
struct gs_host_config host_config;
|
||||||
struct gs_device_mode device_mode;
|
|
||||||
struct gs_device_bittiming bittiming;
|
|
||||||
|
|
||||||
|
CAN_HandleTypeDef *channels[NUM_CAN_CHANNEL];
|
||||||
} USBD_GS_CAN_HandleTypeDef;
|
} USBD_GS_CAN_HandleTypeDef;
|
||||||
|
|
||||||
static uint8_t USBD_GS_CAN_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
static uint8_t USBD_GS_CAN_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||||
@ -127,6 +131,13 @@ static uint8_t USBD_GS_CAN_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void USBD_GS_CAN_SetChannel(USBD_HandleTypeDef *pdev, uint8_t channel, CAN_HandleTypeDef* handle) {
|
||||||
|
USBD_GS_CAN_HandleTypeDef *hcan = (USBD_GS_CAN_HandleTypeDef*) pdev->pClassData;
|
||||||
|
if ((hcan!=NULL) && (channel < NUM_CAN_CHANNEL)) {
|
||||||
|
hcan->channels[channel] = handle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t USBD_GS_CAN_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
static uint8_t USBD_GS_CAN_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||||
{
|
{
|
||||||
(void) cfgidx;
|
(void) cfgidx;
|
||||||
@ -148,6 +159,10 @@ static uint8_t USBD_GS_CAN_EP0_RxReady(USBD_HandleTypeDef *pdev) {
|
|||||||
|
|
||||||
USBD_GS_CAN_HandleTypeDef *hcan = (USBD_GS_CAN_HandleTypeDef*) pdev->pClassData;
|
USBD_GS_CAN_HandleTypeDef *hcan = (USBD_GS_CAN_HandleTypeDef*) pdev->pClassData;
|
||||||
|
|
||||||
|
struct gs_device_bittiming *timing;
|
||||||
|
struct gs_device_mode *mode;
|
||||||
|
CAN_HandleTypeDef *ch;
|
||||||
|
|
||||||
switch (hcan->req_bRequest) {
|
switch (hcan->req_bRequest) {
|
||||||
|
|
||||||
case GS_USB_BREQ_HOST_FORMAT:
|
case GS_USB_BREQ_HOST_FORMAT:
|
||||||
@ -156,20 +171,45 @@ static uint8_t USBD_GS_CAN_EP0_RxReady(USBD_HandleTypeDef *pdev) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GS_USB_BREQ_MODE:
|
case GS_USB_BREQ_MODE:
|
||||||
// TODO set device mode (flags, start/reset...)
|
if (hcan->req_wValue < NUM_CAN_CHANNEL) {
|
||||||
memcpy(&hcan->device_mode, hcan->ep0_buf, sizeof(hcan->device_mode));
|
|
||||||
|
mode = (struct gs_device_mode*)hcan->ep0_buf;
|
||||||
|
ch = hcan->channels[hcan->req_wValue];
|
||||||
|
|
||||||
|
if (mode->mode == GS_CAN_MODE_RESET) {
|
||||||
|
|
||||||
|
can_disable(ch);
|
||||||
|
|
||||||
|
} else if (mode->mode == GS_CAN_MODE_START) {
|
||||||
|
|
||||||
|
can_enable(ch,
|
||||||
|
(mode->flags & GS_CAN_MODE_LOOP_BACK) != 0,
|
||||||
|
(mode->flags & GS_CAN_MODE_LISTEN_ONLY) != 0,
|
||||||
|
(mode->flags & GS_CAN_MODE_ONE_SHOT) != 0,
|
||||||
|
(mode->flags & GS_CAN_MODE_TRIPLE_SAMPLE) != 0
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GS_USB_BREQ_BITTIMING:
|
case GS_USB_BREQ_BITTIMING:
|
||||||
// TODO set bit timing
|
timing = (struct gs_device_bittiming*)hcan->ep0_buf;
|
||||||
memcpy(&hcan->bittiming, hcan->ep0_buf, sizeof(hcan->bittiming));
|
if (hcan->req_wValue < NUM_CAN_CHANNEL) {
|
||||||
|
can_set_bittiming(
|
||||||
|
hcan->channels[hcan->req_wValue],
|
||||||
|
timing->brp,
|
||||||
|
timing->prop_seg + timing->phase_seg1,
|
||||||
|
timing->phase_seg2,
|
||||||
|
timing->sjw
|
||||||
|
);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
hcan->req_bRequest = 0xFF;
|
hcan->req_bRequest = 0xFF;
|
||||||
return USBD_OK;
|
return USBD_OK;
|
||||||
}
|
}
|
||||||
@ -203,7 +243,8 @@ static uint8_t USBD_GS_CAN_Vendor_Request(USBD_HandleTypeDef *pdev, USBD_SetupRe
|
|||||||
case GS_USB_BREQ_MODE:
|
case GS_USB_BREQ_MODE:
|
||||||
case GS_USB_BREQ_BITTIMING:
|
case GS_USB_BREQ_BITTIMING:
|
||||||
hcan->req_bRequest = req->bRequest;
|
hcan->req_bRequest = req->bRequest;
|
||||||
hcan->req_wLength = (uint8_t)req->wLength;
|
hcan->req_wLength = req->wLength;
|
||||||
|
hcan->req_wValue = req->wValue;
|
||||||
USBD_CtlPrepareRx(pdev, hcan->ep0_buf, req->wLength);
|
USBD_CtlPrepareRx(pdev, hcan->ep0_buf, req->wLength);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -324,7 +365,5 @@ void USBD_GS_CAN_SendFrameToHost(
|
|||||||
hf.data[i] = data[i];
|
hf.data[i] = data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hcan->device_mode.mode == GS_CAN_MODE_START) {
|
|
||||||
USBD_GS_CAN_Transmit(pdev, (uint8_t*)&hf, sizeof(hf));
|
USBD_GS_CAN_Transmit(pdev, (uint8_t*)&hf, sizeof(hf));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user