🎨 代码格式化

Signed-off-by: DAVE <ro7enkranz@qq.com>
This commit is contained in:
DAVE 2022-03-29 17:24:25 +08:00
parent cd8bc7e8e6
commit 62c4a43894
23 changed files with 2314 additions and 2209 deletions

152
.clang-format Normal file
View File

@ -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
...

View File

@ -1,3 +1,4 @@
{ {
"makefile.extensionOutputFolder": "./.vscode" "makefile.extensionOutputFolder": "./.vscode",
"editor.detectIndentation": false
} }

View File

@ -2,27 +2,23 @@
#include <stm32f0xx_hal.h> #include <stm32f0xx_hal.h>
#define GPIO_NOAF (0u) #define GPIO_NOAF (0u)
#define _PIN_INIT( _PORT, _PIN, _MODE, _PULL, _SPEED, _AF )\ #define _PIN_INIT(_PORT, _PIN, _MODE, _PULL, _SPEED, _AF) \
HAL_GPIO_Init( GPIO##_PORT, (GPIO_InitTypeDef[])\ HAL_GPIO_Init(GPIO##_PORT, \
{{\ (GPIO_InitTypeDef[]) { \
.Pin = GPIO_PIN_##_PIN,\ {.Pin = GPIO_PIN_##_PIN, .Mode = GPIO_##_MODE, .Pull = GPIO_##_PULL, .Speed = GPIO_##_SPEED, .Alternate = GPIO_##_AF}
.Mode = GPIO_##_MODE,\ })
.Pull = GPIO_##_PULL,\ #define _PIN_HI(_PORT, _PIN, ...) GPIO##_PORT->BSRR = (1u << _PIN)
.Speed = GPIO_##_SPEED,\ #define _PIN_LOW(_PORT, _PIN, ...) GPIO##_PORT->BSRR = (0x10000u << _PIN)
.Alternate = GPIO_##_AF\ #define _PIN_TOGGLE(_PORT, _PIN, ...) \
}} ) do { \
#define _PIN_HI( _PORT, _PIN, ... ) GPIO##_PORT->BSRR = (1u<<_PIN) uint32_t odr = GPIO##_PORT->ODR; \
#define _PIN_LOW( _PORT, _PIN, ... ) GPIO##_PORT->BSRR = (0x10000u<<_PIN) GPIO##_PORT->BSRR = ((odr & (1u << _PIN)) << 16u) | (~odr & (1u << _PIN)); \
#define _PIN_TOGGLE( _PORT, _PIN, ... )\ } while (0)
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_HI(CONFIG) _PIN_HI(CONFIG)
#define PIN_LOW( CONFIG ) _PIN_LOW( CONFIG ) #define PIN_LOW(CONFIG) _PIN_LOW(CONFIG)
#define PIN_TOGGLE( CONFIG ) _PIN_TOGGLE( CONFIG ) #define PIN_TOGGLE(CONFIG) _PIN_TOGGLE(CONFIG)
#define PIN_INIT( CONFIG ) _PIN_INIT( CONFIG ) #define PIN_INIT(CONFIG) _PIN_INIT(CONFIG)
#define PIN_ENABLE_CLOCK( CONFIG ) _PIN_ENABLE_CLOCK( CONFIG ) #define PIN_ENABLE_CLOCK(CONFIG) _PIN_ENABLE_CLOCK(CONFIG)

View File

@ -1,108 +1,110 @@
#include "stm32f0xx_hal.h"
#include "pcan_timestamp.h"
#include "pcan_led.h" #include "pcan_led.h"
#include "pcan_protocol.h" #include "pcan_protocol.h"
#include "pcan_timestamp.h"
#include "pcan_usb.h" #include "pcan_usb.h"
#include "pcan_varian.h" #include "pcan_varian.h"
#include "stm32f0xx_hal.h"
void HAL_MspInit( void ) void HAL_MspInit(void)
{ {
__HAL_RCC_SYSCFG_CLK_ENABLE(); __HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_RCC_PWR_CLK_ENABLE(); __HAL_RCC_PWR_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE();
} }
#if ( HSE_VALUE != 0 ) #if (HSE_VALUE != 0)
void SystemClock_Config(void) void SystemClock_Config(void)
{ {
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };
/* enable HSE */ /* enable HSE */
__HAL_RCC_HSE_CONFIG(RCC_HSE_ON); __HAL_RCC_HSE_CONFIG(RCC_HSE_ON);
while( __HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET ); while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
;
/* enable PLL */ /* enable PLL */
__HAL_RCC_PLL_DISABLE(); __HAL_RCC_PLL_DISABLE();
while( __HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET ); 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 ); #if (HSE_VALUE == 16000000)
#elif ( HSE_VALUE == 8000000 ) __HAL_RCC_PLL_CONFIG(RCC_PLLSOURCE_HSE, RCC_PREDIV_DIV1, RCC_PLL_MUL3);
__HAL_RCC_PLL_CONFIG( RCC_PLLSOURCE_HSE, RCC_PREDIV_DIV1, RCC_PLL_MUL6 ); #elif (HSE_VALUE == 8000000)
__HAL_RCC_PLL_CONFIG(RCC_PLLSOURCE_HSE, RCC_PREDIV_DIV1, RCC_PLL_MUL6);
#endif #endif
__HAL_RCC_PLL_ENABLE(); __HAL_RCC_PLL_ENABLE();
while( __HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET ); while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
;
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1;
|RCC_CLOCKTYPE_PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_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 #else
void SystemClock_Config(void) void SystemClock_Config(void)
{ {
RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_CRSInitTypeDef RCC_CRSInitStruct = {0}; RCC_CRSInitTypeDef RCC_CRSInitStruct = { 0 };
__HAL_RCC_HSI48_ENABLE(); __HAL_RCC_HSI48_ENABLE();
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET ); while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET)
;
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1;
|RCC_CLOCKTYPE_PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI48;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI48; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_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_HSI48 ); __HAL_RCC_USB_CONFIG(RCC_USBCLKSOURCE_HSI48);
/* CRS */ /* CRS */
__HAL_RCC_CRS_CLK_ENABLE(); __HAL_RCC_CRS_CLK_ENABLE();
RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1; RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1;
RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB; RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB;
RCC_CRSInitStruct.Polarity = RCC_CRS_SYNC_POLARITY_RISING; RCC_CRSInitStruct.Polarity = RCC_CRS_SYNC_POLARITY_RISING;
RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE( 48000000, 1000 ); RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000, 1000);
RCC_CRSInitStruct.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT; RCC_CRSInitStruct.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT;
RCC_CRSInitStruct.HSI48CalibrationValue = RCC_CRS_HSI48CALIBRATION_DEFAULT; RCC_CRSInitStruct.HSI48CalibrationValue = RCC_CRS_HSI48CALIBRATION_DEFAULT;
HAL_RCCEx_CRSConfig( &RCC_CRSInitStruct ); HAL_RCCEx_CRSConfig(&RCC_CRSInitStruct);
} }
#endif #endif
void SysTick_Handler( void ) void SysTick_Handler(void)
{ {
HAL_IncTick(); HAL_IncTick();
} }
int main( void ) int main(void)
{ {
HAL_Init(); HAL_Init();
HAL_IncTick(); HAL_IncTick();
SystemClock_Config(); SystemClock_Config();
pcan_variant_io_init(); pcan_variant_io_init();
pcan_usb_init(); pcan_usb_init();
pcan_led_init(); pcan_led_init();
pcan_timestamp_init(); pcan_timestamp_init();
pcan_protocol_init(); pcan_protocol_init();
pcan_led_set_mode( LED_CH0_RX, 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 ); pcan_led_set_mode(LED_CH0_TX, LED_MODE_BLINK_SLOW, 0);
for(;;) for (;;)
{ {
pcan_usb_poll(); pcan_usb_poll();
pcan_led_poll(); pcan_led_poll();
pcan_protocol_poll(); pcan_protocol_poll();
} }
} }

View File

@ -1,343 +1,331 @@
#include <stm32f0xx_hal.h>
#include <string.h>
#include <assert.h>
#include "pcan_can.h" #include "pcan_can.h"
#include "pcan_timestamp.h" #include "pcan_timestamp.h"
#include "pcan_varian.h" #include "pcan_varian.h"
#include <assert.h>
#include <stm32f0xx_hal.h>
#include <string.h>
#define CAN_TX_FIFO_SIZE (100) #define CAN_TX_FIFO_SIZE (100)
static CAN_HandleTypeDef g_hcan = { .Instance = CAN }; static CAN_HandleTypeDef g_hcan = { .Instance = CAN };
#define INTERNAL_CAN_IT_FLAGS ( CAN_IT_TX_MAILBOX_EMPTY |\ #define INTERNAL_CAN_IT_FLAGS \
CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_RX_FIFO1_MSG_PENDING |\ (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_BUSOFF |\ | CAN_IT_LAST_ERROR_CODE | CAN_IT_ERROR)
CAN_IT_ERROR_WARNING |\
CAN_IT_ERROR_PASSIVE |\
CAN_IT_BUSOFF |\
CAN_IT_LAST_ERROR_CODE |\
CAN_IT_ERROR )
static struct static struct
{ {
uint32_t tx_msgs; uint32_t tx_msgs;
uint32_t tx_errs; uint32_t tx_errs;
uint32_t tx_ovfs; uint32_t tx_ovfs;
uint32_t rx_msgs; uint32_t rx_msgs;
uint32_t rx_errs; uint32_t rx_errs;
uint32_t rx_ovfs; uint32_t rx_ovfs;
can_message_t tx_fifo[CAN_TX_FIFO_SIZE]; can_message_t tx_fifo[CAN_TX_FIFO_SIZE];
uint32_t tx_head; uint32_t tx_head;
uint32_t tx_tail; uint32_t tx_tail;
void (*rx_cb)(can_message_t *); void (*rx_cb)(can_message_t *);
void (*can_err_cb)( uint8_t err, uint8_t rx_err, uint8_t tx_err ); void (*can_err_cb)(uint8_t err, uint8_t rx_err, uint8_t tx_err);
} } can_dev = { 0 };
can_dev = { 0 };
void pcan_can_init(void) 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_RX);
PIN_ENABLE_CLOCK( CAN_TX ); PIN_ENABLE_CLOCK(CAN_TX);
PIN_INIT( CAN_RX ); PIN_INIT(CAN_RX);
PIN_INIT( CAN_TX ); PIN_INIT(CAN_TX);
HAL_CAN_DeInit( &g_hcan ); HAL_CAN_DeInit(&g_hcan);
g_hcan.Instance = CAN; g_hcan.Instance = CAN;
g_hcan.Init.Prescaler = 16; g_hcan.Init.Prescaler = 16;
g_hcan.Init.Mode = CAN_MODE_NORMAL; g_hcan.Init.Mode = CAN_MODE_NORMAL;
g_hcan.Init.SyncJumpWidth = CAN_SJW_1TQ; g_hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
g_hcan.Init.TimeSeg1 = CAN_BS1_1TQ; g_hcan.Init.TimeSeg1 = CAN_BS1_1TQ;
g_hcan.Init.TimeSeg2 = CAN_BS2_1TQ; g_hcan.Init.TimeSeg2 = CAN_BS2_1TQ;
g_hcan.Init.TimeTriggeredMode = DISABLE; g_hcan.Init.TimeTriggeredMode = DISABLE;
g_hcan.Init.AutoBusOff = ENABLE; g_hcan.Init.AutoBusOff = ENABLE;
g_hcan.Init.AutoWakeUp = DISABLE; g_hcan.Init.AutoWakeUp = DISABLE;
g_hcan.Init.AutoRetransmission = ENABLE; g_hcan.Init.AutoRetransmission = ENABLE;
g_hcan.Init.ReceiveFifoLocked = DISABLE; g_hcan.Init.ReceiveFifoLocked = DISABLE;
g_hcan.Init.TransmitFifoPriority = ENABLE; g_hcan.Init.TransmitFifoPriority = ENABLE;
if( HAL_CAN_Init( &g_hcan ) != HAL_OK ) if (HAL_CAN_Init(&g_hcan) != HAL_OK)
{ {
assert( 0 ); assert(0);
} }
filter.FilterMode = CAN_FILTERMODE_IDMASK; filter.FilterMode = CAN_FILTERMODE_IDMASK;
filter.FilterScale = CAN_FILTERSCALE_32BIT; filter.FilterScale = CAN_FILTERSCALE_32BIT;
filter.FilterFIFOAssignment = CAN_FILTER_FIFO0; filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
filter.FilterActivation = ENABLE; filter.FilterActivation = ENABLE;
filter.FilterBank = 0; filter.FilterBank = 0;
filter.SlaveStartFilterBank = 0; filter.SlaveStartFilterBank = 0;
if( HAL_CAN_ConfigFilter( &g_hcan, &filter ) != HAL_OK ) if (HAL_CAN_ConfigFilter(&g_hcan, &filter) != HAL_OK)
{ {
assert( 0 ); assert(0);
} }
if( HAL_CAN_ActivateNotification( &g_hcan, INTERNAL_CAN_IT_FLAGS ) != HAL_OK ) if (HAL_CAN_ActivateNotification(&g_hcan, INTERNAL_CAN_IT_FLAGS) != HAL_OK)
{ {
assert( 0 ); 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[] = 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_SJW_1TQ, CAN_SJW_2TQ, CAN_SJW_3TQ, CAN_SJW_4TQ 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 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 ) if (sjw > 4)
sjw = 4; sjw = 4;
if( tseg1 > 16 ) if (tseg1 > 16)
tseg1 = 16; tseg1 = 16;
if( tseg2 > 8 ) if (tseg2 > 8)
tseg2 = 8; tseg2 = 8;
/* CAN bus freq is 48 */ /* CAN bus freq is 48 */
g_hcan.Init.Prescaler = brp * 6; g_hcan.Init.Prescaler = brp * 6;
g_hcan.Init.SyncJumpWidth = sjw_table[sjw - 1]; g_hcan.Init.SyncJumpWidth = sjw_table[sjw - 1];
g_hcan.Init.TimeSeg1 = tseg1_table[tseg1 - 1]; g_hcan.Init.TimeSeg1 = tseg1_table[tseg1 - 1];
g_hcan.Init.TimeSeg2 = tseg2_table[tseg2 - 1]; g_hcan.Init.TimeSeg2 = tseg2_table[tseg2 - 1];
if( HAL_CAN_Init( &g_hcan ) != HAL_OK ) if (HAL_CAN_Init(&g_hcan) != HAL_OK)
{ {
assert( 0 ); 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 }; CAN_TxHeaderTypeDef msg = { .TransmitGlobalTime = DISABLE };
uint32_t txMailbox = 0; uint32_t txMailbox = 0;
if( p_msg->flags & CAN_FLAG_EXTID ) if (p_msg->flags & CAN_FLAG_EXTID)
{ {
msg.ExtId = p_msg->id & 0x1FFFFFFF; msg.ExtId = p_msg->id & 0x1FFFFFFF;
msg.IDE = CAN_ID_EXT; msg.IDE = CAN_ID_EXT;
} }
else else
{ {
msg.StdId = p_msg->id & 0x7FF; msg.StdId = p_msg->id & 0x7FF;
msg.IDE = CAN_ID_STD; msg.IDE = CAN_ID_STD;
} }
msg.DLC = p_msg->dlc; msg.DLC = p_msg->dlc;
msg.RTR = (p_msg->flags & CAN_FLAG_RTR)?CAN_RTR_REMOTE:CAN_RTR_DATA; 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 ) if (HAL_CAN_AddTxMessage(&g_hcan, &msg, (void *)p_msg->data, &txMailbox) != HAL_OK)
return -1; return -1;
return txMailbox; 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 */ /* empty fifo */
if( can_dev.tx_head == can_dev.tx_tail ) if (can_dev.tx_head == can_dev.tx_tail)
return; return;
p_msg = &can_dev.tx_fifo[can_dev.tx_tail]; p_msg = &can_dev.tx_fifo[can_dev.tx_tail];
if( pcan_try_send_message( p_msg ) < 0 ) if (pcan_try_send_message(p_msg) < 0)
return; return;
/* update fifo index */ /* update fifo index */
uint32_t tail = can_dev.tx_tail+1; uint32_t tail = can_dev.tx_tail + 1;
if( tail == CAN_TX_FIFO_SIZE ) if (tail == CAN_TX_FIFO_SIZE)
tail = 0; tail = 0;
can_dev.tx_tail = tail; 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; 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; g_hcan.Init.Mode = silent_mode ? CAN_MODE_SILENT : CAN_MODE_NORMAL;
if( HAL_CAN_Init( &g_hcan ) != HAL_OK ) if (HAL_CAN_Init(&g_hcan) != HAL_OK)
{ {
assert( 0 ); 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; g_hcan.Init.Mode = loopback ? CAN_MODE_LOOPBACK : CAN_MODE_NORMAL;
if( HAL_CAN_Init( &g_hcan ) != HAL_OK ) if (HAL_CAN_Init(&g_hcan) != HAL_OK)
{ {
assert( 0 ); assert(0);
} }
} }
void pcan_can_set_bus_active( uint16_t mode ) void pcan_can_set_bus_active(uint16_t mode)
{ {
if( mode ) if (mode)
{ {
HAL_CAN_Start( &g_hcan ); HAL_CAN_Start(&g_hcan);
HAL_CAN_AbortTxRequest( &g_hcan, CAN_TX_MAILBOX0 | CAN_TX_MAILBOX1 | CAN_TX_MAILBOX2 ); HAL_CAN_AbortTxRequest(&g_hcan, CAN_TX_MAILBOX0 | CAN_TX_MAILBOX1 | CAN_TX_MAILBOX2);
} }
else else
{ {
HAL_CAN_AbortTxRequest( &g_hcan, CAN_TX_MAILBOX0 | CAN_TX_MAILBOX1 | CAN_TX_MAILBOX2 ); HAL_CAN_AbortTxRequest(&g_hcan, CAN_TX_MAILBOX0 | CAN_TX_MAILBOX1 | CAN_TX_MAILBOX2);
HAL_CAN_Stop( &g_hcan ); 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_RxHeaderTypeDef hdr = { 0 };
can_message_t msg = { 0 }; can_message_t msg = { 0 };
if( HAL_CAN_GetRxMessage( hcan, fifo, &hdr, msg.data ) != HAL_OK ) if (HAL_CAN_GetRxMessage(hcan, fifo, &hdr, msg.data) != HAL_OK)
return; return;
if( hdr.IDE == CAN_ID_STD ) if (hdr.IDE == CAN_ID_STD)
{ {
msg.id = hdr.StdId; msg.id = hdr.StdId;
} }
else else
{ {
msg.id = hdr.ExtId; msg.id = hdr.ExtId;
msg.flags |= CAN_FLAG_EXTID; msg.flags |= CAN_FLAG_EXTID;
} }
if( hdr.RTR == CAN_RTR_REMOTE ) if (hdr.RTR == CAN_RTR_REMOTE)
{ {
msg.flags |= CAN_FLAG_RTR; msg.flags |= CAN_FLAG_RTR;
} }
msg.dlc = hdr.DLC; msg.dlc = hdr.DLC;
msg.timestamp = pcan_timestamp_ticks(); msg.timestamp = pcan_timestamp_ticks();
if( can_dev.rx_cb ) if (can_dev.rx_cb)
{ {
can_dev.rx_cb( &msg ); can_dev.rx_cb(&msg);
} }
++can_dev.rx_msgs; ++can_dev.rx_msgs;
} }
void pcan_can_poll(void) void pcan_can_poll(void)
{ {
HAL_CAN_IRQHandler( &g_hcan ); HAL_CAN_IRQHandler(&g_hcan);
pcan_can_flush_tx(); 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 ); UNUSED(hcan);
++can_dev.tx_msgs; ++can_dev.tx_msgs;
} }
void HAL_CAN_TxMailbox1CompleteCallback( CAN_HandleTypeDef *hcan ) void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan)
{ {
UNUSED( hcan ); UNUSED(hcan);
++can_dev.tx_msgs; ++can_dev.tx_msgs;
} }
void HAL_CAN_TxMailbox2CompleteCallback( CAN_HandleTypeDef *hcan ) void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan)
{ {
UNUSED( hcan ); UNUSED(hcan);
++can_dev.tx_msgs; ++can_dev.tx_msgs;
} }
void HAL_CAN_RxFifo0FullCallback( CAN_HandleTypeDef *hcan ) void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan)
{ {
UNUSED( hcan ); UNUSED(hcan);
++can_dev.rx_ovfs; ++can_dev.rx_ovfs;
} }
void HAL_CAN_RxFifo1FullCallback( CAN_HandleTypeDef *hcan ) void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan)
{ {
UNUSED( hcan ); UNUSED(hcan);
++can_dev.rx_ovfs; ++can_dev.rx_ovfs;
} }
void HAL_CAN_SleepCallback( CAN_HandleTypeDef *hcan ){ UNUSED( hcan ); } void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan)
void HAL_CAN_WakeUpFromRxMsgCallback( CAN_HandleTypeDef *hcan ){ UNUSED( hcan ); }
void HAL_CAN_ErrorCallback( CAN_HandleTypeDef *hcan )
{ {
/* handle errors */ UNUSED(hcan);
uint32_t err = HAL_CAN_GetError( hcan ); }
uint8_t can_err = 0; void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan)
{
if ( err & ( HAL_CAN_ERROR_TX_TERR0 | HAL_CAN_ERROR_TX_TERR1 | HAL_CAN_ERROR_TX_TERR2 ) ) UNUSED(hcan);
{ }
++can_dev.tx_errs;
can_err |= CAN_ERROR_FLAG_TX_ERR; void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
} {
/* handle errors */
if( err & HAL_CAN_ERROR_BOF ) uint32_t err = HAL_CAN_GetError(hcan);
{ uint8_t can_err = 0;
can_err |= CAN_ERROR_FLAG_BUSOFF;
} if (err & (HAL_CAN_ERROR_TX_TERR0 | HAL_CAN_ERROR_TX_TERR1 | HAL_CAN_ERROR_TX_TERR2))
{
if( err & ( HAL_CAN_ERROR_RX_FOV0 | HAL_CAN_ERROR_RX_FOV1 ) ) ++can_dev.tx_errs;
{ can_err |= CAN_ERROR_FLAG_TX_ERR;
can_err |= CAN_ERROR_FLAG_RX_OVF; }
}
if (err & HAL_CAN_ERROR_BOF)
if( can_dev.can_err_cb && can_err ) {
{ can_err |= CAN_ERROR_FLAG_BUSOFF;
can_dev.can_err_cb( can_err, can_dev.tx_errs & 0xFF, can_dev.rx_errs ); }
}
if (err & (HAL_CAN_ERROR_RX_FOV0 | HAL_CAN_ERROR_RX_FOV1))
HAL_CAN_ResetError( hcan ); {
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);
} }

