parent
cd8bc7e8e6
commit
62c4a43894
|
@ -0,0 +1,152 @@
|
|||
---
|
||||
Language: Cpp
|
||||
DisableFormat: false
|
||||
# BasedOnStyle: WebKit
|
||||
Standard: Latest
|
||||
ColumnLimit: 180
|
||||
UseTab: Never
|
||||
TabWidth: 4
|
||||
IndentWidth: 4
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
# The extra indent or outdent of access modifiers, e.g. public:.
|
||||
AccessModifierOffset: -4
|
||||
# DeriveLineEnding: true
|
||||
UseCRLF: true
|
||||
# DerivePointerAlignment: false
|
||||
PointerAlignment: Right
|
||||
|
||||
# clang-format 14
|
||||
ReferenceAlignment: Right
|
||||
|
||||
# clang-format 14
|
||||
# PackConstructorInitializers: CurrentLine
|
||||
|
||||
# clang-format 14
|
||||
# SeparateDefinitionBlocks: Always
|
||||
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignArrayOfStructures: Left
|
||||
AlignConsecutiveAssignments: AcrossEmptyLinesAndComments
|
||||
AlignConsecutiveBitFields: AcrossEmptyLinesAndComments
|
||||
AlignConsecutiveDeclarations: AcrossComments
|
||||
AlignConsecutiveMacros: AcrossComments
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: AlignAfterOperator
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: Always
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
# AllowShortIfStatementsOnASingleLine: AllIfsAndElse
|
||||
AllowShortLambdasOnASingleLine: Inline
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
# trailing comma insertion cannot be used with bin packing
|
||||
InsertTrailingCommas: Wrapped
|
||||
BitFieldColonSpacing: Both
|
||||
|
||||
# Allman Custom
|
||||
BreakBeforeBraces: Custom
|
||||
|
||||
# If BreakBeforeBraces is set to Custom,
|
||||
# use this to specify how each individual brace case should be handled. Otherwise, this is ignored.
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: true
|
||||
AfterClass: true
|
||||
AfterControlStatement: Always
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
BeforeLambdaBody: true
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
|
||||
BreakBeforeBinaryOperators: NonAssignment
|
||||
BreakBeforeConceptDeclarations: true
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
BreakInheritanceList: BeforeComma
|
||||
BreakStringLiterals: false
|
||||
CompactNamespaces: false
|
||||
Cpp11BracedListStyle: false
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IncludeBlocks: Merge
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseBlocks: true
|
||||
IndentCaseLabels: true
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentGotoLabels: false
|
||||
IndentPPDirectives: None
|
||||
IndentRequires: false
|
||||
IndentWrappedFunctionNames: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MaxEmptyLinesToKeep: 2
|
||||
NamespaceIndentation: None
|
||||
|
||||
PenaltyBreakAssignment: 20
|
||||
# The penalty for breaking a function call after call(
|
||||
PenaltyBreakBeforeFirstCallParameter: 20
|
||||
PenaltyBreakComment: 300
|
||||
# The penalty for breaking before the first <<
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
|
||||
ReflowComments: true
|
||||
SortIncludes: CaseSensitive
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: true
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatementsExceptControlMacros
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceBeforeSquareBrackets: false
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
StatementAttributeLikeMacros:
|
||||
- Q_EMIT
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
WhitespaceSensitiveMacros:
|
||||
- STRINGIZE
|
||||
- PP_STRINGIZE
|
||||
- BOOST_PP_STRINGIZE
|
||||
- NS_SWIFT_NAME
|
||||
- CF_SWIFT_NAME
|
||||
...
|
|
@ -1,3 +1,4 @@
|
|||
{
|
||||
"makefile.extensionOutputFolder": "./.vscode"
|
||||
"makefile.extensionOutputFolder": "./.vscode",
|
||||
"editor.detectIndentation": false
|
||||
}
|
|
@ -2,27 +2,23 @@
|
|||
#include <stm32f0xx_hal.h>
|
||||
|
||||
#define GPIO_NOAF (0u)
|
||||
#define _PIN_INIT( _PORT, _PIN, _MODE, _PULL, _SPEED, _AF )\
|
||||
HAL_GPIO_Init( GPIO##_PORT, (GPIO_InitTypeDef[])\
|
||||
{{\
|
||||
.Pin = GPIO_PIN_##_PIN,\
|
||||
.Mode = GPIO_##_MODE,\
|
||||
.Pull = GPIO_##_PULL,\
|
||||
.Speed = GPIO_##_SPEED,\
|
||||
.Alternate = GPIO_##_AF\
|
||||
}} )
|
||||
#define _PIN_HI( _PORT, _PIN, ... ) GPIO##_PORT->BSRR = (1u<<_PIN)
|
||||
#define _PIN_LOW( _PORT, _PIN, ... ) GPIO##_PORT->BSRR = (0x10000u<<_PIN)
|
||||
#define _PIN_TOGGLE( _PORT, _PIN, ... )\
|
||||
do{\
|
||||
uint32_t odr = GPIO##_PORT->ODR;\
|
||||
GPIO##_PORT->BSRR = ((odr & (1u<<_PIN)) << 16u) | (~odr & (1u<<_PIN));\
|
||||
}while(0)
|
||||
#define _PIN_INIT(_PORT, _PIN, _MODE, _PULL, _SPEED, _AF) \
|
||||
HAL_GPIO_Init(GPIO##_PORT, \
|
||||
(GPIO_InitTypeDef[]) { \
|
||||
{.Pin = GPIO_PIN_##_PIN, .Mode = GPIO_##_MODE, .Pull = GPIO_##_PULL, .Speed = GPIO_##_SPEED, .Alternate = GPIO_##_AF}
|
||||
})
|
||||
#define _PIN_HI(_PORT, _PIN, ...) GPIO##_PORT->BSRR = (1u << _PIN)
|
||||
#define _PIN_LOW(_PORT, _PIN, ...) GPIO##_PORT->BSRR = (0x10000u << _PIN)
|
||||
#define _PIN_TOGGLE(_PORT, _PIN, ...) \
|
||||
do { \
|
||||
uint32_t odr = GPIO##_PORT->ODR; \
|
||||
GPIO##_PORT->BSRR = ((odr & (1u << _PIN)) << 16u) | (~odr & (1u << _PIN)); \
|
||||
} while (0)
|
||||
|
||||
#define _PIN_ENABLE_CLOCK( _PORT, ... ) __HAL_RCC_GPIO ## _PORT ## _CLK_ENABLE()
|
||||
#define _PIN_ENABLE_CLOCK(_PORT, ...) __HAL_RCC_GPIO##_PORT##_CLK_ENABLE()
|
||||
|
||||
#define PIN_HI( CONFIG ) _PIN_HI( CONFIG )
|
||||
#define PIN_LOW( CONFIG ) _PIN_LOW( CONFIG )
|
||||
#define PIN_TOGGLE( CONFIG ) _PIN_TOGGLE( CONFIG )
|
||||
#define PIN_INIT( CONFIG ) _PIN_INIT( CONFIG )
|
||||
#define PIN_ENABLE_CLOCK( CONFIG ) _PIN_ENABLE_CLOCK( CONFIG )
|
||||
#define PIN_HI(CONFIG) _PIN_HI(CONFIG)
|
||||
#define PIN_LOW(CONFIG) _PIN_LOW(CONFIG)
|
||||
#define PIN_TOGGLE(CONFIG) _PIN_TOGGLE(CONFIG)
|
||||
#define PIN_INIT(CONFIG) _PIN_INIT(CONFIG)
|
||||
#define PIN_ENABLE_CLOCK(CONFIG) _PIN_ENABLE_CLOCK(CONFIG)
|
140
Src/main.c
140
Src/main.c
|
@ -1,108 +1,110 @@
|
|||
#include "stm32f0xx_hal.h"
|
||||
#include "pcan_timestamp.h"
|
||||
#include "pcan_led.h"
|
||||
#include "pcan_protocol.h"
|
||||
#include "pcan_timestamp.h"
|
||||
#include "pcan_usb.h"
|
||||
#include "pcan_varian.h"
|
||||
#include "stm32f0xx_hal.h"
|
||||
|
||||
void HAL_MspInit( void )
|
||||
void HAL_MspInit(void)
|
||||
{
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOF_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOF_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
}
|
||||
|
||||
#if ( HSE_VALUE != 0 )
|
||||
#if (HSE_VALUE != 0)
|
||||
void SystemClock_Config(void)
|
||||
{
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };
|
||||
|
||||
/* enable HSE */
|
||||
__HAL_RCC_HSE_CONFIG(RCC_HSE_ON);
|
||||
while( __HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET );
|
||||
/* enable HSE */
|
||||
__HAL_RCC_HSE_CONFIG(RCC_HSE_ON);
|
||||
while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
|
||||
;
|
||||
|
||||
/* enable PLL */
|
||||
__HAL_RCC_PLL_DISABLE();
|
||||
while( __HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET );
|
||||
#if ( HSE_VALUE == 16000000 )
|
||||
__HAL_RCC_PLL_CONFIG( RCC_PLLSOURCE_HSE, RCC_PREDIV_DIV1, RCC_PLL_MUL3 );
|
||||
#elif ( HSE_VALUE == 8000000 )
|
||||
__HAL_RCC_PLL_CONFIG( RCC_PLLSOURCE_HSE, RCC_PREDIV_DIV1, RCC_PLL_MUL6 );
|
||||
/* enable PLL */
|
||||
__HAL_RCC_PLL_DISABLE();
|
||||
while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
|
||||
;
|
||||
#if (HSE_VALUE == 16000000)
|
||||
__HAL_RCC_PLL_CONFIG(RCC_PLLSOURCE_HSE, RCC_PREDIV_DIV1, RCC_PLL_MUL3);
|
||||
#elif (HSE_VALUE == 8000000)
|
||||
__HAL_RCC_PLL_CONFIG(RCC_PLLSOURCE_HSE, RCC_PREDIV_DIV1, RCC_PLL_MUL6);
|
||||
#endif
|
||||
__HAL_RCC_PLL_ENABLE();
|
||||
while( __HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET );
|
||||
__HAL_RCC_PLL_ENABLE();
|
||||
while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
|
||||
;
|
||||
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|
||||
|RCC_CLOCKTYPE_PCLK1;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
|
||||
|
||||
HAL_RCC_ClockConfig( &RCC_ClkInitStruct, FLASH_LATENCY_1 );
|
||||
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
|
||||
|
||||
__HAL_RCC_USB_CONFIG( RCC_USBCLKSOURCE_PLL );
|
||||
__HAL_RCC_USB_CONFIG(RCC_USBCLKSOURCE_PLL);
|
||||
}
|
||||
#else
|
||||
void SystemClock_Config(void)
|
||||
{
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct;
|
||||
RCC_CRSInitTypeDef RCC_CRSInitStruct = {0};
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct;
|
||||
RCC_CRSInitTypeDef RCC_CRSInitStruct = { 0 };
|
||||
|
||||
__HAL_RCC_HSI48_ENABLE();
|
||||
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET );
|
||||
__HAL_RCC_HSI48_ENABLE();
|
||||
while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET)
|
||||
;
|
||||
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|
||||
|RCC_CLOCKTYPE_PCLK1;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI48;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
|
||||
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI48;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
|
||||
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
|
||||
|
||||
__HAL_RCC_USB_CONFIG( RCC_USBCLKSOURCE_HSI48 );
|
||||
__HAL_RCC_USB_CONFIG(RCC_USBCLKSOURCE_HSI48);
|
||||
|
||||
/* CRS */
|
||||
__HAL_RCC_CRS_CLK_ENABLE();
|
||||
|
||||
RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1;
|
||||
RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB;
|
||||
RCC_CRSInitStruct.Polarity = RCC_CRS_SYNC_POLARITY_RISING;
|
||||
RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE( 48000000, 1000 );
|
||||
RCC_CRSInitStruct.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT;
|
||||
RCC_CRSInitStruct.HSI48CalibrationValue = RCC_CRS_HSI48CALIBRATION_DEFAULT;
|
||||
/* CRS */
|
||||
__HAL_RCC_CRS_CLK_ENABLE();
|
||||
|
||||
HAL_RCCEx_CRSConfig( &RCC_CRSInitStruct );
|
||||
RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1;
|
||||
RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB;
|
||||
RCC_CRSInitStruct.Polarity = RCC_CRS_SYNC_POLARITY_RISING;
|
||||
RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000, 1000);
|
||||
RCC_CRSInitStruct.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT;
|
||||
RCC_CRSInitStruct.HSI48CalibrationValue = RCC_CRS_HSI48CALIBRATION_DEFAULT;
|
||||
|
||||
HAL_RCCEx_CRSConfig(&RCC_CRSInitStruct);
|
||||
}
|
||||
#endif
|
||||
|
||||
void SysTick_Handler( void )
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
HAL_IncTick();
|
||||
HAL_IncTick();
|
||||
}
|
||||
|
||||
int main( void )
|
||||
int main(void)
|
||||
{
|
||||
HAL_Init();
|
||||
HAL_IncTick();
|
||||
HAL_Init();
|
||||
HAL_IncTick();
|
||||
|
||||
SystemClock_Config();
|
||||
SystemClock_Config();
|
||||
|
||||
pcan_variant_io_init();
|
||||
pcan_variant_io_init();
|
||||
|
||||
pcan_usb_init();
|
||||
pcan_led_init();
|
||||
pcan_timestamp_init();
|
||||
pcan_protocol_init();
|
||||
pcan_usb_init();
|
||||
pcan_led_init();
|
||||
pcan_timestamp_init();
|
||||
pcan_protocol_init();
|
||||
|
||||
pcan_led_set_mode( LED_CH0_RX, LED_MODE_BLINK_SLOW, 0 );
|
||||
pcan_led_set_mode( LED_CH0_TX, LED_MODE_BLINK_SLOW, 0 );
|
||||
pcan_led_set_mode(LED_CH0_RX, LED_MODE_BLINK_SLOW, 0);
|
||||
pcan_led_set_mode(LED_CH0_TX, LED_MODE_BLINK_SLOW, 0);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
pcan_usb_poll();
|
||||
pcan_led_poll();
|
||||
pcan_protocol_poll();
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
pcan_usb_poll();
|
||||
pcan_led_poll();
|
||||
pcan_protocol_poll();
|
||||
}
|
||||
}
|
||||
|
|
486
Src/pcan_can.c
486
Src/pcan_can.c
|
@ -1,343 +1,331 @@
|
|||
#include <stm32f0xx_hal.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "pcan_can.h"
|
||||
#include "pcan_timestamp.h"
|
||||
#include "pcan_varian.h"
|
||||
#include <assert.h>
|
||||
#include <stm32f0xx_hal.h>
|
||||
#include <string.h>
|
||||
|
||||
#define CAN_TX_FIFO_SIZE (100)
|
||||
static CAN_HandleTypeDef g_hcan = { .Instance = CAN };
|
||||
#define INTERNAL_CAN_IT_FLAGS ( CAN_IT_TX_MAILBOX_EMPTY |\
|
||||
CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_RX_FIFO1_MSG_PENDING |\
|
||||
CAN_IT_BUSOFF |\
|
||||
CAN_IT_ERROR_WARNING |\
|
||||
CAN_IT_ERROR_PASSIVE |\
|
||||
CAN_IT_BUSOFF |\
|
||||
CAN_IT_LAST_ERROR_CODE |\
|
||||
CAN_IT_ERROR )
|
||||
#define INTERNAL_CAN_IT_FLAGS \
|
||||
(CAN_IT_TX_MAILBOX_EMPTY | CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_RX_FIFO1_MSG_PENDING | CAN_IT_BUSOFF | CAN_IT_ERROR_WARNING | CAN_IT_ERROR_PASSIVE | CAN_IT_BUSOFF \
|
||||
| CAN_IT_LAST_ERROR_CODE | CAN_IT_ERROR)
|
||||
|
||||
static struct
|
||||
{
|
||||
uint32_t tx_msgs;
|
||||
uint32_t tx_errs;
|
||||
uint32_t tx_ovfs;
|
||||
uint32_t tx_msgs;
|
||||
uint32_t tx_errs;
|
||||
uint32_t tx_ovfs;
|
||||
|
||||
uint32_t rx_msgs;
|
||||
uint32_t rx_errs;
|
||||
uint32_t rx_ovfs;
|
||||
uint32_t rx_msgs;
|
||||
uint32_t rx_errs;
|
||||
uint32_t rx_ovfs;
|
||||
|
||||
can_message_t tx_fifo[CAN_TX_FIFO_SIZE];
|
||||
uint32_t tx_head;
|
||||
uint32_t tx_tail;
|
||||
void (*rx_cb)(can_message_t *);
|
||||
void (*can_err_cb)( uint8_t err, uint8_t rx_err, uint8_t tx_err );
|
||||
}
|
||||
can_dev = { 0 };
|
||||
can_message_t tx_fifo[CAN_TX_FIFO_SIZE];
|
||||
uint32_t tx_head;
|
||||
uint32_t tx_tail;
|
||||
void (*rx_cb)(can_message_t *);
|
||||
void (*can_err_cb)(uint8_t err, uint8_t rx_err, uint8_t tx_err);
|
||||
} can_dev = { 0 };
|
||||
|
||||
void pcan_can_init(void)
|
||||
{
|
||||
CAN_FilterTypeDef filter = { 0 };
|
||||
CAN_FilterTypeDef filter = { 0 };
|
||||
|
||||
__HAL_RCC_CAN1_CLK_ENABLE();
|
||||
__HAL_RCC_CAN1_CLK_ENABLE();
|
||||
|
||||
PIN_ENABLE_CLOCK( CAN_RX );
|
||||
PIN_ENABLE_CLOCK( CAN_TX );
|
||||
PIN_ENABLE_CLOCK(CAN_RX);
|
||||
PIN_ENABLE_CLOCK(CAN_TX);
|
||||
|
||||
PIN_INIT( CAN_RX );
|
||||
PIN_INIT( CAN_TX );
|
||||
PIN_INIT(CAN_RX);
|
||||
PIN_INIT(CAN_TX);
|
||||
|
||||
HAL_CAN_DeInit( &g_hcan );
|
||||
HAL_CAN_DeInit(&g_hcan);
|
||||
|
||||
g_hcan.Instance = CAN;
|
||||
g_hcan.Init.Prescaler = 16;
|
||||
g_hcan.Init.Mode = CAN_MODE_NORMAL;
|
||||
g_hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
|
||||
g_hcan.Init.TimeSeg1 = CAN_BS1_1TQ;
|
||||
g_hcan.Init.TimeSeg2 = CAN_BS2_1TQ;
|
||||
g_hcan.Init.TimeTriggeredMode = DISABLE;
|
||||
g_hcan.Init.AutoBusOff = ENABLE;
|
||||
g_hcan.Init.AutoWakeUp = DISABLE;
|
||||
g_hcan.Init.AutoRetransmission = ENABLE;
|
||||
g_hcan.Init.ReceiveFifoLocked = DISABLE;
|
||||
g_hcan.Init.TransmitFifoPriority = ENABLE;
|
||||
g_hcan.Instance = CAN;
|
||||
g_hcan.Init.Prescaler = 16;
|
||||
g_hcan.Init.Mode = CAN_MODE_NORMAL;
|
||||
g_hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
|
||||
g_hcan.Init.TimeSeg1 = CAN_BS1_1TQ;
|
||||
g_hcan.Init.TimeSeg2 = CAN_BS2_1TQ;
|
||||
g_hcan.Init.TimeTriggeredMode = DISABLE;
|
||||
g_hcan.Init.AutoBusOff = ENABLE;
|
||||
g_hcan.Init.AutoWakeUp = DISABLE;
|
||||
g_hcan.Init.AutoRetransmission = ENABLE;
|
||||
g_hcan.Init.ReceiveFifoLocked = DISABLE;
|
||||
g_hcan.Init.TransmitFifoPriority = ENABLE;
|
||||
|
||||
if( HAL_CAN_Init( &g_hcan ) != HAL_OK )
|
||||
{
|
||||
assert( 0 );
|
||||
}
|
||||
if (HAL_CAN_Init(&g_hcan) != HAL_OK)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
filter.FilterMode = CAN_FILTERMODE_IDMASK;
|
||||
filter.FilterScale = CAN_FILTERSCALE_32BIT;
|
||||
filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
|
||||
filter.FilterActivation = ENABLE;
|
||||
filter.FilterBank = 0;
|
||||
filter.SlaveStartFilterBank = 0;
|
||||
|
||||
if( HAL_CAN_ConfigFilter( &g_hcan, &filter ) != HAL_OK )
|
||||
{
|
||||
assert( 0 );
|
||||
}
|
||||
filter.FilterMode = CAN_FILTERMODE_IDMASK;
|
||||
filter.FilterScale = CAN_FILTERSCALE_32BIT;
|
||||
filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
|
||||
filter.FilterActivation = ENABLE;
|
||||
filter.FilterBank = 0;
|
||||
filter.SlaveStartFilterBank = 0;
|
||||
|
||||
if( HAL_CAN_ActivateNotification( &g_hcan, INTERNAL_CAN_IT_FLAGS ) != HAL_OK )
|
||||
{
|
||||
assert( 0 );
|
||||
}
|
||||
if (HAL_CAN_ConfigFilter(&g_hcan, &filter) != HAL_OK)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (HAL_CAN_ActivateNotification(&g_hcan, INTERNAL_CAN_IT_FLAGS) != HAL_OK)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
void pcan_can_set_bitrate( uint16_t brp, uint8_t tseg1, uint8_t tseg2, uint8_t sjw )
|
||||
void pcan_can_set_bitrate(uint16_t brp, uint8_t tseg1, uint8_t tseg2, uint8_t sjw)
|
||||
{
|
||||
static const uint32_t sjw_table[] =
|
||||
{
|
||||
CAN_SJW_1TQ, CAN_SJW_2TQ, CAN_SJW_3TQ, CAN_SJW_4TQ
|
||||
};
|
||||
static const uint32_t tseg1_table[] =
|
||||
{
|
||||
CAN_BS1_1TQ, CAN_BS1_2TQ, CAN_BS1_3TQ, CAN_BS1_4TQ,
|
||||
CAN_BS1_5TQ, CAN_BS1_6TQ, CAN_BS1_7TQ, CAN_BS1_8TQ,
|
||||
CAN_BS1_9TQ, CAN_BS1_10TQ, CAN_BS1_11TQ, CAN_BS1_12TQ,
|
||||
CAN_BS1_13TQ, CAN_BS1_14TQ, CAN_BS1_15TQ, CAN_BS1_16TQ
|
||||
};
|
||||
static const uint32_t tseg2_table[] =
|
||||
{
|
||||
CAN_BS2_1TQ, CAN_BS2_2TQ, CAN_BS2_3TQ, CAN_BS2_4TQ,
|
||||
CAN_BS2_5TQ, CAN_BS2_6TQ, CAN_BS2_7TQ, CAN_BS2_8TQ
|
||||
};
|
||||
static const uint32_t sjw_table[] = { CAN_SJW_1TQ, CAN_SJW_2TQ, CAN_SJW_3TQ, CAN_SJW_4TQ };
|
||||
static const uint32_t tseg1_table[] = { CAN_BS1_1TQ, CAN_BS1_2TQ, CAN_BS1_3TQ, CAN_BS1_4TQ, CAN_BS1_5TQ, CAN_BS1_6TQ, CAN_BS1_7TQ, CAN_BS1_8TQ,
|
||||
CAN_BS1_9TQ, CAN_BS1_10TQ, CAN_BS1_11TQ, CAN_BS1_12TQ, CAN_BS1_13TQ, CAN_BS1_14TQ, CAN_BS1_15TQ, CAN_BS1_16TQ };
|
||||
static const uint32_t tseg2_table[] = { CAN_BS2_1TQ, CAN_BS2_2TQ, CAN_BS2_3TQ, CAN_BS2_4TQ, CAN_BS2_5TQ, CAN_BS2_6TQ, CAN_BS2_7TQ, CAN_BS2_8TQ };
|
||||
|
||||
if( sjw > 4 )
|
||||
sjw = 4;
|
||||
if( tseg1 > 16 )
|
||||
tseg1 = 16;
|
||||
if( tseg2 > 8 )
|
||||
tseg2 = 8;
|
||||
if (sjw > 4)
|
||||
sjw = 4;
|
||||
if (tseg1 > 16)
|
||||
tseg1 = 16;
|
||||
if (tseg2 > 8)
|
||||
tseg2 = 8;
|
||||
|
||||
/* CAN bus freq is 48 */
|
||||
g_hcan.Init.Prescaler = brp * 6;
|
||||
/* CAN bus freq is 48 */
|
||||
g_hcan.Init.Prescaler = brp * 6;
|
||||
|
||||
g_hcan.Init.SyncJumpWidth = sjw_table[sjw - 1];
|
||||
g_hcan.Init.TimeSeg1 = tseg1_table[tseg1 - 1];
|
||||
g_hcan.Init.TimeSeg2 = tseg2_table[tseg2 - 1];
|
||||
g_hcan.Init.SyncJumpWidth = sjw_table[sjw - 1];
|
||||
g_hcan.Init.TimeSeg1 = tseg1_table[tseg1 - 1];
|
||||
g_hcan.Init.TimeSeg2 = tseg2_table[tseg2 - 1];
|
||||
|
||||
if( HAL_CAN_Init( &g_hcan ) != HAL_OK )
|
||||
{
|
||||
assert( 0 );
|
||||
}
|
||||
if (HAL_CAN_Init(&g_hcan) != HAL_OK)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
void pcan_can_install_rx_callback( void (*cb)( can_message_t * ) )
|
||||
void pcan_can_install_rx_callback(void (*cb)(can_message_t *))
|
||||
{
|
||||
can_dev.rx_cb = cb;
|
||||
can_dev.rx_cb = cb;
|
||||
}
|
||||
|
||||
void pcan_can_install_error_callback( void (*cb)( uint8_t, uint8_t, uint8_t ) )
|
||||
void pcan_can_install_error_callback(void (*cb)(uint8_t, uint8_t, uint8_t))
|
||||
{
|
||||
can_dev.can_err_cb = cb;
|
||||
can_dev.can_err_cb = cb;
|
||||
}
|
||||
|
||||
static int pcan_try_send_message( const can_message_t *p_msg )
|
||||
static int pcan_try_send_message(const can_message_t *p_msg)
|
||||
{
|
||||
CAN_TxHeaderTypeDef msg = { .TransmitGlobalTime = DISABLE };
|
||||
uint32_t txMailbox = 0;
|
||||
CAN_TxHeaderTypeDef msg = { .TransmitGlobalTime = DISABLE };
|
||||
uint32_t txMailbox = 0;
|
||||
|
||||
if( p_msg->flags & CAN_FLAG_EXTID )
|
||||
{
|
||||
msg.ExtId = p_msg->id & 0x1FFFFFFF;
|
||||
msg.IDE = CAN_ID_EXT;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.StdId = p_msg->id & 0x7FF;
|
||||
msg.IDE = CAN_ID_STD;
|
||||
}
|
||||
|
||||
msg.DLC = p_msg->dlc;
|
||||
msg.RTR = (p_msg->flags & CAN_FLAG_RTR)?CAN_RTR_REMOTE:CAN_RTR_DATA;
|
||||
|
||||
if( HAL_CAN_AddTxMessage( &g_hcan, &msg, (void*)p_msg->data, &txMailbox ) != HAL_OK )
|
||||
return -1;
|
||||
if (p_msg->flags & CAN_FLAG_EXTID)
|
||||
{
|
||||
msg.ExtId = p_msg->id & 0x1FFFFFFF;
|
||||
msg.IDE = CAN_ID_EXT;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.StdId = p_msg->id & 0x7FF;
|
||||
msg.IDE = CAN_ID_STD;
|
||||
}
|
||||
|
||||
return txMailbox;
|
||||
msg.DLC = p_msg->dlc;
|
||||
msg.RTR = (p_msg->flags & CAN_FLAG_RTR) ? CAN_RTR_REMOTE : CAN_RTR_DATA;
|
||||
|
||||
if (HAL_CAN_AddTxMessage(&g_hcan, &msg, (void *)p_msg->data, &txMailbox) != HAL_OK)
|
||||
return -1;
|
||||
|
||||
return txMailbox;
|
||||
}
|
||||
|
||||
static void pcan_can_flush_tx( void )
|
||||
static void pcan_can_flush_tx(void)
|
||||
{
|
||||
can_message_t *p_msg;
|
||||
can_message_t *p_msg;
|
||||
|
||||
/* empty fifo */
|
||||
if( can_dev.tx_head == can_dev.tx_tail )
|
||||
return;
|
||||
|
||||
p_msg = &can_dev.tx_fifo[can_dev.tx_tail];
|
||||
if( pcan_try_send_message( p_msg ) < 0 )
|
||||
return;
|
||||
/* update fifo index */
|
||||
uint32_t tail = can_dev.tx_tail+1;
|
||||
if( tail == CAN_TX_FIFO_SIZE )
|
||||
tail = 0;
|
||||
can_dev.tx_tail = tail;
|
||||
/* empty fifo */
|
||||
if (can_dev.tx_head == can_dev.tx_tail)
|
||||
return;
|
||||
|
||||
p_msg = &can_dev.tx_fifo[can_dev.tx_tail];
|
||||
if (pcan_try_send_message(p_msg) < 0)
|
||||
return;
|
||||
/* update fifo index */
|
||||
uint32_t tail = can_dev.tx_tail + 1;
|
||||
if (tail == CAN_TX_FIFO_SIZE)
|
||||
tail = 0;
|
||||
can_dev.tx_tail = tail;
|
||||
}
|
||||
|
||||
int pcan_can_send_message( const can_message_t *p_msg )
|
||||
int pcan_can_send_message(const can_message_t *p_msg)
|
||||
{
|
||||
if( !p_msg )
|
||||
if (!p_msg)
|
||||
return 0;
|
||||
|
||||
uint32_t head = can_dev.tx_head + 1;
|
||||
if (head == CAN_TX_FIFO_SIZE)
|
||||
head = 0;
|
||||
/* overflow ? just skip it */
|
||||
if (head == can_dev.tx_tail)
|
||||
{
|
||||
++can_dev.tx_ovfs;
|
||||
return -1;
|
||||
}
|
||||
|
||||
can_dev.tx_fifo[can_dev.tx_head] = *p_msg;
|
||||
can_dev.tx_head = head;
|
||||
|
||||
return 0;
|
||||
|
||||
uint32_t head = can_dev.tx_head+1;
|
||||
if( head == CAN_TX_FIFO_SIZE )
|
||||
head = 0;
|
||||
/* overflow ? just skip it */
|
||||
if( head == can_dev.tx_tail )
|
||||
{
|
||||
++can_dev.tx_ovfs;
|
||||
return -1;
|
||||
}
|
||||
|
||||
can_dev.tx_fifo[can_dev.tx_head] = *p_msg;
|
||||
can_dev.tx_head = head;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pcan_can_set_silent( uint8_t silent_mode )
|
||||
void pcan_can_set_silent(uint8_t silent_mode)
|
||||
{
|
||||
g_hcan.Init.Mode = silent_mode ? CAN_MODE_SILENT: CAN_MODE_NORMAL;
|
||||
if( HAL_CAN_Init( &g_hcan ) != HAL_OK )
|
||||
{
|
||||
assert( 0 );
|
||||
}
|
||||
g_hcan.Init.Mode = silent_mode ? CAN_MODE_SILENT : CAN_MODE_NORMAL;
|
||||
if (HAL_CAN_Init(&g_hcan) != HAL_OK)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
void pcan_can_set_loopback( uint8_t loopback )
|
||||
void pcan_can_set_loopback(uint8_t loopback)
|
||||
{
|
||||
g_hcan.Init.Mode = loopback ? CAN_MODE_LOOPBACK: CAN_MODE_NORMAL;
|
||||
if( HAL_CAN_Init( &g_hcan ) != HAL_OK )
|
||||
{
|
||||
assert( 0 );
|
||||
}
|
||||
g_hcan.Init.Mode = loopback ? CAN_MODE_LOOPBACK : CAN_MODE_NORMAL;
|
||||
if (HAL_CAN_Init(&g_hcan) != HAL_OK)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
void pcan_can_set_bus_active( uint16_t mode )
|
||||
void pcan_can_set_bus_active(uint16_t mode)
|
||||
{
|
||||
if( mode )
|
||||
{
|
||||
HAL_CAN_Start( &g_hcan );
|
||||
HAL_CAN_AbortTxRequest( &g_hcan, CAN_TX_MAILBOX0 | CAN_TX_MAILBOX1 | CAN_TX_MAILBOX2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
HAL_CAN_AbortTxRequest( &g_hcan, CAN_TX_MAILBOX0 | CAN_TX_MAILBOX1 | CAN_TX_MAILBOX2 );
|
||||
HAL_CAN_Stop( &g_hcan );
|
||||
}
|
||||
if (mode)
|
||||
{
|
||||
HAL_CAN_Start(&g_hcan);
|
||||
HAL_CAN_AbortTxRequest(&g_hcan, CAN_TX_MAILBOX0 | CAN_TX_MAILBOX1 | CAN_TX_MAILBOX2);
|
||||
}
|
||||
else
|
||||
{
|
||||
HAL_CAN_AbortTxRequest(&g_hcan, CAN_TX_MAILBOX0 | CAN_TX_MAILBOX1 | CAN_TX_MAILBOX2);
|
||||
HAL_CAN_Stop(&g_hcan);
|
||||
}
|
||||
}
|
||||
|
||||
static void pcan_can_rx_frame( CAN_HandleTypeDef *hcan, uint32_t fifo )
|
||||
static void pcan_can_rx_frame(CAN_HandleTypeDef *hcan, uint32_t fifo)
|
||||
{
|
||||
CAN_RxHeaderTypeDef hdr = { 0 };
|
||||
can_message_t msg = { 0 };
|
||||
CAN_RxHeaderTypeDef hdr = { 0 };
|
||||
can_message_t msg = { 0 };
|
||||
|
||||
if( HAL_CAN_GetRxMessage( hcan, fifo, &hdr, msg.data ) != HAL_OK )
|
||||
return;
|
||||
if (HAL_CAN_GetRxMessage(hcan, fifo, &hdr, msg.data) != HAL_OK)
|
||||
return;
|
||||
|
||||
if( hdr.IDE == CAN_ID_STD )
|
||||
{
|
||||
msg.id = hdr.StdId;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.id = hdr.ExtId;
|
||||
msg.flags |= CAN_FLAG_EXTID;
|
||||
}
|
||||
if (hdr.IDE == CAN_ID_STD)
|
||||
{
|
||||
msg.id = hdr.StdId;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.id = hdr.ExtId;
|
||||
msg.flags |= CAN_FLAG_EXTID;
|
||||
}
|
||||
|
||||
if( hdr.RTR == CAN_RTR_REMOTE )
|
||||
{
|
||||
msg.flags |= CAN_FLAG_RTR;
|
||||
}
|
||||
if (hdr.RTR == CAN_RTR_REMOTE)
|
||||
{
|
||||
msg.flags |= CAN_FLAG_RTR;
|
||||
}
|
||||
|
||||
msg.dlc = hdr.DLC;
|
||||
msg.timestamp = pcan_timestamp_ticks();
|
||||
|
||||
if( can_dev.rx_cb )
|
||||
{
|
||||
can_dev.rx_cb( &msg );
|
||||
}
|
||||
msg.dlc = hdr.DLC;
|
||||
msg.timestamp = pcan_timestamp_ticks();
|
||||
|
||||
++can_dev.rx_msgs;
|
||||
if (can_dev.rx_cb)
|
||||
{
|
||||
can_dev.rx_cb(&msg);
|
||||
}
|
||||
|
||||
++can_dev.rx_msgs;
|
||||
}
|
||||
|
||||
void pcan_can_poll(void)
|
||||
{
|
||||
HAL_CAN_IRQHandler( &g_hcan );
|
||||
pcan_can_flush_tx();
|
||||
HAL_CAN_IRQHandler(&g_hcan);
|
||||
pcan_can_flush_tx();
|
||||
}
|
||||
|
||||
void HAL_CAN_RxFifo0MsgPendingCallback( CAN_HandleTypeDef *hcan )
|
||||
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
|
||||
{
|
||||
pcan_can_rx_frame( hcan, CAN_RX_FIFO0 );
|
||||
pcan_can_rx_frame(hcan, CAN_RX_FIFO0);
|
||||
}
|
||||
|
||||
void HAL_CAN_RxFifo1MsgPendingCallback( CAN_HandleTypeDef *hcan )
|
||||
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)
|
||||
{
|
||||
pcan_can_rx_frame( hcan, CAN_RX_FIFO1 );
|
||||
pcan_can_rx_frame(hcan, CAN_RX_FIFO1);
|
||||
}
|
||||
|
||||
void HAL_CAN_TxMailbox0CompleteCallback( CAN_HandleTypeDef *hcan )
|
||||
void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan)
|
||||
{
|
||||
UNUSED( hcan );
|
||||
++can_dev.tx_msgs;
|
||||
UNUSED(hcan);
|
||||
++can_dev.tx_msgs;
|
||||
}
|
||||
|
||||
void HAL_CAN_TxMailbox1CompleteCallback( CAN_HandleTypeDef *hcan )
|
||||
void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan)
|
||||
{
|
||||
UNUSED( hcan );
|
||||
++can_dev.tx_msgs;
|
||||
UNUSED(hcan);
|
||||
++can_dev.tx_msgs;
|
||||
}
|
||||
|
||||
void HAL_CAN_TxMailbox2CompleteCallback( CAN_HandleTypeDef *hcan )
|
||||
void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan)
|
||||
{
|
||||
UNUSED( hcan );
|
||||
++can_dev.tx_msgs;
|
||||
UNUSED(hcan);
|
||||
++can_dev.tx_msgs;
|
||||
}
|
||||
|
||||
void HAL_CAN_RxFifo0FullCallback( CAN_HandleTypeDef *hcan )
|
||||
void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan)
|
||||
{
|
||||
UNUSED( hcan );
|
||||
++can_dev.rx_ovfs;
|
||||
UNUSED(hcan);
|
||||
++can_dev.rx_ovfs;
|
||||
}
|
||||
|
||||
void HAL_CAN_RxFifo1FullCallback( CAN_HandleTypeDef *hcan )
|
||||
void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan)
|
||||
{
|
||||
UNUSED( hcan );
|
||||
++can_dev.rx_ovfs;
|
||||
UNUSED(hcan);
|
||||
++can_dev.rx_ovfs;
|
||||
}
|
||||
|
||||
void HAL_CAN_SleepCallback( CAN_HandleTypeDef *hcan ){ UNUSED( hcan ); }
|
||||
void HAL_CAN_WakeUpFromRxMsgCallback( CAN_HandleTypeDef *hcan ){ UNUSED( hcan ); }
|
||||
|
||||
void HAL_CAN_ErrorCallback( CAN_HandleTypeDef *hcan )
|
||||
void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan)
|
||||
{
|
||||
/* handle errors */
|
||||
uint32_t err = HAL_CAN_GetError( hcan );
|
||||
uint8_t can_err = 0;
|
||||
|
||||
if ( err & ( HAL_CAN_ERROR_TX_TERR0 | HAL_CAN_ERROR_TX_TERR1 | HAL_CAN_ERROR_TX_TERR2 ) )
|
||||
{
|
||||
++can_dev.tx_errs;
|
||||
can_err |= CAN_ERROR_FLAG_TX_ERR;
|
||||
}
|
||||
|
||||
if( err & HAL_CAN_ERROR_BOF )
|
||||
{
|
||||
can_err |= CAN_ERROR_FLAG_BUSOFF;
|
||||
}
|
||||
|
||||
if( err & ( HAL_CAN_ERROR_RX_FOV0 | HAL_CAN_ERROR_RX_FOV1 ) )
|
||||
{
|
||||
can_err |= CAN_ERROR_FLAG_RX_OVF;
|
||||
}
|
||||
|
||||
if( can_dev.can_err_cb && can_err )
|
||||
{
|
||||
can_dev.can_err_cb( can_err, can_dev.tx_errs & 0xFF, can_dev.rx_errs );
|
||||
}
|
||||
|
||||
HAL_CAN_ResetError( hcan );
|
||||
UNUSED(hcan);
|
||||
}
|
||||
void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan)
|
||||
{
|
||||
UNUSED(hcan);
|
||||
}
|
||||
|
||||
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
|
||||
{
|
||||
/* handle errors */
|
||||
uint32_t err = HAL_CAN_GetError(hcan);
|
||||
uint8_t can_err = 0;
|
||||
|
||||
if (err & (HAL_CAN_ERROR_TX_TERR0 | HAL_CAN_ERROR_TX_TERR1 | HAL_CAN_ERROR_TX_TERR2))
|
||||
{
|
||||
++can_dev.tx_errs;
|
||||
can_err |= CAN_ERROR_FLAG_TX_ERR;
|
||||
}
|
||||
|
||||
if (err & HAL_CAN_ERROR_BOF)
|
||||
{
|
||||
can_err |= CAN_ERROR_FLAG_BUSOFF;
|
||||
}
|
||||
|
||||
if (err & (HAL_CAN_ERROR_RX_FOV0 | HAL_CAN_ERROR_RX_FOV1))
|
||||
{
|
||||
can_err |= CAN_ERROR_FLAG_RX_OVF;
|
||||
}
|
||||
|
||||
if (can_dev.can_err_cb && can_err)
|
||||
{
|
||||
can_dev.can_err_cb(can_err, can_dev.tx_errs & 0xFF, can_dev.rx_errs);
|
||||
}
|
||||
|
||||
HAL_CAN_ResetError(hcan);
|
||||
}
|
||||
|
|
|
@ -5,29 +5,28 @@
|
|||
#define CAN_FLAG_RTR (0x40)
|
||||
#define CAN_FLAG_EXTID (0x80)
|
||||
|
||||
#define CAN_ERROR_FLAG_BUSOFF (1<<0)
|
||||
#define CAN_ERROR_FLAG_RX_OVF (1<<1)
|
||||
#define CAN_ERROR_FLAG_TX_ERR (1<<2)
|
||||
#define CAN_ERROR_FLAG_BUSOFF (1 << 0)
|
||||
#define CAN_ERROR_FLAG_RX_OVF (1 << 1)
|
||||
#define CAN_ERROR_FLAG_TX_ERR (1 << 2)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t id;
|
||||
uint8_t data[8];
|
||||
uint8_t dlc;
|
||||
uint8_t flags;
|
||||
/* for self receive */
|
||||
uint8_t dummy;
|
||||
/* in pcan ticks */
|
||||
uint16_t timestamp;
|
||||
}
|
||||
can_message_t;
|
||||
uint32_t id;
|
||||
uint8_t data[8];
|
||||
uint8_t dlc;
|
||||
uint8_t flags;
|
||||
/* for self receive */
|
||||
uint8_t dummy;
|
||||
/* in pcan ticks */
|
||||
uint16_t timestamp;
|
||||
} can_message_t;
|
||||
|
||||
void pcan_can_init( void );
|
||||
void pcan_can_poll( void );
|
||||
void pcan_can_set_bitrate( uint16_t brp, uint8_t tseg1, uint8_t tseg2, uint8_t sjw );
|
||||
int pcan_can_send_message( const can_message_t *msg );
|
||||
void pcan_can_install_rx_callback( void (*cb)( can_message_t * ) );
|
||||
void pcan_can_install_error_callback( void (*cb)( uint8_t, uint8_t, uint8_t ) );
|
||||
void pcan_can_set_bus_active( uint16_t mode );
|
||||
void pcan_can_set_silent( uint8_t silent_mode );
|
||||
void pcan_can_set_loopback( uint8_t loopback );
|
||||
void pcan_can_init(void);
|
||||
void pcan_can_poll(void);
|
||||
void pcan_can_set_bitrate(uint16_t brp, uint8_t tseg1, uint8_t tseg2, uint8_t sjw);
|
||||
int pcan_can_send_message(const can_message_t *msg);
|
||||
void pcan_can_install_rx_callback(void (*cb)(can_message_t *));
|
||||
void pcan_can_install_error_callback(void (*cb)(uint8_t, uint8_t, uint8_t));
|
||||
void pcan_can_set_bus_active(uint16_t mode);
|
||||
void pcan_can_set_silent(uint8_t silent_mode);
|
||||
void pcan_can_set_loopback(uint8_t loopback);
|
||||
|
|
175
Src/pcan_led.c
175
Src/pcan_led.c
|
@ -1,107 +1,106 @@
|
|||
#include <assert.h>
|
||||
#include "stm32f0xx_hal.h"
|
||||
#include "pcan_timestamp.h"
|
||||
#include "pcan_led.h"
|
||||
#include "pcan_timestamp.h"
|
||||
#include "pcan_varian.h"
|
||||
#include "stm32f0xx_hal.h"
|
||||
#include <assert.h>
|
||||
|
||||
static struct
|
||||
{
|
||||
uint16_t mode;
|
||||
uint16_t arg;
|
||||
uint16_t delay;
|
||||
uint16_t timestamp;
|
||||
uint8_t state;
|
||||
}
|
||||
led_mode_array[LED_TOTAL] = { 0 };
|
||||
uint16_t mode;
|
||||
uint16_t arg;
|
||||
uint16_t delay;
|
||||
uint16_t timestamp;
|
||||
uint8_t state;
|
||||
} led_mode_array[LED_TOTAL] = { 0 };
|
||||
|
||||
void pcan_led_init( void )
|
||||
void pcan_led_init(void)
|
||||
{
|
||||
#ifdef IOPIN_TX
|
||||
PIN_ENABLE_CLOCK( IOPIN_TX );
|
||||
PIN_INIT( IOPIN_TX );
|
||||
PIN_ENABLE_CLOCK(IOPIN_TX);
|
||||
PIN_INIT(IOPIN_TX);
|
||||
#endif
|
||||
#ifdef IOPIN_RX
|
||||
PIN_ENABLE_CLOCK( IOPIN_RX );
|
||||
PIN_INIT( IOPIN_RX );
|
||||
PIN_ENABLE_CLOCK(IOPIN_RX);
|
||||
PIN_INIT(IOPIN_RX);
|
||||
#endif
|
||||
}
|
||||
|
||||
void pcan_led_set_mode( int led, int mode, uint16_t arg )
|
||||
void pcan_led_set_mode(int led, int mode, uint16_t arg)
|
||||
{
|
||||
assert( led < LED_TOTAL );
|
||||
uint16_t ts = pcan_timestamp_millis();
|
||||
assert(led < LED_TOTAL);
|
||||
uint16_t ts = pcan_timestamp_millis();
|
||||
|
||||
led_mode_array[led].mode = mode;
|
||||
if( !led_mode_array[led].timestamp )
|
||||
{
|
||||
led_mode_array[led].timestamp = ts|1;
|
||||
}
|
||||
led_mode_array[led].delay = 0;
|
||||
|
||||
/* set guard time */
|
||||
if( mode == LED_MODE_BLINK_FAST || mode == LED_MODE_BLINK_SLOW )
|
||||
{
|
||||
led_mode_array[led].delay = ( mode == LED_MODE_BLINK_FAST ) ? 50: 200;
|
||||
arg = arg?(ts + arg)|1:0;
|
||||
}
|
||||
|
||||
led_mode_array[led].arg = arg;
|
||||
}
|
||||
|
||||
static void pcan_led_update_state( int led, uint8_t state )
|
||||
{
|
||||
switch( led )
|
||||
{
|
||||
#ifdef IOPIN_TX
|
||||
case LED_CH0_TX:
|
||||
state ? (LED_ON( IOPIN_TX )): (LED_OFF( IOPIN_TX ));
|
||||
break;
|
||||
#endif
|
||||
#ifdef IOPIN_RX
|
||||
case LED_CH0_RX:
|
||||
state ? (LED_ON( IOPIN_RX )): (LED_OFF( IOPIN_RX ));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
(void)state;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void pcan_led_poll( void )
|
||||
{
|
||||
uint16_t ts_ms = pcan_timestamp_millis();
|
||||
|
||||
for( int i = 0; i < LED_TOTAL; i++ )
|
||||
{
|
||||
if( !led_mode_array[i].timestamp )
|
||||
continue;
|
||||
if( (uint16_t)( ts_ms - led_mode_array[i].timestamp ) < led_mode_array[i].delay )
|
||||
continue;
|
||||
|
||||
switch( led_mode_array[i].mode )
|
||||
led_mode_array[led].mode = mode;
|
||||
if (!led_mode_array[led].timestamp)
|
||||
{
|
||||
default:
|
||||
case LED_MODE_NONE:
|
||||
led_mode_array[i].timestamp = 0;
|
||||
break;
|
||||
case LED_MODE_OFF:
|
||||
case LED_MODE_ON:
|
||||
led_mode_array[i].state = ( led_mode_array[i].mode == LED_MODE_ON );
|
||||
led_mode_array[i].timestamp = 0;
|
||||
break;
|
||||
case LED_MODE_BLINK_FAST:
|
||||
case LED_MODE_BLINK_SLOW:
|
||||
led_mode_array[i].state ^= 1;
|
||||
led_mode_array[i].timestamp += led_mode_array[i].delay;
|
||||
led_mode_array[i].timestamp |= 1;
|
||||
if( led_mode_array[i].arg && ( led_mode_array[i].arg <= ts_ms ) )
|
||||
{
|
||||
pcan_led_set_mode( i, LED_MODE_OFF, 0 );
|
||||
}
|
||||
break;
|
||||
led_mode_array[led].timestamp = ts | 1;
|
||||
}
|
||||
led_mode_array[led].delay = 0;
|
||||
|
||||
/* set guard time */
|
||||
if (mode == LED_MODE_BLINK_FAST || mode == LED_MODE_BLINK_SLOW)
|
||||
{
|
||||
led_mode_array[led].delay = (mode == LED_MODE_BLINK_FAST) ? 50 : 200;
|
||||
arg = arg ? (ts + arg) | 1 : 0;
|
||||
}
|
||||
|
||||
pcan_led_update_state( i, led_mode_array[i].state );
|
||||
}
|
||||
led_mode_array[led].arg = arg;
|
||||
}
|
||||
|
||||
static void pcan_led_update_state(int led, uint8_t state)
|
||||
{
|
||||
switch (led)
|
||||
{
|
||||
#ifdef IOPIN_TX
|
||||
case LED_CH0_TX:
|
||||
state ? (LED_ON(IOPIN_TX)) : (LED_OFF(IOPIN_TX));
|
||||
break;
|
||||
#endif
|
||||
#ifdef IOPIN_RX
|
||||
case LED_CH0_RX:
|
||||
state ? (LED_ON(IOPIN_RX)) : (LED_OFF(IOPIN_RX));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
(void)state;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void pcan_led_poll(void)
|
||||
{
|
||||
uint16_t ts_ms = pcan_timestamp_millis();
|
||||
|
||||
for (int i = 0; i < LED_TOTAL; i++)
|
||||
{
|
||||
if (!led_mode_array[i].timestamp)
|
||||
continue;
|
||||
if ((uint16_t)(ts_ms - led_mode_array[i].timestamp) < led_mode_array[i].delay)
|
||||
continue;
|
||||
|
||||
switch (led_mode_array[i].mode)
|
||||
{
|
||||
default:
|
||||
case LED_MODE_NONE:
|
||||
led_mode_array[i].timestamp = 0;
|
||||
break;
|
||||
case LED_MODE_OFF:
|
||||
case LED_MODE_ON:
|
||||
led_mode_array[i].state = (led_mode_array[i].mode == LED_MODE_ON);
|
||||
led_mode_array[i].timestamp = 0;
|
||||
break;
|
||||
case LED_MODE_BLINK_FAST:
|
||||
case LED_MODE_BLINK_SLOW:
|
||||
led_mode_array[i].state ^= 1;
|
||||
led_mode_array[i].timestamp += led_mode_array[i].delay;
|
||||
led_mode_array[i].timestamp |= 1;
|
||||
if (led_mode_array[i].arg && (led_mode_array[i].arg <= ts_ms))
|
||||
{
|
||||
pcan_led_set_mode(i, LED_MODE_OFF, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
pcan_led_update_state(i, led_mode_array[i].state);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,22 +3,22 @@
|
|||
|
||||
enum e_pcan_led
|
||||
{
|
||||
LED_CH0_TX,
|
||||
LED_CH0_RX,
|
||||
LED_STAT,
|
||||
LED_CH0_TX,
|
||||
LED_CH0_RX,
|
||||
LED_STAT,
|
||||
|
||||
LED_TOTAL,
|
||||
LED_TOTAL,
|
||||
};
|
||||
|
||||
enum e_pcan_led_mode
|
||||
{
|
||||
LED_MODE_NONE,
|
||||
LED_MODE_ON,
|
||||
LED_MODE_OFF,
|
||||
LED_MODE_BLINK_FAST,
|
||||
LED_MODE_BLINK_SLOW,
|
||||
LED_MODE_NONE,
|
||||
LED_MODE_ON,
|
||||
LED_MODE_OFF,
|
||||
LED_MODE_BLINK_FAST,
|
||||
LED_MODE_BLINK_SLOW,
|
||||
};
|
||||
|
||||
void pcan_led_init( void );
|
||||
void pcan_led_set_mode( int led, int mode, uint16_t arg );
|
||||
void pcan_led_poll( void );
|
||||
void pcan_led_init(void);
|
||||
void pcan_led_set_mode(int led, int mode, uint16_t arg);
|
||||
void pcan_led_poll(void);
|
||||
|
|
|
@ -4,92 +4,91 @@
|
|||
|
||||
/* pcan-usb parameter get an set function */
|
||||
#pragma pack(push, 1)
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
uint8_t function;
|
||||
uint8_t number;
|
||||
uint8_t param[14];
|
||||
}
|
||||
PCAN_USB_PARAM;
|
||||
uint8_t function;
|
||||
uint8_t number;
|
||||
uint8_t param[14];
|
||||
} PCAN_USB_PARAM;
|
||||
#pragma pack(pop)
|
||||
|
||||
/* USB control cmds get/set */
|
||||
#define PCAN_USB_EX0 0x00
|
||||
#define PCAN_USB_GET 0x01
|
||||
#define PCAN_USB_SET 0x02
|
||||
#define PCAN_USB_EX3 0x03
|
||||
#define PCAN_USB_EX0 0x00
|
||||
#define PCAN_USB_GET 0x01
|
||||
#define PCAN_USB_SET 0x02
|
||||
#define PCAN_USB_EX3 0x03
|
||||
|
||||
/* PCAN-USB commands */
|
||||
#define PCAN_USB_CMD_BITRATE 1
|
||||
#define PCAN_USB_CMD_CLOCK 2
|
||||
#define PCAN_USB_CMD_BUS 3
|
||||
#define PCAN_USB_CMD_DEVID 4
|
||||
#define PCAN_USB_CMD_CFG 5
|
||||
#define PCAN_USB_CMD_SN 6
|
||||
#define PCAN_USB_CMD_REGISTER 9
|
||||
#define PCAN_USB_CMD_EXT_VCC 10
|
||||
#define PCAN_USB_CMD_ERR_FR 11
|
||||
#define PCAN_USB_CMD_LED 12
|
||||
#define PCAN_USB_CMD_DEVDATA 30
|
||||
#define PCAN_USB_CMD_BITRATE 1
|
||||
#define PCAN_USB_CMD_CLOCK 2
|
||||
#define PCAN_USB_CMD_BUS 3
|
||||
#define PCAN_USB_CMD_DEVID 4
|
||||
#define PCAN_USB_CMD_CFG 5
|
||||
#define PCAN_USB_CMD_SN 6
|
||||
#define PCAN_USB_CMD_REGISTER 9
|
||||
#define PCAN_USB_CMD_EXT_VCC 10
|
||||
#define PCAN_USB_CMD_ERR_FR 11
|
||||
#define PCAN_USB_CMD_LED 12
|
||||
#define PCAN_USB_CMD_DEVDATA 30
|
||||
/* USB Mass Storage Mode command (FW >= 8.3.0) */
|
||||
#define PCAN_USB_SETCAN2FLASH 0xC8
|
||||
#define PCAN_USB_SETCAN2FLASH 0xC8
|
||||
|
||||
/* PCAN_USB_CMD_BUS PCAN_USB_SET extension: */
|
||||
#define PCAN_USB_SET_SILENT_MODE 3
|
||||
#define PCAN_USB_SET_SILENT_MODE 3
|
||||
|
||||
/* PCAN-USB rx/tx buffers size */
|
||||
#define PCAN_USB_RX_BUFFER_SIZE 64
|
||||
#define PCAN_USB_TX_BUFFER_SIZE 64
|
||||
#define PCAN_USB_RX_BUFFER_SIZE 64
|
||||
#define PCAN_USB_TX_BUFFER_SIZE 64
|
||||
|
||||
#define PCAN_USB_MSG_HEADER_LEN 2
|
||||
#define PCAN_USB_MSG_HEADER_LEN 2
|
||||
|
||||
/* PCAN-USB adapter internal clock (MHz) */
|
||||
#define PCAN_USB_CRYSTAL_HZ 16000000
|
||||
#define PCAN_USB_CRYSTAL_HZ 16000000
|
||||
|
||||
/* PCAN-USB USB message record status/len field */
|
||||
#define PCAN_USB_STATUSLEN_TIMESTAMP (1 << 7)
|
||||
#define PCAN_USB_STATUSLEN_INTERNAL (1 << 6)
|
||||
#define PCAN_USB_STATUSLEN_EXT_ID (1 << 5)
|
||||
#define PCAN_USB_STATUSLEN_RTR (1 << 4)
|
||||
#define PCAN_USB_STATUSLEN_DLC (0xf)
|
||||
#define PCAN_USB_STATUSLEN_TIMESTAMP (1 << 7)
|
||||
#define PCAN_USB_STATUSLEN_INTERNAL (1 << 6)
|
||||
#define PCAN_USB_STATUSLEN_EXT_ID (1 << 5)
|
||||
#define PCAN_USB_STATUSLEN_RTR (1 << 4)
|
||||
#define PCAN_USB_STATUSLEN_DLC (0xf)
|
||||
|
||||
/* PCAN-USB error flags */
|
||||
#define PCAN_USB_ERROR_TXFULL 0x01
|
||||
#define PCAN_USB_ERROR_RXQOVR 0x02
|
||||
#define PCAN_USB_ERROR_BUS_LIGHT 0x04
|
||||
#define PCAN_USB_ERROR_BUS_HEAVY 0x08
|
||||
#define PCAN_USB_ERROR_BUS_OFF 0x10
|
||||
#define PCAN_USB_ERROR_RXQEMPTY 0x20
|
||||
#define PCAN_USB_ERROR_QOVR 0x40
|
||||
#define PCAN_USB_ERROR_TXQFULL 0x80
|
||||
#define PCAN_USB_ERROR_TXFULL 0x01
|
||||
#define PCAN_USB_ERROR_RXQOVR 0x02
|
||||
#define PCAN_USB_ERROR_BUS_LIGHT 0x04
|
||||
#define PCAN_USB_ERROR_BUS_HEAVY 0x08
|
||||
#define PCAN_USB_ERROR_BUS_OFF 0x10
|
||||
#define PCAN_USB_ERROR_RXQEMPTY 0x20
|
||||
#define PCAN_USB_ERROR_QOVR 0x40
|
||||
#define PCAN_USB_ERROR_TXQFULL 0x80
|
||||
|
||||
/* SJA1000 registers */
|
||||
#define SJA1000_MOD 0 /* mode register */
|
||||
#define SJA1000_CMR 1
|
||||
#define SJA1000_SR 2
|
||||
#define SJA1000_IR 3
|
||||
#define SJA1000_IER 4 /* acceptance code */
|
||||
#define SJA1000_BTR0 6 /* bus timing 0 */
|
||||
#define SJA1000_BTR1 7 /* bus timing 1 */
|
||||
#define SJA1000_OCR 8 /* output control */
|
||||
#define SJA1000_TR 9
|
||||
#define SJA1000_CDR 31
|
||||
#define SJA1000_MOD 0 /* mode register */
|
||||
#define SJA1000_CMR 1
|
||||
#define SJA1000_SR 2
|
||||
#define SJA1000_IR 3
|
||||
#define SJA1000_IER 4 /* acceptance code */
|
||||
#define SJA1000_BTR0 6 /* bus timing 0 */
|
||||
#define SJA1000_BTR1 7 /* bus timing 1 */
|
||||
#define SJA1000_OCR 8 /* output control */
|
||||
#define SJA1000_TR 9
|
||||
#define SJA1000_CDR 31
|
||||
|
||||
/* SJA1000 modes */
|
||||
#define SJA1000_MODE_NORMAL 0x00
|
||||
#define SJA1000_MODE_INIT 0x01
|
||||
#define SJA1000_MODE_NORMAL 0x00
|
||||
#define SJA1000_MODE_INIT 0x01
|
||||
|
||||
/*
|
||||
* tick duration = 42.666 us =>
|
||||
* (tick_number * 44739243) >> 20 ~ (tick_number * 42666) / 1000
|
||||
* accuracy = 10^-7
|
||||
*/
|
||||
#define PCAN_USB_TS_DIV_SHIFTER 20
|
||||
#define PCAN_USB_TS_US_PER_TICK 44739243
|
||||
#define PCAN_USB_TS_DIV_SHIFTER 20
|
||||
#define PCAN_USB_TS_US_PER_TICK 44739243
|
||||
|
||||
/* PCAN-USB messages record types */
|
||||
#define PCAN_USB_REC_ERROR 1
|
||||
#define PCAN_USB_REC_ANALOG 2
|
||||
#define PCAN_USB_REC_BUSLOAD 3
|
||||
#define PCAN_USB_REC_TS 4
|
||||
#define PCAN_USB_REC_BUSEVT 5
|
||||
#define PCAN_USB_REC_ERROR 1
|
||||
#define PCAN_USB_REC_ANALOG 2
|
||||
#define PCAN_USB_REC_BUSLOAD 3
|
||||
#define PCAN_USB_REC_TS 4
|
||||
#define PCAN_USB_REC_BUSEVT 5
|
||||
|
|
1289
Src/pcan_protocol.c
1289
Src/pcan_protocol.c
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
void pcan_protocol_init( void );
|
||||
void pcan_protocol_poll( void );
|
||||
void pcan_protocol_process_command( uint8_t *ptr, uint16_t size );
|
||||
void pcan_protocol_process_data( uint8_t *ptr, uint16_t size );
|
||||
void pcan_protocol_init(void);
|
||||
void pcan_protocol_poll(void);
|
||||
void pcan_protocol_process_command(uint8_t *ptr, uint16_t size);
|
||||
void pcan_protocol_process_data(uint8_t *ptr, uint16_t size);
|
||||
|
|
|
@ -3,35 +3,34 @@
|
|||
|
||||
#define TIM_BUS_FREQ (48000000)
|
||||
|
||||
void pcan_timestamp_init( void )
|
||||
void pcan_timestamp_init(void)
|
||||
{
|
||||
switch (TIM_BUS_FREQ)
|
||||
{
|
||||
case 48000000:
|
||||
/* TIM3 on APB1 bus */
|
||||
__HAL_RCC_TIM3_CLK_ENABLE();
|
||||
|
||||
switch( TIM_BUS_FREQ )
|
||||
{
|
||||
case 48000000:
|
||||
/* TIM3 on APB1 bus */
|
||||
__HAL_RCC_TIM3_CLK_ENABLE();
|
||||
|
||||
TIM3->PSC = (2048-1); /* => tick = 42.666uS */
|
||||
/* set clock division to zero: */
|
||||
TIM3->CR1 &= (uint16_t)(~TIM_CR1_CKD);
|
||||
TIM3->CR1 |= TIM_CLOCKDIVISION_DIV1;
|
||||
/* enable timer */
|
||||
TIM3->CR1 |= TIM_CR1_CEN;
|
||||
break;
|
||||
default:
|
||||
assert( 0 );
|
||||
break;
|
||||
}
|
||||
TIM3->PSC = (2048 - 1); /* => tick = 42.666uS */
|
||||
/* set clock division to zero: */
|
||||
TIM3->CR1 &= (uint16_t)(~TIM_CR1_CKD);
|
||||
TIM3->CR1 |= TIM_CLOCKDIVISION_DIV1;
|
||||
/* enable timer */
|
||||
TIM3->CR1 |= TIM_CR1_CEN;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t pcan_timestamp_millis( void )
|
||||
uint16_t pcan_timestamp_millis(void)
|
||||
{
|
||||
return (HAL_GetTick()&0xFFFF);
|
||||
return (HAL_GetTick() & 0xFFFF);
|
||||
}
|
||||
|
||||
uint16_t pcan_timestamp_ticks( void )
|
||||
uint16_t pcan_timestamp_ticks(void)
|
||||
{
|
||||
/* 1 pcan tick => 42.666 us */
|
||||
return TIM3->CNT;
|
||||
/* 1 pcan tick => 42.666 us */
|
||||
return TIM3->CNT;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#define PCAN_TICKS_FROM_US( _us ) (((uint32_t)_us*1000u)/42666u)
|
||||
#define PCAN_TICKS_FROM_US(_us) (((uint32_t)_us * 1000u) / 42666u)
|
||||
|
||||
void pcan_timestamp_init( void );
|
||||
uint16_t pcan_timestamp_ticks( void );
|
||||
uint16_t pcan_timestamp_millis( void );
|
||||
void pcan_timestamp_init(void);
|
||||
uint16_t pcan_timestamp_ticks(void);
|
||||
uint16_t pcan_timestamp_millis(void);
|
||||
|
|
566
Src/pcan_usb.c
566
Src/pcan_usb.c
|
@ -1,47 +1,46 @@
|
|||
#include <stm32f0xx_hal.h>
|
||||
#include <assert.h>
|
||||
#include "usbd_ctlreq.h"
|
||||
#include "usbd_ioreq.h"
|
||||
#include "usbd_conf.h"
|
||||
#include "usbd_helper.h"
|
||||
#include "pcan_protocol.h"
|
||||
#include "pcan_led.h"
|
||||
#include "pcan_usb.h"
|
||||
#include "pcan_led.h"
|
||||
#include "pcan_protocol.h"
|
||||
#include "usbd_conf.h"
|
||||
#include "usbd_ctlreq.h"
|
||||
#include "usbd_helper.h"
|
||||
#include "usbd_ioreq.h"
|
||||
#include <assert.h>
|
||||
#include <stm32f0xx_hal.h>
|
||||
|
||||
USBD_HandleTypeDef hUsbDeviceFS;
|
||||
USBD_HandleTypeDef hUsbDeviceFS;
|
||||
extern USBD_DescriptorsTypeDef FS_Desc;
|
||||
static struct t_class_data pcan_data = { 0 };
|
||||
static struct t_class_data pcan_data = { 0 };
|
||||
|
||||