View File

@ -5,29 +5,28 @@
#define CAN_FLAG_RTR (0x40) #define CAN_FLAG_RTR (0x40)
#define CAN_FLAG_EXTID (0x80) #define CAN_FLAG_EXTID (0x80)
#define CAN_ERROR_FLAG_BUSOFF (1<<0) #define CAN_ERROR_FLAG_BUSOFF (1 << 0)
#define CAN_ERROR_FLAG_RX_OVF (1<<1) #define CAN_ERROR_FLAG_RX_OVF (1 << 1)
#define CAN_ERROR_FLAG_TX_ERR (1<<2) #define CAN_ERROR_FLAG_TX_ERR (1 << 2)
typedef struct typedef struct
{ {
uint32_t id; uint32_t id;
uint8_t data[8]; uint8_t data[8];
uint8_t dlc; uint8_t dlc;
uint8_t flags; uint8_t flags;
/* for self receive */ /* for self receive */
uint8_t dummy; uint8_t dummy;
/* in pcan ticks */ /* in pcan ticks */
uint16_t timestamp; uint16_t timestamp;
} } can_message_t;
can_message_t;
void pcan_can_init( void ); void pcan_can_init(void);
void pcan_can_poll( void ); void pcan_can_poll(void);
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);
int pcan_can_send_message( const can_message_t *msg ); 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_rx_callback(void (*cb)(can_message_t *));
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));
void pcan_can_set_bus_active( uint16_t mode ); void pcan_can_set_bus_active(uint16_t mode);
void pcan_can_set_silent( uint8_t silent_mode ); void pcan_can_set_silent(uint8_t silent_mode);
void pcan_can_set_loopback( uint8_t loopback ); void pcan_can_set_loopback(uint8_t loopback);

View File

@ -1,107 +1,106 @@
#include <assert.h>
#include "stm32f0xx_hal.h"
#include "pcan_timestamp.h"
#include "pcan_led.h" #include "pcan_led.h"
#include "pcan_timestamp.h"
#include "pcan_varian.h" #include "pcan_varian.h"
#include "stm32f0xx_hal.h"
#include <assert.h>
static struct static struct
{ {
uint16_t mode; uint16_t mode;
uint16_t arg; uint16_t arg;
uint16_t delay; uint16_t delay;
uint16_t timestamp; uint16_t timestamp;
uint8_t state; uint8_t state;
} } led_mode_array[LED_TOTAL] = { 0 };
led_mode_array[LED_TOTAL] = { 0 };
void pcan_led_init( void ) void pcan_led_init(void)
{ {
#ifdef IOPIN_TX #ifdef IOPIN_TX
PIN_ENABLE_CLOCK( IOPIN_TX ); PIN_ENABLE_CLOCK(IOPIN_TX);
PIN_INIT( IOPIN_TX ); PIN_INIT(IOPIN_TX);
#endif #endif
#ifdef IOPIN_RX #ifdef IOPIN_RX
PIN_ENABLE_CLOCK( IOPIN_RX ); PIN_ENABLE_CLOCK(IOPIN_RX);
PIN_INIT( IOPIN_RX ); PIN_INIT(IOPIN_RX);
#endif #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 ); assert(led < LED_TOTAL);
uint16_t ts = pcan_timestamp_millis(); uint16_t ts = pcan_timestamp_millis();
led_mode_array[led].mode = mode; led_mode_array[led].mode = mode;
if( !led_mode_array[led].timestamp ) 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 )
{ {
default: led_mode_array[led].timestamp = ts | 1;
case LED_MODE_NONE: }
led_mode_array[i].timestamp = 0; led_mode_array[led].delay = 0;
break;
case LED_MODE_OFF: /* set guard time */
case LED_MODE_ON: if (mode == LED_MODE_BLINK_FAST || mode == LED_MODE_BLINK_SLOW)
led_mode_array[i].state = ( led_mode_array[i].mode == LED_MODE_ON ); {
led_mode_array[i].timestamp = 0; led_mode_array[led].delay = (mode == LED_MODE_BLINK_FAST) ? 50 : 200;
break; arg = arg ? (ts + arg) | 1 : 0;
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 ); 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);
}
} }

View File

@ -3,22 +3,22 @@
enum e_pcan_led enum e_pcan_led
{ {
LED_CH0_TX, LED_CH0_TX,
LED_CH0_RX, LED_CH0_RX,
LED_STAT, LED_STAT,
LED_TOTAL, LED_TOTAL,
}; };
enum e_pcan_led_mode enum e_pcan_led_mode
{ {
LED_MODE_NONE, LED_MODE_NONE,
LED_MODE_ON, LED_MODE_ON,
LED_MODE_OFF, LED_MODE_OFF,
LED_MODE_BLINK_FAST, LED_MODE_BLINK_FAST,
LED_MODE_BLINK_SLOW, LED_MODE_BLINK_SLOW,
}; };
void pcan_led_init( void ); void pcan_led_init(void);
void pcan_led_set_mode( int led, int mode, uint16_t arg ); void pcan_led_set_mode(int led, int mode, uint16_t arg);
void pcan_led_poll( void ); void pcan_led_poll(void);

View File

@ -6,90 +6,89 @@
#pragma pack(push, 1) #pragma pack(push, 1)
typedef struct typedef struct
{ {
uint8_t function; uint8_t function;
uint8_t number; uint8_t number;
uint8_t param[14]; uint8_t param[14];
} } PCAN_USB_PARAM;
PCAN_USB_PARAM;
#pragma pack(pop) #pragma pack(pop)
/* USB control cmds get/set */ /* USB control cmds get/set */
#define PCAN_USB_EX0 0x00 #define PCAN_USB_EX0 0x00
#define PCAN_USB_GET 0x01 #define PCAN_USB_GET 0x01
#define PCAN_USB_SET 0x02 #define PCAN_USB_SET 0x02
#define PCAN_USB_EX3 0x03 #define PCAN_USB_EX3 0x03
/* PCAN-USB commands */ /* PCAN-USB commands */
#define PCAN_USB_CMD_BITRATE 1 #define PCAN_USB_CMD_BITRATE 1
#define PCAN_USB_CMD_CLOCK 2 #define PCAN_USB_CMD_CLOCK 2
#define PCAN_USB_CMD_BUS 3 #define PCAN_USB_CMD_BUS 3
#define PCAN_USB_CMD_DEVID 4 #define PCAN_USB_CMD_DEVID 4
#define PCAN_USB_CMD_CFG 5 #define PCAN_USB_CMD_CFG 5
#define PCAN_USB_CMD_SN 6 #define PCAN_USB_CMD_SN 6
#define PCAN_USB_CMD_REGISTER 9 #define PCAN_USB_CMD_REGISTER 9
#define PCAN_USB_CMD_EXT_VCC 10 #define PCAN_USB_CMD_EXT_VCC 10
#define PCAN_USB_CMD_ERR_FR 11 #define PCAN_USB_CMD_ERR_FR 11
#define PCAN_USB_CMD_LED 12 #define PCAN_USB_CMD_LED 12
#define PCAN_USB_CMD_DEVDATA 30 #define PCAN_USB_CMD_DEVDATA 30
/* USB Mass Storage Mode command (FW >= 8.3.0) */ /* 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: */ /* 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 */ /* PCAN-USB rx/tx buffers size */
#define PCAN_USB_RX_BUFFER_SIZE 64 #define PCAN_USB_RX_BUFFER_SIZE 64
#define PCAN_USB_TX_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) */ /* 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 */ /* PCAN-USB USB message record status/len field */
#define PCAN_USB_STATUSLEN_TIMESTAMP (1 << 7) #define PCAN_USB_STATUSLEN_TIMESTAMP (1 << 7)
#define PCAN_USB_STATUSLEN_INTERNAL (1 << 6) #define PCAN_USB_STATUSLEN_INTERNAL (1 << 6)
#define PCAN_USB_STATUSLEN_EXT_ID (1 << 5) #define PCAN_USB_STATUSLEN_EXT_ID (1 << 5)
#define PCAN_USB_STATUSLEN_RTR (1 << 4) #define PCAN_USB_STATUSLEN_RTR (1 << 4)
#define PCAN_USB_STATUSLEN_DLC (0xf) #define PCAN_USB_STATUSLEN_DLC (0xf)
/* PCAN-USB error flags */ /* PCAN-USB error flags */
#define PCAN_USB_ERROR_TXFULL 0x01 #define PCAN_USB_ERROR_TXFULL 0x01
#define PCAN_USB_ERROR_RXQOVR 0x02 #define PCAN_USB_ERROR_RXQOVR 0x02
#define PCAN_USB_ERROR_BUS_LIGHT 0x04 #define PCAN_USB_ERROR_BUS_LIGHT 0x04
#define PCAN_USB_ERROR_BUS_HEAVY 0x08 #define PCAN_USB_ERROR_BUS_HEAVY 0x08
#define PCAN_USB_ERROR_BUS_OFF 0x10 #define PCAN_USB_ERROR_BUS_OFF 0x10
#define PCAN_USB_ERROR_RXQEMPTY 0x20 #define PCAN_USB_ERROR_RXQEMPTY 0x20
#define PCAN_USB_ERROR_QOVR 0x40 #define PCAN_USB_ERROR_QOVR 0x40
#define PCAN_USB_ERROR_TXQFULL 0x80 #define PCAN_USB_ERROR_TXQFULL 0x80
/* SJA1000 registers */ /* SJA1000 registers */
#define SJA1000_MOD 0 /* mode register */ #define SJA1000_MOD 0 /* mode register */
#define SJA1000_CMR 1 #define SJA1000_CMR 1
#define SJA1000_SR 2 #define SJA1000_SR 2
#define SJA1000_IR 3 #define SJA1000_IR 3
#define SJA1000_IER 4 /* acceptance code */ #define SJA1000_IER 4 /* acceptance code */
#define SJA1000_BTR0 6 /* bus timing 0 */ #define SJA1000_BTR0 6 /* bus timing 0 */
#define SJA1000_BTR1 7 /* bus timing 1 */ #define SJA1000_BTR1 7 /* bus timing 1 */
#define SJA1000_OCR 8 /* output control */ #define SJA1000_OCR 8 /* output control */
#define SJA1000_TR 9 #define SJA1000_TR 9
#define SJA1000_CDR 31 #define SJA1000_CDR 31
/* SJA1000 modes */ /* SJA1000 modes */
#define SJA1000_MODE_NORMAL 0x00 #define SJA1000_MODE_NORMAL 0x00
#define SJA1000_MODE_INIT 0x01 #define SJA1000_MODE_INIT 0x01
/* /*
* tick duration = 42.666 us => * tick duration = 42.666 us =>
* (tick_number * 44739243) >> 20 ~ (tick_number * 42666) / 1000 * (tick_number * 44739243) >> 20 ~ (tick_number * 42666) / 1000
* accuracy = 10^-7 * accuracy = 10^-7
*/ */
#define PCAN_USB_TS_DIV_SHIFTER 20 #define PCAN_USB_TS_DIV_SHIFTER 20
#define PCAN_USB_TS_US_PER_TICK 44739243 #define PCAN_USB_TS_US_PER_TICK 44739243
/* PCAN-USB messages record types */ /* PCAN-USB messages record types */
#define PCAN_USB_REC_ERROR 1 #define PCAN_USB_REC_ERROR 1
#define PCAN_USB_REC_ANALOG 2 #define PCAN_USB_REC_ANALOG 2
#define PCAN_USB_REC_BUSLOAD 3 #define PCAN_USB_REC_BUSLOAD 3
#define PCAN_USB_REC_TS 4 #define PCAN_USB_REC_TS 4
#define PCAN_USB_REC_BUSEVT 5 #define PCAN_USB_REC_BUSEVT 5

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
void pcan_protocol_init( void ); void pcan_protocol_init(void);
void pcan_protocol_poll( void ); void pcan_protocol_poll(void);
void pcan_protocol_process_command( uint8_t *ptr, uint16_t size ); 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_process_data(uint8_t *ptr, uint16_t size);

View File

@ -3,35 +3,34 @@
#define TIM_BUS_FREQ (48000000) #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 ) TIM3->PSC = (2048 - 1); /* => tick = 42.666uS */
{ /* set clock division to zero: */
case 48000000: TIM3->CR1 &= (uint16_t)(~TIM_CR1_CKD);
/* TIM3 on APB1 bus */ TIM3->CR1 |= TIM_CLOCKDIVISION_DIV1;
__HAL_RCC_TIM3_CLK_ENABLE(); /* enable timer */
TIM3->CR1 |= TIM_CR1_CEN;
TIM3->PSC = (2048-1); /* => tick = 42.666uS */ break;
/* set clock division to zero: */ default:
TIM3->CR1 &= (uint16_t)(~TIM_CR1_CKD); assert(0);
TIM3->CR1 |= TIM_CLOCKDIVISION_DIV1; break;
/* 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 */ /* 1 pcan tick => 42.666 us */
return TIM3->CNT; return TIM3->CNT;
} }

View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include <stdint.h> #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 ); void pcan_timestamp_init(void);
uint16_t pcan_timestamp_ticks( void ); uint16_t pcan_timestamp_ticks(void);
uint16_t pcan_timestamp_millis( void ); uint16_t pcan_timestamp_millis(void);

View File

@ -1,38 +1,37 @@
#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_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; extern USBD_DescriptorsTypeDef FS_Desc;
static struct t_class_data pcan_data = { 0 }; static struct t_class_data pcan_data = { 0 };
struct t_pcan_description struct t_pcan_description
{ {
USB_CONFIGURATION_DESCRIPTOR con0; USB_CONFIGURATION_DESCRIPTOR con0;
USB_INTERFACE_DESCRIPTOR if0; USB_INTERFACE_DESCRIPTOR if0;
USB_ENDPOINT_DESCRIPTOR ep1; USB_ENDPOINT_DESCRIPTOR ep1;
USB_ENDPOINT_DESCRIPTOR ep2; USB_ENDPOINT_DESCRIPTOR ep2;
USB_ENDPOINT_DESCRIPTOR ep3; USB_ENDPOINT_DESCRIPTOR ep3;
USB_ENDPOINT_DESCRIPTOR ep4; USB_ENDPOINT_DESCRIPTOR ep4;
}; };
__ALIGN_BEGIN static const USB_DEVICE_QUALIFIER_DESCRIPTOR dev_qua __ALIGN_END = __ALIGN_BEGIN static const USB_DEVICE_QUALIFIER_DESCRIPTOR dev_qua __ALIGN_END = {
{ .bLength = sizeof(USB_DEVICE_QUALIFIER_DESCRIPTOR),
.bLength = sizeof( USB_DEVICE_QUALIFIER_DESCRIPTOR ), .bDescriptorType = USB_QUALIFIER_DESCRIPTOR_TYPE,
.bDescriptorType = USB_QUALIFIER_DESCRIPTOR_TYPE, .bcdUSB = 0x0100, /* 1.0 */
.bcdUSB = 0x0100, /* 1.0 */ .bDeviceClass = 0,
.bDeviceClass = 0, .bDeviceSubClass = 0,
.bDeviceSubClass = 0, .bDeviceProtocol = 0,
.bDeviceProtocol = 0, .bMaxPacketSize0 = 64,
.bMaxPacketSize0 = 64, .bNumConfigurations = 1,
.bNumConfigurations = 1, .bReserved = 0,
.bReserved = 0,
}; };
__ALIGN_BEGIN static struct t_pcan_description pcan_usb_dev __ALIGN_END = __ALIGN_BEGIN static struct t_pcan_description pcan_usb_dev __ALIGN_END =
@ -99,139 +98,134 @@ __ALIGN_BEGIN static struct t_pcan_description pcan_usb_dev __ALIGN_END =
}; };
static uint8_t device_init( USBD_HandleTypeDef *pdev, uint8_t cfgidx ) static uint8_t device_init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{ {
USB_ENDPOINT_DESCRIPTOR *p_ep = &pcan_usb_dev.ep1; USB_ENDPOINT_DESCRIPTOR *p_ep = &pcan_usb_dev.ep1;
UNUSED( cfgidx ); UNUSED(cfgidx);
for( int i = 0; i < pcan_usb_dev.if0.bNumEndpoints; i++ ) for (int i = 0; i < pcan_usb_dev.if0.bNumEndpoints; i++)
{
uint8_t ep_addr = p_ep[i].bEndpointAddress;
if( p_ep[i].bmAttributes == USB_ENDPOINT_TYPE_BULK )
{ {
if( pdev->dev_speed == USBD_SPEED_FULL ) uint8_t ep_addr = p_ep[i].bEndpointAddress;
;
else if( pdev->dev_speed == USBD_SPEED_HIGH ) if (p_ep[i].bmAttributes == USB_ENDPOINT_TYPE_BULK)
; {
else if (pdev->dev_speed == USBD_SPEED_FULL)
assert( 0 ); ;
else if (pdev->dev_speed == USBD_SPEED_HIGH)
;
else
assert(0);
}
USBD_LL_OpenEP(pdev, ep_addr, p_ep[i].bmAttributes, p_ep[i].wMaxPacketSize);
if ((ep_addr & 0x80) != 0)
pdev->ep_in[ep_addr & EP_ADDR_MSK].is_used = 1;
else
pdev->ep_out[ep_addr & EP_ADDR_MSK].is_used = 1;
} }
USBD_LL_OpenEP( pdev, ep_addr, pdev->pClassData = (void *)&pcan_data;
p_ep[i].bmAttributes,
p_ep[i].wMaxPacketSize );
if( ( ep_addr & 0x80 ) != 0 )
pdev->ep_in[ep_addr & EP_ADDR_MSK].is_used = 1;
else
pdev->ep_out[ep_addr & EP_ADDR_MSK].is_used = 1;
}
pdev->pClassData = (void*)&pcan_data;
USBD_LL_PrepareReceive( pdev, PCAN_USB_EP_CMDOUT, pcan_data.buffer_cmd, sizeof( pcan_data.buffer_cmd ) ); USBD_LL_PrepareReceive(pdev, PCAN_USB_EP_CMDOUT, pcan_data.buffer_cmd, sizeof(pcan_data.buffer_cmd));
USBD_LL_PrepareReceive( pdev, PCAN_USB_EP_MSGOUT, pcan_data.buffer_data, sizeof( pcan_data.buffer_data ) ); USBD_LL_PrepareReceive(pdev, PCAN_USB_EP_MSGOUT, pcan_data.buffer_data, sizeof(pcan_data.buffer_data));
return USBD_OK; return USBD_OK;
} }
static uint8_t device_deinit( USBD_HandleTypeDef *pdev, uint8_t cfgidx ) static uint8_t device_deinit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{ {
USB_ENDPOINT_DESCRIPTOR const *p_ep = &pcan_usb_dev.ep1; USB_ENDPOINT_DESCRIPTOR const *p_ep = &pcan_usb_dev.ep1;
UNUSED( cfgidx ); UNUSED(cfgidx);
for( int i = 0; i < pcan_usb_dev.if0.bNumEndpoints; i++ ) for (int i = 0; i < pcan_usb_dev.if0.bNumEndpoints; i++)
{ {
uint8_t ep_addr = p_ep[i].bEndpointAddress; uint8_t ep_addr = p_ep[i].bEndpointAddress;
USBD_LL_CloseEP( pdev, ep_addr ); USBD_LL_CloseEP(pdev, ep_addr);
if( ( ep_addr & 0x80 ) != 0 ) if ((ep_addr & 0x80) != 0)
pdev->ep_in[ep_addr & EP_ADDR_MSK].is_used = 0; pdev->ep_in[ep_addr & EP_ADDR_MSK].is_used = 0;
else else
pdev->ep_out[ep_addr & EP_ADDR_MSK].is_used = 0; pdev->ep_out[ep_addr & EP_ADDR_MSK].is_used = 0;
} }
pdev->pClassData = (void*)0; pdev->pClassData = (void *)0;
return USBD_OK; return USBD_OK;
} }
uint16_t pcan_usb_send_command_buffer( const void *p, uint16_t size ) uint16_t pcan_usb_send_command_buffer(const void *p, uint16_t size)
{ {
USBD_HandleTypeDef *pdev = &hUsbDeviceFS; USBD_HandleTypeDef *pdev = &hUsbDeviceFS;
if( pdev->ep_in[PCAN_USB_EP_CMDIN & 0xFU].total_length ) if (pdev->ep_in[PCAN_USB_EP_CMDIN & 0xFU].total_length)
return 0;
pdev->ep_in[PCAN_USB_EP_CMDIN & 0xFU].total_length = size;
if (USBD_LL_Transmit(pdev, PCAN_USB_EP_CMDIN, (void *)p, size) == USBD_OK)
return size;
return 0; return 0;
pdev->ep_in[PCAN_USB_EP_CMDIN & 0xFU].total_length = size;
if( USBD_LL_Transmit( pdev, PCAN_USB_EP_CMDIN, (void*)p, size ) == USBD_OK )
return size;
return 0;
} }
uint16_t pcan_usb_send_data_buffer( const void *p, uint16_t size ) uint16_t pcan_usb_send_data_buffer(const void *p, uint16_t size)
{ {
USBD_HandleTypeDef *pdev = &hUsbDeviceFS; USBD_HandleTypeDef *pdev = &hUsbDeviceFS;
if( pdev->ep_in[PCAN_USB_EP_MSGIN & 0xFU].total_length ) if (pdev->ep_in[PCAN_USB_EP_MSGIN & 0xFU].total_length)
return 0;
pdev->ep_in[PCAN_USB_EP_MSGIN & 0xFU].total_length = size;
if (USBD_LL_Transmit(pdev, PCAN_USB_EP_MSGIN, (void *)p, size) == USBD_OK)
return size;
return 0; return 0;
pdev->ep_in[PCAN_USB_EP_MSGIN & 0xFU].total_length = size;
if( USBD_LL_Transmit( pdev, PCAN_USB_EP_MSGIN, (void*)p, size ) == USBD_OK )
return size;
return 0;
} }
void pcan_usb_poll( void ) void pcan_usb_poll(void)
{ {
HAL_PCD_IRQHandler( &hpcd_USB_FS ); HAL_PCD_IRQHandler(&hpcd_USB_FS);
} }
static uint8_t device_setup( USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req ) static uint8_t device_setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{ {
switch( req->bRequest ) switch (req->bRequest)
{ {
/* get info */ /* get info */
case 0: case 0:
switch( req->wValue ) switch (req->wValue)
{ {
case 0: /* bootloader info */ case 0: /* bootloader info */
{ {
static const uint8_t bootloader_info[] = { static const uint8_t bootloader_info[] = { 0x00, 0x00, 0x08, 0x04, 0x00, 0x08, 0x07, 0x00, 0x04, 0x02, 0xe0, 0x07, 0x01, 0x00, 0x00, 0x00 };
0x00, 0x00, 0x08, 0x04, 0x00, 0x08, 0x07, 0x00, USBD_CtlSendData(pdev, (void *)bootloader_info, sizeof(bootloader_info));
0x04, 0x02, 0xe0, 0x07, 0x01, 0x00, 0x00, 0x00
};
USBD_CtlSendData( pdev, (void*)bootloader_info, sizeof( bootloader_info ) );
pcan_led_set_mode( LED_CH0_RX, LED_MODE_ON, 0 ); pcan_led_set_mode(LED_CH0_RX, LED_MODE_ON, 0);
pcan_led_set_mode( LED_CH0_TX, LED_MODE_ON, 0 ); pcan_led_set_mode(LED_CH0_TX, LED_MODE_ON, 0);
/* reset endpoints */ /* reset endpoints */
pcan_flush_ep( PCAN_USB_EP_MSGIN ); pcan_flush_ep(PCAN_USB_EP_MSGIN);
pcan_flush_ep( PCAN_USB_EP_CMDIN ); pcan_flush_ep(PCAN_USB_EP_CMDIN);
} }
break; break;
} }
break; break;
} }
return USBD_OK; return USBD_OK;
} }
static uint8_t device_ep0_rx_ready( USBD_HandleTypeDef *pdev ) static uint8_t device_ep0_rx_ready(USBD_HandleTypeDef *pdev)
{ {
UNUSED( pdev ); UNUSED(pdev);
return USBD_OK; return USBD_OK;
} }
/* data was sent to PC */ /* data was sent to PC */
static uint8_t device_data_in( USBD_HandleTypeDef *pdev, uint8_t epnum ) static uint8_t device_data_in(USBD_HandleTypeDef *pdev, uint8_t epnum)
{ {
struct t_class_data *p_data = (void*)pdev->pClassData; struct t_class_data *p_data = (void *)pdev->pClassData;
if( pdev->pClassData == 0 ) if (pdev->pClassData == 0)
return USBD_FAIL; return USBD_FAIL;
/* use ZLP */ /* use ZLP */
#if 0 #if 0
@ -258,165 +252,161 @@ static uint8_t device_data_in( USBD_HandleTypeDef *pdev, uint8_t epnum )
p_data->ep_tx_in_use[epnum] = 0; p_data->ep_tx_in_use[epnum] = 0;
} }
#else #else
pdev->ep_in[epnum].total_length = 0U; pdev->ep_in[epnum].total_length = 0U;
p_data->ep_tx_in_use[epnum] = 0; p_data->ep_tx_in_use[epnum] = 0;
#endif #endif
return USBD_OK; return USBD_OK;
} }
/* data was received from PC */ /* data was received from PC */
static uint8_t device_data_out( USBD_HandleTypeDef *pdev, uint8_t epnum ) static uint8_t device_data_out(USBD_HandleTypeDef *pdev, uint8_t epnum)
{ {
int size; int size;
if( pdev->pClassData == 0 ) if (pdev->pClassData == 0)
return USBD_FAIL; return USBD_FAIL;
size = USBD_LL_GetRxDataSize( pdev, epnum ); size = USBD_LL_GetRxDataSize(pdev, epnum);
(void)size; (void)size;
if( epnum == PCAN_USB_EP_CMDOUT ) if (epnum == PCAN_USB_EP_CMDOUT)
{
pcan_protocol_process_command( pcan_data.buffer_cmd, size );
USBD_LL_PrepareReceive( pdev, PCAN_USB_EP_CMDOUT, pcan_data.buffer_cmd, sizeof( pcan_data.buffer_cmd ) );
}
else if( epnum == PCAN_USB_EP_MSGOUT )
{
pcan_protocol_process_data( pcan_data.buffer_data, size );
USBD_LL_PrepareReceive( pdev, PCAN_USB_EP_MSGOUT, pcan_data.buffer_data, sizeof( pcan_data.buffer_data ) );
}
else
{
return USBD_FAIL;
}
return USBD_OK;
}
static uint8_t *device_get_hs_cfg( uint16_t *length )
{
*length = sizeof( struct t_pcan_description );
return (void*)&pcan_usb_dev;
}
static uint8_t *device_get_fs_cfg( uint16_t *length )
{
*length = sizeof( struct t_pcan_description );
return (void*)&pcan_usb_dev;
}
static uint8_t *device_get_other_speed_cfg( uint16_t *length )
{
*length = sizeof( struct t_pcan_description );
return (void*)&pcan_usb_dev;
}
static uint8_t *device_get_device_qualifier( uint16_t *length )
{
*length = sizeof( USB_DEVICE_QUALIFIER_DESCRIPTOR );
return (void*)&dev_qua;
}
static uint8_t *device_get_user_string( USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length )
{
UNUSED( pdev );
if( index == 10 )
{
__ALIGN_BEGIN static const uint16_t vendor_descriptor[1+24] __ALIGN_END =
{ {
0x0332, pcan_protocol_process_command(pcan_data.buffer_cmd, size);
'P','E','A','K','-','S','y','s','t','e','m',' ','T','e','c','h','n','i','k',' ','G','m','b','H' USBD_LL_PrepareReceive(pdev, PCAN_USB_EP_CMDOUT, pcan_data.buffer_cmd, sizeof(pcan_data.buffer_cmd));
}; }
*length = sizeof( vendor_descriptor ); else if (epnum == PCAN_USB_EP_MSGOUT)
return (uint8_t*)vendor_descriptor; {
} pcan_protocol_process_data(pcan_data.buffer_data, size);
return 0; USBD_LL_PrepareReceive(pdev, PCAN_USB_EP_MSGOUT, pcan_data.buffer_data, sizeof(pcan_data.buffer_data));
}
else
{
return USBD_FAIL;
}
return USBD_OK;
} }
USBD_ClassTypeDef usbd_pcan = static uint8_t *device_get_hs_cfg(uint16_t *length)
{ {
.Init = device_init, *length = sizeof(struct t_pcan_description);
.DeInit = device_deinit, return (void *)&pcan_usb_dev;
.Setup = device_setup, }
.EP0_TxSent = 0,
.EP0_RxReady = device_ep0_rx_ready, static uint8_t *device_get_fs_cfg(uint16_t *length)
.DataIn = device_data_in, {
.DataOut = device_data_out, *length = sizeof(struct t_pcan_description);
.SOF = 0, return (void *)&pcan_usb_dev;
.IsoINIncomplete = 0, }
.IsoOUTIncomplete = 0,
.GetHSConfigDescriptor = device_get_hs_cfg, static uint8_t *device_get_other_speed_cfg(uint16_t *length)
.GetFSConfigDescriptor = device_get_fs_cfg, {
.GetOtherSpeedConfigDescriptor = device_get_other_speed_cfg, *length = sizeof(struct t_pcan_description);
.GetDeviceQualifierDescriptor = device_get_device_qualifier, return (void *)&pcan_usb_dev;
}
static uint8_t *device_get_device_qualifier(uint16_t *length)
{
*length = sizeof(USB_DEVICE_QUALIFIER_DESCRIPTOR);
return (void *)&dev_qua;
}
static uint8_t *device_get_user_string(USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length)
{
UNUSED(pdev);
if (index == 10)
{
__ALIGN_BEGIN static const uint16_t vendor_descriptor[1 + 24] __ALIGN_END = { 0x0332, 'P', 'E', 'A', 'K', '-', 'S', 'y', 's', 't', 'e', 'm', ' ',
'T', 'e', 'c', 'h', 'n', 'i', 'k', ' ', 'G', 'm', 'b', 'H' };
*length = sizeof(vendor_descriptor);
return (uint8_t *)vendor_descriptor;
}
return 0;
}
USBD_ClassTypeDef usbd_pcan = {
.Init = device_init,
.DeInit = device_deinit,
.Setup = device_setup,
.EP0_TxSent = 0,
.EP0_RxReady = device_ep0_rx_ready,
.DataIn = device_data_in,
.DataOut = device_data_out,
.SOF = 0,
.IsoINIncomplete = 0,
.IsoOUTIncomplete = 0,
.GetHSConfigDescriptor = device_get_hs_cfg,
.GetFSConfigDescriptor = device_get_fs_cfg,
.GetOtherSpeedConfigDescriptor = device_get_other_speed_cfg,
.GetDeviceQualifierDescriptor = device_get_device_qualifier,
#if (USBD_SUPPORT_USER_STRING_DESC == 1U) #if (USBD_SUPPORT_USER_STRING_DESC == 1U)
.GetUsrStrDescriptor = device_get_user_string, .GetUsrStrDescriptor = device_get_user_string,
#endif #endif
}; };
void pcan_usb_init( void ) void pcan_usb_init(void)
{ {
if( USBD_Init( &hUsbDeviceFS, &FS_Desc, DEVICE_FS ) != USBD_OK ) if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)
{ {
assert( 0 ); assert(0);
} }
if( USBD_RegisterClass( &hUsbDeviceFS, &usbd_pcan ) != USBD_OK ) if (USBD_RegisterClass(&hUsbDeviceFS, &usbd_pcan) != USBD_OK)
{ {
assert( 0 ); assert(0);
} }
if( USBD_Start(&hUsbDeviceFS) != USBD_OK ) if (USBD_Start(&hUsbDeviceFS) != USBD_OK)
{ {
assert( 0 ); assert(0);
} }
} }
int pcan_flush_ep( uint8_t ep ) int pcan_flush_ep(uint8_t ep)
{ {
USBD_HandleTypeDef *pdev = &hUsbDeviceFS; USBD_HandleTypeDef *pdev = &hUsbDeviceFS;
struct t_class_data *p_data = (void*)pdev->pClassData; struct t_class_data *p_data = (void *)pdev->pClassData;
p_data->ep_tx_in_use[ep&0x0F] = 0; p_data->ep_tx_in_use[ep & 0x0F] = 0;
return USBD_LL_FlushEP( pdev, ep ) == USBD_OK; return USBD_LL_FlushEP(pdev, ep) == USBD_OK;
} }
int pcan_flush_data( struct t_m2h_fsm *pfsm, void *src, int size ) int pcan_flush_data(struct t_m2h_fsm *pfsm, void *src, int size)
{ {
USBD_HandleTypeDef *pdev = &hUsbDeviceFS; USBD_HandleTypeDef *pdev = &hUsbDeviceFS;
struct t_class_data *p_data = (void*)pdev->pClassData; struct t_class_data *p_data = (void *)pdev->pClassData;
if( !p_data ) if (!p_data)
return 0;
switch( pfsm->state )
{
case 1:
if( p_data->ep_tx_in_use[pfsm->ep_addr&0x0F] )
{
p_data->ep_tx_data_pending[pfsm->ep_addr&0x0F] = size;
return 0; return 0;
}
pfsm->state = 0;
/* fall through */
case 0:
assert( p_data->ep_tx_in_use[pfsm->ep_addr&0x0F] == 0 );
if( size > pfsm->dbsize )
break;
memcpy( pfsm->pdbuf, src, size );
p_data->ep_tx_in_use[pfsm->ep_addr&0x0F] = 1;
/* prepare data transmit */
pdev->ep_in[pfsm->ep_addr & EP_ADDR_MSK].total_length = size;
/* no pending data */
p_data->ep_tx_data_pending[pfsm->ep_addr&0x0F] = 0;
USBD_LL_Transmit( pdev, pfsm->ep_addr, pfsm->pdbuf, size );
pfsm->total_tx += size; switch (pfsm->state)
pfsm->state = 1; {
return 1; case 1:
} if (p_data->ep_tx_in_use[pfsm->ep_addr & 0x0F])
{
p_data->ep_tx_data_pending[pfsm->ep_addr & 0x0F] = size;
return 0;
}
pfsm->state = 0;
/* fall through */
case 0:
assert(p_data->ep_tx_in_use[pfsm->ep_addr & 0x0F] == 0);
if (size > pfsm->dbsize)
break;
memcpy(pfsm->pdbuf, src, size);
p_data->ep_tx_in_use[pfsm->ep_addr & 0x0F] = 1;
/* prepare data transmit */
pdev->ep_in[pfsm->ep_addr & EP_ADDR_MSK].total_length = size;
/* no pending data */
p_data->ep_tx_data_pending[pfsm->ep_addr & 0x0F] = 0;
USBD_LL_Transmit(pdev, pfsm->ep_addr, pfsm->pdbuf, size);
return 0; pfsm->total_tx += size;
pfsm->state = 1;
return 1;
}
return 0;
} }

View File

@ -2,33 +2,32 @@
#include <stdint.h> #include <stdint.h>
/* PCAN-USB Endpoints */ /* PCAN-USB Endpoints */
#define PCAN_USB_EP_CMDOUT 0x01 #define PCAN_USB_EP_CMDOUT 0x01
#define PCAN_USB_EP_CMDIN 0x81 #define PCAN_USB_EP_CMDIN 0x81
#define PCAN_USB_EP_MSGOUT 0x02 #define PCAN_USB_EP_MSGOUT 0x02
#define PCAN_USB_EP_MSGIN 0x82 #define PCAN_USB_EP_MSGIN 0x82
struct t_class_data struct t_class_data
{ {
uint16_t ep_tx_data_pending[15]; uint16_t ep_tx_data_pending[15];
uint8_t ep_tx_in_use[15]; uint8_t ep_tx_in_use[15];
uint8_t buffer_cmd[16]; uint8_t buffer_cmd[16];
uint8_t buffer_data[64]; uint8_t buffer_data[64];
}; };
struct t_m2h_fsm struct t_m2h_fsm
{ {
uint8_t state; uint8_t state;
uint8_t ep_addr; uint8_t ep_addr;
uint8_t *pdbuf; uint8_t *pdbuf;
int dbsize; int dbsize;
uint32_t total_tx; uint32_t total_tx;
}; };
int pcan_flush_ep( uint8_t ep ); int pcan_flush_ep(uint8_t ep);
int pcan_flush_data( struct t_m2h_fsm *pfsm, void *src, int size ); int pcan_flush_data(struct t_m2h_fsm *pfsm, void *src, int size);
uint16_t pcan_usb_send_command_buffer( const void *p, uint16_t size );
uint16_t pcan_usb_send_data_buffer( const void *p, uint16_t size );
void pcan_usb_init( void );
void pcan_usb_poll( void );
uint16_t pcan_usb_send_command_buffer(const void *p, uint16_t size);
uint16_t pcan_usb_send_data_buffer(const void *p, uint16_t size);
void pcan_usb_init(void);
void pcan_usb_poll(void);

View File

@ -2,19 +2,19 @@
#include "io_macro.h" #include "io_macro.h"
#if (defined CANABLE) || (defined ENTREE) || (defined CANTACT_8 ) || (defined CANTACT_16 ) #if (defined CANABLE) || (defined ENTREE) || (defined CANTACT_8) || (defined CANTACT_16)
#define IOPIN_TX A, 1, MODE_OUTPUT_PP, NOPULL, SPEED_FREQ_MEDIUM, NOAF #define IOPIN_TX A, 1, MODE_OUTPUT_PP, NOPULL, SPEED_FREQ_MEDIUM, NOAF
#define IOPIN_RX A, 0, MODE_OUTPUT_PP, NOPULL, SPEED_FREQ_MEDIUM, NOAF #define IOPIN_RX A, 0, MODE_OUTPUT_PP, NOPULL, SPEED_FREQ_MEDIUM, NOAF
#define LED_ON PIN_HI #define LED_ON PIN_HI
#define LED_OFF PIN_LOW #define LED_OFF PIN_LOW
#define CAN_RX B, 8, MODE_AF_PP, NOPULL, SPEED_FREQ_HIGH, AF4_CAN #define CAN_RX B, 8, MODE_AF_PP, NOPULL, SPEED_FREQ_HIGH, AF4_CAN
#define CAN_TX B, 9, MODE_AF_PP, NOPULL, SPEED_FREQ_HIGH, AF4_CAN #define CAN_TX B, 9, MODE_AF_PP, NOPULL, SPEED_FREQ_HIGH, AF4_CAN
#define pcan_variant_io_init() #define pcan_variant_io_init()
#elif (defined OLLIE) #elif (defined OLLIE)
#define CAN_RX B, 8, MODE_AF_PP, NOPULL, SPEED_FREQ_HIGH, AF4_CAN #define CAN_RX B, 8, MODE_AF_PP, NOPULL, SPEED_FREQ_HIGH, AF4_CAN
#define CAN_TX B, 9, MODE_AF_PP, NOPULL, SPEED_FREQ_HIGH, AF4_CAN #define CAN_TX B, 9, MODE_AF_PP, NOPULL, SPEED_FREQ_HIGH, AF4_CAN
#define pcan_variant_io_init() #define pcan_variant_io_init()
#else #else

View File

@ -1,34 +1,34 @@
#pragma once #pragma once
#define unpack_u8( ptr ) ( ((uint8_t*)(ptr))[0] ) #define unpack_u8(ptr) (((uint8_t *)(ptr))[0])
#define unpack_u16( ptr ) (\ #define unpack_u16(ptr) ((((uint8_t *)(ptr))[1] << 8) | (((uint8_t *)(ptr))[0]))
( ((uint8_t*)(ptr))[1] << 8 ) |\ #define unpack_u32(ptr) ((((uint8_t *)ptr)[3] << 24) | (((uint8_t *)ptr)[2] << 16) | (((uint8_t *)ptr)[1] << 8) | (((uint8_t *)ptr)[0]))
( ((uint8_t*)(ptr))[0] ) )
#define unpack_u32( ptr ) (\
( ((uint8_t*)ptr)[3] << 24 ) |\
( ((uint8_t*)ptr)[2] << 16 ) |\
( ((uint8_t*)ptr)[1] << 8 ) |\
( ((uint8_t*)ptr)[0] ) )
#define unpack_float( ptr ) *(float*)(uint32_t[]){ unpack_u32( ptr ) } #define unpack_float(ptr) \
*(float *)(uint32_t[]) \
{ \
unpack_u32(ptr) \
}
#define pack_u8( ptr, data ) ( ((uint8_t*)(ptr))[0] = ( data ) ) #define pack_u8(ptr, data) (((uint8_t *)(ptr))[0] = (data))
#define pack_u16( ptr, data ) do{ \ #define pack_u16(ptr, data) \
((uint8_t*)(ptr))[0] = (data)&0xFF;\ do { \
((uint8_t*)(ptr))[1] = ((data)>>8)&0xFF;\ ((uint8_t *)(ptr))[0] = (data)&0xFF; \
}while(0) ((uint8_t *)(ptr))[1] = ((data) >> 8) & 0xFF; \
} while (0)
#define pack_u24( ptr, data ) do{ \ #define pack_u24(ptr, data) \
(uint8_t*)(ptr)[0] = (data)& 0xFF; \ do { \
(uint8_t*)(ptr)[1] = ( ( data ) >> 8 ) & 0xFF; \ (uint8_t *)(ptr)[0] = (data)&0xFF; \
(uint8_t*)(ptr)[2] = ( ( data ) >> 16 ) & 0xFF; \ (uint8_t *)(ptr)[1] = ((data) >> 8) & 0xFF; \
}while( 0 ) (uint8_t *)(ptr)[2] = ((data) >> 16) & 0xFF; \
} while (0)
#define pack_u32( _xptr, _xdata ) do{ \
((uint8_t*)(_xptr))[0] = (_xdata)&0xFF;\
((uint8_t*)(_xptr))[1] = ((_xdata)>>8)&0xFF;\
((uint8_t*)(_xptr))[2] = ((_xdata)>>16)&0xFF;\
((uint8_t*)(_xptr))[3] = ((_xdata)>>24)&0xFF;\
}while(0)
#define pack_u32(_xptr, _xdata) \
do { \
((uint8_t *)(_xptr))[0] = (_xdata)&0xFF; \
((uint8_t *)(_xptr))[1] = ((_xdata) >> 8) & 0xFF; \
((uint8_t *)(_xptr))[2] = ((_xdata) >> 16) & 0xFF; \
((uint8_t *)(_xptr))[3] = ((_xdata) >> 24) & 0xFF; \
} while (0)

View File

@ -1,12 +1,12 @@
#pragma once #pragma once
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define HAL_MODULE_ENABLED #define HAL_MODULE_ENABLED
/*#define HAL_ADC_MODULE_ENABLED */ /*#define HAL_ADC_MODULE_ENABLED */
/*#define HAL_CRYP_MODULE_ENABLED */ /*#define HAL_CRYP_MODULE_ENABLED */
#define HAL_CAN_MODULE_ENABLED #define HAL_CAN_MODULE_ENABLED
/*#define HAL_CEC_MODULE_ENABLED */ /*#define HAL_CEC_MODULE_ENABLED */
@ -40,231 +40,233 @@
/* #define HAL_I2C_MODULE_ENABLED */ /* #define HAL_I2C_MODULE_ENABLED */
#if !defined (HSE_VALUE) #if !defined(HSE_VALUE)
#define HSE_VALUE ((uint32_t)16000000) /*!< Value of the External oscillator in Hz */ #define HSE_VALUE ((uint32_t)16000000) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */ #endif /* HSE_VALUE */
#if !defined (HSE_STARTUP_TIMEOUT) #if !defined(HSE_STARTUP_TIMEOUT)
#define HSE_STARTUP_TIMEOUT ((uint32_t)100) /*!< Time out for HSE start up, in ms */ #define HSE_STARTUP_TIMEOUT ((uint32_t)100) /*!< Time out for HSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */ #endif /* HSE_STARTUP_TIMEOUT */
#if !defined (HSI_VALUE) #if !defined(HSI_VALUE)
#define HSI_VALUE ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/ #define HSI_VALUE ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */ #endif /* HSI_VALUE */
#if !defined (HSI_STARTUP_TIMEOUT) #if !defined(HSI_STARTUP_TIMEOUT)
#define HSI_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for HSI start up */ #define HSI_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for HSI start up */
#endif /* HSI_STARTUP_TIMEOUT */ #endif /* HSI_STARTUP_TIMEOUT */
/** /**
* @brief Internal High Speed oscillator for ADC (HSI14) value. * @brief Internal High Speed oscillator for ADC (HSI14) value.
*/ */
#if !defined (HSI14_VALUE) #if !defined(HSI14_VALUE)
#define HSI14_VALUE ((uint32_t)14000000) /*!< Value of the Internal High Speed oscillator for ADC in Hz. #define HSI14_VALUE \
The real value may vary depending on the variations ((uint32_t)14000000) /*!< Value of the Internal High Speed oscillator for ADC in Hz. \
in voltage and temperature. */ The real value may vary depending on the variations \
#endif /* HSI14_VALUE */ in voltage and temperature. */
#endif /* HSI14_VALUE */
/** /**
* @brief Internal High Speed oscillator for USB (HSI48) value. * @brief Internal High Speed oscillator for USB (HSI48) value.
*/ */
#if !defined (HSI48_VALUE) #if !defined(HSI48_VALUE)
#define HSI48_VALUE ((uint32_t)48000000) /*!< Value of the Internal High Speed oscillator for USB in Hz. #define HSI48_VALUE \
The real value may vary depending on the variations ((uint32_t)48000000) /*!< Value of the Internal High Speed oscillator for USB in Hz. \
in voltage and temperature. */ The real value may vary depending on the variations \
#endif /* HSI48_VALUE */ in voltage and temperature. */
#endif /* HSI48_VALUE */
/** /**
* @brief Internal Low Speed oscillator (LSI) value. * @brief Internal Low Speed oscillator (LSI) value.
*/ */
#if !defined (LSI_VALUE) #if !defined(LSI_VALUE)
#define LSI_VALUE ((uint32_t)40000) #define LSI_VALUE ((uint32_t)40000)
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz \
The real value may vary depending on the variations The real value may vary depending on the variations \
in voltage and temperature. */ in voltage and temperature. */
/** /**
* @brief External Low Speed oscillator (LSI) value. * @brief External Low Speed oscillator (LSI) value.
*/ */
#if !defined (LSE_VALUE) #if !defined(LSE_VALUE)
#define LSE_VALUE ((uint32_t)32768) /*!< Value of the External Low Speed oscillator in Hz */ #define LSE_VALUE ((uint32_t)32768) /*!< Value of the External Low Speed oscillator in Hz */
#endif /* LSE_VALUE */ #endif /* LSE_VALUE */
#if !defined (LSE_STARTUP_TIMEOUT) #if !defined(LSE_STARTUP_TIMEOUT)
#define LSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for LSE start up, in ms */ #define LSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for LSE start up, in ms */
#endif /* LSE_STARTUP_TIMEOUT */ #endif /* LSE_STARTUP_TIMEOUT */
/* Tip: To avoid modifying this file each time you need to use different HSE, /* Tip: To avoid modifying this file each time you need to use different HSE,
=== you can define the HSE value in your toolchain compiler preprocessor. */ === you can define the HSE value in your toolchain compiler preprocessor. */
/* ########################### System Configuration ######################### */ /* ########################### System Configuration ######################### */
/** /**
* @brief This is the HAL system configuration section * @brief This is the HAL system configuration section
*/ */
#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */ #define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */
#define TICK_INT_PRIORITY ((uint32_t)0) /*!< tick interrupt priority (lowest by default) */ #define TICK_INT_PRIORITY ((uint32_t)0) /*!< tick interrupt priority (lowest by default) */
/* Warning: Must be set to higher priority for HAL_Delay() */ /* Warning: Must be set to higher priority for HAL_Delay() */
/* and HAL_GetTick() usage under interrupt context */ /* and HAL_GetTick() usage under interrupt context */
#define USE_RTOS 0 #define USE_RTOS 0
#define PREFETCH_ENABLE 1 #define PREFETCH_ENABLE 1
#define INSTRUCTION_CACHE_ENABLE 0 #define INSTRUCTION_CACHE_ENABLE 0
#define DATA_CACHE_ENABLE 0 #define DATA_CACHE_ENABLE 0
#define USE_SPI_CRC 0U #define USE_SPI_CRC 0U
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ #define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ #define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */
#define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ #define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */
#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ #define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */
#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ #define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */
#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ #define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */
#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ #define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */
#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ #define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ #define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ #define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ #define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ #define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ #define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ #define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ #define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
#define USE_HAL_TSC_REGISTER_CALLBACKS 0U /* TSC register callback disabled */ #define USE_HAL_TSC_REGISTER_CALLBACKS 0U /* TSC register callback disabled */
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ #define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */
/* ########################## Assert Selection ############################## */ /* ########################## Assert Selection ############################## */
/** /**
* @brief Uncomment the line below to expanse the "assert_param" macro in the * @brief Uncomment the line below to expanse the "assert_param" macro in the
* HAL drivers code * HAL drivers code
*/ */
/* #define USE_FULL_ASSERT 1U */ /* #define USE_FULL_ASSERT 1U */
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
/** /**
* @brief Include module's header file * @brief Include module's header file
*/ */
#ifdef HAL_RCC_MODULE_ENABLED #ifdef HAL_RCC_MODULE_ENABLED
#include "stm32f0xx_hal_rcc.h" #include "stm32f0xx_hal_rcc.h"
#endif /* HAL_RCC_MODULE_ENABLED */ #endif /* HAL_RCC_MODULE_ENABLED */
#ifdef HAL_GPIO_MODULE_ENABLED #ifdef HAL_GPIO_MODULE_ENABLED
#include "stm32f0xx_hal_gpio.h" #include "stm32f0xx_hal_gpio.h"
#endif /* HAL_GPIO_MODULE_ENABLED */ #endif /* HAL_GPIO_MODULE_ENABLED */
#ifdef HAL_EXTI_MODULE_ENABLED #ifdef HAL_EXTI_MODULE_ENABLED
#include "stm32f0xx_hal_exti.h" #include "stm32f0xx_hal_exti.h"
#endif /* HAL_EXTI_MODULE_ENABLED */ #endif /* HAL_EXTI_MODULE_ENABLED */
#ifdef HAL_DMA_MODULE_ENABLED #ifdef HAL_DMA_MODULE_ENABLED
#include "stm32f0xx_hal_dma.h" #include "stm32f0xx_hal_dma.h"
#endif /* HAL_DMA_MODULE_ENABLED */ #endif /* HAL_DMA_MODULE_ENABLED */
#ifdef HAL_CORTEX_MODULE_ENABLED #ifdef HAL_CORTEX_MODULE_ENABLED
#include "stm32f0xx_hal_cortex.h" #include "stm32f0xx_hal_cortex.h"
#endif /* HAL_CORTEX_MODULE_ENABLED */ #endif /* HAL_CORTEX_MODULE_ENABLED */
#ifdef HAL_ADC_MODULE_ENABLED #ifdef HAL_ADC_MODULE_ENABLED
#include "stm32f0xx_hal_adc.h" #include "stm32f0xx_hal_adc.h"
#endif /* HAL_ADC_MODULE_ENABLED */ #endif /* HAL_ADC_MODULE_ENABLED */
#ifdef HAL_CAN_MODULE_ENABLED #ifdef HAL_CAN_MODULE_ENABLED
#include "stm32f0xx_hal_can.h" #include "stm32f0xx_hal_can.h"
#endif /* HAL_CAN_MODULE_ENABLED */ #endif /* HAL_CAN_MODULE_ENABLED */
#ifdef HAL_CEC_MODULE_ENABLED #ifdef HAL_CEC_MODULE_ENABLED
#include "stm32f0xx_hal_cec.h" #include "stm32f0xx_hal_cec.h"
#endif /* HAL_CEC_MODULE_ENABLED */ #endif /* HAL_CEC_MODULE_ENABLED */
#ifdef HAL_COMP_MODULE_ENABLED #ifdef HAL_COMP_MODULE_ENABLED
#include "stm32f0xx_hal_comp.h" #include "stm32f0xx_hal_comp.h"
#endif /* HAL_COMP_MODULE_ENABLED */ #endif /* HAL_COMP_MODULE_ENABLED */
#ifdef HAL_CRC_MODULE_ENABLED #ifdef HAL_CRC_MODULE_ENABLED
#include "stm32f0xx_hal_crc.h" #include "stm32f0xx_hal_crc.h"
#endif /* HAL_CRC_MODULE_ENABLED */ #endif /* HAL_CRC_MODULE_ENABLED */
#ifdef HAL_DAC_MODULE_ENABLED #ifdef HAL_DAC_MODULE_ENABLED
#include "stm32f0xx_hal_dac.h" #include "stm32f0xx_hal_dac.h"
#endif /* HAL_DAC_MODULE_ENABLED */ #endif /* HAL_DAC_MODULE_ENABLED */
#ifdef HAL_FLASH_MODULE_ENABLED #ifdef HAL_FLASH_MODULE_ENABLED
#include "stm32f0xx_hal_flash.h" #include "stm32f0xx_hal_flash.h"
#endif /* HAL_FLASH_MODULE_ENABLED */ #endif /* HAL_FLASH_MODULE_ENABLED */
#ifdef HAL_I2C_MODULE_ENABLED #ifdef HAL_I2C_MODULE_ENABLED
#include "stm32f0xx_hal_i2c.h" #include "stm32f0xx_hal_i2c.h"
#endif /* HAL_I2C_MODULE_ENABLED */ #endif /* HAL_I2C_MODULE_ENABLED */
#ifdef HAL_I2S_MODULE_ENABLED #ifdef HAL_I2S_MODULE_ENABLED
#include "stm32f0xx_hal_i2s.h" #include "stm32f0xx_hal_i2s.h"
#endif /* HAL_I2S_MODULE_ENABLED */ #endif /* HAL_I2S_MODULE_ENABLED */
#ifdef HAL_IRDA_MODULE_ENABLED #ifdef HAL_IRDA_MODULE_ENABLED
#include "stm32f0xx_hal_irda.h" #include "stm32f0xx_hal_irda.h"
#endif /* HAL_IRDA_MODULE_ENABLED */ #endif /* HAL_IRDA_MODULE_ENABLED */
#ifdef HAL_IWDG_MODULE_ENABLED #ifdef HAL_IWDG_MODULE_ENABLED
#include "stm32f0xx_hal_iwdg.h" #include "stm32f0xx_hal_iwdg.h"
#endif /* HAL_IWDG_MODULE_ENABLED */ #endif /* HAL_IWDG_MODULE_ENABLED */
#ifdef HAL_PCD_MODULE_ENABLED #ifdef HAL_PCD_MODULE_ENABLED
#include "stm32f0xx_hal_pcd.h" #include "stm32f0xx_hal_pcd.h"
#endif /* HAL_PCD_MODULE_ENABLED */ #endif /* HAL_PCD_MODULE_ENABLED */
#ifdef HAL_PWR_MODULE_ENABLED #ifdef HAL_PWR_MODULE_ENABLED
#include "stm32f0xx_hal_pwr.h" #include "stm32f0xx_hal_pwr.h"
#endif /* HAL_PWR_MODULE_ENABLED */ #endif /* HAL_PWR_MODULE_ENABLED */
#ifdef HAL_RTC_MODULE_ENABLED #ifdef HAL_RTC_MODULE_ENABLED
#include "stm32f0xx_hal_rtc.h" #include "stm32f0xx_hal_rtc.h"
#endif /* HAL_RTC_MODULE_ENABLED */ #endif /* HAL_RTC_MODULE_ENABLED */
#ifdef HAL_SMARTCARD_MODULE_ENABLED #ifdef HAL_SMARTCARD_MODULE_ENABLED
#include "stm32f0xx_hal_smartcard.h" #include "stm32f0xx_hal_smartcard.h"
#endif /* HAL_SMARTCARD_MODULE_ENABLED */ #endif /* HAL_SMARTCARD_MODULE_ENABLED */
#ifdef HAL_SMBUS_MODULE_ENABLED #ifdef HAL_SMBUS_MODULE_ENABLED
#include "stm32f0xx_hal_smbus.h" #include "stm32f0xx_hal_smbus.h"
#endif /* HAL_SMBUS_MODULE_ENABLED */ #endif /* HAL_SMBUS_MODULE_ENABLED */
#ifdef HAL_SPI_MODULE_ENABLED #ifdef HAL_SPI_MODULE_ENABLED
#include "stm32f0xx_hal_spi.h" #include "stm32f0xx_hal_spi.h"
#endif /* HAL_SPI_MODULE_ENABLED */ #endif /* HAL_SPI_MODULE_ENABLED */
#ifdef HAL_TIM_MODULE_ENABLED #ifdef HAL_TIM_MODULE_ENABLED
#include "stm32f0xx_hal_tim.h" #include "stm32f0xx_hal_tim.h"
#endif /* HAL_TIM_MODULE_ENABLED */ #endif /* HAL_TIM_MODULE_ENABLED */
#ifdef HAL_TSC_MODULE_ENABLED #ifdef HAL_TSC_MODULE_ENABLED
#include "stm32f0xx_hal_tsc.h" #include "stm32f0xx_hal_tsc.h"
#endif /* HAL_TSC_MODULE_ENABLED */ #endif /* HAL_TSC_MODULE_ENABLED */
#ifdef HAL_UART_MODULE_ENABLED #ifdef HAL_UART_MODULE_ENABLED
#include "stm32f0xx_hal_uart.h" #include "stm32f0xx_hal_uart.h"
#endif /* HAL_UART_MODULE_ENABLED */ #endif /* HAL_UART_MODULE_ENABLED */
#ifdef HAL_USART_MODULE_ENABLED #ifdef HAL_USART_MODULE_ENABLED
#include "stm32f0xx_hal_usart.h" #include "stm32f0xx_hal_usart.h"
#endif /* HAL_USART_MODULE_ENABLED */ #endif /* HAL_USART_MODULE_ENABLED */
#ifdef HAL_WWDG_MODULE_ENABLED #ifdef HAL_WWDG_MODULE_ENABLED
#include "stm32f0xx_hal_wwdg.h" #include "stm32f0xx_hal_wwdg.h"
#endif /* HAL_WWDG_MODULE_ENABLED */ #endif /* HAL_WWDG_MODULE_ENABLED */
/* Exported macro ------------------------------------------------------------*/ /* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT #ifdef USE_FULL_ASSERT
/** /**
* @brief The assert_param macro is used for function's parameters check. * @brief The assert_param macro is used for function's parameters check.
* @param expr If expr is false, it calls assert_failed function * @param expr If expr is false, it calls assert_failed function
* which reports the name of the source file and the source * which reports the name of the source file and the source
* line number of the call that failed. * line number of the call that failed.
* If expr is true, it returns no value. * If expr is true, it returns no value.
* @retval None * @retval None
*/ */
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */ /* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line); void assert_failed(uint8_t *file, uint32_t line);
#else #else
#define assert_param(expr) ((void)0U) #define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */ #endif /* USE_FULL_ASSERT */
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,265 +1,266 @@
/** /**
****************************************************************************** ******************************************************************************
* @file system_stm32f0xx.c * @file system_stm32f0xx.c
* @author MCD Application Team * @author MCD Application Team
* @brief CMSIS Cortex-M0 Device Peripheral Access Layer System Source File. * @brief CMSIS Cortex-M0 Device Peripheral Access Layer System Source File.
* *
* 1. This file provides two functions and one global variable to be called from * 1. This file provides two functions and one global variable to be called from
* user application: * user application:
* - SystemInit(): This function is called at startup just after reset and * - SystemInit(): This function is called at startup just after reset and
* before branch to main program. This call is made inside * before branch to main program. This call is made inside
* the "startup_stm32f0xx.s" file. * the "startup_stm32f0xx.s" file.
* *
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick * by the user application to setup the SysTick
* timer or configure other parameters. * timer or configure other parameters.
* *
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed * be called whenever the core clock is changed
* during program execution. * during program execution.
* *
* 2. After each device reset the HSI (8 MHz) is used as system clock source. * 2. After each device reset the HSI (8 MHz) is used as system clock source.
* Then SystemInit() function is called, in "startup_stm32f0xx.s" file, to * Then SystemInit() function is called, in "startup_stm32f0xx.s" file, to
* configure the system clock before to branch to main program. * configure the system clock before to branch to main program.
* *
* 3. This file configures the system clock as follows: * 3. This file configures the system clock as follows:
*============================================================================= *=============================================================================
* Supported STM32F0xx device * Supported STM32F0xx device
*----------------------------------------------------------------------------- *-----------------------------------------------------------------------------
* System Clock source | HSI * System Clock source | HSI
*----------------------------------------------------------------------------- *-----------------------------------------------------------------------------
* SYSCLK(Hz) | 8000000 * SYSCLK(Hz) | 8000000
*----------------------------------------------------------------------------- *-----------------------------------------------------------------------------
* HCLK(Hz) | 8000000 * HCLK(Hz) | 8000000
*----------------------------------------------------------------------------- *-----------------------------------------------------------------------------
* AHB Prescaler | 1 * AHB Prescaler | 1
*----------------------------------------------------------------------------- *-----------------------------------------------------------------------------
* APB1 Prescaler | 1 * APB1 Prescaler | 1
*----------------------------------------------------------------------------- *-----------------------------------------------------------------------------
*============================================================================= *=============================================================================
****************************************************************************** ******************************************************************************
* @attention * @attention
* *
* <h2><center>&copy; Copyright (c) 2016 STMicroelectronics. * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
* All rights reserved.</center></h2> * All rights reserved.</center></h2>
* *
* This software component is licensed by ST under BSD 3-Clause license, * This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the * the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at: * License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause * opensource.org/licenses/BSD-3-Clause
* *
****************************************************************************** ******************************************************************************
*/ */
/** @addtogroup CMSIS /** @addtogroup CMSIS
* @{ * @{
*/ */
/** @addtogroup stm32f0xx_system /** @addtogroup stm32f0xx_system
* @{ * @{
*/ */
/** @addtogroup STM32F0xx_System_Private_Includes /** @addtogroup STM32F0xx_System_Private_Includes
* @{ * @{
*/ */
#include "stm32f0xx.h" #include "stm32f0xx.h"
/** /**
* @} * @}
*/ */
/** @addtogroup STM32F0xx_System_Private_TypesDefinitions /** @addtogroup STM32F0xx_System_Private_TypesDefinitions
* @{ * @{
*/ */
/** /**
* @} * @}
*/ */
/** @addtogroup STM32F0xx_System_Private_Defines /** @addtogroup STM32F0xx_System_Private_Defines
* @{ * @{
*/ */
#if !defined (HSE_VALUE) #if !defined(HSE_VALUE)
#define HSE_VALUE ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz. #define HSE_VALUE \
This value can be provided and adapted by the user application. */ ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz. \
#endif /* HSE_VALUE */ This value can be provided and adapted by the user application. */
#endif /* HSE_VALUE */
#if !defined (HSI_VALUE) #if !defined(HSI_VALUE)
#define HSI_VALUE ((uint32_t)8000000) /*!< Default value of the Internal oscillator in Hz. #define HSI_VALUE \
This value can be provided and adapted by the user application. */ ((uint32_t)8000000) /*!< Default value of the Internal oscillator in Hz. \
#endif /* HSI_VALUE */ This value can be provided and adapted by the user application. */
#endif /* HSI_VALUE */
#if !defined (HSI48_VALUE) #if !defined(HSI48_VALUE)
#define HSI48_VALUE ((uint32_t)48000000) /*!< Default value of the HSI48 Internal oscillator in Hz. #define HSI48_VALUE \
This value can be provided and adapted by the user application. */ ((uint32_t)48000000) /*!< Default value of the HSI48 Internal oscillator in Hz. \
#endif /* HSI48_VALUE */ This value can be provided and adapted by the user application. */
#endif /* HSI48_VALUE */
/** /**
* @} * @}
*/ */
/** @addtogroup STM32F0xx_System_Private_Macros /** @addtogroup STM32F0xx_System_Private_Macros
* @{ * @{
*/ */
/** /**
* @} * @}
*/ */
/** @addtogroup STM32F0xx_System_Private_Variables /** @addtogroup STM32F0xx_System_Private_Variables
* @{ * @{
*/ */
/* This variable is updated in three ways: /* This variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate() 1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetHCLKFreq() 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
Note: If you use this function to configure the system clock there is no need to Note: If you use this function to configure the system clock there is no need to
call the 2 first functions listed above, since SystemCoreClock variable is call the 2 first functions listed above, since SystemCoreClock variable is
updated automatically. updated automatically.
*/ */
uint32_t SystemCoreClock = 8000000; uint32_t SystemCoreClock = 8000000;
const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; const uint8_t AHBPrescTable[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9 };
const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4}; const uint8_t APBPrescTable[8] = { 0, 0, 0, 0, 1, 2, 3, 4 };
/** /**
* @} * @}
*/ */
/** @addtogroup STM32F0xx_System_Private_FunctionPrototypes /** @addtogroup STM32F0xx_System_Private_FunctionPrototypes
* @{ * @{
*/ */
/** /**
* @} * @}
*/ */
/** @addtogroup STM32F0xx_System_Private_Functions /** @addtogroup STM32F0xx_System_Private_Functions
* @{ * @{
*/ */
/** /**
* @brief Setup the microcontroller system. * @brief Setup the microcontroller system.
* @param None * @param None
* @retval None * @retval None
*/ */
void SystemInit(void) void SystemInit(void)
{ {
/* NOTE :SystemInit(): This function is called at startup just after reset and /* NOTE :SystemInit(): This function is called at startup just after reset and
before branch to main program. This call is made inside before branch to main program. This call is made inside
the "startup_stm32f0xx.s" file. the "startup_stm32f0xx.s" file.
User can setups the default system clock (System clock source, PLL Multiplier User can setups the default system clock (System clock source, PLL Multiplier
and Divider factors, AHB/APBx prescalers and Flash settings). and Divider factors, AHB/APBx prescalers and Flash settings).
*/ */
} }
/** /**
* @brief Update SystemCoreClock variable according to Clock Register Values. * @brief Update SystemCoreClock variable according to Clock Register Values.
* The SystemCoreClock variable contains the core clock (HCLK), it can * The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or configure * be used by the user application to setup the SysTick timer or configure
* other parameters. * other parameters.
* *
* @note Each time the core clock (HCLK) changes, this function must be called * @note Each time the core clock (HCLK) changes, this function must be called
* to update SystemCoreClock variable value. Otherwise, any configuration * to update SystemCoreClock variable value. Otherwise, any configuration
* based on this variable will be incorrect. * based on this variable will be incorrect.
* *
* @note - The system frequency computed by this function is not the real * @note - The system frequency computed by this function is not the real
* frequency in the chip. It is calculated based on the predefined * frequency in the chip. It is calculated based on the predefined
* constant and the selected clock source: * constant and the selected clock source:
* *
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
* *
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
* *
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
* or HSI_VALUE(*) multiplied/divided by the PLL factors. * or HSI_VALUE(*) multiplied/divided by the PLL factors.
* *
* (*) HSI_VALUE is a constant defined in stm32f0xx_hal.h file (default value * (*) HSI_VALUE is a constant defined in stm32f0xx_hal.h file (default value
* 8 MHz) but the real value may vary depending on the variations * 8 MHz) but the real value may vary depending on the variations
* in voltage and temperature. * in voltage and temperature.
* *
* (**) HSE_VALUE is a constant defined in stm32f0xx_hal.h file (default value * (**) HSE_VALUE is a constant defined in stm32f0xx_hal.h file (default value
* 8 MHz), user has to ensure that HSE_VALUE is same as the real * 8 MHz), user has to ensure that HSE_VALUE is same as the real
* frequency of the crystal used. Otherwise, this function may * frequency of the crystal used. Otherwise, this function may
* have wrong result. * have wrong result.
* *
* - The result of this function could be not correct when using fractional * - The result of this function could be not correct when using fractional
* value for HSE crystal. * value for HSE crystal.
* *
* @param None * @param None
* @retval None * @retval None
*/ */
void SystemCoreClockUpdate (void) void SystemCoreClockUpdate(void)
{ {
uint32_t tmp = 0, pllmull = 0, pllsource = 0, predivfactor = 0; uint32_t tmp = 0, pllmull = 0, pllsource = 0, predivfactor = 0;
/* Get SYSCLK source -------------------------------------------------------*/ /* Get SYSCLK source -------------------------------------------------------*/
tmp = RCC->CFGR & RCC_CFGR_SWS; tmp = RCC->CFGR & RCC_CFGR_SWS;
switch (tmp) switch (tmp)
{ {
case RCC_CFGR_SWS_HSI: /* HSI used as system clock */ case RCC_CFGR_SWS_HSI: /* HSI used as system clock */
SystemCoreClock = HSI_VALUE; SystemCoreClock = HSI_VALUE;
break; break;
case RCC_CFGR_SWS_HSE: /* HSE used as system clock */ case RCC_CFGR_SWS_HSE: /* HSE used as system clock */
SystemCoreClock = HSE_VALUE; SystemCoreClock = HSE_VALUE;
break; break;
case RCC_CFGR_SWS_PLL: /* PLL used as system clock */ case RCC_CFGR_SWS_PLL: /* PLL used as system clock */
/* Get PLL clock source and multiplication factor ----------------------*/ /* Get PLL clock source and multiplication factor ----------------------*/
pllmull = RCC->CFGR & RCC_CFGR_PLLMUL; pllmull = RCC->CFGR & RCC_CFGR_PLLMUL;
pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
pllmull = ( pllmull >> 18) + 2; pllmull = (pllmull >> 18) + 2;
predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1; predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1;
if (pllsource == RCC_CFGR_PLLSRC_HSE_PREDIV) if (pllsource == RCC_CFGR_PLLSRC_HSE_PREDIV)
{ {
/* HSE used as PLL clock source : SystemCoreClock = HSE/PREDIV * PLLMUL */ /* HSE used as PLL clock source : SystemCoreClock = HSE/PREDIV * PLLMUL */
SystemCoreClock = (HSE_VALUE/predivfactor) * pllmull; SystemCoreClock = (HSE_VALUE / predivfactor) * pllmull;
} }
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx) #if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx)
else if (pllsource == RCC_CFGR_PLLSRC_HSI48_PREDIV) else if (pllsource == RCC_CFGR_PLLSRC_HSI48_PREDIV)
{ {
/* HSI48 used as PLL clock source : SystemCoreClock = HSI48/PREDIV * PLLMUL */ /* HSI48 used as PLL clock source : SystemCoreClock = HSI48/PREDIV * PLLMUL */
SystemCoreClock = (HSI48_VALUE/predivfactor) * pllmull; SystemCoreClock = (HSI48_VALUE / predivfactor) * pllmull;
} }
#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx */ #endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx */
else else
{ {
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6) \ #if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6) || defined(STM32F078xx) || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F070xB) \
|| defined(STM32F078xx) || defined(STM32F071xB) || defined(STM32F072xB) \ || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC)
|| defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) /* HSI used as PLL clock source : SystemCoreClock = HSI/PREDIV * PLLMUL */
/* HSI used as PLL clock source : SystemCoreClock = HSI/PREDIV * PLLMUL */ SystemCoreClock = (HSI_VALUE / predivfactor) * pllmull;
SystemCoreClock = (HSI_VALUE/predivfactor) * pllmull;
#else #else
/* HSI used as PLL clock source : SystemCoreClock = HSI/2 * PLLMUL */ /* HSI used as PLL clock source : SystemCoreClock = HSI/2 * PLLMUL */
SystemCoreClock = (HSI_VALUE >> 1) * pllmull; SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
#endif /* STM32F042x6 || STM32F048xx || STM32F070x6 || #endif /* STM32F042x6 || STM32F048xx || STM32F070x6 || \
STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || \
STM32F091xC || STM32F098xx || STM32F030xC */ STM32F091xC || STM32F098xx || STM32F030xC */
} }
break; break;
default: /* HSI used as system clock */ default: /* HSI used as system clock */
SystemCoreClock = HSI_VALUE; SystemCoreClock = HSI_VALUE;
break; break;
} }
/* Compute HCLK clock frequency ----------------*/ /* Compute HCLK clock frequency ----------------*/
/* Get HCLK prescaler */ /* Get HCLK prescaler */
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
/* HCLK clock frequency */ /* HCLK clock frequency */
SystemCoreClock >>= tmp; SystemCoreClock >>= tmp;
} }
/** /**
* @} * @}
*/ */
/** /**
* @} * @}
*/ */
/** /**
* @} * @}
*/ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -1,331 +1,331 @@
#include <assert.h> #include "usbd_conf.h"
#include "stm32f0xx.h" #include "stm32f0xx.h"
#include "stm32f0xx_hal.h" #include "stm32f0xx_hal.h"
#include "usbd_def.h"
#include "usbd_core.h" #include "usbd_core.h"
#include "usbd_conf.h" #include "usbd_def.h"
#include <assert.h>
PCD_HandleTypeDef hpcd_USB_FS; PCD_HandleTypeDef hpcd_USB_FS;
void Error_Handler(void); void Error_Handler(void);
static USBD_StatusTypeDef USBD_Get_USB_Status( HAL_StatusTypeDef hal_status ); static USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status);
static void SystemClockConfig_Resume( void ); static void SystemClockConfig_Resume(void);
extern void SystemClock_Config( void ); extern void SystemClock_Config(void);
void HAL_PCD_MspInit( PCD_HandleTypeDef* pcdHandle ) void HAL_PCD_MspInit(PCD_HandleTypeDef *pcdHandle)
{ {
if( pcdHandle->Instance == USB ) if (pcdHandle->Instance == USB)
{ {
__HAL_RCC_USB_CLK_ENABLE(); __HAL_RCC_USB_CLK_ENABLE();
} }
} }
void HAL_PCD_MspDeInit( PCD_HandleTypeDef* pcdHandle ) void HAL_PCD_MspDeInit(PCD_HandleTypeDef *pcdHandle)
{ {
if( pcdHandle->Instance == USB ) if (pcdHandle->Instance == USB)
{ {
__HAL_RCC_USB_CLK_DISABLE(); __HAL_RCC_USB_CLK_DISABLE();
HAL_NVIC_DisableIRQ( USB_IRQn ); HAL_NVIC_DisableIRQ(USB_IRQn);
} }
} }
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
{ {
USBD_LL_SetupStage((USBD_HandleTypeDef*)hpcd->pData, (uint8_t *)hpcd->Setup); USBD_LL_SetupStage((USBD_HandleTypeDef *)hpcd->pData, (uint8_t *)hpcd->Setup);
} }
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{ {
USBD_LL_DataOutStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff); USBD_LL_DataOutStage((USBD_HandleTypeDef *)hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff);
} }
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{ {
USBD_LL_DataInStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff); USBD_LL_DataInStage((USBD_HandleTypeDef *)hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff);
} }
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
{ {
USBD_LL_SOF((USBD_HandleTypeDef*)hpcd->pData); USBD_LL_SOF((USBD_HandleTypeDef *)hpcd->pData);
} }
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
{ {
USBD_SpeedTypeDef speed = USBD_SPEED_FULL; USBD_SpeedTypeDef speed = USBD_SPEED_FULL;
if( hpcd->Init.speed != PCD_SPEED_FULL ) if (hpcd->Init.speed != PCD_SPEED_FULL)
{ {
assert(0); assert(0);
} }
USBD_LL_SetSpeed((USBD_HandleTypeDef*)hpcd->pData, speed); USBD_LL_SetSpeed((USBD_HandleTypeDef *)hpcd->pData, speed);
USBD_LL_Reset((USBD_HandleTypeDef*)hpcd->pData); USBD_LL_Reset((USBD_HandleTypeDef *)hpcd->pData);
} }
void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
{ {
USBD_LL_Suspend( (USBD_HandleTypeDef*)hpcd->pData ); USBD_LL_Suspend((USBD_HandleTypeDef *)hpcd->pData);
if (hpcd->Init.low_power_enable) if (hpcd->Init.low_power_enable)
{ {
/* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register. */ /* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register. */
SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
} }
} }
void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
{ {
if (hpcd->Init.low_power_enable) if (hpcd->Init.low_power_enable)
{ {
/* Reset SLEEPDEEP bit of Cortex System Control Register. */ /* Reset SLEEPDEEP bit of Cortex System Control Register. */
SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); SCB->SCR &= (uint32_t) ~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
SystemClockConfig_Resume(); SystemClockConfig_Resume();
} }
USBD_LL_Resume((USBD_HandleTypeDef*)hpcd->pData); USBD_LL_Resume((USBD_HandleTypeDef *)hpcd->pData);
} }
void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{ {
USBD_LL_IsoOUTIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum); USBD_LL_IsoOUTIncomplete((USBD_HandleTypeDef *)hpcd->pData, epnum);
} }
void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{ {
USBD_LL_IsoINIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum); USBD_LL_IsoINIncomplete((USBD_HandleTypeDef *)hpcd->pData, epnum);
} }
void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
{ {
USBD_LL_DevConnected((USBD_HandleTypeDef*)hpcd->pData); USBD_LL_DevConnected((USBD_HandleTypeDef *)hpcd->pData);
} }
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
{ {
USBD_LL_DevDisconnected((USBD_HandleTypeDef*)hpcd->pData); USBD_LL_DevDisconnected((USBD_HandleTypeDef *)hpcd->pData);
} }
USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
{ {
hpcd_USB_FS.pData = pdev; hpcd_USB_FS.pData = pdev;
pdev->pData = &hpcd_USB_FS; pdev->pData = &hpcd_USB_FS;
hpcd_USB_FS.Instance = USB; hpcd_USB_FS.Instance = USB;
hpcd_USB_FS.Init.dev_endpoints = 6; hpcd_USB_FS.Init.dev_endpoints = 6;
hpcd_USB_FS.Init.speed = PCD_SPEED_FULL; hpcd_USB_FS.Init.speed = PCD_SPEED_FULL;
hpcd_USB_FS.Init.phy_itface = PCD_PHY_EMBEDDED; hpcd_USB_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
hpcd_USB_FS.Init.low_power_enable = DISABLE; hpcd_USB_FS.Init.low_power_enable = DISABLE;
hpcd_USB_FS.Init.lpm_enable = DISABLE; hpcd_USB_FS.Init.lpm_enable = DISABLE;
hpcd_USB_FS.Init.battery_charging_enable = DISABLE; hpcd_USB_FS.Init.battery_charging_enable = DISABLE;
if( HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK ) if (HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK)
{ {
assert( 0 ); assert(0);
} }
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x18+(0*USB_FS_MAX_PACKET_SIZE)); HAL_PCDEx_PMAConfig((PCD_HandleTypeDef *)pdev->pData, 0x00, PCD_SNG_BUF, 0x18 + (0 * USB_FS_MAX_PACKET_SIZE));
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x18+(1*USB_FS_MAX_PACKET_SIZE)); HAL_PCDEx_PMAConfig((PCD_HandleTypeDef *)pdev->pData, 0x80, PCD_SNG_BUF, 0x18 + (1 * USB_FS_MAX_PACKET_SIZE));
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x01 , PCD_SNG_BUF, 0x18+(2*USB_FS_MAX_PACKET_SIZE)); HAL_PCDEx_PMAConfig((PCD_HandleTypeDef *)pdev->pData, 0x01, PCD_SNG_BUF, 0x18 + (2 * USB_FS_MAX_PACKET_SIZE));
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x81 , PCD_SNG_BUF, 0x18+(3*USB_FS_MAX_PACKET_SIZE)); HAL_PCDEx_PMAConfig((PCD_HandleTypeDef *)pdev->pData, 0x81, PCD_SNG_BUF, 0x18 + (3 * USB_FS_MAX_PACKET_SIZE));
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x02 , PCD_SNG_BUF, 0x18+(4*USB_FS_MAX_PACKET_SIZE)); HAL_PCDEx_PMAConfig((PCD_HandleTypeDef *)pdev->pData, 0x02, PCD_SNG_BUF, 0x18 + (4 * USB_FS_MAX_PACKET_SIZE));
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x82 , PCD_SNG_BUF, 0x18+(5*USB_FS_MAX_PACKET_SIZE)); HAL_PCDEx_PMAConfig((PCD_HandleTypeDef *)pdev->pData, 0x82, PCD_SNG_BUF, 0x18 + (5 * USB_FS_MAX_PACKET_SIZE));
return USBD_OK; return USBD_OK;
} }
USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev) USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev)
{ {
HAL_StatusTypeDef hal_status = HAL_OK; HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK; USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_DeInit(pdev->pData); hal_status = HAL_PCD_DeInit(pdev->pData);
usb_status = USBD_Get_USB_Status(hal_status); usb_status = USBD_Get_USB_Status(hal_status);
return usb_status; return usb_status;
} }
USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev)
{ {
HAL_StatusTypeDef hal_status = HAL_OK; HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK; USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_Start(pdev->pData); hal_status = HAL_PCD_Start(pdev->pData);
usb_status = USBD_Get_USB_Status(hal_status); usb_status = USBD_Get_USB_Status(hal_status);
return usb_status; return usb_status;
} }
USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev) USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev)
{ {
HAL_StatusTypeDef hal_status = HAL_OK; HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK; USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_Stop(pdev->pData); hal_status = HAL_PCD_Stop(pdev->pData);
usb_status = USBD_Get_USB_Status(hal_status); usb_status = USBD_Get_USB_Status(hal_status);
return usb_status; return usb_status;
} }
USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps) USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps)
{ {
HAL_StatusTypeDef hal_status = HAL_OK; HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK; USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Open(pdev->pData, ep_addr, ep_mps, ep_type); hal_status = HAL_PCD_EP_Open(pdev->pData, ep_addr, ep_mps, ep_type);
usb_status = USBD_Get_USB_Status(hal_status); usb_status = USBD_Get_USB_Status(hal_status);
return usb_status; return usb_status;
} }
USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{ {
HAL_StatusTypeDef hal_status = HAL_OK; HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK; USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Close(pdev->pData, ep_addr); hal_status = HAL_PCD_EP_Close(pdev->pData, ep_addr);
usb_status = USBD_Get_USB_Status(hal_status); usb_status = USBD_Get_USB_Status(hal_status);
return usb_status; return usb_status;
} }
USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{ {
HAL_StatusTypeDef hal_status = HAL_OK; HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK; USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Flush(pdev->pData, ep_addr); hal_status = HAL_PCD_EP_Flush(pdev->pData, ep_addr);
usb_status = USBD_Get_USB_Status(hal_status); usb_status = USBD_Get_USB_Status(hal_status);
return usb_status; return usb_status;
} }
USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{ {
HAL_StatusTypeDef hal_status = HAL_OK; HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK; USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_SetStall(pdev->pData, ep_addr); hal_status = HAL_PCD_EP_SetStall(pdev->pData, ep_addr);
usb_status = USBD_Get_USB_Status(hal_status); usb_status = USBD_Get_USB_Status(hal_status);
return usb_status; return usb_status;
} }
USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{ {
HAL_StatusTypeDef hal_status = HAL_OK; HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK; USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_ClrStall(pdev->pData, ep_addr); hal_status = HAL_PCD_EP_ClrStall(pdev->pData, ep_addr);
usb_status = USBD_Get_USB_Status(hal_status); usb_status = USBD_Get_USB_Status(hal_status);
return usb_status; return usb_status;
} }
uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{ {
PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef*) pdev->pData; PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)pdev->pData;
if((ep_addr & 0x80) == 0x80) if ((ep_addr & 0x80) == 0x80)
{ {
return hpcd->IN_ep[ep_addr & 0x7F].is_stall; return hpcd->IN_ep[ep_addr & 0x7F].is_stall;
} }
else else
{ {
return hpcd->OUT_ep[ep_addr & 0x7F].is_stall; return hpcd->OUT_ep[ep_addr & 0x7F].is_stall;
} }
} }
USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr) USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr)
{ {
HAL_StatusTypeDef hal_status = HAL_OK; HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK; USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_SetAddress(pdev->pData, dev_addr); hal_status = HAL_PCD_SetAddress(pdev->pData, dev_addr);
usb_status = USBD_Get_USB_Status(hal_status); usb_status = USBD_Get_USB_Status(hal_status);
return usb_status; return usb_status;
} }
USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint16_t size) USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint16_t size)
{ {
HAL_StatusTypeDef hal_status = HAL_OK; HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK; USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size); hal_status = HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size);
usb_status = USBD_Get_USB_Status(hal_status); usb_status = USBD_Get_USB_Status(hal_status);
return usb_status; return usb_status;
} }
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint16_t size) USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint16_t size)
{ {
HAL_StatusTypeDef hal_status = HAL_OK; HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK; USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size); hal_status = HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size);
usb_status = USBD_Get_USB_Status(hal_status); usb_status = USBD_Get_USB_Status(hal_status);
return usb_status; return usb_status;
} }
uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{ {
return HAL_PCD_EP_GetRxCount((PCD_HandleTypeDef*) pdev->pData, ep_addr); return HAL_PCD_EP_GetRxCount((PCD_HandleTypeDef *)pdev->pData, ep_addr);
} }
void USBD_LL_Delay(uint32_t Delay) void USBD_LL_Delay(uint32_t Delay)
{ {
HAL_Delay(Delay); HAL_Delay(Delay);
} }
void *USBD_static_malloc(uint32_t size) void *USBD_static_malloc(uint32_t size)
{ {
(void)size; (void)size;
return 0; return 0;
} }
void USBD_static_free(void *p) void USBD_static_free(void *p)
{ {
(void)p; (void)p;
} }
static void SystemClockConfig_Resume(void) static void SystemClockConfig_Resume(void)
{ {
SystemClock_Config(); SystemClock_Config();
} }
USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status) USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status)
{ {
USBD_StatusTypeDef usb_status = USBD_OK; USBD_StatusTypeDef usb_status = USBD_OK;
switch (hal_status) switch (hal_status)
{ {
case HAL_OK : case HAL_OK:
usb_status = USBD_OK; usb_status = USBD_OK;
break; break;
case HAL_ERROR : case HAL_ERROR:
usb_status = USBD_FAIL; usb_status = USBD_FAIL;
break; break;
case HAL_BUSY : case HAL_BUSY:
usb_status = USBD_BUSY; usb_status = USBD_BUSY;
break; break;
case HAL_TIMEOUT : case HAL_TIMEOUT:
usb_status = USBD_FAIL; usb_status = USBD_FAIL;
break; break;
default : default:
usb_status = USBD_FAIL; usb_status = USBD_FAIL;
break; break;
} }
return usb_status; return usb_status;
} }

View File

@ -1,14 +1,14 @@
#pragma once #pragma once
#include "stm32f0xx.h"
#include "stm32f0xx_hal.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "stm32f0xx.h"
#include "stm32f0xx_hal.h"
#define USBD_SUPPORT_USER_STRING_DESC (1) #define USBD_SUPPORT_USER_STRING_DESC (1)
#define USBD_DEBUG_LEVEL 0 #define USBD_DEBUG_LEVEL 0
#define DEVICE_FS 0 #define DEVICE_FS 0
extern PCD_HandleTypeDef hpcd_USB_FS; extern PCD_HandleTypeDef hpcd_USB_FS;

View File

@ -1,94 +1,84 @@
#include "usbd_core.h"
#include "usbd_conf.h" #include "usbd_conf.h"
#include "usbd_core.h"
#define USBD_VID 0x0C72 #define USBD_VID 0x0C72
#define USBD_PID_FS 0x000C #define USBD_PID_FS 0x000C
#define USBD_LANGID_STRING 1033 #define USBD_LANGID_STRING 1033
#define USBD_MAX_STR_DESC_SIZ 0x100U #define USBD_MAX_STR_DESC_SIZ 0x100U
uint8_t * USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t * USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t * USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); uint8_t *USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t * USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); uint8_t *USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t * USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); uint8_t *USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t * USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t * USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); uint8_t *USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = __ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
{ 0x12, /*bLength */
0x12, /*bLength */ USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
USB_DESC_TYPE_DEVICE, /*bDescriptorType*/ 0x00, /*bcdUSB */
0x00, /*bcdUSB */ 0x01,
0x01, 0x00, /*bDeviceClass*/
0x00, /*bDeviceClass*/ 0x00, /*bDeviceSubClass*/
0x00, /*bDeviceSubClass*/ 0x00, /*bDeviceProtocol*/
0x00, /*bDeviceProtocol*/ USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
USB_MAX_EP0_SIZE, /*bMaxPacketSize*/ LOBYTE(USBD_VID), /*idVendor*/
LOBYTE(USBD_VID), /*idVendor*/ HIBYTE(USBD_VID), /*idVendor*/
HIBYTE(USBD_VID), /*idVendor*/ LOBYTE(USBD_PID_FS), /*idProduct*/
LOBYTE(USBD_PID_FS), /*idProduct*/ HIBYTE(USBD_PID_FS), /*idProduct*/
HIBYTE(USBD_PID_FS), /*idProduct*/ 0xff, /*bcdDevice*/
0xff, /*bcdDevice*/ 0x54,
0x54, 10, /*Index of manufacturer string*/
10, /*Index of manufacturer string*/ 4, /*Index of product string*/
4, /*Index of product string*/ 0, /*Index of serial number string*/
0, /*Index of serial number string*/ USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
}; };
__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = __ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = { USB_LEN_LANGID_STR_DESC,
{ USB_DESC_TYPE_STRING,
USB_LEN_LANGID_STR_DESC, LOBYTE(USBD_LANGID_STRING),
USB_DESC_TYPE_STRING, HIBYTE(USBD_LANGID_STRING) };
LOBYTE(USBD_LANGID_STRING),
HIBYTE(USBD_LANGID_STRING)
};
uint8_t * USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{ {
UNUSED(speed); UNUSED(speed);
*length = sizeof(USBD_FS_DeviceDesc); *length = sizeof(USBD_FS_DeviceDesc);
return USBD_FS_DeviceDesc; return USBD_FS_DeviceDesc;
} }
uint8_t * USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{ {
UNUSED(speed); UNUSED(speed);
*length = sizeof(USBD_LangIDDesc); *length = sizeof(USBD_LangIDDesc);
return USBD_LangIDDesc; return USBD_LangIDDesc;
} }
/* must be here: 1, 2 */ /* must be here: 1, 2 */
uint8_t * USBD_FS_HugeStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) uint8_t *USBD_FS_HugeStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{ {
UNUSED( speed ); UNUSED(speed);
/* little hack to save some flash memory */ /* little hack to save some flash memory */
__ALIGN_BEGIN static const uint16_t huge_descriptor[1/*+126*/] __ALIGN_END = { 0x03FE }; __ALIGN_BEGIN static const uint16_t huge_descriptor[1 /*+126*/] __ALIGN_END = { 0x03FE };
*length = sizeof( huge_descriptor ); *length = sizeof(huge_descriptor);
return (uint8_t*)huge_descriptor; return (uint8_t *)huge_descriptor;
} }
uint8_t * USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{ {
UNUSED(speed); UNUSED(speed);
__ALIGN_BEGIN static const uint16_t cfg_descriptor[1+8] __ALIGN_END = __ALIGN_BEGIN static const uint16_t cfg_descriptor[1 + 8] __ALIGN_END = { 0x0312, 'P', 'C', 'A', 'N', '-', 'U', 'S', 'B' };
{ *length = sizeof(cfg_descriptor);
0x0312, return (uint8_t *)cfg_descriptor;
'P','C','A','N','-','U','S','B'
};
*length = sizeof( cfg_descriptor );
return (uint8_t*)cfg_descriptor;
} }
USBD_DescriptorsTypeDef FS_Desc = USBD_DescriptorsTypeDef FS_Desc = {
{ .GetDeviceDescriptor = USBD_FS_DeviceDescriptor,
.GetDeviceDescriptor = USBD_FS_DeviceDescriptor, .GetLangIDStrDescriptor = USBD_FS_LangIDStrDescriptor,
.GetLangIDStrDescriptor = USBD_FS_LangIDStrDescriptor, .GetManufacturerStrDescriptor = USBD_FS_HugeStrDescriptor,
.GetManufacturerStrDescriptor = USBD_FS_HugeStrDescriptor, .GetProductStrDescriptor = USBD_FS_HugeStrDescriptor,
.GetProductStrDescriptor = USBD_FS_HugeStrDescriptor, .GetSerialStrDescriptor = 0,
.GetSerialStrDescriptor = 0, .GetConfigurationStrDescriptor = USBD_FS_ConfigStrDescriptor,
.GetConfigurationStrDescriptor = USBD_FS_ConfigStrDescriptor, .GetInterfaceStrDescriptor = 0,
.GetInterfaceStrDescriptor = 0,
}; };

View File

@ -14,20 +14,20 @@
#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 0x08 #define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 0x08
/* USB_ENDPOINT_DESCRIPTOR.bmAttributes constants */ /* USB_ENDPOINT_DESCRIPTOR.bmAttributes constants */
#define USB_ENDPOINT_TYPE_MASK 0x03 #define USB_ENDPOINT_TYPE_MASK 0x03
#define USB_ENDPOINT_TYPE_CONTROL 0x00 #define USB_ENDPOINT_TYPE_CONTROL 0x00
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 #define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
#define USB_ENDPOINT_TYPE_BULK 0x02 #define USB_ENDPOINT_TYPE_BULK 0x02
#define USB_ENDPOINT_TYPE_INTERRUPT 0x03 #define USB_ENDPOINT_TYPE_INTERRUPT 0x03
/* USB_CONFIGURATION_DESCRIPTOR.bmAttributes constants */ /* USB_CONFIGURATION_DESCRIPTOR.bmAttributes constants */
#define USB_CONFIG_POWERED_MASK 0xc0 #define USB_CONFIG_POWERED_MASK 0xc0
#define USB_CONFIG_BUS_POWERED 0x80 #define USB_CONFIG_BUS_POWERED 0x80
#ifndef USB_CONFIG_SELF_POWERED #ifndef USB_CONFIG_SELF_POWERED
#define USB_CONFIG_SELF_POWERED 0x40 #define USB_CONFIG_SELF_POWERED 0x40
#endif #endif
#ifndef USB_CONFIG_REMOTE_WAKEUP #ifndef USB_CONFIG_REMOTE_WAKEUP
#define USB_CONFIG_REMOTE_WAKEUP 0x20 #define USB_CONFIG_REMOTE_WAKEUP 0x20
#endif #endif
#define USB_DEVICE_CLASS_RESERVED 0x00 #define USB_DEVICE_CLASS_RESERVED 0x00
@ -42,101 +42,92 @@
#define USB_DEVICE_CLASS_HUB 0x09 #define USB_DEVICE_CLASS_HUB 0x09
#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF #define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF
#pragma pack( push, 1 ) #pragma pack(push, 1)
typedef struct _USB_COMMON_DESCRIPTOR typedef struct _USB_COMMON_DESCRIPTOR
{ {
uint8_t bLength; uint8_t bLength;
uint8_t bDescriptorType; uint8_t bDescriptorType;
} } USB_COMMON_DESCRIPTOR, *PUSB_COMMON_DESCRIPTOR;
USB_COMMON_DESCRIPTOR, *PUSB_COMMON_DESCRIPTOR;
typedef struct _USB_CONFIGURATION_DESCRIPTOR typedef struct _USB_CONFIGURATION_DESCRIPTOR
{ {
uint8_t bLength; uint8_t bLength;
uint8_t bDescriptorType; uint8_t bDescriptorType;
uint16_t wTotalLength; uint16_t wTotalLength;
uint8_t bNumInterfaces; uint8_t bNumInterfaces;
uint8_t bConfigurationValue; uint8_t bConfigurationValue;
uint8_t iConfiguration; uint8_t iConfiguration;
uint8_t bmAttributes; uint8_t bmAttributes;
uint8_t MaxPower; uint8_t MaxPower;
} } USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR;
USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR;
typedef struct _USB_DEVICE_DESCRIPTOR typedef struct _USB_DEVICE_DESCRIPTOR
{ {
uint8_t bLength; uint8_t bLength;
uint8_t bDescriptorType; uint8_t bDescriptorType;
uint16_t bcdUSB; uint16_t bcdUSB;
uint8_t bDeviceClass; uint8_t bDeviceClass;
uint8_t bDeviceSubClass; uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol; uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0; uint8_t bMaxPacketSize0;
uint16_t idVendor; uint16_t idVendor;
uint16_t idProduct; uint16_t idProduct;
uint16_t bcdDevice; uint16_t bcdDevice;
uint8_t iManufacturer; uint8_t iManufacturer;
uint8_t iProduct; uint8_t iProduct;
uint8_t iSerialNumber; uint8_t iSerialNumber;
uint8_t bNumConfigurations; uint8_t bNumConfigurations;
} } USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
typedef struct _USB_DEVICE_QUALIFIER_DESCRIPTOR typedef struct _USB_DEVICE_QUALIFIER_DESCRIPTOR
{ {
uint8_t bLength; uint8_t bLength;
uint8_t bDescriptorType; uint8_t bDescriptorType;
uint16_t bcdUSB; uint16_t bcdUSB;
uint8_t bDeviceClass; uint8_t bDeviceClass;
uint8_t bDeviceSubClass; uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol; uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0; uint8_t bMaxPacketSize0;
uint8_t bNumConfigurations; uint8_t bNumConfigurations;
uint8_t bReserved; uint8_t bReserved;
} } USB_DEVICE_QUALIFIER_DESCRIPTOR, *PUSB_DEVICE_QUALIFIER_DESCRIPTOR;
USB_DEVICE_QUALIFIER_DESCRIPTOR, *PUSB_DEVICE_QUALIFIER_DESCRIPTOR;
typedef enum _USB_DEVICE_SPEED typedef enum _USB_DEVICE_SPEED
{ {
UsbLowSpeed, UsbLowSpeed,
UsbFullSpeed, UsbFullSpeed,
UsbHighSpeed, UsbHighSpeed,
UsbSuperSpeed UsbSuperSpeed
} } USB_DEVICE_SPEED;
USB_DEVICE_SPEED;
typedef struct _USB_ENDPOINT_DESCRIPTOR typedef struct _USB_ENDPOINT_DESCRIPTOR
{ {
uint8_t bLength; uint8_t bLength;
uint8_t bDescriptorType; uint8_t bDescriptorType;
uint8_t bEndpointAddress; uint8_t bEndpointAddress;
uint8_t bmAttributes; uint8_t bmAttributes;
uint16_t wMaxPacketSize; uint16_t wMaxPacketSize;
uint8_t bInterval; uint8_t bInterval;
} } USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR;
USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR;
typedef struct _USB_INTERFACE_DESCRIPTOR typedef struct _USB_INTERFACE_DESCRIPTOR
{ {
uint8_t bLength; uint8_t bLength;
uint8_t bDescriptorType; uint8_t bDescriptorType;
uint8_t bInterfaceNumber; uint8_t bInterfaceNumber;
uint8_t bAlternateSetting; uint8_t bAlternateSetting;
uint8_t bNumEndpoints; uint8_t bNumEndpoints;
uint8_t bInterfaceClass; uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass; uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol; uint8_t bInterfaceProtocol;
uint8_t iInterface; uint8_t iInterface;
} } USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR;
USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR;
typedef struct _USB_STRING_DESCRIPTOR typedef struct _USB_STRING_DESCRIPTOR
{ {
uint8_t bLength; uint8_t bLength;
uint8_t bDescriptorType; uint8_t bDescriptorType;
uint16_t bString[1]; uint16_t bString[1];
} } USB_STRING_DESCRIPTOR, *PUSB_STRING_DESCRIPTOR;
USB_STRING_DESCRIPTOR, *PUSB_STRING_DESCRIPTOR;
#pragma pack( pop )
#pragma pack(pop)