sdio+fatfs创建

This commit is contained in:
sc committed 2025-10-19 00:26:13 +08:00
commit f762d5d7f8
2473 files changed
+1192014

No files matched your search

+36
View File
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-10-18 RealThread first version
*/
#include <rtthread.h>
#include <board.h>
#include <drv_common.h>
RT_WEAK void rt_hw_board_init()
{
extern void hw_board_init(char *clock_src, int32_t clock_src_freq, int32_t clock_target_freq);
/* Heap initialization */
#if defined(RT_USING_HEAP)
rt_system_heap_init((void *) HEAP_BEGIN, (void *) HEAP_END);
#endif
hw_board_init(BSP_CLOCK_SOURCE, BSP_CLOCK_SOURCE_FREQ_MHZ, BSP_CLOCK_SYSTEM_FREQ_MHZ);
/* Set the shell console output device */
#if defined(RT_USING_DEVICE) && defined(RT_USING_CONSOLE)
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
/* Board underlying hardware initialization */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
}
+372
View File
@@ -0,0 +1,372 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-10-18 RealThread first version
*/
#ifndef __BOARD_H__
#define __BOARD_H__
#include <stm32f4xx.h>
#include <drv_common.h>
#ifdef __cplusplus
extern "C"
{
#endif
/*-------------------------- CHIP CONFIG BEGIN --------------------------*/
#define CHIP_FAMILY_STM32
#define CHIP_SERIES_STM32F4
#define CHIP_NAME_STM32F407ZG
/*-------------------------- CHIP CONFIG END --------------------------*/
/*-------------------------- ROM/RAM CONFIG BEGIN --------------------------*/
#define ROM_START ((uint32_t)0x08000000)
#define ROM_SIZE (1024 * 1024)
#define ROM_END ((uint32_t)(ROM_START + ROM_SIZE))
#define RAM_START (0x20000000)
#define RAM_SIZE (128 * 1024)
#define RAM_END (RAM_START + RAM_SIZE)
/*-------------------------- ROM/RAM CONFIG END --------------------------*/
/*-------------------------- CLOCK CONFIG BEGIN --------------------------*/
#define BSP_CLOCK_SOURCE ("HSI")
#define BSP_CLOCK_SOURCE_FREQ_MHZ ((int32_t)0)
#define BSP_CLOCK_SYSTEM_FREQ_MHZ ((int32_t)168)
/*-------------------------- CLOCK CONFIG END --------------------------*/
/*-------------------------- UART CONFIG BEGIN --------------------------*/
/** After configuring corresponding UART or UART DMA, you can use it.
*
* STEP 1, define macro define related to the serial port opening based on the serial port number
* such as #define BSP_USING_UART1
*
* STEP 2, according to the corresponding pin of serial port, define the related serial port information macro
* such as #define BSP_UART1_TX_PIN "PA9"
* #define BSP_UART1_RX_PIN "PA10"
*
* STEP 3, if you want using SERIAL DMA, you must open it in the RT-Thread Settings.
* RT-Thread Setting -> Components -> Device Drivers -> Serial Device Drivers -> Enable Serial DMA Mode
*
* STEP 4, according to serial port number to define serial port tx/rx DMA function in the board.h file
* such as #define BSP_UART1_RX_USING_DMA
*
*/
#define BSP_USING_UART1
#define BSP_UART1_TX_PIN "PA9"
#define BSP_UART1_RX_PIN "PA10"
/*-------------------------- UART CONFIG END --------------------------*/
/*-------------------------- I2C CONFIG BEGIN --------------------------*/
/** if you want to use i2c bus(soft simulate) you can use the following instructions.
*
* STEP 1, open i2c driver framework(soft simulate) support in the RT-Thread Settings file
*
* STEP 2, define macro related to the i2c bus
* such as #define BSP_USING_I2C1
*
* STEP 3, according to the corresponding pin of i2c port, modify the related i2c port and pin information
* such as #define BSP_I2C1_SCL_PIN GET_PIN(port, pin) -> GET_PIN(C, 11)
* #define BSP_I2C1_SDA_PIN GET_PIN(port, pin) -> GET_PIN(C, 12)
*/
/*#define BSP_USING_I2C1*/
#ifdef BSP_USING_I2C1
#define BSP_I2C1_SCL_PIN GET_PIN(port, pin)
#define BSP_I2C1_SDA_PIN GET_PIN(port, pin)
#endif
/*#define BSP_USING_I2C2*/
#ifdef BSP_USING_I2C2
#define BSP_I2C2_SCL_PIN GET_PIN(port, pin)
#define BSP_I2C2_SDA_PIN GET_PIN(port, pin)
#endif
/*-------------------------- I2C CONFIG END --------------------------*/
/*-------------------------- SPI CONFIG BEGIN --------------------------*/
/** if you want to use spi bus you can use the following instructions.
*
* STEP 1, open spi driver framework support in the RT-Thread Settings file
*
* STEP 2, define macro related to the spi bus
* such as #define BSP_USING_SPI1
*
* STEP 3, copy your spi init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file
* such as void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
*
* STEP 4, modify your stm32xxxx_hal_config.h file to support spi peripherals. define macro related to the peripherals
* such as #define HAL_SPI_MODULE_ENABLED
*/
/*#define BSP_USING_SPI1*/
/*#define BSP_USING_SPI2*/
/*#define BSP_USING_SPI3*/
/*-------------------------- SPI CONFIG END --------------------------*/
/*-------------------------- QSPI CONFIG BEGIN --------------------------*/
/** if you want to use qspi you can use the following instructions.
*
* STEP 1, open qspi driver framework support in the RT-Thread Settings file
*
* STEP 2, define macro related to the qspi
* such as #define BSP_USING_QSPI
*
* STEP 3, copy your qspi init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file
* such as void HAL_QSPI_MspInit(QSPI_HandleTypeDef* hqspi)
*
* STEP 4, modify your stm32xxxx_hal_config.h file to support qspi peripherals. define macro related to the peripherals
* such as #define HAL_QSPI_MODULE_ENABLED
*
*/
/*#define BSP_USING_QSPI*/
/*-------------------------- QSPI CONFIG END --------------------------*/
/*-------------------------- PWM CONFIG BEGIN --------------------------*/
/** if you want to use pwm you can use the following instructions.
*
* STEP 1, open pwm driver framework support in the RT-Thread Settings file
*
* STEP 2, define macro related to the pwm
* such as #define BSP_USING_PWM1
*
* STEP 3, copy your pwm timer init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end if board.c file
* such as void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) and
* void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
*
* STEP 4, modify your stm32xxxx_hal_config.h file to support pwm peripherals. define macro related to the peripherals
* such as #define HAL_TIM_MODULE_ENABLED
*
*/
/*#define BSP_USING_PWM1*/
/*#define BSP_USING_PWM2*/
/*#define BSP_USING_PWM3*/
/*-------------------------- PWM CONFIG END --------------------------*/
/*-------------------------- ADC CONFIG BEGIN --------------------------*/
/** if you want to use adc you can use the following instructions.
*
* STEP 1, open adc driver framework support in the RT-Thread Settings file
*
* STEP 2, define macro related to the adc
* such as #define BSP_USING_ADC1
*
* STEP 3, copy your adc init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file
* such as void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
*
* STEP 4, modify your stm32xxxx_hal_config.h file to support adc peripherals. define macro related to the peripherals
* such as #define HAL_ADC_MODULE_ENABLED
*
*/
/*#define BSP_USING_ADC1*/
/*#define BSP_USING_ADC2*/
/*#define BSP_USING_ADC3*/
/*-------------------------- ADC CONFIG END --------------------------*/
/*-------------------------- WDT CONFIG BEGIN --------------------------*/
/** if you want to use wdt you can use the following instructions.
*
* STEP 1, open wdt driver framework support in the RT-Thread Settings file
*
* STEP 2, modify your stm32xxxx_hal_config.h file to support wdt peripherals. define macro related to the peripherals
* such as #define HAL_IWDG_MODULE_ENABLED
*
*/
/*-------------------------- WDT CONFIG END --------------------------*/
/*-------------------------- HARDWARE TIMER CONFIG BEGIN --------------------------*/
/** if you want to use hardware timer you can use the following instructions.
*
* STEP 1, open hwtimer driver framework support in the RT-Thread Settings file
*
* STEP 2, define macro related to the hwtimer
* such as #define BSP_USING_TIM and
* #define BSP_USING_TIM1
*
* STEP 3, copy your hardwire timer init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file
* such as void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
*
* STEP 4, modify your stm32xxxx_hal_config.h file to support hardwere timer peripherals. define macro related to the peripherals
* such as #define HAL_TIM_MODULE_ENABLED
*
*/
/*#define BSP_USING_TIM*/
#ifdef BSP_USING_TIM
/*#define BSP_USING_TIM15*/
/*#define BSP_USING_TIM16*/
/*#define BSP_USING_TIM17*/
#endif
/*-------------------------- HAREWARE TIMER CONFIG END --------------------------*/
/*-------------------------- RTC CONFIG BEGIN --------------------------*/
/** if you want to use rtc(hardware) you can use the following instructions.
*
* STEP 1, open rtc driver framework(hardware) support in the RT-Thread Settings file
*
* STEP 2, define macro related to the rtc
* such as BSP_USING_ONCHIP_RTC
*
* STEP 3, modify your stm32xxxx_hal_config.h file to support rtc peripherals. define macro related to the peripherals
* such as #define HAL_RTC_MODULE_ENABLED
*
*/
/*#define BSP_USING_ONCHIP_RTC*/
/*-------------------------- RTC CONFIG END --------------------------*/
/*-------------------------- SDIO CONFIG BEGIN --------------------------*/
/** if you want to use sdio you can use the following instructions.
*
* STEP 1, open sdio driver framework support in the RT-Thread Settings file
*
* STEP 2, define macro related to the sdio
* such as BSP_USING_SDIO
*
* STEP 3, copy your sdio init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file
* such as void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
*
* STEP 4, modify your stm32xxxx_hal_config.h file to support sdio peripherals. define macro related to the peripherals
* such as #define HAL_SD_MODULE_ENABLED
*
* STEP 5, config your device file system or another applications
*
*/
/*#define BSP_USING_SDIO*/
#define BSP_USING_SDIO
/*-------------------------- SDIO CONFIG END --------------------------*/
/*-------------------------- ETH CONFIG BEGIN --------------------------*/
/** if you want to use eth you can use the following instructions.
*
* STEP 1, define macro related to the eth
* such as BSP_USING_ETH
*
* STEP 2, copy your eth init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end if board.c file
* such as void HAL_ETH_MspInit(ETH_HandleTypeDef* heth)
*
* STEP 3, modify your stm32xxxx_hal_config.h file to support eth peripherals. define macro related to the peripherals
* such as #define HAL_ETH_MODULE_ENABLED
*
* STEP 4, config your phy type
* such as #define PHY_USING_LAN8720A
* #define PHY_USING_DM9161CEP
* #define PHY_USING_DP83848C
* STEP 5, implement your phy reset function in the end of board.c file
* void phy_reset(void)
*
* STEP 6, config your lwip or other network stack
*
*/
/*#define BSP_USING_ETH*/
#ifdef BSP_USING_ETH
/*#define PHY_USING_LAN8720A*/
/*#define PHY_USING_DM9161CEP*/
/*#define PHY_USING_DP83848C*/
#endif
/*-------------------------- ETH CONFIG END --------------------------*/
/*-------------------------- USB HOST CONFIG BEGIN --------------------------*/
/** if you want to use usb host you can use the following instructions.
*
* STEP 1, open usb host driver framework support in the RT-Thread Settings file
*
* STEP 2, define macro related to the usb host
* such as BSP_USING_USBHOST
*
* STEP 3, copy your usb host init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file
* such as void HAL_HCD_MspInit(HCD_HandleTypeDef* hhcd)
*
* STEP 4, config your usb peripheral clock in SystemClock_Config() generated by STM32CubeMX and replace this function in board.c
*
* STEP 5, modify your stm32xxxx_hal_config.h file to support usb host peripherals. define macro related to the peripherals
* such as #define HAL_HCD_MODULE_ENABLED
*
*/
/*#define BSP_USING_USBHOST*/
/*-------------------------- USB HOST CONFIG END --------------------------*/
/*-------------------------- USB DEVICE CONFIG BEGIN --------------------------*/
/** if you want to use usb device you can use the following instructions.
*
* STEP 1, open usb device driver framework support in the RT-Thread Settings file
*
* STEP 2 define macro related to the usb device
* such as BSP_USING_USBDEVICE
*
* STEP 3, copy your usb device init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file
* such as void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd)
*
* STEP 4, config your usb peripheral clock in SystemClock_Config() generated by STM32CubeMX and replace this function in board.c
*
* STEP 5, modify your stm32xxxx_hal_config.h file to support usb device peripherals. define macro related to the peripherals
* such as #define HAL_PCD_MODULE_ENABLED
*
*/
/*#define BSP_USING_USBDEVICE*/
/*-------------------------- USB DEVICE CONFIG END --------------------------*/
/*-------------------------- ON_CHIP_FLASH CONFIG BEGIN --------------------------*/
/** if you want to use on chip flash you can use the following instructions.
*
* STEP 1 define macro related to the on chip flash
* such as BSP_USING_ON_CHIP_FLASH
*
* STEP 2, modify your stm32xxxx_hal_config.h file to support on chip flash peripherals. define macro related to the peripherals
* such as #define HAL_FLASH_MODULE_ENABLED
*
*/
/*#define BSP_USING_ON_CHIP_FLASH*/
/*-------------------------- ON_CHIP_FLASH CONFIG END --------------------------*/
#ifdef __cplusplus
}
#endif
#endif /* __BOARD_H__ */
+320
View File
@@ -0,0 +1,320 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-05 zylx first version
* 2018-12-12 greedyhao Porting for stm32f7xx
* 2019-02-01 yuneizhilin fix the stm32_adc_init function initialization issue
* 2020-06-17 thread-liu Porting for stm32mp1xx
* 2020-10-14 Dozingfiretruck Porting for stm32wbxx
*/
#include <board.h>
#if defined(BSP_USING_ADC1) || defined(BSP_USING_ADC2) || defined(BSP_USING_ADC3)
#include "drv_config.h"
//#define DRV_DEBUG
#define LOG_TAG "drv.adc"
#include <drv_log.h>
static ADC_HandleTypeDef adc_config[] =
{
#ifdef BSP_USING_ADC1
ADC1_CONFIG,
#endif
#ifdef BSP_USING_ADC2
ADC2_CONFIG,
#endif
#ifdef BSP_USING_ADC3
ADC3_CONFIG,
#endif
};
struct stm32_adc
{
ADC_HandleTypeDef ADC_Handler;
struct rt_adc_device stm32_adc_device;
};
static struct stm32_adc stm32_adc_obj[sizeof(adc_config) / sizeof(adc_config[0])];
static rt_err_t stm32_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
{
ADC_HandleTypeDef *stm32_adc_handler;
RT_ASSERT(device != RT_NULL);
stm32_adc_handler = device->parent.user_data;
if (enabled)
{
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined (SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) || defined (SOC_SERIES_STM32WB)
ADC_Enable(stm32_adc_handler);
#else
__HAL_ADC_ENABLE(stm32_adc_handler);
#endif
}
else
{
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined (SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) || defined (SOC_SERIES_STM32WB)
ADC_Disable(stm32_adc_handler);
#else
__HAL_ADC_DISABLE(stm32_adc_handler);
#endif
}
return RT_EOK;
}
static rt_uint32_t stm32_adc_get_channel(rt_uint32_t channel)
{
rt_uint32_t stm32_channel = 0;
switch (channel)
{
case 0:
stm32_channel = ADC_CHANNEL_0;
break;
case 1:
stm32_channel = ADC_CHANNEL_1;
break;
case 2:
stm32_channel = ADC_CHANNEL_2;
break;
case 3:
stm32_channel = ADC_CHANNEL_3;
break;
case 4:
stm32_channel = ADC_CHANNEL_4;
break;
case 5:
stm32_channel = ADC_CHANNEL_5;
break;
case 6:
stm32_channel = ADC_CHANNEL_6;
break;
case 7:
stm32_channel = ADC_CHANNEL_7;
break;
case 8:
stm32_channel = ADC_CHANNEL_8;
break;
case 9:
stm32_channel = ADC_CHANNEL_9;
break;
case 10:
stm32_channel = ADC_CHANNEL_10;
break;
case 11:
stm32_channel = ADC_CHANNEL_11;
break;
case 12:
stm32_channel = ADC_CHANNEL_12;
break;
case 13:
stm32_channel = ADC_CHANNEL_13;
break;
case 14:
stm32_channel = ADC_CHANNEL_14;
break;
case 15:
stm32_channel = ADC_CHANNEL_15;
break;
#ifdef ADC_CHANNEL_16
case 16:
stm32_channel = ADC_CHANNEL_16;
break;
#endif
case 17:
stm32_channel = ADC_CHANNEL_17;
break;
#ifdef ADC_CHANNEL_18
case 18:
stm32_channel = ADC_CHANNEL_18;
break;
#endif
#ifdef ADC_CHANNEL_19
case 19:
stm32_channel = ADC_CHANNEL_19;
break;
#endif
}
return stm32_channel;
}
static rt_err_t stm32_get_adc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
{
ADC_ChannelConfTypeDef ADC_ChanConf;
ADC_HandleTypeDef *stm32_adc_handler;
RT_ASSERT(device != RT_NULL);
RT_ASSERT(value != RT_NULL);
stm32_adc_handler = device->parent.user_data;
rt_memset(&ADC_ChanConf, 0, sizeof(ADC_ChanConf));
#ifndef ADC_CHANNEL_16
if (channel == 16)
{
LOG_E("ADC channel must not be 16.");
return -RT_ERROR;
}
#endif
/* ADC channel number is up to 17 */
#if !defined(ADC_CHANNEL_18)
if (channel <= 17)
/* ADC channel number is up to 19 */
#elif defined(ADC_CHANNEL_19)
if (channel <= 19)
/* ADC channel number is up to 18 */
#else
if (channel <= 18)
#endif
{
/* set stm32 ADC channel */
ADC_ChanConf.Channel = stm32_adc_get_channel(channel);
}
else
{
#if !defined(ADC_CHANNEL_18)
LOG_E("ADC channel must be between 0 and 17.");
#elif defined(ADC_CHANNEL_19)
LOG_E("ADC channel must be between 0 and 19.");
#else
LOG_E("ADC channel must be between 0 and 18.");
#endif
return -RT_ERROR;
}
#if defined(SOC_SERIES_STM32MP1) || defined (SOC_SERIES_STM32H7) || defined (SOC_SERIES_STM32WB)
ADC_ChanConf.Rank = ADC_REGULAR_RANK_1;
#else
ADC_ChanConf.Rank = 1;
#endif
#if defined(SOC_SERIES_STM32F0)
ADC_ChanConf.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
#elif defined(SOC_SERIES_STM32F1)
ADC_ChanConf.SamplingTime = ADC_SAMPLETIME_55CYCLES_5;
#elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
ADC_ChanConf.SamplingTime = ADC_SAMPLETIME_112CYCLES;
#elif defined(SOC_SERIES_STM32L4)
ADC_ChanConf.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;
#elif defined(SOC_SERIES_STM32MP1)
ADC_ChanConf.SamplingTime = ADC_SAMPLETIME_810CYCLES_5;
#elif defined(SOC_SERIES_STM32H7)
ADC_ChanConf.SamplingTime = ADC_SAMPLETIME_64CYCLES_5;
#elif defined (SOC_SERIES_STM32WB)
ADC_ChanConf.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
#endif
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4) || defined (SOC_SERIES_STM32WB)
ADC_ChanConf.Offset = 0;
#endif
#if defined(SOC_SERIES_STM32L4)
ADC_ChanConf.OffsetNumber = ADC_OFFSET_NONE;
ADC_ChanConf.SingleDiff = LL_ADC_SINGLE_ENDED;
#elif defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) || defined (SOC_SERIES_STM32WB)
ADC_ChanConf.OffsetNumber = ADC_OFFSET_NONE; /* ADC channel affected to offset number */
ADC_ChanConf.Offset = 0;
ADC_ChanConf.SingleDiff = ADC_SINGLE_ENDED; /* ADC channel differential mode */
#endif
HAL_ADC_ConfigChannel(stm32_adc_handler, &ADC_ChanConf);
/* perform an automatic ADC calibration to improve the conversion accuracy */
#if defined(SOC_SERIES_STM32L4) || defined (SOC_SERIES_STM32WB)
if (HAL_ADCEx_Calibration_Start(stm32_adc_handler, ADC_ChanConf.SingleDiff) != HAL_OK)
{
LOG_E("ADC calibration error!\n");
return -RT_ERROR;
}
#elif defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7)
/* Run the ADC linear calibration in single-ended mode */
if (HAL_ADCEx_Calibration_Start(stm32_adc_handler, ADC_CALIB_OFFSET_LINEARITY, ADC_ChanConf.SingleDiff) != HAL_OK)
{
LOG_E("ADC open linear calibration error!\n");
/* Calibration Error */
return -RT_ERROR;
}
#endif
/* start ADC */
HAL_ADC_Start(stm32_adc_handler);
/* Wait for the ADC to convert */
HAL_ADC_PollForConversion(stm32_adc_handler, 100);
/* get ADC value */
*value = (rt_uint32_t)HAL_ADC_GetValue(stm32_adc_handler);
return RT_EOK;
}
static const struct rt_adc_ops stm_adc_ops =
{
.enabled = stm32_adc_enabled,
.convert = stm32_get_adc_value,
};
static int stm32_adc_init(void)
{
int result = RT_EOK;
/* save adc name */
char name_buf[5] = {'a', 'd', 'c', '0', 0};
int i = 0;
for (i = 0; i < sizeof(adc_config) / sizeof(adc_config[0]); i++)
{
/* ADC init */
name_buf[3] = '0';
stm32_adc_obj[i].ADC_Handler = adc_config[i];
#if defined(ADC1)
if (stm32_adc_obj[i].ADC_Handler.Instance == ADC1)
{
name_buf[3] = '1';
}
#endif
#if defined(ADC2)
if (stm32_adc_obj[i].ADC_Handler.Instance == ADC2)
{
name_buf[3] = '2';
}
#endif
#if defined(ADC3)
if (stm32_adc_obj[i].ADC_Handler.Instance == ADC3)
{
name_buf[3] = '3';
}
#endif
if (HAL_ADC_Init(&stm32_adc_obj[i].ADC_Handler) != HAL_OK)
{
LOG_E("%s init failed", name_buf);
result = -RT_ERROR;
}
else
{
/* register ADC device */
if (rt_hw_adc_register(&stm32_adc_obj[i].stm32_adc_device, name_buf, &stm_adc_ops, &stm32_adc_obj[i].ADC_Handler) == RT_EOK)
{
LOG_D("%s init success", name_buf);
}
else
{
LOG_E("%s register failed", name_buf);
result = -RT_ERROR;
}
}
}
return result;
}
INIT_BOARD_EXPORT(stm32_adc_init);
#endif /* BSP_USING_ADC */
+1001
View File
File diff suppressed because it is too large. Load diff
+77
View File
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-10-26 ChenYong first version
* 2020-01-08 xiangxistu add HSI configuration
*/
#include <board.h>
#include <rtthread.h>
#include <stm32f4xx.h>
#include "drv_common.h"
#define DBG_TAG "board"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
void system_clock_config(int target_freq_mhz)
{
RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };
RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = target_freq_mhz;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
}
int clock_information(void)
{
LOG_D("System Clock information");
LOG_D("SYSCLK_Frequency = %d", HAL_RCC_GetSysClockFreq());
LOG_D("HCLK_Frequency = %d", HAL_RCC_GetHCLKFreq());
LOG_D("PCLK1_Frequency = %d", HAL_RCC_GetPCLK1Freq());
LOG_D("PCLK2_Frequency = %d", HAL_RCC_GetPCLK2Freq());
return RT_EOK;
}
INIT_BOARD_EXPORT(clock_information);
void clk_init(char *clk_source, int source_freq, int target_freq)
{
/*
* Use SystemClock_Config generated from STM32CubeMX for clock init
* system_clock_config(target_freq);
*/
extern void SystemClock_Config(void);
SystemClock_Config();
}
+207
View File
@@ -0,0 +1,207 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-7 SummerGift first version
*/
#include "drv_common.h"
#include "board.h"
#ifdef RT_USING_SERIAL
#ifdef RT_USING_SERIAL_V2
#include "drv_usart_v2.h"
#else
#include "drv_usart.h"
#endif /* RT_USING_SERIAL */
#endif /* RT_USING_SERIAL_V2 */
#define DBG_TAG "drv_common"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#ifdef RT_USING_FINSH
#include <finsh.h>
static void reboot(uint8_t argc, char **argv)
{
rt_hw_cpu_reset();
}
MSH_CMD_EXPORT(reboot, Reboot System);
#endif /* RT_USING_FINSH */
extern __IO uint32_t uwTick;
static uint32_t _systick_ms = 1;
/* SysTick configuration */
void rt_hw_systick_init(void)
{
HAL_SYSTICK_Config(SystemCoreClock / RT_TICK_PER_SECOND);
NVIC_SetPriority(SysTick_IRQn, 0xFF);
_systick_ms = 1000u / RT_TICK_PER_SECOND;
if(_systick_ms == 0)
_systick_ms = 1;
}
/**
* This is the timer interrupt service routine.
*
*/
void SysTick_Handler(void)
{
/* enter interrupt */
rt_interrupt_enter();
if(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)
HAL_IncTick();
rt_tick_increase();
/* leave interrupt */
rt_interrupt_leave();
}
uint32_t HAL_GetTick(void)
{
if(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)
HAL_IncTick();
return uwTick;
}
void HAL_IncTick(void)
{
uwTick += _systick_ms;
}
void HAL_SuspendTick(void)
{
}
void HAL_ResumeTick(void)
{
}
void HAL_Delay(__IO uint32_t Delay)
{
if (rt_thread_self())
{
rt_thread_mdelay(Delay);
}
else
{
for (rt_uint32_t count = 0; count < Delay; count++)
{
rt_hw_us_delay(1000);
}
}
}
/* re-implement tick interface for STM32 HAL */
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
rt_hw_systick_init();
/* Return function status */
return HAL_OK;
}
/**
* @brief This function is executed in case of error occurrence.
* @param None
* @retval None
*/
void _Error_Handler(char *s, int num)
{
/* USER CODE BEGIN Error_Handler */
/* User can add his own implementation to report the HAL error return state */
LOG_E("Error_Handler at file:%s num:%d", s, num);
while (1)
{
}
/* USER CODE END Error_Handler */
}
/**
* This function will delay for some us.
*
* @param us the delay time of us
*/
void rt_hw_us_delay(rt_uint32_t us)
{
rt_uint32_t ticks;
rt_uint32_t told, tnow, tcnt = 0;
rt_uint32_t reload = SysTick->LOAD;
ticks = us * reload / (1000000 / RT_TICK_PER_SECOND);
told = SysTick->VAL;
while (1)
{
tnow = SysTick->VAL;
if (tnow != told)
{
if (tnow < told)
{
tcnt += told - tnow;
}
else
{
tcnt += reload - tnow + told;
}
told = tnow;
if (tcnt >= ticks)
{
break;
}
}
}
}
/**
* This function will initial STM32 board.
*/
void hw_board_init(char *clock_src, int32_t clock_src_freq, int32_t clock_target_freq)
{
extern void rt_hw_systick_init(void);
extern void clk_init(char *clk_source, int source_freq, int target_freq);
#ifdef BSP_SCB_ENABLE_I_CACHE
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
#endif
#ifdef BSP_SCB_ENABLE_D_CACHE
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
#endif
/* HAL_Init() function is called at the beginning of the program */
HAL_Init();
/* enable interrupt */
__set_PRIMASK(0);
/* System clock initialization */
clk_init(clock_src, clock_src_freq, clock_target_freq);
/* disbale interrupt */
__set_PRIMASK(1);
rt_hw_systick_init();
/* Pin driver initialization is open by default */
#ifdef RT_USING_PIN
extern int rt_hw_pin_init(void);
rt_hw_pin_init();
#endif
/* USART driver initialization is open by default */
#ifdef RT_USING_SERIAL
extern int rt_hw_usart_init(void);
rt_hw_usart_init();
#endif
}
+743
View File
@@ -0,0 +1,743 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-07-10 Ernest 1st version
* 2020-10-14 Dozingfiretruck Porting for stm32wbxx
* 2020-11-26 thread-liu add hash
* 2020-11-26 thread-liu add cryp
* 2020-12-11 WKJay fix build problem
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#ifdef RT_USING_HWCRYPTO
#include <stdlib.h>
#include <string.h>
#include "drv_crypto.h"
#include "drv_config.h"
struct stm32_hwcrypto_device
{
struct rt_hwcrypto_device dev;
struct rt_mutex mutex;
};
#if defined(BSP_USING_CRC)
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32MP1)
static struct hwcrypto_crc_cfg crc_backup_cfg;
static int reverse_bit(rt_uint32_t n)
{
n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa);
n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc);
n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0);
n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00);
n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000);
return n;
}
#endif /* defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) */
static rt_uint32_t _crc_update(struct hwcrypto_crc *ctx, const rt_uint8_t *in, rt_size_t length)
{
rt_uint32_t result = 0;
struct stm32_hwcrypto_device *stm32_hw_dev = (struct stm32_hwcrypto_device *)ctx->parent.device->user_data;
#if defined(SOC_SERIES_STM32L4)|| defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32MP1)
CRC_HandleTypeDef *HW_TypeDef = (CRC_HandleTypeDef *)(ctx->parent.contex);
#endif
rt_mutex_take(&stm32_hw_dev->mutex, RT_WAITING_FOREVER);
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32MP1)
if (memcmp(&crc_backup_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg)) != 0)
{
if (HW_TypeDef->Init.DefaultPolynomialUse == DEFAULT_POLYNOMIAL_DISABLE)
{
HW_TypeDef->Init.GeneratingPolynomial = ctx ->crc_cfg.poly;
}
else
{
HW_TypeDef->Init.GeneratingPolynomial = DEFAULT_CRC32_POLY;
}
switch (ctx ->crc_cfg.flags)
{
case 0:
HW_TypeDef->Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;
HW_TypeDef->Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
break;
case CRC_FLAG_REFIN:
HW_TypeDef->Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE;
break;
case CRC_FLAG_REFOUT:
HW_TypeDef->Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE;
break;
case CRC_FLAG_REFIN|CRC_FLAG_REFOUT:
HW_TypeDef->Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE;
HW_TypeDef->Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE;
break;
default :
goto _exit;
}
switch(ctx ->crc_cfg.width)
{
#if defined(CRC_POLYLENGTH_7B) && defined(CRC_POLYLENGTH_8B) && defined(CRC_POLYLENGTH_16B) && defined(CRC_POLYLENGTH_32B)
case 7:
HW_TypeDef->Init.CRCLength = CRC_POLYLENGTH_7B;
break;
case 8:
HW_TypeDef->Init.CRCLength = CRC_POLYLENGTH_8B;
break;
case 16:
HW_TypeDef->Init.CRCLength = CRC_POLYLENGTH_16B;
break;
case 32:
HW_TypeDef->Init.CRCLength = CRC_POLYLENGTH_32B;
break;
default :
goto _exit;
#else
case 32:
HW_TypeDef->Init.CRCLength = CRC_POLYLENGTH_32B;
break;
default :
goto _exit;
#endif /* defined(CRC_POLYLENGTH_7B) && defined(CRC_POLYLENGTH_8B) && defined(CRC_POLYLENGTH_16B) && defined(CRC_POLYLENGTH_32B) */
}
if (HW_TypeDef->Init.DefaultInitValueUse == DEFAULT_INIT_VALUE_DISABLE)
{
HW_TypeDef->Init.InitValue = ctx ->crc_cfg.last_val;
}
if (HAL_CRC_Init(HW_TypeDef) != HAL_OK)
{
goto _exit;
}
memcpy(&crc_backup_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg));
}
if (HAL_CRC_STATE_READY != HAL_CRC_GetState(HW_TypeDef))
{
goto _exit;
}
#else
if (ctx->crc_cfg.flags != 0 || ctx->crc_cfg.last_val != 0xFFFFFFFF || ctx->crc_cfg.xorout != 0 || length % 4 != 0)
{
goto _exit;
}
length /= 4;
#endif /* defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) */
result = HAL_CRC_Accumulate(ctx->parent.contex, (rt_uint32_t *)in, length);
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32MP1)
if (HW_TypeDef->Init.OutputDataInversionMode)
{
ctx ->crc_cfg.last_val = reverse_bit(result);
}
else
{
ctx ->crc_cfg.last_val = result;
}
crc_backup_cfg.last_val = ctx ->crc_cfg.last_val;
result = (result ? result ^ (ctx ->crc_cfg.xorout) : result);
#endif /* defined(SOC_SERIES_STM32L4)|| defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) */
_exit:
rt_mutex_release(&stm32_hw_dev->mutex);
return result;
}
static const struct hwcrypto_crc_ops crc_ops =
{
.update = _crc_update,
};
#endif /* BSP_USING_CRC */
#if defined(BSP_USING_RNG)
static rt_uint32_t _rng_rand(struct hwcrypto_rng *ctx)
{
rt_uint32_t gen_random = 0;
RNG_HandleTypeDef *HW_TypeDef = (RNG_HandleTypeDef *)(ctx->parent.contex);
if (HAL_OK == HAL_RNG_GenerateRandomNumber(HW_TypeDef, &gen_random))
{
return gen_random ;
}
return 0;
}
static const struct hwcrypto_rng_ops rng_ops =
{
.update = _rng_rand,
};
#endif /* BSP_USING_RNG */
#if defined(BSP_USING_HASH)
static rt_err_t _hash_update(struct hwcrypto_hash *ctx, const rt_uint8_t *in, rt_size_t length)
{
rt_uint32_t tickstart = 0;
rt_uint32_t result = RT_EOK;
struct stm32_hwcrypto_device *stm32_hw_dev = (struct stm32_hwcrypto_device *)ctx->parent.device->user_data;
rt_mutex_take(&stm32_hw_dev->mutex, RT_WAITING_FOREVER);
#if defined(SOC_SERIES_STM32MP1)
HASH_HandleTypeDef *HW_TypeDef = (HASH_HandleTypeDef *)(ctx->parent.contex);
/* Start HASH computation using DMA transfer */
switch (ctx->parent.type)
{
case HWCRYPTO_TYPE_SHA224:
result = HAL_HASHEx_SHA224_Start_DMA(HW_TypeDef, (uint8_t *)in, length);
break;
case HWCRYPTO_TYPE_SHA256:
result = HAL_HASHEx_SHA256_Start_DMA(HW_TypeDef, (uint8_t *)in, length);
break;
case HWCRYPTO_TYPE_MD5:
result = HAL_HASH_MD5_Start_DMA(HW_TypeDef, (uint8_t *)in, length);
break;
case HWCRYPTO_TYPE_SHA1:
result = HAL_HASH_SHA1_Start_DMA(HW_TypeDef, (uint8_t *)in, length);
break;
default :
rt_kprintf("not support hash type: %x", ctx->parent.type);
break;
}
if (result != HAL_OK)
{
goto _exit;
}
/* Wait for DMA transfer to complete */
tickstart = rt_tick_get();
while (HAL_HASH_GetState(HW_TypeDef) == HAL_HASH_STATE_BUSY)
{
if (rt_tick_get() - tickstart > 0xFFFF)
{
result = RT_ETIMEOUT;
goto _exit;
}
}
#endif
_exit:
rt_mutex_release(&stm32_hw_dev->mutex);
return result;
}
static rt_err_t _hash_finish(struct hwcrypto_hash *ctx, rt_uint8_t *out, rt_size_t length)
{
rt_uint32_t result = RT_EOK;
struct stm32_hwcrypto_device *stm32_hw_dev = (struct stm32_hwcrypto_device *)ctx->parent.device->user_data;
rt_mutex_take(&stm32_hw_dev->mutex, RT_WAITING_FOREVER);
#if defined(SOC_SERIES_STM32MP1)
HASH_HandleTypeDef *HW_TypeDef = (HASH_HandleTypeDef *)(ctx->parent.contex);
/* Get the computed digest value */
switch (ctx->parent.type)
{
case HWCRYPTO_TYPE_SHA224:
result = HAL_HASHEx_SHA224_Finish(HW_TypeDef, (uint8_t *)out, length);
break;
case HWCRYPTO_TYPE_SHA256:
result = HAL_HASHEx_SHA256_Finish(HW_TypeDef, (uint8_t *)out, length);
break;
case HWCRYPTO_TYPE_MD5:
result = HAL_HASH_MD5_Finish(HW_TypeDef, (uint8_t *)out, length);
break;
case HWCRYPTO_TYPE_SHA1:
result = HAL_HASH_SHA1_Finish(HW_TypeDef, (uint8_t *)out, length);
break;
default :
rt_kprintf("not support hash type: %x", ctx->parent.type);
break;
}
if (result != HAL_OK)
{
goto _exit;
}
#endif
_exit:
rt_mutex_release(&stm32_hw_dev->mutex);
return result;
}
static const struct hwcrypto_hash_ops hash_ops =
{
.update = _hash_update,
.finish = _hash_finish
};
#endif /* BSP_USING_HASH */
#if defined(BSP_USING_CRYP)
static rt_err_t _cryp_crypt(struct hwcrypto_symmetric *ctx,
struct hwcrypto_symmetric_info *info)
{
rt_uint32_t result = RT_EOK;
rt_uint32_t tickstart = 0;
struct stm32_hwcrypto_device *stm32_hw_dev = (struct stm32_hwcrypto_device *)ctx->parent.device->user_data;
rt_mutex_take(&stm32_hw_dev->mutex, RT_WAITING_FOREVER);
#if defined(SOC_SERIES_STM32MP1)
CRYP_HandleTypeDef *HW_TypeDef = (CRYP_HandleTypeDef *)(ctx->parent.contex);
switch (ctx->parent.type)
{
case HWCRYPTO_TYPE_AES_ECB:
HW_TypeDef->Init.Algorithm = CRYP_AES_ECB;
break;
case HWCRYPTO_TYPE_AES_CBC:
HW_TypeDef->Init.Algorithm = CRYP_AES_CBC;
break;
case HWCRYPTO_TYPE_AES_CTR:
HW_TypeDef->Init.Algorithm = CRYP_AES_CTR;
break;
case HWCRYPTO_TYPE_DES_ECB:
HW_TypeDef->Init.Algorithm = CRYP_DES_ECB;
break;
case HWCRYPTO_TYPE_DES_CBC:
HW_TypeDef->Init.Algorithm = CRYP_DES_CBC;
break;
default :
rt_kprintf("not support cryp type: %x", ctx->parent.type);
break;
}
HAL_CRYP_DeInit(HW_TypeDef);
HW_TypeDef->Init.DataType = CRYP_DATATYPE_8B;
HW_TypeDef->Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
HW_TypeDef->Init.KeySize = CRYP_KEYSIZE_128B;
HW_TypeDef->Init.pKey = (uint32_t*)ctx->key;
result = HAL_CRYP_Init(HW_TypeDef);
if (result != HAL_OK)
{
/* Initialization Error */
goto _exit;
}
if (info->mode == HWCRYPTO_MODE_ENCRYPT)
{
result = HAL_CRYP_Encrypt_DMA(HW_TypeDef, (uint32_t *)info->in, info->length, (uint32_t *)info->out);
}
else if (info->mode == HWCRYPTO_MODE_DECRYPT)
{
result = HAL_CRYP_Decrypt_DMA(HW_TypeDef, (uint32_t *)info->in, info->length, (uint32_t *)info->out);
}
else
{
rt_kprintf("error cryp mode : %02x!\n", info->mode);
result = RT_ERROR;
goto _exit;
}
if (result != HAL_OK)
{
goto _exit;
}
tickstart = rt_tick_get();
while (HAL_CRYP_GetState(HW_TypeDef) != HAL_CRYP_STATE_READY)
{
if (rt_tick_get() - tickstart > 0xFFFF)
{
result = RT_ETIMEOUT;
goto _exit;
}
}
#endif
if (result != HAL_OK)
{
goto _exit;
}
_exit:
rt_mutex_release(&stm32_hw_dev->mutex);
return result;
}
static const struct hwcrypto_symmetric_ops cryp_ops =
{
.crypt = _cryp_crypt
};
#endif
static rt_err_t _crypto_create(struct rt_hwcrypto_ctx *ctx)
{
rt_err_t res = RT_EOK;
switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
{
#if defined(BSP_USING_RNG)
case HWCRYPTO_TYPE_RNG:
{
RNG_HandleTypeDef *hrng = rt_calloc(1, sizeof(RNG_HandleTypeDef));
if (RT_NULL == hrng)
{
res = -RT_ERROR;
break;
}
#if defined(SOC_SERIES_STM32MP1)
hrng->Instance = RNG2;
#else
hrng->Instance = RNG;
#endif
HAL_RNG_Init(hrng);
ctx->contex = hrng;
((struct hwcrypto_rng *)ctx)->ops = &rng_ops;
break;
}
#endif /* BSP_USING_RNG */
#if defined(BSP_USING_CRC)
case HWCRYPTO_TYPE_CRC:
{
CRC_HandleTypeDef *hcrc = rt_calloc(1, sizeof(CRC_HandleTypeDef));
if (RT_NULL == hcrc)
{
res = -RT_ERROR;
break;
}
#if defined(SOC_SERIES_STM32MP1)
hcrc->Instance = CRC2;
#else
hcrc->Instance = CRC;
#endif
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32MP1)
hcrc->Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE;
hcrc->Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE;
hcrc->Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE;
hcrc->Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE;
hcrc->InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
#else
if (HAL_CRC_Init(hcrc) != HAL_OK)
{
res = -RT_ERROR;
}
#endif /* defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) */
ctx->contex = hcrc;
((struct hwcrypto_crc *)ctx)->ops = &crc_ops;
break;
}
#endif /* BSP_USING_CRC */
#if defined(BSP_USING_HASH)
case HWCRYPTO_TYPE_MD5:
case HWCRYPTO_TYPE_SHA1:
case HWCRYPTO_TYPE_SHA2:
{
HASH_HandleTypeDef *hash = rt_calloc(1, sizeof(HASH_HandleTypeDef));
if (RT_NULL == hash)
{
res = -RT_ERROR;
break;
}
#if defined(SOC_SERIES_STM32MP1)
/* enable dma for hash */
__HAL_RCC_DMA2_CLK_ENABLE();
HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);
hash->Init.DataType = HASH_DATATYPE_8B;
if (HAL_HASH_Init(hash) != HAL_OK)
{
res = -RT_ERROR;
}
#endif
ctx->contex = hash;
((struct hwcrypto_hash *)ctx)->ops = &hash_ops;
break;
}
#endif /* BSP_USING_HASH */
#if defined(BSP_USING_CRYP)
case HWCRYPTO_TYPE_AES:
case HWCRYPTO_TYPE_DES:
case HWCRYPTO_TYPE_3DES:
case HWCRYPTO_TYPE_RC4:
case HWCRYPTO_TYPE_GCM:
{
CRYP_HandleTypeDef *cryp = rt_calloc(1, sizeof(CRYP_HandleTypeDef));
if (RT_NULL == cryp)
{
res = -RT_ERROR;
break;
}
#if defined(SOC_SERIES_STM32MP1)
cryp->Instance = CRYP2;
/* enable dma for cryp */
__HAL_RCC_DMA2_CLK_ENABLE();
HAL_NVIC_SetPriority(DMA2_Stream5_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn);
HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
if (HAL_CRYP_Init(cryp) != HAL_OK)
{
res = -RT_ERROR;
}
#endif
ctx->contex = cryp;
((struct hwcrypto_symmetric *)ctx)->ops = &cryp_ops;
break;
}
#endif /* BSP_USING_CRYP */
default:
res = -RT_ERROR;
break;
}
return res;
}
static void _crypto_destroy(struct rt_hwcrypto_ctx *ctx)
{
switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
{
#if defined(BSP_USING_RNG)
case HWCRYPTO_TYPE_RNG:
break;
#endif /* BSP_USING_RNG */
#if defined(BSP_USING_CRC)
case HWCRYPTO_TYPE_CRC:
__HAL_CRC_DR_RESET((CRC_HandleTypeDef *)ctx-> contex);
HAL_CRC_DeInit((CRC_HandleTypeDef *)(ctx->contex));
break;
#endif /* BSP_USING_CRC */
#if defined(BSP_USING_HASH)
case HWCRYPTO_TYPE_MD5:
case HWCRYPTO_TYPE_SHA1:
case HWCRYPTO_TYPE_SHA2:
__HAL_HASH_RESET_HANDLE_STATE((HASH_HandleTypeDef *)(ctx->contex));
HAL_HASH_DeInit((HASH_HandleTypeDef *)(ctx->contex));
break;
#endif /* BSP_USING_HASH */
#if defined(BSP_USING_CRYP)
case HWCRYPTO_TYPE_AES:
case HWCRYPTO_TYPE_DES:
case HWCRYPTO_TYPE_3DES:
case HWCRYPTO_TYPE_RC4:
case HWCRYPTO_TYPE_GCM:
HAL_CRYP_DeInit((CRYP_HandleTypeDef *)(ctx->contex));
break;
#endif /* BSP_USING_CRYP */
default:
break;
}
rt_free(ctx->contex);
}
static rt_err_t _crypto_clone(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
{
rt_err_t res = RT_EOK;
switch (src->type & HWCRYPTO_MAIN_TYPE_MASK)
{
#if defined(BSP_USING_RNG)
case HWCRYPTO_TYPE_RNG:
if (des->contex && src->contex)
{
rt_memcpy(des->contex, src->contex, sizeof(RNG_HandleTypeDef));
}
break;
#endif /* BSP_USING_RNG */
#if defined(BSP_USING_CRC)
case HWCRYPTO_TYPE_CRC:
if (des->contex && src->contex)
{
rt_memcpy(des->contex, src->contex, sizeof(CRC_HandleTypeDef));
}
break;
#endif /* BSP_USING_CRC */
#if defined(BSP_USING_HASH)
case HWCRYPTO_TYPE_MD5:
case HWCRYPTO_TYPE_SHA1:
case HWCRYPTO_TYPE_SHA2:
if (des->contex && src->contex)
{
rt_memcpy(des->contex, src->contex, sizeof(HASH_HandleTypeDef));
}
break;
#endif /* BSP_USING_HASH */
#if defined(BSP_USING_CRYP)
case HWCRYPTO_TYPE_AES:
case HWCRYPTO_TYPE_DES:
case HWCRYPTO_TYPE_3DES:
case HWCRYPTO_TYPE_RC4:
case HWCRYPTO_TYPE_GCM:
if (des->contex && src->contex)
{
rt_memcpy(des->contex, src->contex, sizeof(CRYP_HandleTypeDef));
}
break;
#endif /* BSP_USING_CRYP */
default:
res = -RT_ERROR;
break;
}
return res;
}
static void _crypto_reset(struct rt_hwcrypto_ctx *ctx)
{
switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
{
#if defined(BSP_USING_RNG)
case HWCRYPTO_TYPE_RNG:
break;
#endif /* BSP_USING_RNG */
#if defined(BSP_USING_CRC)
case HWCRYPTO_TYPE_CRC:
__HAL_CRC_DR_RESET((CRC_HandleTypeDef *)ctx-> contex);
break;
#endif /* BSP_USING_CRC */
#if defined(BSP_USING_HASH)
case HWCRYPTO_TYPE_MD5:
case HWCRYPTO_TYPE_SHA1:
case HWCRYPTO_TYPE_SHA2:
__HAL_HASH_RESET_HANDLE_STATE((HASH_HandleTypeDef *)(ctx->contex));
break;
#endif /* BSP_USING_HASH*/
#if defined(BSP_USING_CRYP)
case HWCRYPTO_TYPE_AES:
case HWCRYPTO_TYPE_DES:
case HWCRYPTO_TYPE_3DES:
case HWCRYPTO_TYPE_RC4:
case HWCRYPTO_TYPE_GCM:
break;
#endif /* BSP_USING_CRYP */
default:
break;
}
}
#if defined(HASH2_IN_DMA_INSTANCE)
void HASH2_DMA_IN_IRQHandler(void)
{
extern DMA_HandleTypeDef hdma_hash_in;
/* enter interrupt */
rt_interrupt_enter();
HAL_DMA_IRQHandler(&hdma_hash_in);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#if defined(CRYP2_IN_DMA_INSTANCE)
void CRYP2_DMA_IN_IRQHandler(void)
{
extern DMA_HandleTypeDef hdma_cryp_in;
/* enter interrupt */
rt_interrupt_enter();
HAL_DMA_IRQHandler(&hdma_cryp_in);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#if defined (CRYP2_OUT_DMA_INSTANCE)
void CRYP2_DMA_OUT_IRQHandler(void)
{
extern DMA_HandleTypeDef hdma_cryp_out;
/* enter interrupt */
rt_interrupt_enter();
HAL_DMA_IRQHandler(&hdma_cryp_out);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
static const struct rt_hwcrypto_ops _ops =
{
.create = _crypto_create,
.destroy = _crypto_destroy,
.copy = _crypto_clone,
.reset = _crypto_reset,
};
int stm32_hw_crypto_device_init(void)
{
static struct stm32_hwcrypto_device _crypto_dev;
rt_uint32_t cpuid[3] = {0};
_crypto_dev.dev.ops = &_ops;
#if defined(BSP_USING_UDID)
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
cpuid[0] = HAL_GetUIDw0();
cpuid[1] = HAL_GetUIDw1();
#elif defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1)
cpuid[0] = HAL_GetREVID();
cpuid[1] = HAL_GetDEVID();
#endif
#endif /* BSP_USING_UDID */
_crypto_dev.dev.id = 0;
rt_memcpy(&_crypto_dev.dev.id, cpuid, 8);
_crypto_dev.dev.user_data = &_crypto_dev;
if (rt_hwcrypto_register(&_crypto_dev.dev, RT_HWCRYPTO_DEFAULT_NAME) != RT_EOK)
{
return -1;
}
rt_mutex_init(&_crypto_dev.mutex, RT_HWCRYPTO_DEFAULT_NAME, RT_IPC_FLAG_PRIO);
return 0;
}
INIT_DEVICE_EXPORT(stm32_hw_crypto_device_init);
#endif
+215
View File
@@ -0,0 +1,215 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-06-18 thread-liu the first version
* 2020-10-09 thread-liu Porting for stm32h7xx
*/
#include <board.h>
#if defined(BSP_USING_DAC1) || defined(BSP_USING_DAC2)
#include "drv_config.h"
//#define DRV_DEBUG
#define LOG_TAG "drv.dac"
#include <drv_log.h>
static DAC_HandleTypeDef dac_config[] =
{
#ifdef BSP_USING_DAC1
DAC1_CONFIG,
#endif
#ifdef BSP_USING_DAC2
DAC2_CONFIG,
#endif
};
struct stm32_dac
{
DAC_HandleTypeDef DAC_Handler;
struct rt_dac_device stm32_dac_device;
};
static struct stm32_dac stm32_dac_obj[sizeof(dac_config) / sizeof(dac_config[0])];
static rt_uint32_t stm32_dac_get_channel(rt_uint32_t channel)
{
rt_uint32_t stm32_channel = 0;
switch (channel)
{
case 1:
stm32_channel = DAC_CHANNEL_1;
break;
case 2:
stm32_channel = DAC_CHANNEL_2;
break;
default:
RT_ASSERT(0);
break;
}
return stm32_channel;
}
static rt_err_t stm32_dac_enabled(struct rt_dac_device *device, rt_uint32_t channel)
{
uint32_t dac_channel;
DAC_HandleTypeDef *stm32_dac_handler;
RT_ASSERT(device != RT_NULL);
stm32_dac_handler = device->parent.user_data;
#if defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F4)
if ((channel <= 2) && (channel > 0))
{
/* set stm32 dac channel */
dac_channel = stm32_dac_get_channel(channel);
}
else
{
LOG_E("dac channel must be 1 or 2.");
return -RT_ERROR;
}
HAL_DAC_Start(stm32_dac_handler, dac_channel);
#endif
return RT_EOK;
}
static rt_err_t stm32_dac_disabled(struct rt_dac_device *device, rt_uint32_t channel)
{
uint32_t dac_channel;
DAC_HandleTypeDef *stm32_dac_handler;
RT_ASSERT(device != RT_NULL);
stm32_dac_handler = device->parent.user_data;
#if defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F4)
if ((channel <= 2) && (channel > 0))
{
/* set stm32 dac channel */
dac_channel = stm32_dac_get_channel(channel);
}
else
{
LOG_E("dac channel must be 1 or 2.");
return -RT_ERROR;
}
HAL_DAC_Stop(stm32_dac_handler, dac_channel);
#endif
return RT_EOK;
}
static rt_err_t stm32_set_dac_value(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value)
{
uint32_t dac_channel;
DAC_ChannelConfTypeDef DAC_ChanConf;
DAC_HandleTypeDef *stm32_dac_handler;
RT_ASSERT(device != RT_NULL);
RT_ASSERT(value != RT_NULL);
stm32_dac_handler = device->parent.user_data;
rt_memset(&DAC_ChanConf, 0, sizeof(DAC_ChanConf));
#if defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F4)
if ((channel <= 2) && (channel > 0))
{
/* set stm32 dac channel */
dac_channel = stm32_dac_get_channel(channel);
}
else
{
LOG_E("dac channel must be 1 or 2.");
return -RT_ERROR;
}
#endif
#if defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F4)
DAC_ChanConf.DAC_Trigger = DAC_TRIGGER_NONE;
DAC_ChanConf.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
#endif
/* config dac out channel*/
if (HAL_DAC_ConfigChannel(stm32_dac_handler, &DAC_ChanConf, dac_channel) != HAL_OK)
{
LOG_D("Config dac out channel Error!\n");
return -RT_ERROR;
}
/* set dac channel out value*/
if (HAL_DAC_SetValue(stm32_dac_handler, dac_channel, DAC_ALIGN_12B_R, *value) != HAL_OK)
{
LOG_D("Setting dac channel out value Error!\n");
return -RT_ERROR;
}
/* start dac */
if (HAL_DAC_Start(stm32_dac_handler, dac_channel) != HAL_OK)
{
LOG_D("Start dac Error!\n");
return -RT_ERROR;
}
return RT_EOK;
}
static const struct rt_dac_ops stm_dac_ops =
{
.disabled = stm32_dac_disabled,
.enabled = stm32_dac_enabled,
.convert = stm32_set_dac_value,
};
static int stm32_dac_init(void)
{
int result = RT_EOK;
/* save dac name */
char name_buf[5] = {'d', 'a', 'c', '0', 0};
int i = 0;
for (i = 0; i < sizeof(dac_config) / sizeof(dac_config[0]); i++)
{
/* dac init */
name_buf[3] = '0';
stm32_dac_obj[i].DAC_Handler = dac_config[i];
#if defined(DAC1)
if (stm32_dac_obj[i].DAC_Handler.Instance == DAC1)
{
name_buf[3] = '1';
}
#endif
#if defined(DAC2)
if (stm32_dac_obj[i].dac_Handler.Instance == DAC2)
{
name_buf[3] = '2';
}
#endif
if (HAL_DAC_Init(&stm32_dac_obj[i].DAC_Handler) != HAL_OK)
{
LOG_E("%s init failed", name_buf);
result = -RT_ERROR;
}
else
{
/* register dac device */
if (rt_hw_dac_register(&stm32_dac_obj[i].stm32_dac_device, name_buf, &stm_dac_ops, &stm32_dac_obj[i].DAC_Handler) == RT_EOK)
{
LOG_D("%s init success", name_buf);
}
else
{
LOG_E("%s register failed", name_buf);
result = -RT_ERROR;
}
}
}
return result;
}
INIT_DEVICE_EXPORT(stm32_dac_init);
#endif /* BSP_USING_DAC */
+671
View File
@@ -0,0 +1,671 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-19 SummerGift first version
* 2018-12-25 zylx fix some bugs
* 2019-06-10 SummerGift optimize PHY state detection process
* 2019-09-03 xiaofan optimize link change detection process
*/
#include <board.h>
#ifdef BSP_USING_ETH
#include "drv_config.h"
#include "drv_eth.h"
#include <netif/ethernetif.h>
#include <lwipopts.h>
/*
* Emac driver uses CubeMX tool to generate emac and phy's configuration,
* the configuration files can be found in CubeMX_Config folder.
*/
/* debug option */
//#define ETH_RX_DUMP
//#define ETH_TX_DUMP
//#define DRV_DEBUG
#define LOG_TAG "drv.emac"
#include <drv_log.h>
#define MAX_ADDR_LEN 6
struct rt_stm32_eth
{
/* inherit from ethernet device */
struct eth_device parent;
#ifndef PHY_USING_INTERRUPT_MODE
rt_timer_t poll_link_timer;
#endif
/* interface address info, hw address */
rt_uint8_t dev_addr[MAX_ADDR_LEN];
/* ETH_Speed */
rt_uint32_t ETH_Speed;
/* ETH_Duplex_Mode */
rt_uint32_t ETH_Mode;
};
static ETH_DMADescTypeDef *DMARxDscrTab, *DMATxDscrTab;
static rt_uint8_t *Rx_Buff, *Tx_Buff;
static ETH_HandleTypeDef EthHandle;
static struct rt_stm32_eth stm32_eth_device;
#if defined(ETH_RX_DUMP) || defined(ETH_TX_DUMP)
#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
{
unsigned char *buf = (unsigned char *)ptr;
int i, j;
for (i = 0; i < buflen; i += 16)
{
rt_kprintf("%08X: ", i);
for (j = 0; j < 16; j++)
if (i + j < buflen)
rt_kprintf("%02X ", buf[i + j]);
else
rt_kprintf(" ");
rt_kprintf(" ");
for (j = 0; j < 16; j++)
if (i + j < buflen)
rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
rt_kprintf("\n");
}
}
#endif
extern void phy_reset(void);
/* EMAC initialization function */
static rt_err_t rt_stm32_eth_init(rt_device_t dev)
{
__HAL_RCC_ETH_CLK_ENABLE();
phy_reset();
/* ETHERNET Configuration */
EthHandle.Instance = ETH;
EthHandle.Init.MACAddr = (rt_uint8_t *)&stm32_eth_device.dev_addr[0];
EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_DISABLE;
EthHandle.Init.Speed = ETH_SPEED_100M;
EthHandle.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
EthHandle.Init.RxMode = ETH_RXINTERRUPT_MODE;
#ifdef RT_LWIP_USING_HW_CHECKSUM
EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
#else
EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_SOFTWARE;
#endif
HAL_ETH_DeInit(&EthHandle);
/* configure ethernet peripheral (GPIOs, clocks, MAC, DMA) */
if (HAL_ETH_Init(&EthHandle) != HAL_OK)
{
LOG_E("eth hardware init failed");
}
else
{
LOG_D("eth hardware init success");
}
/* Initialize Tx Descriptors list: Chain Mode */
HAL_ETH_DMATxDescListInit(&EthHandle, DMATxDscrTab, Tx_Buff, ETH_TXBUFNB);
/* Initialize Rx Descriptors list: Chain Mode */
HAL_ETH_DMARxDescListInit(&EthHandle, DMARxDscrTab, Rx_Buff, ETH_RXBUFNB);
/* ETH interrupt Init */
HAL_NVIC_SetPriority(ETH_IRQn, 0x07, 0);
HAL_NVIC_EnableIRQ(ETH_IRQn);
/* Enable MAC and DMA transmission and reception */
if (HAL_ETH_Start(&EthHandle) == HAL_OK)
{
LOG_D("emac hardware start");
}
else
{
LOG_E("emac hardware start faild");
return -RT_ERROR;
}
return RT_EOK;
}
static rt_err_t rt_stm32_eth_open(rt_device_t dev, rt_uint16_t oflag)
{
LOG_D("emac open");
return RT_EOK;
}
static rt_err_t rt_stm32_eth_close(rt_device_t dev)
{
LOG_D("emac close");
return RT_EOK;
}
static rt_size_t rt_stm32_eth_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
LOG_D("emac read");
rt_set_errno(-RT_ENOSYS);
return 0;
}
static rt_size_t rt_stm32_eth_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
LOG_D("emac write");
rt_set_errno(-RT_ENOSYS);
return 0;
}
static rt_err_t rt_stm32_eth_control(rt_device_t dev, int cmd, void *args)
{
switch (cmd)
{
case NIOCTL_GADDR:
/* get mac address */
if (args)
{
SMEMCPY(args, stm32_eth_device.dev_addr, 6);
}
else
{
return -RT_ERROR;
}
break;
default :
break;
}
return RT_EOK;
}
/* ethernet device interface */
/* transmit data*/
rt_err_t rt_stm32_eth_tx(rt_device_t dev, struct pbuf *p)
{
rt_err_t ret = RT_ERROR;
HAL_StatusTypeDef state;
struct pbuf *q;
uint8_t *buffer = (uint8_t *)(EthHandle.TxDesc->Buffer1Addr);
__IO ETH_DMADescTypeDef *DmaTxDesc;
uint32_t framelength = 0;
uint32_t bufferoffset = 0;
uint32_t byteslefttocopy = 0;
uint32_t payloadoffset = 0;
DmaTxDesc = EthHandle.TxDesc;
bufferoffset = 0;
/* copy frame from pbufs to driver buffers */
for (q = p; q != NULL; q = q->next)
{
/* Is this buffer available? If not, goto error */
if ((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
{
LOG_D("buffer not valid");
ret = ERR_USE;
goto error;
}
/* Get bytes in current lwIP buffer */
byteslefttocopy = q->len;
payloadoffset = 0;
/* Check if the length of data to copy is bigger than Tx buffer size*/
while ((byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE)
{
/* Copy data to Tx buffer*/
SMEMCPY((uint8_t *)((uint8_t *)buffer + bufferoffset), (uint8_t *)((uint8_t *)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset));
/* Point to next descriptor */
DmaTxDesc = (ETH_DMADescTypeDef *)(DmaTxDesc->Buffer2NextDescAddr);
/* Check if the buffer is available */
if ((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
{
LOG_E("dma tx desc buffer is not valid");
ret = ERR_USE;
goto error;
}
buffer = (uint8_t *)(DmaTxDesc->Buffer1Addr);
byteslefttocopy = byteslefttocopy - (ETH_TX_BUF_SIZE - bufferoffset);
payloadoffset = payloadoffset + (ETH_TX_BUF_SIZE - bufferoffset);
framelength = framelength + (ETH_TX_BUF_SIZE - bufferoffset);
bufferoffset = 0;
}
/* Copy the remaining bytes */
SMEMCPY((uint8_t *)((uint8_t *)buffer + bufferoffset), (uint8_t *)((uint8_t *)q->payload + payloadoffset), byteslefttocopy);
bufferoffset = bufferoffset + byteslefttocopy;
framelength = framelength + byteslefttocopy;
}
#ifdef ETH_TX_DUMP
dump_hex(buffer, p->tot_len);
#endif
/* Prepare transmit descriptors to give to DMA */
/* TODO Optimize data send speed*/
LOG_D("transmit frame length :%d", framelength);
/* wait for unlocked */
while (EthHandle.Lock == HAL_LOCKED);
state = HAL_ETH_TransmitFrame(&EthHandle, framelength);
if (state != HAL_OK)
{
LOG_E("eth transmit frame faild: %d", state);
}
ret = ERR_OK;
error:
/* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */
if ((EthHandle.Instance->DMASR & ETH_DMASR_TUS) != (uint32_t)RESET)
{
/* Clear TUS ETHERNET DMA flag */
EthHandle.Instance->DMASR = ETH_DMASR_TUS;
/* Resume DMA transmission*/
EthHandle.Instance->DMATPDR = 0;
}
return ret;
}
/* receive data*/
struct pbuf *rt_stm32_eth_rx(rt_device_t dev)
{
struct pbuf *p = NULL;
struct pbuf *q = NULL;
HAL_StatusTypeDef state;
uint16_t len = 0;
uint8_t *buffer;
__IO ETH_DMADescTypeDef *dmarxdesc;
uint32_t bufferoffset = 0;
uint32_t payloadoffset = 0;
uint32_t byteslefttocopy = 0;
uint32_t i = 0;
/* Get received frame */
state = HAL_ETH_GetReceivedFrame_IT(&EthHandle);
if (state != HAL_OK)
{
LOG_D("receive frame faild");
return NULL;
}
/* Obtain the size of the packet and put it into the "len" variable. */
len = EthHandle.RxFrameInfos.length;
buffer = (uint8_t *)EthHandle.RxFrameInfos.buffer;
LOG_D("receive frame len : %d", len);
if (len > 0)
{
/* We allocate a pbuf chain of pbufs from the Lwip buffer pool */
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
}
#ifdef ETH_RX_DUMP
dump_hex(buffer, p->tot_len);
#endif
if (p != NULL)
{
dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc;
bufferoffset = 0;
for (q = p; q != NULL; q = q->next)
{
byteslefttocopy = q->len;
payloadoffset = 0;
/* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/
while ((byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE)
{
/* Copy data to pbuf */
SMEMCPY((uint8_t *)((uint8_t *)q->payload + payloadoffset), (uint8_t *)((uint8_t *)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset));
/* Point to next descriptor */
dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
buffer = (uint8_t *)(dmarxdesc->Buffer1Addr);
byteslefttocopy = byteslefttocopy - (ETH_RX_BUF_SIZE - bufferoffset);
payloadoffset = payloadoffset + (ETH_RX_BUF_SIZE - bufferoffset);
bufferoffset = 0;
}
/* Copy remaining data in pbuf */
SMEMCPY((uint8_t *)((uint8_t *)q->payload + payloadoffset), (uint8_t *)((uint8_t *)buffer + bufferoffset), byteslefttocopy);
bufferoffset = bufferoffset + byteslefttocopy;
}
}
/* Release descriptors to DMA */
/* Point to first descriptor */
dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc;
/* Set Own bit in Rx descriptors: gives the buffers back to DMA */
for (i = 0; i < EthHandle.RxFrameInfos.SegCount; i++)
{
dmarxdesc->Status |= ETH_DMARXDESC_OWN;
dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
}
/* Clear Segment_Count */
EthHandle.RxFrameInfos.SegCount = 0;
/* When Rx Buffer unavailable flag is set: clear it and resume reception */
if ((EthHandle.Instance->DMASR & ETH_DMASR_RBUS) != (uint32_t)RESET)
{
/* Clear RBUS ETHERNET DMA flag */
EthHandle.Instance->DMASR = ETH_DMASR_RBUS;
/* Resume DMA reception */
EthHandle.Instance->DMARPDR = 0;
}
return p;
}
/* interrupt service routine */
void ETH_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_ETH_IRQHandler(&EthHandle);
/* leave interrupt */
rt_interrupt_leave();
}
void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
{
rt_err_t result;
result = eth_device_ready(&(stm32_eth_device.parent));
if (result != RT_EOK)
{
LOG_I("RxCpltCallback err = %d", result);
}
}
void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
{
LOG_E("eth err");
}
enum {
PHY_LINK = (1 << 0),
PHY_100M = (1 << 1),
PHY_FULL_DUPLEX = (1 << 2),
};
static void phy_linkchange()
{
static rt_uint8_t phy_speed = 0;
rt_uint8_t phy_speed_new = 0;
rt_uint32_t status;
HAL_ETH_ReadPHYRegister(&EthHandle, PHY_BASIC_STATUS_REG, (uint32_t *)&status);
LOG_D("phy basic status reg is 0x%X", status);
if (status & (PHY_AUTONEGO_COMPLETE_MASK | PHY_LINKED_STATUS_MASK))
{
rt_uint32_t SR = 0;
phy_speed_new |= PHY_LINK;
HAL_ETH_ReadPHYRegister(&EthHandle, PHY_Status_REG, (uint32_t *)&SR);
LOG_D("phy control status reg is 0x%X", SR);
if (PHY_Status_SPEED_100M(SR))
{
phy_speed_new |= PHY_100M;
}
if (PHY_Status_FULL_DUPLEX(SR))
{
phy_speed_new |= PHY_FULL_DUPLEX;
}
}
if (phy_speed != phy_speed_new)
{
phy_speed = phy_speed_new;
if (phy_speed & PHY_LINK)
{
LOG_D("link up");
if (phy_speed & PHY_100M)
{
LOG_D("100Mbps");
stm32_eth_device.ETH_Speed = ETH_SPEED_100M;
}
else
{
stm32_eth_device.ETH_Speed = ETH_SPEED_10M;
LOG_D("10Mbps");
}
if (phy_speed & PHY_FULL_DUPLEX)
{
LOG_D("full-duplex");
stm32_eth_device.ETH_Mode = ETH_MODE_FULLDUPLEX;
}
else
{
LOG_D("half-duplex");
stm32_eth_device.ETH_Mode = ETH_MODE_HALFDUPLEX;
}
/* send link up. */
eth_device_linkchange(&stm32_eth_device.parent, RT_TRUE);
}
else
{
LOG_I("link down");
eth_device_linkchange(&stm32_eth_device.parent, RT_FALSE);
}
}
}
#ifdef PHY_USING_INTERRUPT_MODE
static void eth_phy_isr(void *args)
{
rt_uint32_t status = 0;
HAL_ETH_ReadPHYRegister(&EthHandle, PHY_INTERRUPT_FLAG_REG, (uint32_t *)&status);
LOG_D("phy interrupt status reg is 0x%X", status);
phy_linkchange();
}
#endif /* PHY_USING_INTERRUPT_MODE */
static void phy_monitor_thread_entry(void *parameter)
{
uint8_t phy_addr = 0xFF;
uint8_t detected_count = 0;
while(phy_addr == 0xFF)
{
/* phy search */
rt_uint32_t i, temp;
for (i = 0; i <= 0x1F; i++)
{
EthHandle.Init.PhyAddress = i;
HAL_ETH_ReadPHYRegister(&EthHandle, PHY_ID1_REG, (uint32_t *)&temp);
if (temp != 0xFFFF && temp != 0x00)
{
phy_addr = i;
break;
}
}
detected_count++;
rt_thread_mdelay(1000);
if (detected_count > 10)
{
LOG_E("No PHY device was detected, please check hardware!");
}
}
LOG_D("Found a phy, address:0x%02X", phy_addr);
/* RESET PHY */
LOG_D("RESET PHY!");
HAL_ETH_WritePHYRegister(&EthHandle, PHY_BASIC_CONTROL_REG, PHY_RESET_MASK);
rt_thread_mdelay(2000);
HAL_ETH_WritePHYRegister(&EthHandle, PHY_BASIC_CONTROL_REG, PHY_AUTO_NEGOTIATION_MASK);
phy_linkchange();
#ifdef PHY_USING_INTERRUPT_MODE
/* configuration intterrupt pin */
rt_pin_mode(PHY_INT_PIN, PIN_MODE_INPUT_PULLUP);
rt_pin_attach_irq(PHY_INT_PIN, PIN_IRQ_MODE_FALLING, eth_phy_isr, (void *)"callbackargs");
rt_pin_irq_enable(PHY_INT_PIN, PIN_IRQ_ENABLE);
/* enable phy interrupt */
HAL_ETH_WritePHYRegister(&EthHandle, PHY_INTERRUPT_MASK_REG, PHY_INT_MASK);
#if defined(PHY_INTERRUPT_CTRL_REG)
HAL_ETH_WritePHYRegister(&EthHandle, PHY_INTERRUPT_CTRL_REG, PHY_INTERRUPT_EN);
#endif
#else /* PHY_USING_INTERRUPT_MODE */
stm32_eth_device.poll_link_timer = rt_timer_create("phylnk", (void (*)(void*))phy_linkchange,
NULL, RT_TICK_PER_SECOND, RT_TIMER_FLAG_PERIODIC);
if (!stm32_eth_device.poll_link_timer || rt_timer_start(stm32_eth_device.poll_link_timer) != RT_EOK)
{
LOG_E("Start link change detection timer failed");
}
#endif /* PHY_USING_INTERRUPT_MODE */
}
/* Register the EMAC device */
static int rt_hw_stm32_eth_init(void)
{
rt_err_t state = RT_EOK;
/* Prepare receive and send buffers */
Rx_Buff = (rt_uint8_t *)rt_calloc(ETH_RXBUFNB, ETH_MAX_PACKET_SIZE);
if (Rx_Buff == RT_NULL)
{
LOG_E("No memory");
state = -RT_ENOMEM;
goto __exit;
}
Tx_Buff = (rt_uint8_t *)rt_calloc(ETH_TXBUFNB, ETH_MAX_PACKET_SIZE);
if (Tx_Buff == RT_NULL)
{
LOG_E("No memory");
state = -RT_ENOMEM;
goto __exit;
}
DMARxDscrTab = (ETH_DMADescTypeDef *)rt_calloc(ETH_RXBUFNB, sizeof(ETH_DMADescTypeDef));
if (DMARxDscrTab == RT_NULL)
{
LOG_E("No memory");
state = -RT_ENOMEM;
goto __exit;
}
DMATxDscrTab = (ETH_DMADescTypeDef *)rt_calloc(ETH_TXBUFNB, sizeof(ETH_DMADescTypeDef));
if (DMATxDscrTab == RT_NULL)
{
LOG_E("No memory");
state = -RT_ENOMEM;
goto __exit;
}
stm32_eth_device.ETH_Speed = ETH_SPEED_100M;
stm32_eth_device.ETH_Mode = ETH_MODE_FULLDUPLEX;
/* OUI 00-80-E1 STMICROELECTRONICS. */
stm32_eth_device.dev_addr[0] = 0x00;
stm32_eth_device.dev_addr[1] = 0x80;
stm32_eth_device.dev_addr[2] = 0xE1;
/* generate MAC addr from 96bit unique ID (only for test). */
stm32_eth_device.dev_addr[3] = *(rt_uint8_t *)(UID_BASE + 4);
stm32_eth_device.dev_addr[4] = *(rt_uint8_t *)(UID_BASE + 2);
stm32_eth_device.dev_addr[5] = *(rt_uint8_t *)(UID_BASE + 0);
stm32_eth_device.parent.parent.init = rt_stm32_eth_init;
stm32_eth_device.parent.parent.open = rt_stm32_eth_open;
stm32_eth_device.parent.parent.close = rt_stm32_eth_close;
stm32_eth_device.parent.parent.read = rt_stm32_eth_read;
stm32_eth_device.parent.parent.write = rt_stm32_eth_write;
stm32_eth_device.parent.parent.control = rt_stm32_eth_control;
stm32_eth_device.parent.parent.user_data = RT_NULL;
stm32_eth_device.parent.eth_rx = rt_stm32_eth_rx;
stm32_eth_device.parent.eth_tx = rt_stm32_eth_tx;
/* register eth device */
state = eth_device_init(&(stm32_eth_device.parent), "e0");
if (RT_EOK == state)
{
LOG_D("emac device init success");
}
else
{
LOG_E("emac device init faild: %d", state);
state = -RT_ERROR;
goto __exit;
}
/* start phy monitor */
rt_thread_t tid;
tid = rt_thread_create("phy",
phy_monitor_thread_entry,
RT_NULL,
1024,
RT_THREAD_PRIORITY_MAX - 2,
2);
if (tid != RT_NULL)
{
rt_thread_startup(tid);
}
else
{
state = -RT_ERROR;
}
__exit:
if (state != RT_EOK)
{
if (Rx_Buff)
{
rt_free(Rx_Buff);
}
if (Tx_Buff)
{
rt_free(Tx_Buff);
}
if (DMARxDscrTab)
{
rt_free(DMARxDscrTab);
}
if (DMATxDscrTab)
{
rt_free(DMATxDscrTab);
}
}
return state;
}
INIT_DEVICE_EXPORT(rt_hw_stm32_eth_init);
#endif
+420
View File
@@ -0,0 +1,420 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-5 SummerGift first version
*/
#include "board.h"
#ifdef BSP_USING_ON_CHIP_FLASH
#include "drv_config.h"
#include "drv_flash.h"
#if defined(RT_USING_FAL) || defined(PKG_USING_FAL)
#include "fal.h"
#endif
//#define DRV_DEBUG
#define LOG_TAG "drv.flash"
#include <drv_log.h>
/* Base address of the Flash sectors Bank 1 */
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbytes */
#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbytes */
#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbytes */
#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbytes */
#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbytes */
#define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base @ of Sector 8, 128 Kbytes */
#define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) /* Base @ of Sector 9, 128 Kbytes */
#define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 Kbytes */
#define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 Kbytes */
/* Base address of the Flash sectors Bank 2 */
#define ADDR_FLASH_SECTOR_12 ((uint32_t)0x08100000) /* Base @ of Sector 0, 16 Kbytes */
#define ADDR_FLASH_SECTOR_13 ((uint32_t)0x08104000) /* Base @ of Sector 1, 16 Kbytes */
#define ADDR_FLASH_SECTOR_14 ((uint32_t)0x08108000) /* Base @ of Sector 2, 16 Kbytes */
#define ADDR_FLASH_SECTOR_15 ((uint32_t)0x0810C000) /* Base @ of Sector 3, 16 Kbytes */
#define ADDR_FLASH_SECTOR_16 ((uint32_t)0x08110000) /* Base @ of Sector 4, 64 Kbytes */
#define ADDR_FLASH_SECTOR_17 ((uint32_t)0x08120000) /* Base @ of Sector 5, 128 Kbytes */
#define ADDR_FLASH_SECTOR_18 ((uint32_t)0x08140000) /* Base @ of Sector 6, 128 Kbytes */
#define ADDR_FLASH_SECTOR_19 ((uint32_t)0x08160000) /* Base @ of Sector 7, 128 Kbytes */
#define ADDR_FLASH_SECTOR_20 ((uint32_t)0x08180000) /* Base @ of Sector 8, 128 Kbytes */
#define ADDR_FLASH_SECTOR_21 ((uint32_t)0x081A0000) /* Base @ of Sector 9, 128 Kbytes */
#define ADDR_FLASH_SECTOR_22 ((uint32_t)0x081C0000) /* Base @ of Sector 10, 128 Kbytes */
#define ADDR_FLASH_SECTOR_23 ((uint32_t)0x081E0000) /* Base @ of Sector 11, 128 Kbytes */
/**
* @brief Gets the sector of a given address
* @param None
* @retval The sector of a given address
*/
static rt_uint32_t GetSector(rt_uint32_t Address)
{
rt_uint32_t sector = 0;
if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
{
sector = FLASH_SECTOR_0;
}
else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
{
sector = FLASH_SECTOR_1;
}
else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
{
sector = FLASH_SECTOR_2;
}
else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
{
sector = FLASH_SECTOR_3;
}
else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
{
sector = FLASH_SECTOR_4;
}
else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
{
sector = FLASH_SECTOR_5;
}
else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
{
sector = FLASH_SECTOR_6;
}
else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))
{
sector = FLASH_SECTOR_7;
}
#if defined(FLASH_SECTOR_8)
else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8))
{
sector = FLASH_SECTOR_8;
}
#endif
#if defined(FLASH_SECTOR_9)
else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9))
{
sector = FLASH_SECTOR_9;
}
#endif
#if defined(FLASH_SECTOR_10)
else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10))
{
sector = FLASH_SECTOR_10;
}
#endif
#if defined(FLASH_SECTOR_11)
else if((Address < ADDR_FLASH_SECTOR_12) && (Address >= ADDR_FLASH_SECTOR_11))
{
sector = FLASH_SECTOR_11;
}
#endif
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx)
else if((Address < ADDR_FLASH_SECTOR_13) && (Address >= ADDR_FLASH_SECTOR_12))
{
sector = FLASH_SECTOR_12;
}
else if((Address < ADDR_FLASH_SECTOR_14) && (Address >= ADDR_FLASH_SECTOR_13))
{
sector = FLASH_SECTOR_13;
}
else if((Address < ADDR_FLASH_SECTOR_15) && (Address >= ADDR_FLASH_SECTOR_14))
{
sector = FLASH_SECTOR_14;
}
else if((Address < ADDR_FLASH_SECTOR_16) && (Address >= ADDR_FLASH_SECTOR_15))
{
sector = FLASH_SECTOR_15;
}
else if((Address < ADDR_FLASH_SECTOR_17) && (Address >= ADDR_FLASH_SECTOR_16))
{
sector = FLASH_SECTOR_16;
}
else if((Address < ADDR_FLASH_SECTOR_18) && (Address >= ADDR_FLASH_SECTOR_17))
{
sector = FLASH_SECTOR_17;
}
else if((Address < ADDR_FLASH_SECTOR_19) && (Address >= ADDR_FLASH_SECTOR_18))
{
sector = FLASH_SECTOR_18;
}
else if((Address < ADDR_FLASH_SECTOR_20) && (Address >= ADDR_FLASH_SECTOR_19))
{
sector = FLASH_SECTOR_19;
}
else if((Address < ADDR_FLASH_SECTOR_21) && (Address >= ADDR_FLASH_SECTOR_20))
{
sector = FLASH_SECTOR_20;
}
else if((Address < ADDR_FLASH_SECTOR_22) && (Address >= ADDR_FLASH_SECTOR_21))
{
sector = FLASH_SECTOR_21;
}
else if((Address < ADDR_FLASH_SECTOR_23) && (Address >= ADDR_FLASH_SECTOR_22))
{
sector = FLASH_SECTOR_22;
}
else /* (Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_23) */
{
sector = FLASH_SECTOR_23;
}
#endif
return sector;
}
/**
* Read data from flash.
* @note This operation's units is word.
*
* @param addr flash address
* @param buf buffer to store read data
* @param size read bytes size
*
* @return result
*/
int stm32_flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size)
{
size_t i;
if ((addr + size) > STM32_FLASH_END_ADDRESS)
{
LOG_E("read outrange flash size! addr is (0x%p)", (void*)(addr + size));
return -1;
}
for (i = 0; i < size; i++, buf++, addr++)
{
*buf = *(rt_uint8_t *) addr;
}
return size;
}
/**
* Write data to flash.
* @note This operation's units is word.
* @note This operation must after erase. @see flash_erase.
*
* @param addr flash address
* @param buf the write data buffer
* @param size write bytes size
*
* @return result
*/
int stm32_flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size)
{
rt_err_t result = RT_EOK;
rt_uint32_t end_addr = addr + size;
rt_uint32_t written_size = 0;
rt_uint32_t write_size = 0;
if ((end_addr) > STM32_FLASH_END_ADDRESS)
{
LOG_E("write outrange flash size! addr is (0x%p)", (void*)(addr + size));
return -RT_EINVAL;
}
if (size < 1)
{
return -RT_EINVAL;
}
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
while (written_size < size)
{
if (((addr + written_size) % 4 == 0) && (size - written_size >= 4))
{
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr + written_size, *((rt_uint32_t *)(buf + written_size))) == HAL_OK)
{
if (*(rt_uint32_t *)(addr + written_size) != *(rt_uint32_t *)(buf + written_size))
{
result = -RT_ERROR;
break;
}
}
else
{
result = -RT_ERROR;
break;
}
write_size = 4;
}
else if (((addr + written_size) % 2 == 0) && (size - written_size >= 2))
{
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, addr + written_size, *((rt_uint16_t *)(buf + written_size))) == HAL_OK)
{
if (*(rt_uint16_t *)(addr + written_size) != *(rt_uint16_t *)(buf + written_size))
{
result = -RT_ERROR;
break;
}
}
else
{
result = -RT_ERROR;
break;
}
write_size = 2;
}
else
{
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, addr + written_size, *((rt_uint8_t *)(buf + written_size))) == HAL_OK)
{
if (*(rt_uint8_t *)(addr + written_size) != *(rt_uint8_t *)(buf + written_size))
{
result = -RT_ERROR;
break;
}
}
else
{
result = -RT_ERROR;
break;
}
write_size = 1;
}
written_size += write_size;
}
HAL_FLASH_Lock();
if (result != RT_EOK)
{
return result;
}
return size;
}
/**
* Erase data on flash.
* @note This operation is irreversible.
* @note This operation's units is different which on many chips.
*
* @param addr flash address
* @param size erase bytes size
*
* @return result
*/
int stm32_flash_erase(rt_uint32_t addr, size_t size)
{
rt_err_t result = RT_EOK;
rt_uint32_t FirstSector = 0, NbOfSectors = 0;
rt_uint32_t SECTORError = 0;
if ((addr + size) > STM32_FLASH_END_ADDRESS)
{
LOG_E("ERROR: erase outrange flash size! addr is (0x%p)\n", (void*)(addr + size));
return -RT_EINVAL;
}
if (size < 1)
{
return -RT_EINVAL;
}
/*Variable used for Erase procedure*/
FLASH_EraseInitTypeDef EraseInitStruct;
/* Unlock the Flash to enable the flash control register access */
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
/* Get the 1st sector to erase */
FirstSector = GetSector(addr);
/* Get the number of sector to erase from 1st sector*/
NbOfSectors = GetSector(addr + size - 1) - FirstSector + 1;
/* Fill EraseInit structure*/
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
EraseInitStruct.Sector = FirstSector;
EraseInitStruct.NbSectors = NbOfSectors;
if (HAL_FLASHEx_Erase(&EraseInitStruct, (uint32_t *)&SECTORError) != HAL_OK)
{
result = -RT_ERROR;
goto __exit;
}
__exit:
HAL_FLASH_Lock();
if (result != RT_EOK)
{
return result;
}
LOG_D("erase done: addr (0x%p), size %d", (void*)addr, size);
return size;
}
#if defined(RT_USING_FAL) || defined(PKG_USING_FAL)
static int fal_flash_read_16k(long offset, rt_uint8_t *buf, size_t size);
static int fal_flash_read_64k(long offset, rt_uint8_t *buf, size_t size);
static int fal_flash_read_128k(long offset, rt_uint8_t *buf, size_t size);
static int fal_flash_write_16k(long offset, const rt_uint8_t *buf, size_t size);
static int fal_flash_write_64k(long offset, const rt_uint8_t *buf, size_t size);
static int fal_flash_write_128k(long offset, const rt_uint8_t *buf, size_t size);
static int fal_flash_erase_16k(long offset, size_t size);
static int fal_flash_erase_64k(long offset, size_t size);
static int fal_flash_erase_128k(long offset, size_t size);
const struct fal_flash_dev stm32_onchip_flash_16k = { "onchip_flash_16k", STM32_FLASH_START_ADRESS_16K, FLASH_SIZE_GRANULARITY_16K, (16 * 1024), {NULL, fal_flash_read_16k, fal_flash_write_16k, fal_flash_erase_16k} };
const struct fal_flash_dev stm32_onchip_flash_64k = { "onchip_flash_64k", STM32_FLASH_START_ADRESS_64K, FLASH_SIZE_GRANULARITY_64K, (64 * 1024), {NULL, fal_flash_read_64k, fal_flash_write_64k, fal_flash_erase_64k} };
const struct fal_flash_dev stm32_onchip_flash_128k = { "onchip_flash_128k", STM32_FLASH_START_ADRESS_128K, FLASH_SIZE_GRANULARITY_128K, (128 * 1024), {NULL, fal_flash_read_128k, fal_flash_write_128k, fal_flash_erase_128k} };
static int fal_flash_read_16k(long offset, rt_uint8_t *buf, size_t size)
{
return stm32_flash_read(stm32_onchip_flash_16k.addr + offset, buf, size);
}
static int fal_flash_read_64k(long offset, rt_uint8_t *buf, size_t size)
{
return stm32_flash_read(stm32_onchip_flash_64k.addr + offset, buf, size);
}
static int fal_flash_read_128k(long offset, rt_uint8_t *buf, size_t size)
{
return stm32_flash_read(stm32_onchip_flash_128k.addr + offset, buf, size);
}
static int fal_flash_write_16k(long offset, const rt_uint8_t *buf, size_t size)
{
return stm32_flash_write(stm32_onchip_flash_16k.addr + offset, buf, size);
}
static int fal_flash_write_64k(long offset, const rt_uint8_t *buf, size_t size)
{
return stm32_flash_write(stm32_onchip_flash_64k.addr + offset, buf, size);
}
static int fal_flash_write_128k(long offset, const rt_uint8_t *buf, size_t size)
{
return stm32_flash_write(stm32_onchip_flash_128k.addr + offset, buf, size);
}
static int fal_flash_erase_16k(long offset, size_t size)
{
return stm32_flash_erase(stm32_onchip_flash_16k.addr + offset, size);
}
static int fal_flash_erase_64k(long offset, size_t size)
{
return stm32_flash_erase(stm32_onchip_flash_64k.addr + offset, size);
}
static int fal_flash_erase_128k(long offset, size_t size)
{
return stm32_flash_erase(stm32_onchip_flash_128k.addr + offset, size);
}
#endif
#endif /* BSP_USING_ON_CHIP_FLASH */
+801
View File
@@ -0,0 +1,801 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-06 balanceTWK first version
* 2019-04-23 WillianChan Fix GPIO serial number disorder
* 2020-06-16 thread-liu add STM32MP1
* 2020-09-01 thread-liu add GPIOZ
* 2020-09-18 geniusgogo optimization design pin-index algorithm
*/
#include <board.h>
#ifdef RT_USING_PIN
#define PIN_NUM(port, no) (((((port) & 0xFu) << 4) | ((no) & 0xFu)))
#define PIN_PORT(pin) ((uint8_t)(((pin) >> 4) & 0xFu))
#define PIN_NO(pin) ((uint8_t)((pin) & 0xFu))
#if defined(SOC_SERIES_STM32MP1)
#if defined(GPIOZ)
#define gpioz_port_base (175) /* PIN_STPORT_MAX * 16 - 16 */
#define PIN_STPORT(pin) ((pin > gpioz_port_base) ? ((GPIO_TypeDef *)(GPIOZ_BASE )) : ((GPIO_TypeDef *)(GPIOA_BASE + (0x1000u * PIN_PORT(pin)))))
#else
#define PIN_STPORT(pin) ((GPIO_TypeDef *)(GPIOA_BASE + (0x1000u * PIN_PORT(pin))))
#endif /* GPIOZ */
#else
#define PIN_STPORT(pin) ((GPIO_TypeDef *)(GPIOA_BASE + (0x400u * PIN_PORT(pin))))
#endif /* SOC_SERIES_STM32MP1 */
#define PIN_STPIN(pin) ((uint16_t)(1u << PIN_NO(pin)))
#if defined(GPIOZ)
#define __STM32_PORT_MAX 12u
#elif defined(GPIOK)
#define __STM32_PORT_MAX 11u
#elif defined(GPIOJ)
#define __STM32_PORT_MAX 10u
#elif defined(GPIOI)
#define __STM32_PORT_MAX 9u
#elif defined(GPIOH)
#define __STM32_PORT_MAX 8u
#elif defined(GPIOG)
#define __STM32_PORT_MAX 7u
#elif defined(GPIOF)
#define __STM32_PORT_MAX 6u
#elif defined(GPIOE)
#define __STM32_PORT_MAX 5u
#elif defined(GPIOD)
#define __STM32_PORT_MAX 4u
#elif defined(GPIOC)
#define __STM32_PORT_MAX 3u
#elif defined(GPIOB)
#define __STM32_PORT_MAX 2u
#elif defined(GPIOA)
#define __STM32_PORT_MAX 1u
#else
#define __STM32_PORT_MAX 0u
#error Unsupported STM32 GPIO peripheral.
#endif
#define PIN_STPORT_MAX __STM32_PORT_MAX
struct pin_irq_map
{
rt_uint16_t pinbit;
IRQn_Type irqno;
};
static const struct pin_irq_map pin_irq_map[] =
{
#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32G0)
{GPIO_PIN_0, EXTI0_1_IRQn},
{GPIO_PIN_1, EXTI0_1_IRQn},
{GPIO_PIN_2, EXTI2_3_IRQn},
{GPIO_PIN_3, EXTI2_3_IRQn},
{GPIO_PIN_4, EXTI4_15_IRQn},
{GPIO_PIN_5, EXTI4_15_IRQn},
{GPIO_PIN_6, EXTI4_15_IRQn},
{GPIO_PIN_7, EXTI4_15_IRQn},
{GPIO_PIN_8, EXTI4_15_IRQn},
{GPIO_PIN_9, EXTI4_15_IRQn},
{GPIO_PIN_10, EXTI4_15_IRQn},
{GPIO_PIN_11, EXTI4_15_IRQn},
{GPIO_PIN_12, EXTI4_15_IRQn},
{GPIO_PIN_13, EXTI4_15_IRQn},
{GPIO_PIN_14, EXTI4_15_IRQn},
{GPIO_PIN_15, EXTI4_15_IRQn},
#elif defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32L5) || defined(SOC_SERIES_STM32U5)
{GPIO_PIN_0, EXTI0_IRQn},
{GPIO_PIN_1, EXTI1_IRQn},
{GPIO_PIN_2, EXTI2_IRQn},
{GPIO_PIN_3, EXTI3_IRQn},
{GPIO_PIN_4, EXTI4_IRQn},
{GPIO_PIN_5, EXTI5_IRQn},
{GPIO_PIN_6, EXTI6_IRQn},
{GPIO_PIN_7, EXTI7_IRQn},
{GPIO_PIN_8, EXTI8_IRQn},
{GPIO_PIN_9, EXTI9_IRQn},
{GPIO_PIN_10, EXTI10_IRQn},
{GPIO_PIN_11, EXTI11_IRQn},
{GPIO_PIN_12, EXTI12_IRQn},
{GPIO_PIN_13, EXTI13_IRQn},
{GPIO_PIN_14, EXTI14_IRQn},
{GPIO_PIN_15, EXTI15_IRQn},
#elif defined(SOC_SERIES_STM32F3)
{GPIO_PIN_0, EXTI0_IRQn},
{GPIO_PIN_1, EXTI1_IRQn},
{GPIO_PIN_2, EXTI2_TSC_IRQn},
{GPIO_PIN_3, EXTI3_IRQn},
{GPIO_PIN_4, EXTI4_IRQn},
{GPIO_PIN_5, EXTI9_5_IRQn},
{GPIO_PIN_6, EXTI9_5_IRQn},
{GPIO_PIN_7, EXTI9_5_IRQn},
{GPIO_PIN_8, EXTI9_5_IRQn},
{GPIO_PIN_9, EXTI9_5_IRQn},
{GPIO_PIN_10, EXTI15_10_IRQn},
{GPIO_PIN_11, EXTI15_10_IRQn},
{GPIO_PIN_12, EXTI15_10_IRQn},
{GPIO_PIN_13, EXTI15_10_IRQn},
{GPIO_PIN_14, EXTI15_10_IRQn},
{GPIO_PIN_15, EXTI15_10_IRQn},
#else
{GPIO_PIN_0, EXTI0_IRQn},
{GPIO_PIN_1, EXTI1_IRQn},
{GPIO_PIN_2, EXTI2_IRQn},
{GPIO_PIN_3, EXTI3_IRQn},
{GPIO_PIN_4, EXTI4_IRQn},
{GPIO_PIN_5, EXTI9_5_IRQn},
{GPIO_PIN_6, EXTI9_5_IRQn},
{GPIO_PIN_7, EXTI9_5_IRQn},
{GPIO_PIN_8, EXTI9_5_IRQn},
{GPIO_PIN_9, EXTI9_5_IRQn},
{GPIO_PIN_10, EXTI15_10_IRQn},
{GPIO_PIN_11, EXTI15_10_IRQn},
{GPIO_PIN_12, EXTI15_10_IRQn},
{GPIO_PIN_13, EXTI15_10_IRQn},
{GPIO_PIN_14, EXTI15_10_IRQn},
{GPIO_PIN_15, EXTI15_10_IRQn},
#endif
};
static struct rt_pin_irq_hdr pin_irq_hdr_tab[] =
{
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
};
static uint32_t pin_irq_enable_mask = 0;
#define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
static rt_base_t stm32_pin_get(const char *name)
{
rt_base_t pin = 0;
int hw_port_num, hw_pin_num = 0;
int i, name_len;
name_len = rt_strlen(name);
if ((name_len < 4) || (name_len >= 6))
{
return -RT_EINVAL;
}
if ((name[0] != 'P') || (name[2] != '.'))
{
return -RT_EINVAL;
}
if ((name[1] >= 'A') && (name[1] <= 'Z'))
{
hw_port_num = (int)(name[1] - 'A');
}
else
{
return -RT_EINVAL;
}
for (i = 3; i < name_len; i++)
{
hw_pin_num *= 10;
hw_pin_num += name[i] - '0';
}
pin = PIN_NUM(hw_port_num, hw_pin_num);
return pin;
}
static void stm32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
{
GPIO_TypeDef *gpio_port;
uint16_t gpio_pin;
if (PIN_PORT(pin) < PIN_STPORT_MAX)
{
gpio_port = PIN_STPORT(pin);
gpio_pin = PIN_STPIN(pin);
HAL_GPIO_WritePin(gpio_port, gpio_pin, (GPIO_PinState)value);
}
}
static int stm32_pin_read(rt_device_t dev, rt_base_t pin)
{
GPIO_TypeDef *gpio_port;
uint16_t gpio_pin;
int value = PIN_LOW;
if (PIN_PORT(pin) < PIN_STPORT_MAX)
{
gpio_port = PIN_STPORT(pin);
gpio_pin = PIN_STPIN(pin);
value = HAL_GPIO_ReadPin(gpio_port, gpio_pin);
}
return value;
}
static void stm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
{
GPIO_InitTypeDef GPIO_InitStruct;
if (PIN_PORT(pin) >= PIN_STPORT_MAX)
{
return;
}
/* Configure GPIO_InitStructure */
GPIO_InitStruct.Pin = PIN_STPIN(pin);
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
if (mode == PIN_MODE_OUTPUT)
{
/* output setting */
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
}
else if (mode == PIN_MODE_INPUT)
{
/* input setting: not pull. */
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
}
else if (mode == PIN_MODE_INPUT_PULLUP)
{
/* input setting: pull up. */
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
}
else if (mode == PIN_MODE_INPUT_PULLDOWN)
{
/* input setting: pull down. */
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
}
else if (mode == PIN_MODE_OUTPUT_OD)
{
/* output setting: od. */
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
}
HAL_GPIO_Init(PIN_STPORT(pin), &GPIO_InitStruct);
}
rt_inline rt_int32_t bit2bitno(rt_uint32_t bit)
{
rt_uint8_t i;
for (i = 0; i < 32; i++)
{
if ((0x01 << i) == bit)
{
return i;
}
}
return -1;
}
rt_inline const struct pin_irq_map *get_pin_irq_map(uint32_t pinbit)
{
rt_int32_t mapindex = bit2bitno(pinbit);
if (mapindex < 0 || mapindex >= ITEM_NUM(pin_irq_map))
{
return RT_NULL;
}
return &pin_irq_map[mapindex];
};
static rt_err_t stm32_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
rt_uint32_t mode, void (*hdr)(void *args), void *args)
{
rt_base_t level;
rt_int32_t irqindex = -1;
if (PIN_PORT(pin) >= PIN_STPORT_MAX)
{
return -RT_ENOSYS;
}
irqindex = bit2bitno(PIN_STPIN(pin));
if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
{
return RT_ENOSYS;
}
level = rt_hw_interrupt_disable();
if (pin_irq_hdr_tab[irqindex].pin == pin &&
pin_irq_hdr_tab[irqindex].hdr == hdr &&
pin_irq_hdr_tab[irqindex].mode == mode &&
pin_irq_hdr_tab[irqindex].args == args)
{
rt_hw_interrupt_enable(level);
return RT_EOK;
}
if (pin_irq_hdr_tab[irqindex].pin != -1)
{
rt_hw_interrupt_enable(level);
return RT_EBUSY;
}
pin_irq_hdr_tab[irqindex].pin = pin;
pin_irq_hdr_tab[irqindex].hdr = hdr;
pin_irq_hdr_tab[irqindex].mode = mode;
pin_irq_hdr_tab[irqindex].args = args;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
static rt_err_t stm32_pin_dettach_irq(struct rt_device *device, rt_int32_t pin)
{
rt_base_t level;
rt_int32_t irqindex = -1;
if (PIN_PORT(pin) >= PIN_STPORT_MAX)
{
return -RT_ENOSYS;
}
irqindex = bit2bitno(PIN_STPIN(pin));
if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
{
return RT_ENOSYS;
}
level = rt_hw_interrupt_disable();
if (pin_irq_hdr_tab[irqindex].pin == -1)
{
rt_hw_interrupt_enable(level);
return RT_EOK;
}
pin_irq_hdr_tab[irqindex].pin = -1;
pin_irq_hdr_tab[irqindex].hdr = RT_NULL;
pin_irq_hdr_tab[irqindex].mode = 0;
pin_irq_hdr_tab[irqindex].args = RT_NULL;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
static rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin,
rt_uint32_t enabled)
{
const struct pin_irq_map *irqmap;
rt_base_t level;
rt_int32_t irqindex = -1;
GPIO_InitTypeDef GPIO_InitStruct;
if (PIN_PORT(pin) >= PIN_STPORT_MAX)
{
return -RT_ENOSYS;
}
if (enabled == PIN_IRQ_ENABLE)
{
irqindex = bit2bitno(PIN_STPIN(pin));
if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
{
return RT_ENOSYS;
}
level = rt_hw_interrupt_disable();
if (pin_irq_hdr_tab[irqindex].pin == -1)
{
rt_hw_interrupt_enable(level);
return RT_ENOSYS;
}
irqmap = &pin_irq_map[irqindex];
/* Configure GPIO_InitStructure */
GPIO_InitStruct.Pin = PIN_STPIN(pin);
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
switch (pin_irq_hdr_tab[irqindex].mode)
{
case PIN_IRQ_MODE_RISING:
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
break;
case PIN_IRQ_MODE_FALLING:
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
break;
case PIN_IRQ_MODE_RISING_FALLING:
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
break;
}
HAL_GPIO_Init(PIN_STPORT(pin), &GPIO_InitStruct);
HAL_NVIC_SetPriority(irqmap->irqno, 5, 0);
HAL_NVIC_EnableIRQ(irqmap->irqno);
pin_irq_enable_mask |= irqmap->pinbit;
rt_hw_interrupt_enable(level);
}
else if (enabled == PIN_IRQ_DISABLE)
{
irqmap = get_pin_irq_map(PIN_STPIN(pin));
if (irqmap == RT_NULL)
{
return RT_ENOSYS;
}
level = rt_hw_interrupt_disable();
HAL_GPIO_DeInit(PIN_STPORT(pin), PIN_STPIN(pin));
pin_irq_enable_mask &= ~irqmap->pinbit;
#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)
if ((irqmap->pinbit >= GPIO_PIN_0) && (irqmap->pinbit <= GPIO_PIN_1))
{
if (!(pin_irq_enable_mask & (GPIO_PIN_0 | GPIO_PIN_1)))
{
HAL_NVIC_DisableIRQ(irqmap->irqno);
}
}
else if ((irqmap->pinbit >= GPIO_PIN_2) && (irqmap->pinbit <= GPIO_PIN_3))
{
if (!(pin_irq_enable_mask & (GPIO_PIN_2 | GPIO_PIN_3)))
{
HAL_NVIC_DisableIRQ(irqmap->irqno);
}
}
else if ((irqmap->pinbit >= GPIO_PIN_4) && (irqmap->pinbit <= GPIO_PIN_15))
{
if (!(pin_irq_enable_mask & (GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 |
GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15)))
{
HAL_NVIC_DisableIRQ(irqmap->irqno);
}
}
else
{
HAL_NVIC_DisableIRQ(irqmap->irqno);
}
#else
if ((irqmap->pinbit >= GPIO_PIN_5) && (irqmap->pinbit <= GPIO_PIN_9))
{
if (!(pin_irq_enable_mask & (GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9)))
{
HAL_NVIC_DisableIRQ(irqmap->irqno);
}
}
else if ((irqmap->pinbit >= GPIO_PIN_10) && (irqmap->pinbit <= GPIO_PIN_15))
{
if (!(pin_irq_enable_mask & (GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15)))
{
HAL_NVIC_DisableIRQ(irqmap->irqno);
}
}
else
{
HAL_NVIC_DisableIRQ(irqmap->irqno);
}
#endif
rt_hw_interrupt_enable(level);
}
else
{
return -RT_ENOSYS;
}
return RT_EOK;
}
const static struct rt_pin_ops _stm32_pin_ops =
{
stm32_pin_mode,
stm32_pin_write,
stm32_pin_read,
stm32_pin_attach_irq,
stm32_pin_dettach_irq,
stm32_pin_irq_enable,
stm32_pin_get,
};
rt_inline void pin_irq_hdr(int irqno)
{
if (pin_irq_hdr_tab[irqno].hdr)
{
pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args);
}
}
#if defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32MP1)
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
pin_irq_hdr(bit2bitno(GPIO_Pin));
}
void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
{
pin_irq_hdr(bit2bitno(GPIO_Pin));
}
#else
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
pin_irq_hdr(bit2bitno(GPIO_Pin));
}
#endif
#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32L0)
void EXTI0_1_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
rt_interrupt_leave();
}
void EXTI2_3_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3);
rt_interrupt_leave();
}
void EXTI4_15_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_14);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_15);
rt_interrupt_leave();
}
#elif defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32U5)
void EXTI0_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
rt_interrupt_leave();
}
void EXTI1_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
rt_interrupt_leave();
}
void EXTI2_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
rt_interrupt_leave();
}
void EXTI3_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3);
rt_interrupt_leave();
}
void EXTI4_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
rt_interrupt_leave();
}
void EXTI5_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5);
rt_interrupt_leave();
}
void EXTI6_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6);
rt_interrupt_leave();
}
void EXTI7_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
rt_interrupt_leave();
}
void EXTI8_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);
rt_interrupt_leave();
}
void EXTI9_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
rt_interrupt_leave();
}
void EXTI10_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);
rt_interrupt_leave();
}
void EXTI11_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);
rt_interrupt_leave();
}
void EXTI12_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
rt_interrupt_leave();
}
void EXTI13_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
rt_interrupt_leave();
}
void EXTI14_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_14);
rt_interrupt_leave();
}
void EXTI15_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_15);
rt_interrupt_leave();
}
#else
void EXTI0_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
rt_interrupt_leave();
}
void EXTI1_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
rt_interrupt_leave();
}
void EXTI2_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
rt_interrupt_leave();
}
void EXTI3_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3);
rt_interrupt_leave();
}
void EXTI4_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
rt_interrupt_leave();
}
void EXTI9_5_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
rt_interrupt_leave();
}
void EXTI15_10_IRQHandler(void)
{
rt_interrupt_enter();
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_14);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_15);
rt_interrupt_leave();
}
#endif
int rt_hw_pin_init(void)
{
#if defined(__HAL_RCC_GPIOA_CLK_ENABLE)
__HAL_RCC_GPIOA_CLK_ENABLE();
#endif
#if defined(__HAL_RCC_GPIOB_CLK_ENABLE)
__HAL_RCC_GPIOB_CLK_ENABLE();
#endif
#if defined(__HAL_RCC_GPIOC_CLK_ENABLE)
__HAL_RCC_GPIOC_CLK_ENABLE();
#endif
#if defined(__HAL_RCC_GPIOD_CLK_ENABLE)
__HAL_RCC_GPIOD_CLK_ENABLE();
#endif
#if defined(__HAL_RCC_GPIOE_CLK_ENABLE)
__HAL_RCC_GPIOE_CLK_ENABLE();
#endif
#if defined(__HAL_RCC_GPIOF_CLK_ENABLE)
__HAL_RCC_GPIOF_CLK_ENABLE();
#endif
#if defined(__HAL_RCC_GPIOG_CLK_ENABLE)
#ifdef SOC_SERIES_STM32L4
HAL_PWREx_EnableVddIO2();
#endif
__HAL_RCC_GPIOG_CLK_ENABLE();
#endif
#if defined(__HAL_RCC_GPIOH_CLK_ENABLE)
__HAL_RCC_GPIOH_CLK_ENABLE();
#endif
#if defined(__HAL_RCC_GPIOI_CLK_ENABLE)
__HAL_RCC_GPIOI_CLK_ENABLE();
#endif
#if defined(__HAL_RCC_GPIOJ_CLK_ENABLE)
__HAL_RCC_GPIOJ_CLK_ENABLE();
#endif
#if defined(__HAL_RCC_GPIOK_CLK_ENABLE)
__HAL_RCC_GPIOK_CLK_ENABLE();
#endif
return rt_device_pin_register("pin", &_stm32_pin_ops, RT_NULL);
}
#endif /* RT_USING_PIN */
+600
View File
@@ -0,0 +1,600 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-10 zylx first version
* 2020-06-16 thread-liu Porting for stm32mp1
* 2020-08-25 linyongkang Fix the timer clock frequency doubling problem
* 2020-10-14 Dozingfiretruck Porting for stm32wbxx
*/
#include <board.h>
#ifdef BSP_USING_TIM
#include "drv_config.h"
//#define DRV_DEBUG
#define LOG_TAG "drv.hwtimer"
#include <drv_log.h>
#ifdef RT_USING_HWTIMER
enum
{
#ifdef BSP_USING_TIM1
TIM1_INDEX,
#endif
#ifdef BSP_USING_TIM2
TIM2_INDEX,
#endif
#ifdef BSP_USING_TIM3
TIM3_INDEX,
#endif
#ifdef BSP_USING_TIM4
TIM4_INDEX,
#endif
#ifdef BSP_USING_TIM5
TIM5_INDEX,
#endif
#ifdef BSP_USING_TIM6
TIM6_INDEX,
#endif
#ifdef BSP_USING_TIM7
TIM7_INDEX,
#endif
#ifdef BSP_USING_TIM8
TIM8_INDEX,
#endif
#ifdef BSP_USING_TIM9
TIM9_INDEX,
#endif
#ifdef BSP_USING_TIM10
TIM10_INDEX,
#endif
#ifdef BSP_USING_TIM11
TIM11_INDEX,
#endif
#ifdef BSP_USING_TIM12
TIM12_INDEX,
#endif
#ifdef BSP_USING_TIM13
TIM13_INDEX,
#endif
#ifdef BSP_USING_TIM14
TIM14_INDEX,
#endif
#ifdef BSP_USING_TIM15
TIM15_INDEX,
#endif
#ifdef BSP_USING_TIM16
TIM16_INDEX,
#endif
#ifdef BSP_USING_TIM17
TIM17_INDEX,
#endif
};
struct stm32_hwtimer
{
rt_hwtimer_t time_device;
TIM_HandleTypeDef tim_handle;
IRQn_Type tim_irqn;
char *name;
};
static struct stm32_hwtimer stm32_hwtimer_obj[] =
{
#ifdef BSP_USING_TIM1
TIM1_CONFIG,
#endif
#ifdef BSP_USING_TIM2
TIM2_CONFIG,
#endif
#ifdef BSP_USING_TIM3
TIM3_CONFIG,
#endif
#ifdef BSP_USING_TIM4
TIM4_CONFIG,
#endif
#ifdef BSP_USING_TIM5
TIM5_CONFIG,
#endif
#ifdef BSP_USING_TIM6
TIM6_CONFIG,
#endif
#ifdef BSP_USING_TIM7
TIM7_CONFIG,
#endif
#ifdef BSP_USING_TIM8
TIM8_CONFIG,
#endif
#ifdef BSP_USING_TIM9
TIM9_CONFIG,
#endif
#ifdef BSP_USING_TIM10
TIM10_CONFIG,
#endif
#ifdef BSP_USING_TIM11
TIM11_CONFIG,
#endif
#ifdef BSP_USING_TIM12
TIM12_CONFIG,
#endif
#ifdef BSP_USING_TIM13
TIM13_CONFIG,
#endif
#ifdef BSP_USING_TIM14
TIM14_CONFIG,
#endif
#ifdef BSP_USING_TIM15
TIM15_CONFIG,
#endif
#ifdef BSP_USING_TIM16
TIM16_CONFIG,
#endif
#ifdef BSP_USING_TIM17
TIM17_CONFIG,
#endif
};
/* APBx timer clocks frequency doubler state related to APB1CLKDivider value */
static void pclkx_doubler_get(rt_uint32_t *pclk1_doubler, rt_uint32_t *pclk2_doubler)
{
rt_uint32_t flatency = 0;
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RT_ASSERT(pclk1_doubler != RT_NULL);
RT_ASSERT(pclk1_doubler != RT_NULL);
HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &flatency);
*pclk1_doubler = 1;
*pclk2_doubler = 1;
#if defined(SOC_SERIES_STM32MP1)
if (RCC_ClkInitStruct.APB1_Div != RCC_APB1_DIV1)
{
*pclk1_doubler = 2;
}
if (RCC_ClkInitStruct.APB2_Div != RCC_APB2_DIV1)
{
*pclk2_doubler = 2;
}
#else
if (RCC_ClkInitStruct.APB1CLKDivider != RCC_HCLK_DIV1)
{
*pclk1_doubler = 2;
}
#if !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32G0)
if (RCC_ClkInitStruct.APB2CLKDivider != RCC_HCLK_DIV1)
{
*pclk2_doubler = 2;
}
#endif
#endif
}
static void timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
{
uint32_t prescaler_value = 0;
uint32_t pclk1_doubler, pclk2_doubler;
TIM_HandleTypeDef *tim = RT_NULL;
struct stm32_hwtimer *tim_device = RT_NULL;
RT_ASSERT(timer != RT_NULL);
if (state)
{
tim = (TIM_HandleTypeDef *)timer->parent.user_data;
tim_device = (struct stm32_hwtimer *)timer;
pclkx_doubler_get(&pclk1_doubler, &pclk2_doubler);
/* time init */
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
if (tim->Instance == TIM9 || tim->Instance == TIM10 || tim->Instance == TIM11)
#elif defined(SOC_SERIES_STM32L4)
if (tim->Instance == TIM15 || tim->Instance == TIM16 || tim->Instance == TIM17)
#elif defined(SOC_SERIES_STM32WB)
if (tim->Instance == TIM16 || tim->Instance == TIM17)
#elif defined(SOC_SERIES_STM32MP1)
if(tim->Instance == TIM14 || tim->Instance == TIM16 || tim->Instance == TIM17)
#elif defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)
if (0)
#endif
{
#if !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32G0)
prescaler_value = (uint32_t)(HAL_RCC_GetPCLK2Freq() * pclk2_doubler / 10000) - 1;
#endif
}
else
{
prescaler_value = (uint32_t)(HAL_RCC_GetPCLK1Freq() * pclk1_doubler / 10000) - 1;
}
tim->Init.Period = 10000 - 1;
tim->Init.Prescaler = prescaler_value;
tim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
if (timer->info->cntmode == HWTIMER_CNTMODE_UP)
{
tim->Init.CounterMode = TIM_COUNTERMODE_UP;
}
else
{
tim->Init.CounterMode = TIM_COUNTERMODE_DOWN;
}
tim->Init.RepetitionCounter = 0;
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB)
tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
#endif
if (HAL_TIM_Base_Init(tim) != HAL_OK)
{
LOG_E("%s init failed", tim_device->name);
return;
}
else
{
/* set the TIMx priority */
HAL_NVIC_SetPriority(tim_device->tim_irqn, 3, 0);
/* enable the TIMx global Interrupt */
HAL_NVIC_EnableIRQ(tim_device->tim_irqn);
/* clear update flag */
__HAL_TIM_CLEAR_FLAG(tim, TIM_FLAG_UPDATE);
/* enable update request source */
__HAL_TIM_URS_ENABLE(tim);
LOG_D("%s init success", tim_device->name);
}
}
}
static rt_err_t timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode)
{
rt_err_t result = RT_EOK;
TIM_HandleTypeDef *tim = RT_NULL;
RT_ASSERT(timer != RT_NULL);
tim = (TIM_HandleTypeDef *)timer->parent.user_data;
/* set tim cnt */
__HAL_TIM_SET_COUNTER(tim, 0);
/* set tim arr */
__HAL_TIM_SET_AUTORELOAD(tim, t - 1);
if (opmode == HWTIMER_MODE_ONESHOT)
{
/* set timer to single mode */
tim->Instance->CR1 |= TIM_OPMODE_SINGLE;
}
else
{
tim->Instance->CR1 &= (~TIM_OPMODE_SINGLE);
}
/* start timer */
if (HAL_TIM_Base_Start_IT(tim) != HAL_OK)
{
LOG_E("TIM start failed");
result = -RT_ERROR;
}
return result;
}
static void timer_stop(rt_hwtimer_t *timer)
{
TIM_HandleTypeDef *tim = RT_NULL;
RT_ASSERT(timer != RT_NULL);
tim = (TIM_HandleTypeDef *)timer->parent.user_data;
/* stop timer */
HAL_TIM_Base_Stop_IT(tim);
/* set tim cnt */
__HAL_TIM_SET_COUNTER(tim, 0);
}
static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
{
TIM_HandleTypeDef *tim = RT_NULL;
rt_err_t result = RT_EOK;
uint32_t pclk1_doubler, pclk2_doubler;
RT_ASSERT(timer != RT_NULL);
RT_ASSERT(arg != RT_NULL);
tim = (TIM_HandleTypeDef *)timer->parent.user_data;
switch (cmd)
{
case HWTIMER_CTRL_FREQ_SET:
{
rt_uint32_t freq;
rt_uint16_t val;
/* set timer frequence */
freq = *((rt_uint32_t *)arg);
pclkx_doubler_get(&pclk1_doubler, &pclk2_doubler);
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
if (tim->Instance == TIM9 || tim->Instance == TIM10 || tim->Instance == TIM11)
#elif defined(SOC_SERIES_STM32L4)
if (tim->Instance == TIM15 || tim->Instance == TIM16 || tim->Instance == TIM17)
#elif defined(SOC_SERIES_STM32WB)
if (tim->Instance == TIM16 || tim->Instance == TIM17)
#elif defined(SOC_SERIES_STM32MP1)
if(tim->Instance == TIM14 || tim->Instance == TIM16 || tim->Instance == TIM17)
#elif defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)
if (0)
#endif
{
#if !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32G0)
val = HAL_RCC_GetPCLK2Freq() * pclk2_doubler / freq;
#endif
}
else
{
val = HAL_RCC_GetPCLK1Freq() * pclk1_doubler / freq;
}
__HAL_TIM_SET_PRESCALER(tim, val - 1);
/* Update frequency value */
tim->Instance->EGR |= TIM_EVENTSOURCE_UPDATE;
}
break;
default:
{
result = -RT_ENOSYS;
}
break;
}
return result;
}
static rt_uint32_t timer_counter_get(rt_hwtimer_t *timer)
{
TIM_HandleTypeDef *tim = RT_NULL;
RT_ASSERT(timer != RT_NULL);
tim = (TIM_HandleTypeDef *)timer->parent.user_data;
return tim->Instance->CNT;
}
static const struct rt_hwtimer_info _info = TIM_DEV_INFO_CONFIG;
static const struct rt_hwtimer_ops _ops =
{
.init = timer_init,
.start = timer_start,
.stop = timer_stop,
.count_get = timer_counter_get,
.control = timer_ctrl,
};
#ifdef BSP_USING_TIM2
void TIM2_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM2_INDEX].tim_handle);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_TIM3
void TIM3_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM3_INDEX].tim_handle);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_TIM4
void TIM4_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM4_INDEX].tim_handle);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_TIM5
void TIM5_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM5_INDEX].tim_handle);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_TIM11
void TIM1_TRG_COM_TIM11_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM11_INDEX].tim_handle);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_TIM13
void TIM8_UP_TIM13_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM13_INDEX].tim_handle);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_TIM14
#if defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
void TIM8_TRG_COM_TIM14_IRQHandler(void)
#elif defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32MP1)
void TIM14_IRQHandler(void)
#endif
{
/* enter interrupt */
rt_interrupt_enter();
HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM14_INDEX].tim_handle);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_TIM15
void TIM1_BRK_TIM15_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM15_INDEX].tim_handle);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_TIM16
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WB)
void TIM1_UP_TIM16_IRQHandler(void)
#elif defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32MP1)
void TIM16_IRQHandler(void)
#endif
{
/* enter interrupt */
rt_interrupt_enter();
HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM16_INDEX].tim_handle);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_TIM17
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WB)
void TIM1_TRG_COM_TIM17_IRQHandler(void)
#elif defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32MP1)
void TIM17_IRQHandler(void)
#endif
{
/* enter interrupt */
rt_interrupt_enter();
HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM17_INDEX].tim_handle);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
#ifdef BSP_USING_TIM2
if (htim->Instance == TIM2)
{
rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM2_INDEX].time_device);
}
#endif
#ifdef BSP_USING_TIM3
if (htim->Instance == TIM3)
{
rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM3_INDEX].time_device);
}
#endif
#ifdef BSP_USING_TIM4
if (htim->Instance == TIM4)
{
rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM4_INDEX].time_device);
}
#endif
#ifdef BSP_USING_TIM5
if (htim->Instance == TIM5)
{
rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM5_INDEX].time_device);
}
#endif
#ifdef BSP_USING_TIM11
if (htim->Instance == TIM11)
{
rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM11_INDEX].time_device);
}
#endif
#ifdef BSP_USING_TIM13
if (htim->Instance == TIM13)
{
rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM13_INDEX].time_device);
}
#endif
#ifdef BSP_USING_TIM14
if (htim->Instance == TIM14)
{
rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM14_INDEX].time_device);
}
#endif
#ifdef BSP_USING_TIM15
if (htim->Instance == TIM15)
{
rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM15_INDEX].time_device);
}
#endif
#ifdef BSP_USING_TIM16
if (htim->Instance == TIM16)
{
rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM16_INDEX].time_device);
}
#endif
#ifdef BSP_USING_TIM17
if (htim->Instance == TIM17)
{
rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM17_INDEX].time_device);
}
#endif
}
static int stm32_hwtimer_init(void)
{
int i = 0;
int result = RT_EOK;
for (i = 0; i < sizeof(stm32_hwtimer_obj) / sizeof(stm32_hwtimer_obj[0]); i++)
{
stm32_hwtimer_obj[i].time_device.info = &_info;
stm32_hwtimer_obj[i].time_device.ops = &_ops;
if (rt_device_hwtimer_register(&stm32_hwtimer_obj[i].time_device, stm32_hwtimer_obj[i].name, &stm32_hwtimer_obj[i].tim_handle) == RT_EOK)
{
LOG_D("%s register success", stm32_hwtimer_obj[i].name);
}
else
{
LOG_E("%s register failed", stm32_hwtimer_obj[i].name);
result = -RT_ERROR;
}
}
return result;
}
INIT_BOARD_EXPORT(stm32_hwtimer_init);
#endif /* RT_USING_HWTIMER */
#endif /* BSP_USING_TIM */
+403
View File
@@ -0,0 +1,403 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-01-08 zylx first version
*/
#include <board.h>
#ifdef BSP_USING_LCD
#include <lcd_port.h>
#include <string.h>
//#define DRV_DEBUG
#define LOG_TAG "drv.lcd"
#include <drv_log.h>
#define LCD_DEVICE(dev) (struct drv_lcd_device*)(dev)
static LTDC_HandleTypeDef LtdcHandle = {0};
struct drv_lcd_device
{
struct rt_device parent;
struct rt_device_graphic_info lcd_info;
struct rt_semaphore lcd_lock;
/* 0:front_buf is being used 1: back_buf is being used*/
rt_uint8_t cur_buf;
rt_uint8_t *front_buf;
rt_uint8_t *back_buf;
};
struct drv_lcd_device _lcd;
static rt_err_t drv_lcd_init(struct rt_device *device)
{
struct drv_lcd_device *lcd = LCD_DEVICE(device);
/* nothing, right now */
lcd = lcd;
return RT_EOK;
}
static rt_err_t drv_lcd_control(struct rt_device *device, int cmd, void *args)
{
struct drv_lcd_device *lcd = LCD_DEVICE(device);
switch (cmd)
{
case RTGRAPHIC_CTRL_RECT_UPDATE:
{
/* update */
if (_lcd.cur_buf)
{
/* back_buf is being used */
memcpy(_lcd.front_buf, _lcd.lcd_info.framebuffer, LCD_BUF_SIZE);
/* Configure the color frame buffer start address */
LTDC_LAYER(&LtdcHandle, 0)->CFBAR &= ~(LTDC_LxCFBAR_CFBADD);
LTDC_LAYER(&LtdcHandle, 0)->CFBAR = (uint32_t)(_lcd.front_buf);
_lcd.cur_buf = 0;
}
else
{
/* front_buf is being used */
memcpy(_lcd.back_buf, _lcd.lcd_info.framebuffer, LCD_BUF_SIZE);
/* Configure the color frame buffer start address */
LTDC_LAYER(&LtdcHandle, 0)->CFBAR &= ~(LTDC_LxCFBAR_CFBADD);
LTDC_LAYER(&LtdcHandle, 0)->CFBAR = (uint32_t)(_lcd.back_buf);
_lcd.cur_buf = 1;
}
rt_sem_take(&_lcd.lcd_lock, RT_TICK_PER_SECOND / 20);
HAL_LTDC_Relaod(&LtdcHandle, LTDC_SRCR_VBR);
}
break;
case RTGRAPHIC_CTRL_GET_INFO:
{
struct rt_device_graphic_info *info = (struct rt_device_graphic_info *)args;
RT_ASSERT(info != RT_NULL);
info->pixel_format = lcd->lcd_info.pixel_format;
info->bits_per_pixel = 16;
info->width = lcd->lcd_info.width;
info->height = lcd->lcd_info.height;
info->framebuffer = lcd->lcd_info.framebuffer;
}
break;
default:
return -RT_EINVAL;
}
return RT_EOK;
}
void HAL_LTDC_ReloadEventCallback(LTDC_HandleTypeDef *hltdc)
{
/* emable line interupt */
__HAL_LTDC_ENABLE_IT(&LtdcHandle, LTDC_IER_LIE);
}
void HAL_LTDC_LineEventCallback(LTDC_HandleTypeDef *hltdc)
{
rt_sem_release(&_lcd.lcd_lock);
}
void LTDC_IRQHandler(void)
{
rt_interrupt_enter();
HAL_LTDC_IRQHandler(&LtdcHandle);
rt_interrupt_leave();
}
rt_err_t stm32_lcd_init(struct drv_lcd_device *lcd)
{
LTDC_LayerCfgTypeDef pLayerCfg = {0};
/* LTDC Initialization -------------------------------------------------------*/
/* Polarity configuration */
/* Initialize the horizontal synchronization polarity as active low */
LtdcHandle.Init.HSPolarity = LTDC_HSPOLARITY_AL;
/* Initialize the vertical synchronization polarity as active low */
LtdcHandle.Init.VSPolarity = LTDC_VSPOLARITY_AL;
/* Initialize the data enable polarity as active low */
LtdcHandle.Init.DEPolarity = LTDC_DEPOLARITY_AL;
/* Initialize the pixel clock polarity as input pixel clock */
LtdcHandle.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
/* Timing configuration */
/* Horizontal synchronization width = Hsync - 1 */
LtdcHandle.Init.HorizontalSync = LCD_HSYNC_WIDTH - 1;
/* Vertical synchronization height = Vsync - 1 */
LtdcHandle.Init.VerticalSync = LCD_VSYNC_HEIGHT - 1;
/* Accumulated horizontal back porch = Hsync + HBP - 1 */
LtdcHandle.Init.AccumulatedHBP = LCD_HSYNC_WIDTH + LCD_HBP - 1;
/* Accumulated vertical back porch = Vsync + VBP - 1 */
LtdcHandle.Init.AccumulatedVBP = LCD_VSYNC_HEIGHT + LCD_VBP - 1;
/* Accumulated active width = Hsync + HBP + Active Width - 1 */
LtdcHandle.Init.AccumulatedActiveW = LCD_HSYNC_WIDTH + LCD_HBP + lcd->lcd_info.width - 1 ;
/* Accumulated active height = Vsync + VBP + Active Heigh - 1 */
LtdcHandle.Init.AccumulatedActiveH = LCD_VSYNC_HEIGHT + LCD_VBP + lcd->lcd_info.height - 1;
/* Total height = Vsync + VBP + Active Heigh + VFP - 1 */
LtdcHandle.Init.TotalHeigh = LtdcHandle.Init.AccumulatedActiveH + LCD_VFP;
/* Total width = Hsync + HBP + Active Width + HFP - 1 */
LtdcHandle.Init.TotalWidth = LtdcHandle.Init.AccumulatedActiveW + LCD_HFP;
/* Configure R,G,B component values for LCD background color */
LtdcHandle.Init.Backcolor.Blue = 0;
LtdcHandle.Init.Backcolor.Green = 0;
LtdcHandle.Init.Backcolor.Red = 0;
LtdcHandle.Instance = LTDC;
/* Layer1 Configuration ------------------------------------------------------*/
/* Windowing configuration */
pLayerCfg.WindowX0 = 0;
pLayerCfg.WindowX1 = lcd->lcd_info.width;
pLayerCfg.WindowY0 = 0;
pLayerCfg.WindowY1 = lcd->lcd_info.height;
/* Pixel Format configuration*/
if (lcd->lcd_info.pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565)
{
pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
}
else if (lcd->lcd_info.pixel_format == RTGRAPHIC_PIXEL_FORMAT_ARGB888)
{
pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_ARGB8888;
}
else if (lcd->lcd_info.pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB888)
{
pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB888;
}
else if (lcd->lcd_info.pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB888)
{
pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB888;
}
else
{
LOG_E("unsupported pixel format");
return -RT_ERROR;
}
/* Start Address configuration : frame buffer is located at FLASH memory */
pLayerCfg.FBStartAdress = (uint32_t)lcd->front_buf;
/* Alpha constant (255 totally opaque) */
pLayerCfg.Alpha = 255;
/* Default Color configuration (configure A,R,G,B component values) */
pLayerCfg.Alpha0 = 255;
pLayerCfg.Backcolor.Blue = 0;
pLayerCfg.Backcolor.Green = 0;
pLayerCfg.Backcolor.Red = 0;
/* Configure blending factors */
/* Constant Alpha value: pLayerCfg.Alpha / 255
C: Current Layer Color
Cs: Background color
BC = Constant Alpha x C + (1 - Constant Alpha ) x Cs */
/* BlendingFactor1: Pixel Alpha x Constant Alpha */
pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
/* BlendingFactor2: 1 - (Pixel Alpha x Constant Alpha) */
pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
/* Configure the number of lines and number of pixels per line */
pLayerCfg.ImageWidth = lcd->lcd_info.width;
pLayerCfg.ImageHeight = lcd->lcd_info.height;
/* Configure the LTDC */
if (HAL_LTDC_Init(&LtdcHandle) != HAL_OK)
{
LOG_E("LTDC init failed");
return -RT_ERROR;
}
/* Configure the Background Layer*/
if (HAL_LTDC_ConfigLayer(&LtdcHandle, &pLayerCfg, 0) != HAL_OK)
{
LOG_E("LTDC layer init failed");
return -RT_ERROR;
}
else
{
/* enable LTDC interrupt */
HAL_NVIC_SetPriority(LTDC_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(LTDC_IRQn);
LOG_D("LTDC init success");
return RT_EOK;
}
}
#if defined(LCD_BACKLIGHT_USING_PWM)
void turn_on_lcd_backlight(void)
{
struct rt_device_pwm *pwm_dev;
/* turn on the LCD backlight */
pwm_dev = (struct rt_device_pwm *)rt_device_find(LCD_PWM_DEV_NAME);
/* pwm frequency:100K = 10000ns */
rt_pwm_set(pwm_dev, LCD_PWM_DEV_CHANNEL, 10000, 10000);
rt_pwm_enable(pwm_dev, LCD_PWM_DEV_CHANNEL);
}
#elif defined(LCD_BACKLIGHT_USING_GPIO)
void turn_on_lcd_backlight(void)
{
rt_pin_mode(LCD_BL_GPIO_NUM, PIN_MODE_OUTPUT);
rt_pin_mode(LCD_DISP_GPIO_NUM, PIN_MODE_OUTPUT);
rt_pin_write(LCD_DISP_GPIO_NUM, PIN_HIGH);
rt_pin_write(LCD_BL_GPIO_NUM, PIN_HIGH);
}
#else
void turn_on_lcd_backlight(void)
{
}
#endif
#ifdef RT_USING_DEVICE_OPS
const static struct rt_device_ops lcd_ops =
{
drv_lcd_init,
RT_NULL,
RT_NULL,
RT_NULL,
RT_NULL,
drv_lcd_control
};
#endif
int drv_lcd_hw_init(void)
{
rt_err_t result = RT_EOK;
struct rt_device *device = &_lcd.parent;
/* memset _lcd to zero */
memset(&_lcd, 0x00, sizeof(_lcd));
/* init lcd_lock semaphore */
result = rt_sem_init(&_lcd.lcd_lock, "lcd_lock", 0, RT_IPC_FLAG_FIFO);
if (result != RT_EOK)
{
LOG_E("init semaphore failed!\n");
result = -RT_ENOMEM;
goto __exit;
}
/* config LCD dev info */
_lcd.lcd_info.height = LCD_HEIGHT;
_lcd.lcd_info.width = LCD_WIDTH;
_lcd.lcd_info.bits_per_pixel = LCD_BITS_PER_PIXEL;
_lcd.lcd_info.pixel_format = LCD_PIXEL_FORMAT;
/* malloc memory for Triple Buffering */
_lcd.lcd_info.framebuffer = rt_malloc(LCD_BUF_SIZE);
_lcd.back_buf = rt_malloc(LCD_BUF_SIZE);
_lcd.front_buf = rt_malloc(LCD_BUF_SIZE);
if (_lcd.lcd_info.framebuffer == RT_NULL || _lcd.back_buf == RT_NULL || _lcd.front_buf == RT_NULL)
{
LOG_E("init frame buffer failed!\n");
result = -RT_ENOMEM;
goto __exit;
}
/* memset buff to 0xFF */
memset(_lcd.lcd_info.framebuffer, 0xFF, LCD_BUF_SIZE);
memset(_lcd.back_buf, 0xFF, LCD_BUF_SIZE);
memset(_lcd.front_buf, 0xFF, LCD_BUF_SIZE);
device->type = RT_Device_Class_Graphic;
#ifdef RT_USING_DEVICE_OPS
device->ops = &lcd_ops;
#else
device->init = drv_lcd_init;
device->control = drv_lcd_control;
#endif
/* register lcd device */
rt_device_register(device, "lcd", RT_DEVICE_FLAG_RDWR);
/* init stm32 LTDC */
if (stm32_lcd_init(&_lcd) != RT_EOK)
{
result = -RT_ERROR;
goto __exit;
}
else
{
turn_on_lcd_backlight();
}
__exit:
if (result != RT_EOK)
{
rt_sem_detach(&_lcd.lcd_lock);
if (_lcd.lcd_info.framebuffer)
{
rt_free(_lcd.lcd_info.framebuffer);
}
if (_lcd.back_buf)
{
rt_free(_lcd.back_buf);
}
if (_lcd.front_buf)
{
rt_free(_lcd.front_buf);
}
}
return result;
}
INIT_DEVICE_EXPORT(drv_lcd_hw_init);
#ifdef DRV_DEBUG
#ifdef FINSH_USING_MSH
int lcd_test()
{
struct drv_lcd_device *lcd;
lcd = (struct drv_lcd_device *)rt_device_find("lcd");
while (1)
{
/* red */
for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
{
lcd->lcd_info.framebuffer[2 * i] = 0x00;
lcd->lcd_info.framebuffer[2 * i + 1] = 0xF8;
}
lcd->parent.control(&lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
rt_thread_mdelay(1000);
/* green */
for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
{
lcd->lcd_info.framebuffer[2 * i] = 0xE0;
lcd->lcd_info.framebuffer[2 * i + 1] = 0x07;
}
lcd->parent.control(&lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
rt_thread_mdelay(1000);
/* blue */
for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
{
lcd->lcd_info.framebuffer[2 * i] = 0x1F;
lcd->lcd_info.framebuffer[2 * i + 1] = 0x00;
}
lcd->parent.control(&lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
rt_thread_mdelay(1000);
}
}
MSH_CMD_EXPORT(lcd_test, lcd_test);
#endif /* FINSH_USING_MSH */
#endif /* DRV_DEBUG */
#endif /* BSP_USING_LCD */
+254
View File
@@ -0,0 +1,254 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-05-23 WillianChan first version
*/
#include <board.h>
#ifdef BSP_USING_LCD_MIPI
#include <lcd_port.h>
#include <string.h>
DSI_HandleTypeDef hdsi;
DSI_VidCfgTypeDef hdsi_video;
LTDC_HandleTypeDef hltdc;
struct stm32_lcd
{
struct rt_device parent;
struct rt_device_graphic_info info;
};
struct stm32_lcd lcd;
extern void stm32_mipi_lcd_init(void);
extern void stm32_mipi_lcd_config(rt_uint32_t pixel_format);
extern void stm32_mipi_display_on(void);
extern void stm32_mipi_display_off(void);
rt_err_t ltdc_init(void)
{
uint32_t lcd_clock = 27429;
uint32_t lanebyte_clock = 62500;
uint32_t HSA = LCD_HSYNC, HFP = LCD_HFP, HBP = LCD_HBP, HACT = LCD_WIDTH;
uint32_t VSA = LCD_VSYNC, VFP = LCD_VFP, VBP = LCD_VBP, VACT = LCD_HEIGHT;
stm32_mipi_lcd_init();
__HAL_RCC_LTDC_CLK_ENABLE();
__HAL_RCC_LTDC_FORCE_RESET();
__HAL_RCC_LTDC_RELEASE_RESET();
__HAL_RCC_DSI_CLK_ENABLE();
__HAL_RCC_DSI_FORCE_RESET();
__HAL_RCC_DSI_RELEASE_RESET();
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
PeriphClkInitStruct.PLLSAI.PLLSAIN = 384;
PeriphClkInitStruct.PLLSAI.PLLSAIR = 7;
PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_2;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
HAL_NVIC_SetPriority(LTDC_IRQn, 3, 0);
HAL_NVIC_SetPriority(DSI_IRQn, 3, 0);
HAL_NVIC_EnableIRQ(LTDC_IRQn);
HAL_NVIC_EnableIRQ(DSI_IRQn);
DSI_PLLInitTypeDef dsi_pll;
hdsi.Instance = DSI;
hdsi.Init.NumberOfLanes = DSI_TWO_DATA_LANES;
hdsi.Init.TXEscapeCkdiv = lanebyte_clock / 15620;
dsi_pll.PLLNDIV = 125;
dsi_pll.PLLIDF = DSI_PLL_IN_DIV2;
dsi_pll.PLLODF = DSI_PLL_OUT_DIV1;
HAL_DSI_DeInit(&hdsi);
HAL_DSI_Init(&hdsi, &dsi_pll);
hdsi_video.VirtualChannelID = 0;
hdsi_video.ColorCoding = DSI_RGB565;
hdsi_video.VSPolarity = DSI_VSYNC_ACTIVE_HIGH;
hdsi_video.HSPolarity = DSI_HSYNC_ACTIVE_HIGH;
hdsi_video.DEPolarity = DSI_DATA_ENABLE_ACTIVE_HIGH;
hdsi_video.Mode = DSI_VID_MODE_BURST;
hdsi_video.NullPacketSize = 0xFFF;
hdsi_video.NumberOfChunks = 0;
hdsi_video.PacketSize = HACT;
hdsi_video.HorizontalSyncActive = (HSA * lanebyte_clock) / lcd_clock;
hdsi_video.HorizontalBackPorch = (HBP * lanebyte_clock) / lcd_clock;
hdsi_video.HorizontalLine = ((HACT + HSA + HBP + HFP) * lanebyte_clock) / lcd_clock;
hdsi_video.VerticalSyncActive = VSA;
hdsi_video.VerticalBackPorch = VBP;
hdsi_video.VerticalFrontPorch = VFP;
hdsi_video.VerticalActive = VACT;
hdsi_video.LPCommandEnable = DSI_LP_COMMAND_ENABLE;
hdsi_video.LPLargestPacketSize = 16;
hdsi_video.LPVACTLargestPacketSize = 0;
hdsi_video.LPHorizontalFrontPorchEnable = DSI_LP_HFP_ENABLE;
hdsi_video.LPHorizontalBackPorchEnable = DSI_LP_HBP_ENABLE;
hdsi_video.LPVerticalActiveEnable = DSI_LP_VACT_ENABLE;
hdsi_video.LPVerticalFrontPorchEnable = DSI_LP_VFP_ENABLE;
hdsi_video.LPVerticalBackPorchEnable = DSI_LP_VBP_ENABLE;
hdsi_video.LPVerticalSyncActiveEnable = DSI_LP_VSYNC_ENABLE;
HAL_DSI_ConfigVideoMode(&hdsi, &hdsi_video);
DSI_PHY_TimerTypeDef dsi_phy;
dsi_phy.ClockLaneHS2LPTime = 35;
dsi_phy.ClockLaneLP2HSTime = 35;
dsi_phy.DataLaneHS2LPTime = 35;
dsi_phy.DataLaneLP2HSTime = 35;
dsi_phy.DataLaneMaxReadTime = 0;
dsi_phy.StopWaitTime = 10;
HAL_DSI_ConfigPhyTimer(&hdsi, &dsi_phy);
hltdc.Instance = LTDC;
hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
hltdc.Init.HorizontalSync = (HSA - 1);
hltdc.Init.AccumulatedHBP = (HSA + HBP - 1);
hltdc.Init.AccumulatedActiveW = (LCD_WIDTH + HSA + HBP - 1);
hltdc.Init.TotalWidth = (LCD_WIDTH + HSA + HBP + HFP - 1);
hltdc.LayerCfg->ImageWidth = LCD_WIDTH;
hltdc.LayerCfg->ImageHeight = LCD_HEIGHT;
hltdc.Init.Backcolor.Blue = 0x00;
hltdc.Init.Backcolor.Green = 0x00;
hltdc.Init.Backcolor.Red = 0x00;
HAL_LTDCEx_StructInitFromVideoConfig(&hltdc, &(hdsi_video));
HAL_LTDC_Init(&(hltdc));
HAL_DSI_Start(&(hdsi));
stm32_mipi_lcd_config(RTGRAPHIC_PIXEL_FORMAT_RGB565);
return RT_EOK;
}
void ltdc_layer_init(uint16_t index, uint32_t framebuffer)
{
LTDC_LayerCfgTypeDef layer_cfg;
layer_cfg.WindowX0 = 0;
layer_cfg.WindowX1 = LCD_WIDTH;
layer_cfg.WindowY0 = 0;
layer_cfg.WindowY1 = LCD_HEIGHT;
layer_cfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
layer_cfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
layer_cfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
layer_cfg.Alpha = 255;
layer_cfg.Alpha0 = 0;
layer_cfg.ImageWidth = LCD_WIDTH;
layer_cfg.ImageHeight = LCD_HEIGHT;
layer_cfg.Backcolor.Blue = 0;
layer_cfg.Backcolor.Green = 0;
layer_cfg.Backcolor.Red = 0;
layer_cfg.FBStartAdress = framebuffer;
HAL_LTDC_ConfigLayer(&hltdc, &layer_cfg, index);
}
void LTDC_IRQHandler(void)
{
rt_interrupt_enter();
HAL_LTDC_IRQHandler(&hltdc);
rt_interrupt_leave();
}
static rt_err_t stm32_lcd_init(rt_device_t device)
{
lcd.info.width = LCD_WIDTH;
lcd.info.height = LCD_HEIGHT;
lcd.info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565;
lcd.info.bits_per_pixel = 16;
lcd.info.framebuffer = (void *)rt_malloc_align(LCD_WIDTH * LCD_HEIGHT * (lcd.info.bits_per_pixel / 8), 32);;
memset(lcd.info.framebuffer, 0, LCD_WIDTH * LCD_HEIGHT * (lcd.info.bits_per_pixel / 8));
ltdc_init();
ltdc_layer_init(0, (uint32_t)lcd.info.framebuffer);
return RT_EOK;
}
static rt_err_t stm32_lcd_control(rt_device_t device, int cmd, void *args)
{
switch(cmd)
{
case RTGRAPHIC_CTRL_RECT_UPDATE:
break;
case RTGRAPHIC_CTRL_POWERON:
stm32_mipi_display_on();
break;
case RTGRAPHIC_CTRL_POWEROFF:
stm32_mipi_display_off();
break;
case RTGRAPHIC_CTRL_GET_INFO:
rt_memcpy(args, &lcd.info, sizeof(lcd.info));
break;
case RTGRAPHIC_CTRL_SET_MODE:
break;
case RTGRAPHIC_CTRL_GET_EXT:
break;
}
return RT_EOK;
}
int rt_hw_lcd_init(void)
{
rt_err_t ret;
rt_memset(&lcd, 0x00, sizeof(lcd));
lcd.parent.type = RT_Device_Class_Graphic;
lcd.parent.init = stm32_lcd_init;
lcd.parent.open = RT_NULL;
lcd.parent.close = RT_NULL;
lcd.parent.read = RT_NULL;
lcd.parent.write = RT_NULL;
lcd.parent.control = stm32_lcd_control;
lcd.parent.user_data = (void *)&lcd.info;
ret = rt_device_register(&lcd.parent, "lcd", RT_DEVICE_FLAG_RDWR);
return ret;
}
INIT_DEVICE_EXPORT(rt_hw_lcd_init);
RT_WEAK void stm32_mipi_lcd_init(void)
{
rt_kprintf("please Implementation function %s\n", __func__);
}
RT_WEAK void stm32_mipi_lcd_config(rt_uint32_t pixel_format)
{
rt_kprintf("please Implementation function %s\n", __func__);
}
RT_WEAK void stm32_mipi_display_on(void)
{
rt_kprintf("please Implementation function %s\n", __func__);
}
RT_WEAK void stm32_mipi_display_off(void)
{
rt_kprintf("please Implementation function %s\n", __func__);
}
#endif /* BSP_USING_LCD_MIPI */
+126
View File
@@ -0,0 +1,126 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-05-06 Zero-Free first version
*/
#include <board.h>
#ifdef RT_USING_PM
#include <drv_lptim.h>
static LPTIM_HandleTypeDef LptimHandle;
void LPTIM1_IRQHandler(void)
{
HAL_LPTIM_IRQHandler(&LptimHandle);
}
void HAL_LPTIM_CompareMatchCallback(LPTIM_HandleTypeDef *hlptim)
{
/* enter interrupt */
rt_interrupt_enter();
/* leave interrupt */
rt_interrupt_leave();
}
/**
* This function get current count value of LPTIM
*
* @return the count vlaue
*/
rt_uint32_t stm32l4_lptim_get_current_tick(void)
{
return HAL_LPTIM_ReadCounter(&LptimHandle);
}
/**
* This function get the max value that LPTIM can count
*
* @return the max count
*/
rt_uint32_t stm32l4_lptim_get_tick_max(void)
{
return (0xFFFF);
}
/**
* This function start LPTIM with reload value
*
* @param reload The value that LPTIM count down from
*
* @return RT_EOK
*/
rt_err_t stm32l4_lptim_start(rt_uint32_t reload)
{
HAL_LPTIM_TimeOut_Start_IT(&LptimHandle, 0xFFFF, reload);
return (RT_EOK);
}
/**
* This function stop LPTIM
*/
void stm32l4_lptim_stop(void)
{
rt_uint32_t _ier;
_ier = LptimHandle.Instance->IER;
LptimHandle.Instance->ICR = LptimHandle.Instance->ISR & _ier;
}
/**
* This function get the count clock of LPTIM
*
* @return the count clock frequency in Hz
*/
rt_uint32_t stm32l4_lptim_get_countfreq(void)
{
return 32000 / 32;
}
/**
* This function initialize the lptim
*/
int stm32l4_hw_lptim_init(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct = {0};
/* Enable LSI clock */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
/* Select the LSI clock as LPTIM peripheral clock */
RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPTIM1;
RCC_PeriphCLKInitStruct.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_LSI;
HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct);
LptimHandle.Instance = LPTIM1;
LptimHandle.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
LptimHandle.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV32;
LptimHandle.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
LptimHandle.Init.OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH;
LptimHandle.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
LptimHandle.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
if (HAL_LPTIM_Init(&LptimHandle) != HAL_OK)
{
return -1;
}
NVIC_ClearPendingIRQ(LPTIM1_IRQn);
NVIC_SetPriority(LPTIM1_IRQn, 0);
NVIC_EnableIRQ(LPTIM1_IRQn);
return 0;
}
INIT_DEVICE_EXPORT(stm32l4_hw_lptim_init);
#endif
+252
View File
@@ -0,0 +1,252 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-05-06 Zero-Free first version
*/
#include <board.h>
#ifdef RT_USING_PM
#include <drv_lptim.h>
static void uart_console_reconfig(void)
{
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
rt_device_control(rt_console_get_device(), RT_DEVICE_CTRL_CONFIG, &config);
}
/**
* This function will put STM32L4xx into sleep mode.
*
* @param pm pointer to power manage structure
*/
static void sleep(struct rt_pm *pm, uint8_t mode)
{
switch (mode)
{
case PM_SLEEP_MODE_NONE:
break;
case PM_SLEEP_MODE_IDLE:
// __WFI();
break;
case PM_SLEEP_MODE_LIGHT:
if (pm->run_mode == PM_RUN_MODE_LOW_SPEED)
{
/* Enter LP SLEEP Mode, Enable low-power regulator */
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
}
else
{
/* Enter SLEEP Mode, Main regulator is ON */
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
}
break;
case PM_SLEEP_MODE_DEEP:
/* Enter STOP 2 mode */
HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
/* Re-configure the system clock */
SystemClock_ReConfig(pm->run_mode);
break;
case PM_SLEEP_MODE_STANDBY:
/* Enter STANDBY mode */
HAL_PWR_EnterSTANDBYMode();
break;
case PM_SLEEP_MODE_SHUTDOWN:
/* Enter SHUTDOWNN mode */
HAL_PWREx_EnterSHUTDOWNMode();
break;
default:
RT_ASSERT(0);
break;
}
}
static uint8_t run_speed[PM_RUN_MODE_MAX][2] =
{
{80, 0},
{80, 1},
{24, 2},
{2, 3},
};
static void run(struct rt_pm *pm, uint8_t mode)
{
static uint8_t last_mode;
static char *run_str[] = PM_RUN_MODE_NAMES;
if (mode == last_mode)
return;
last_mode = mode;
/* 1. 设置 MSI 作为 SYSCLK 时钟源,以修改 PLL */
SystemClock_MSI_ON();
/* 2. 根据RUN模式切换时钟频率(HSI) */
switch (mode)
{
case PM_RUN_MODE_HIGH_SPEED:
case PM_RUN_MODE_NORMAL_SPEED:
HAL_PWREx_DisableLowPowerRunMode();
SystemClock_80M();
/* Configure the main internal regulator output voltage (Range1 by default)*/
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
break;
case PM_RUN_MODE_MEDIUM_SPEED:
HAL_PWREx_DisableLowPowerRunMode();
SystemClock_24M();
/* Configure the main internal regulator output voltage */
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2);
break;
case PM_RUN_MODE_LOW_SPEED:
SystemClock_2M();
/* Enter LP RUN mode */
HAL_PWREx_EnableLowPowerRunMode();
break;
default:
break;
}
/* 3. 关闭 MSI 时钟 */
// SystemClock_MSI_OFF();
/* 4. 更新外设时钟 */
uart_console_reconfig();
/* Re-Configure the Systick time */
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / RT_TICK_PER_SECOND);
/* Re-Configure the Systick */
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
rt_kprintf("switch to %s mode, frequency = %d MHz\n", run_str[mode], run_speed[mode][0]);
}
/**
* This function caculate the PM tick from OS tick
*
* @param tick OS tick
*
* @return the PM tick
*/
static rt_tick_t stm32l4_pm_tick_from_os_tick(rt_tick_t tick)
{
rt_uint32_t freq = stm32l4_lptim_get_countfreq();
return (freq * tick / RT_TICK_PER_SECOND);
}
/**
* This function caculate the OS tick from PM tick
*
* @param tick PM tick
*
* @return the OS tick
*/
static rt_tick_t stm32l4_os_tick_from_pm_tick(rt_uint32_t tick)
{
static rt_uint32_t os_tick_remain = 0;
rt_uint32_t ret, freq;
freq = stm32l4_lptim_get_countfreq();
ret = (tick * RT_TICK_PER_SECOND + os_tick_remain) / freq;
os_tick_remain += (tick * RT_TICK_PER_SECOND);
os_tick_remain %= freq;
return ret;
}
/**
* This function start the timer of pm
*
* @param pm Pointer to power manage structure
* @param timeout How many OS Ticks that MCU can sleep
*/
static void pm_timer_start(struct rt_pm *pm, rt_uint32_t timeout)
{
RT_ASSERT(pm != RT_NULL);
RT_ASSERT(timeout > 0);
if (timeout != RT_TICK_MAX)
{
/* Convert OS Tick to pmtimer timeout value */
timeout = stm32l4_pm_tick_from_os_tick(timeout);
if (timeout > stm32l4_lptim_get_tick_max())
{
timeout = stm32l4_lptim_get_tick_max();
}
/* Enter PM_TIMER_MODE */
stm32l4_lptim_start(timeout);
}
}
/**
* This function stop the timer of pm
*
* @param pm Pointer to power manage structure
*/
static void pm_timer_stop(struct rt_pm *pm)
{
RT_ASSERT(pm != RT_NULL);
/* Reset pmtimer status */
stm32l4_lptim_stop();
}
/**
* This function calculate how many OS Ticks that MCU have suspended
*
* @param pm Pointer to power manage structure
*
* @return OS Ticks
*/
static rt_tick_t pm_timer_get_tick(struct rt_pm *pm)
{
rt_uint32_t timer_tick;
RT_ASSERT(pm != RT_NULL);
timer_tick = stm32l4_lptim_get_current_tick();
return stm32l4_os_tick_from_pm_tick(timer_tick);
}
/**
* This function initialize the power manager
*/
int drv_pm_hw_init(void)
{
static const struct rt_pm_ops _ops =
{
sleep,
run,
pm_timer_start,
pm_timer_stop,
pm_timer_get_tick
};
rt_uint8_t timer_mask = 0;
/* Enable Power Clock */
__HAL_RCC_PWR_CLK_ENABLE();
/* initialize timer mask */
timer_mask = 1UL << PM_SLEEP_MODE_DEEP;
/* initialize system pm module */
rt_system_pm_init(&_ops, timer_mask, RT_NULL);
return 0;
}
INIT_BOARD_EXPORT(drv_pm_hw_init);
#endif
+304
View File
@@ -0,0 +1,304 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-08-23 balanceTWK first version
*/
#include "board.h"
#include "drv_config.h"
#ifdef RT_USING_PULSE_ENCODER
//#define DRV_DEBUG
#define LOG_TAG "drv.pulse_encoder"
#include <drv_log.h>
#if !defined(BSP_USING_PULSE_ENCODER1) && !defined(BSP_USING_PULSE_ENCODER2) && !defined(BSP_USING_PULSE_ENCODER3) \
&& !defined(BSP_USING_PULSE_ENCODER4) && !defined(BSP_USING_PULSE_ENCODER5) && !defined(BSP_USING_PULSE_ENCODER6)
#error "Please define at least one BSP_USING_PULSE_ENCODERx"
/* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
#endif
#define AUTO_RELOAD_VALUE 0x7FFF
enum
{
#ifdef BSP_USING_PULSE_ENCODER1
PULSE_ENCODER1_INDEX,
#endif
#ifdef BSP_USING_PULSE_ENCODER2
PULSE_ENCODER2_INDEX,
#endif
#ifdef BSP_USING_PULSE_ENCODER3
PULSE_ENCODER3_INDEX,
#endif
#ifdef BSP_USING_PULSE_ENCODER4
PULSE_ENCODER4_INDEX,
#endif
#ifdef BSP_USING_PULSE_ENCODER5
PULSE_ENCODER5_INDEX,
#endif
#ifdef BSP_USING_PULSE_ENCODER6
PULSE_ENCODER6_INDEX,
#endif
};
struct stm32_pulse_encoder_device
{
struct rt_pulse_encoder_device pulse_encoder;
TIM_HandleTypeDef tim_handler;
IRQn_Type encoder_irqn;
rt_int32_t over_under_flowcount;
char *name;
};
static struct stm32_pulse_encoder_device stm32_pulse_encoder_obj[] =
{
#ifdef BSP_USING_PULSE_ENCODER1
PULSE_ENCODER1_CONFIG,
#endif
#ifdef BSP_USING_PULSE_ENCODER2
PULSE_ENCODER2_CONFIG,
#endif
#ifdef BSP_USING_PULSE_ENCODER3
PULSE_ENCODER3_CONFIG,
#endif
#ifdef BSP_USING_PULSE_ENCODER4
PULSE_ENCODER4_CONFIG,
#endif
#ifdef BSP_USING_PULSE_ENCODER5
PULSE_ENCODER5_CONFIG,
#endif
#ifdef BSP_USING_PULSE_ENCODER6
PULSE_ENCODER6_CONFIG,
#endif
};
rt_err_t pulse_encoder_init(struct rt_pulse_encoder_device *pulse_encoder)
{
TIM_Encoder_InitTypeDef sConfig;
TIM_MasterConfigTypeDef sMasterConfig;
struct stm32_pulse_encoder_device *stm32_device;
stm32_device = (struct stm32_pulse_encoder_device*)pulse_encoder;
stm32_device->tim_handler.Init.Prescaler = 0;
stm32_device->tim_handler.Init.CounterMode = TIM_COUNTERMODE_UP;
stm32_device->tim_handler.Init.Period = AUTO_RELOAD_VALUE;
stm32_device->tim_handler.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
stm32_device->tim_handler.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
sConfig.EncoderMode = TIM_ENCODERMODE_TI12;
sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
sConfig.IC1Filter = 3;
sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
sConfig.IC2Filter = 3;
if (HAL_TIM_Encoder_Init(&stm32_device->tim_handler, &sConfig) != HAL_OK)
{
LOG_E("pulse_encoder init failed");
return -RT_ERROR;
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&stm32_device->tim_handler, &sMasterConfig))
{
LOG_E("TIMx master config failed");
return -RT_ERROR;
}
else
{
HAL_NVIC_SetPriority(stm32_device->encoder_irqn, 3, 0);
/* enable the TIMx global Interrupt */
HAL_NVIC_EnableIRQ(stm32_device->encoder_irqn);
/* clear update flag */
__HAL_TIM_CLEAR_FLAG(&stm32_device->tim_handler, TIM_FLAG_UPDATE);
/* enable update request source */
__HAL_TIM_URS_ENABLE(&stm32_device->tim_handler);
}
return RT_EOK;
}
rt_err_t pulse_encoder_clear_count(struct rt_pulse_encoder_device *pulse_encoder)
{
struct stm32_pulse_encoder_device *stm32_device;
stm32_device = (struct stm32_pulse_encoder_device*)pulse_encoder;
stm32_device->over_under_flowcount = 0;
__HAL_TIM_SET_COUNTER(&stm32_device->tim_handler, 0);
return RT_EOK;
}
rt_int32_t pulse_encoder_get_count(struct rt_pulse_encoder_device *pulse_encoder)
{
struct stm32_pulse_encoder_device *stm32_device;
stm32_device = (struct stm32_pulse_encoder_device*)pulse_encoder;
return (rt_int32_t)((rt_int16_t)__HAL_TIM_GET_COUNTER(&stm32_device->tim_handler) + stm32_device->over_under_flowcount * AUTO_RELOAD_VALUE);
}
rt_err_t pulse_encoder_control(struct rt_pulse_encoder_device *pulse_encoder, rt_uint32_t cmd, void *args)
{
rt_err_t result;
struct stm32_pulse_encoder_device *stm32_device;
stm32_device = (struct stm32_pulse_encoder_device*)pulse_encoder;
result = RT_EOK;
switch (cmd)
{
case PULSE_ENCODER_CMD_ENABLE:
HAL_TIM_Encoder_Start(&stm32_device->tim_handler, TIM_CHANNEL_ALL);
HAL_TIM_Encoder_Start_IT(&stm32_device->tim_handler, TIM_CHANNEL_ALL);
break;
case PULSE_ENCODER_CMD_DISABLE:
HAL_TIM_Encoder_Stop(&stm32_device->tim_handler, TIM_CHANNEL_ALL);
HAL_TIM_Encoder_Stop_IT(&stm32_device->tim_handler, TIM_CHANNEL_ALL);
break;
default:
result = -RT_ENOSYS;
break;
}
return result;
}
void pulse_encoder_update_isr(struct stm32_pulse_encoder_device *device)
{
/* TIM Update event */
if (__HAL_TIM_GET_FLAG(&device->tim_handler, TIM_FLAG_UPDATE) != RESET)
{
__HAL_TIM_CLEAR_IT(&device->tim_handler, TIM_IT_UPDATE);
if (__HAL_TIM_IS_TIM_COUNTING_DOWN(&device->tim_handler))
{
device->over_under_flowcount--;
}
else
{
device->over_under_flowcount++;
}
}
/* Capture compare 1 event */
if (__HAL_TIM_GET_FLAG(&device->tim_handler, TIM_FLAG_CC1) != RESET)
{
__HAL_TIM_CLEAR_IT(&device->tim_handler, TIM_IT_CC1);
}
/* Capture compare 2 event */
if (__HAL_TIM_GET_FLAG(&device->tim_handler, TIM_FLAG_CC2) != RESET)
{
__HAL_TIM_CLEAR_IT(&device->tim_handler, TIM_IT_CC2);
}
/* Capture compare 3 event */
if (__HAL_TIM_GET_FLAG(&device->tim_handler, TIM_FLAG_CC3) != RESET)
{
__HAL_TIM_CLEAR_IT(&device->tim_handler, TIM_IT_CC3);
}
/* Capture compare 4 event */
if (__HAL_TIM_GET_FLAG(&device->tim_handler, TIM_FLAG_CC4) != RESET)
{
__HAL_TIM_CLEAR_IT(&device->tim_handler, TIM_IT_CC4);
}
/* TIM Break input event */
if (__HAL_TIM_GET_FLAG(&device->tim_handler, TIM_FLAG_BREAK) != RESET)
{
__HAL_TIM_CLEAR_IT(&device->tim_handler, TIM_IT_BREAK);
}
/* TIM Trigger detection event */
if (__HAL_TIM_GET_FLAG(&device->tim_handler, TIM_FLAG_TRIGGER) != RESET)
{
__HAL_TIM_CLEAR_IT(&device->tim_handler, TIM_IT_TRIGGER);
}
/* TIM commutation event */
if (__HAL_TIM_GET_FLAG(&device->tim_handler, TIM_FLAG_COM) != RESET)
{
__HAL_TIM_CLEAR_IT(&device->tim_handler, TIM_FLAG_COM);
}
}
#ifdef BSP_USING_PULSE_ENCODER1
#if defined(SOC_SERIES_STM32F4)
void TIM1_UP_TIM10_IRQHandler(void)
#elif defined(SOC_SERIES_STM32F1)
void TIM1_UP_IRQHandler(void)
#else
#error "Please check TIM1's IRQHandler"
#endif
{
/* enter interrupt */
rt_interrupt_enter();
pulse_encoder_update_isr(&stm32_pulse_encoder_obj[PULSE_ENCODER1_INDEX]);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_PULSE_ENCODER2
void TIM2_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
pulse_encoder_update_isr(&stm32_pulse_encoder_obj[PULSE_ENCODER2_INDEX]);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_PULSE_ENCODER3
void TIM3_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
pulse_encoder_update_isr(&stm32_pulse_encoder_obj[PULSE_ENCODER3_INDEX]);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_PULSE_ENCODER4
void TIM4_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
pulse_encoder_update_isr(&stm32_pulse_encoder_obj[PULSE_ENCODER4_INDEX]);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
static const struct rt_pulse_encoder_ops _ops =
{
.init = pulse_encoder_init,
.get_count = pulse_encoder_get_count,
.clear_count = pulse_encoder_clear_count,
.control = pulse_encoder_control,
};
int hw_pulse_encoder_init(void)
{
int i;
int result;
result = RT_EOK;
for (i = 0; i < sizeof(stm32_pulse_encoder_obj) / sizeof(stm32_pulse_encoder_obj[0]); i++)
{
stm32_pulse_encoder_obj[i].pulse_encoder.type = AB_PHASE_PULSE_ENCODER;
stm32_pulse_encoder_obj[i].pulse_encoder.ops = &_ops;
if (rt_device_pulse_encoder_register(&stm32_pulse_encoder_obj[i].pulse_encoder, stm32_pulse_encoder_obj[i].name, RT_NULL) != RT_EOK)
{
LOG_E("%s register failed", stm32_pulse_encoder_obj[i].name);
result = -RT_ERROR;
}
}
return result;
}
INIT_BOARD_EXPORT(hw_pulse_encoder_init);
#endif
+635
View File
@@ -0,0 +1,635 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-13 zylx first version
* 2021-01-23 thread-liu Fix the timer clock frequency doubling problem
*/
#include <board.h>
#ifdef RT_USING_PWM
#include "drv_config.h"
#include <drivers/rt_drv_pwm.h>
//#define DRV_DEBUG
#define LOG_TAG "drv.pwm"
#include <drv_log.h>
#define MAX_PERIOD 65535
#define MIN_PERIOD 3
#define MIN_PULSE 2
extern void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
enum
{
#ifdef BSP_USING_PWM1
PWM1_INDEX,
#endif
#ifdef BSP_USING_PWM2
PWM2_INDEX,
#endif
#ifdef BSP_USING_PWM3
PWM3_INDEX,
#endif
#ifdef BSP_USING_PWM4
PWM4_INDEX,
#endif
#ifdef BSP_USING_PWM5
PWM5_INDEX,
#endif
#ifdef BSP_USING_PWM6
PWM6_INDEX,
#endif
#ifdef BSP_USING_PWM7
PWM7_INDEX,
#endif
#ifdef BSP_USING_PWM8
PWM8_INDEX,
#endif
#ifdef BSP_USING_PWM9
PWM9_INDEX,
#endif
#ifdef BSP_USING_PWM10
PWM10_INDEX,
#endif
#ifdef BSP_USING_PWM11
PWM11_INDEX,
#endif
#ifdef BSP_USING_PWM12
PWM12_INDEX,
#endif
#ifdef BSP_USING_PWM13
PWM13_INDEX,
#endif
#ifdef BSP_USING_PWM14
PWM14_INDEX,
#endif
#ifdef BSP_USING_PWM15
PWM15_INDEX,
#endif
#ifdef BSP_USING_PWM16
PWM16_INDEX,
#endif
#ifdef BSP_USING_PWM17
PWM17_INDEX,
#endif
};
struct stm32_pwm
{
struct rt_device_pwm pwm_device;
TIM_HandleTypeDef tim_handle;
rt_uint8_t channel;
char *name;
};
static struct stm32_pwm stm32_pwm_obj[] =
{
#ifdef BSP_USING_PWM1
PWM1_CONFIG,
#endif
#ifdef BSP_USING_PWM2
PWM2_CONFIG,
#endif
#ifdef BSP_USING_PWM3
PWM3_CONFIG,
#endif
#ifdef BSP_USING_PWM4
PWM4_CONFIG,
#endif
#ifdef BSP_USING_PWM5
PWM5_CONFIG,
#endif
#ifdef BSP_USING_PWM6
PWM6_CONFIG,
#endif
#ifdef BSP_USING_PWM7
PWM7_CONFIG,
#endif
#ifdef BSP_USING_PWM8
PWM8_CONFIG,
#endif
#ifdef BSP_USING_PWM9
PWM9_CONFIG,
#endif
#ifdef BSP_USING_PWM10
PWM10_CONFIG,
#endif
#ifdef BSP_USING_PWM11
PWM11_CONFIG,
#endif
#ifdef BSP_USING_PWM12
PWM12_CONFIG,
#endif
#ifdef BSP_USING_PWM13
PWM13_CONFIG,
#endif
#ifdef BSP_USING_PWM14
PWM14_CONFIG,
#endif
#ifdef BSP_USING_PWM15
PWM15_CONFIG,
#endif
#ifdef BSP_USING_PWM16
PWM16_CONFIG,
#endif
#ifdef BSP_USING_PWM17
PWM17_CONFIG,
#endif
};
/* APBx timer clocks frequency doubler state related to APB1CLKDivider value */
static void pclkx_doubler_get(rt_uint32_t *pclk1_doubler, rt_uint32_t *pclk2_doubler)
{
rt_uint32_t flatency = 0;
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RT_ASSERT(pclk1_doubler != RT_NULL);
RT_ASSERT(pclk1_doubler != RT_NULL);
HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &flatency);
*pclk1_doubler = 1;
*pclk2_doubler = 1;
#if defined(SOC_SERIES_STM32MP1)
if (RCC_ClkInitStruct.APB1_Div != RCC_APB1_DIV1)
{
*pclk1_doubler = 2;
}
if (RCC_ClkInitStruct.APB2_Div != RCC_APB2_DIV1)
{
*pclk2_doubler = 2;
}
#else
if (RCC_ClkInitStruct.APB1CLKDivider != RCC_HCLK_DIV1)
{
*pclk1_doubler = 2;
}
#if !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32G0)
if (RCC_ClkInitStruct.APB2CLKDivider != RCC_HCLK_DIV1)
{
*pclk2_doubler = 2;
}
#endif
#endif
}
static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg);
static struct rt_pwm_ops drv_ops =
{
drv_pwm_control
};
static rt_err_t drv_pwm_enable(TIM_HandleTypeDef *htim, struct rt_pwm_configuration *configuration, rt_bool_t enable)
{
/* Converts the channel number to the channel number of Hal library */
rt_uint32_t channel = 0x04 * (configuration->channel - 1);
if (!configuration->complementary)
{
if (!enable)
{
HAL_TIM_PWM_Stop(htim, channel);
}
else
{
HAL_TIM_PWM_Start(htim, channel);
}
}
else if (configuration->complementary)
{
if (!enable)
{
HAL_TIMEx_PWMN_Stop(htim, channel);
}
else
{
HAL_TIMEx_PWMN_Start(htim, channel);
}
}
return RT_EOK;
}
static rt_err_t drv_pwm_get(TIM_HandleTypeDef *htim, struct rt_pwm_configuration *configuration)
{
/* Converts the channel number to the channel number of Hal library */
rt_uint32_t channel = 0x04 * (configuration->channel - 1);
rt_uint64_t tim_clock;
rt_uint32_t pclk1_doubler, pclk2_doubler;
pclkx_doubler_get(&pclk1_doubler, &pclk2_doubler);
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
if (htim->Instance == TIM9 || htim->Instance == TIM10 || htim->Instance == TIM11)
#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32H7)
if (htim->Instance == TIM15 || htim->Instance == TIM16 || htim->Instance == TIM17)
#elif defined(SOC_SERIES_STM32MP1)
if (htim->Instance == TIM4)
#elif defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)
if (0)
#endif
{
#if !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32G0)
tim_clock = (rt_uint32_t)(HAL_RCC_GetPCLK2Freq() * pclk2_doubler);
#endif
}
else
{
tim_clock = (rt_uint32_t)(HAL_RCC_GetPCLK1Freq() * pclk1_doubler);
}
if (__HAL_TIM_GET_CLOCKDIVISION(htim) == TIM_CLOCKDIVISION_DIV2)
{
tim_clock = tim_clock / 2;
}
else if (__HAL_TIM_GET_CLOCKDIVISION(htim) == TIM_CLOCKDIVISION_DIV4)
{
tim_clock = tim_clock / 4;
}
/* Convert nanosecond to frequency and duty cycle. 1s = 1 * 1000 * 1000 * 1000 ns */
tim_clock /= 1000000UL;
configuration->period = (__HAL_TIM_GET_AUTORELOAD(htim) + 1) * (htim->Instance->PSC + 1) * 1000UL / tim_clock;
configuration->pulse = (__HAL_TIM_GET_COMPARE(htim, channel) + 1) * (htim->Instance->PSC + 1) * 1000UL / tim_clock;
return RT_EOK;
}
static rt_err_t drv_pwm_set(TIM_HandleTypeDef *htim, struct rt_pwm_configuration *configuration)
{
rt_uint32_t period, pulse;
rt_uint64_t tim_clock, psc;
rt_uint32_t pclk1_doubler, pclk2_doubler;
/* Converts the channel number to the channel number of Hal library */
rt_uint32_t channel = 0x04 * (configuration->channel - 1);
pclkx_doubler_get(&pclk1_doubler, &pclk2_doubler);
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
if (htim->Instance == TIM9 || htim->Instance == TIM10 || htim->Instance == TIM11)
#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32H7)|| defined(SOC_SERIES_STM32F3)
if (htim->Instance == TIM15 || htim->Instance == TIM16 || htim->Instance == TIM17)
#elif defined(SOC_SERIES_STM32MP1)
if (htim->Instance == TIM4)
#elif defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)
if (0)
#endif
{
#if !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32G0)
tim_clock = (rt_uint32_t)(HAL_RCC_GetPCLK2Freq() * pclk2_doubler);
#endif
}
else
{
tim_clock = (rt_uint32_t)(HAL_RCC_GetPCLK1Freq() * pclk1_doubler);
}
/* Convert nanosecond to frequency and duty cycle. 1s = 1 * 1000 * 1000 * 1000 ns */
tim_clock /= 1000000UL;
period = (unsigned long long)configuration->period * tim_clock / 1000ULL ;
psc = period / MAX_PERIOD + 1;
period = period / psc;
__HAL_TIM_SET_PRESCALER(htim, psc - 1);
if (period < MIN_PERIOD)
{
period = MIN_PERIOD;
}
__HAL_TIM_SET_AUTORELOAD(htim, period - 1);
pulse = (unsigned long long)configuration->pulse * tim_clock / psc / 1000ULL;
if (pulse < MIN_PULSE)
{
pulse = MIN_PULSE;
}
else if (pulse > period)
{
pulse = period;
}
__HAL_TIM_SET_COMPARE(htim, channel, pulse - 1);
__HAL_TIM_SET_COUNTER(htim, 0);
/* Update frequency value */
HAL_TIM_GenerateEvent(htim, TIM_EVENTSOURCE_UPDATE);
return RT_EOK;
}
static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
{
struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg;
TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)device->parent.user_data;
switch (cmd)
{
case PWMN_CMD_ENABLE:
configuration->complementary = RT_TRUE;
case PWM_CMD_ENABLE:
return drv_pwm_enable(htim, configuration, RT_TRUE);
case PWMN_CMD_DISABLE:
configuration->complementary = RT_FALSE;
case PWM_CMD_DISABLE:
return drv_pwm_enable(htim, configuration, RT_FALSE);
case PWM_CMD_SET:
return drv_pwm_set(htim, configuration);
case PWM_CMD_GET:
return drv_pwm_get(htim, configuration);
default:
return RT_EINVAL;
}
}
static rt_err_t stm32_hw_pwm_init(struct stm32_pwm *device)
{
rt_err_t result = RT_EOK;
TIM_HandleTypeDef *tim = RT_NULL;
TIM_OC_InitTypeDef oc_config = {0};
TIM_MasterConfigTypeDef master_config = {0};
TIM_ClockConfigTypeDef clock_config = {0};
RT_ASSERT(device != RT_NULL);
tim = (TIM_HandleTypeDef *)&device->tim_handle;
/* configure the timer to pwm mode */
tim->Init.Prescaler = 0;
tim->Init.CounterMode = TIM_COUNTERMODE_UP;
tim->Init.Period = 0;
tim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4)
tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
#endif
if (HAL_TIM_Base_Init(tim) != HAL_OK)
{
LOG_E("%s pwm init failed", device->name);
result = -RT_ERROR;
goto __exit;
}
if (HAL_TIM_PWM_Init(tim) != HAL_OK)
{
LOG_E("%s pwm init failed", device->name);
result = -RT_ERROR;
goto __exit;
}
clock_config.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(tim, &clock_config) != HAL_OK)
{
LOG_E("%s clock init failed", device->name);
result = -RT_ERROR;
goto __exit;
}
master_config.MasterOutputTrigger = TIM_TRGO_RESET;
master_config.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(tim, &master_config) != HAL_OK)
{
LOG_E("%s master config failed", device->name);
result = -RT_ERROR;
goto __exit;
}
oc_config.OCMode = TIM_OCMODE_PWM1;
oc_config.Pulse = 0;
oc_config.OCPolarity = TIM_OCPOLARITY_HIGH;
oc_config.OCFastMode = TIM_OCFAST_DISABLE;
oc_config.OCNIdleState = TIM_OCNIDLESTATE_RESET;
oc_config.OCIdleState = TIM_OCIDLESTATE_RESET;
/* config pwm channel */
if (device->channel & 0x01)
{
if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_1) != HAL_OK)
{
LOG_E("%s channel1 config failed", device->name);
result = -RT_ERROR;
goto __exit;
}
}
if (device->channel & 0x02)
{
if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_2) != HAL_OK)
{
LOG_E("%s channel2 config failed", device->name);
result = -RT_ERROR;
goto __exit;
}
}
if (device->channel & 0x04)
{
if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_3) != HAL_OK)
{
LOG_E("%s channel3 config failed", device->name);
result = -RT_ERROR;
goto __exit;
}
}
if (device->channel & 0x08)
{
if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_4) != HAL_OK)
{
LOG_E("%s channel4 config failed", device->name);
result = -RT_ERROR;
goto __exit;
}
}
/* pwm pin configuration */
HAL_TIM_MspPostInit(tim);
/* enable update request source */
__HAL_TIM_URS_ENABLE(tim);
__exit:
return result;
}
static void pwm_get_channel(void)
{
#ifdef BSP_USING_PWM1_CH1
stm32_pwm_obj[PWM1_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM1_CH2
stm32_pwm_obj[PWM1_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM1_CH3
stm32_pwm_obj[PWM1_INDEX].channel |= 1 << 2;
#endif
#ifdef BSP_USING_PWM1_CH4
stm32_pwm_obj[PWM1_INDEX].channel |= 1 << 3;
#endif
#ifdef BSP_USING_PWM2_CH1
stm32_pwm_obj[PWM2_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM2_CH2
stm32_pwm_obj[PWM2_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM2_CH3
stm32_pwm_obj[PWM2_INDEX].channel |= 1 << 2;
#endif
#ifdef BSP_USING_PWM2_CH4
stm32_pwm_obj[PWM2_INDEX].channel |= 1 << 3;
#endif
#ifdef BSP_USING_PWM3_CH1
stm32_pwm_obj[PWM3_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM3_CH2
stm32_pwm_obj[PWM3_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM3_CH3
stm32_pwm_obj[PWM3_INDEX].channel |= 1 << 2;
#endif
#ifdef BSP_USING_PWM3_CH4
stm32_pwm_obj[PWM3_INDEX].channel |= 1 << 3;
#endif
#ifdef BSP_USING_PWM4_CH1
stm32_pwm_obj[PWM4_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM4_CH2
stm32_pwm_obj[PWM4_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM4_CH3
stm32_pwm_obj[PWM4_INDEX].channel |= 1 << 2;
#endif
#ifdef BSP_USING_PWM4_CH4
stm32_pwm_obj[PWM4_INDEX].channel |= 1 << 3;
#endif
#ifdef BSP_USING_PWM5_CH1
stm32_pwm_obj[PWM5_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM5_CH2
stm32_pwm_obj[PWM5_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM5_CH3
stm32_pwm_obj[PWM5_INDEX].channel |= 1 << 2;
#endif
#ifdef BSP_USING_PWM5_CH4
stm32_pwm_obj[PWM5_INDEX].channel |= 1 << 3;
#endif
#ifdef BSP_USING_PWM6_CH1
stm32_pwm_obj[PWM6_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM6_CH2
stm32_pwm_obj[PWM6_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM6_CH3
stm32_pwm_obj[PWM6_INDEX].channel |= 1 << 2;
#endif
#ifdef BSP_USING_PWM6_CH4
stm32_pwm_obj[PWM6_INDEX].channel |= 1 << 3;
#endif
#ifdef BSP_USING_PWM7_CH1
stm32_pwm_obj[PWM7_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM7_CH2
stm32_pwm_obj[PWM7_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM7_CH3
stm32_pwm_obj[PWM7_INDEX].channel |= 1 << 2;
#endif
#ifdef BSP_USING_PWM7_CH4
stm32_pwm_obj[PWM7_INDEX].channel |= 1 << 3;
#endif
#ifdef BSP_USING_PWM8_CH1
stm32_pwm_obj[PWM8_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM8_CH2
stm32_pwm_obj[PWM8_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM8_CH3
stm32_pwm_obj[PWM8_INDEX].channel |= 1 << 2;
#endif
#ifdef BSP_USING_PWM8_CH4
stm32_pwm_obj[PWM8_INDEX].channel |= 1 << 3;
#endif
#ifdef BSP_USING_PWM9_CH1
stm32_pwm_obj[PWM9_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM9_CH2
stm32_pwm_obj[PWM9_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM9_CH3
stm32_pwm_obj[PWM9_INDEX].channel |= 1 << 2;
#endif
#ifdef BSP_USING_PWM9_CH4
stm32_pwm_obj[PWM9_INDEX].channel |= 1 << 3;
#endif
#ifdef BSP_USING_PWM12_CH1
stm32_pwm_obj[PWM12_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM12_CH2
stm32_pwm_obj[PWM12_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM16_CH1
stm32_pwm_obj[PWM16_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM17_CH1
stm32_pwm_obj[PWM17_INDEX].channel |= 1 << 0;
#endif
}
static int stm32_pwm_init(void)
{
int i = 0;
int result = RT_EOK;
pwm_get_channel();
for (i = 0; i < sizeof(stm32_pwm_obj) / sizeof(stm32_pwm_obj[0]); i++)
{
/* pwm init */
if (stm32_hw_pwm_init(&stm32_pwm_obj[i]) != RT_EOK)
{
LOG_E("%s init failed", stm32_pwm_obj[i].name);
result = -RT_ERROR;
goto __exit;
}
else
{
LOG_D("%s init success", stm32_pwm_obj[i].name);
/* register pwm device */
if (rt_device_pwm_register(&stm32_pwm_obj[i].pwm_device, stm32_pwm_obj[i].name, &drv_ops, &stm32_pwm_obj[i].tim_handle) == RT_EOK)
{
LOG_D("%s register success", stm32_pwm_obj[i].name);
}
else
{
LOG_E("%s register failed", stm32_pwm_obj[i].name);
result = -RT_ERROR;
}
}
}
__exit:
return result;
}
INIT_DEVICE_EXPORT(stm32_pwm_init);
#endif /* RT_USING_PWM */
+400
View File
@@ -0,0 +1,400 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-27 zylx first version
*/
#include "board.h"
#ifdef RT_USING_QSPI
#include "drv_qspi.h"
#include "drv_config.h"
#define DRV_DEBUG
#define LOG_TAG "drv.qspi"
#include <drv_log.h>
#if defined(BSP_USING_QSPI)
struct stm32_hw_spi_cs
{
uint16_t pin;
};
struct stm32_qspi_bus
{
QSPI_HandleTypeDef QSPI_Handler;
char *bus_name;
#ifdef BSP_QSPI_USING_DMA
DMA_HandleTypeDef hdma_quadspi;
#endif
};
struct rt_spi_bus _qspi_bus1;
struct stm32_qspi_bus _stm32_qspi_bus;
static int stm32_qspi_init(struct rt_qspi_device *device, struct rt_qspi_configuration *qspi_cfg)
{
int result = RT_EOK;
unsigned int i = 1;
RT_ASSERT(device != RT_NULL);
RT_ASSERT(qspi_cfg != RT_NULL);
struct rt_spi_configuration *cfg = &qspi_cfg->parent;
struct stm32_qspi_bus *qspi_bus = device->parent.bus->parent.user_data;
rt_memset(&qspi_bus->QSPI_Handler, 0, sizeof(qspi_bus->QSPI_Handler));
QSPI_HandleTypeDef QSPI_Handler_config = QSPI_BUS_CONFIG;
qspi_bus->QSPI_Handler = QSPI_Handler_config;
#if defined(SOC_SERIES_STM32MP1)
while (cfg->max_hz < HAL_RCC_GetACLKFreq() / (i + 1))
#else
while (cfg->max_hz < HAL_RCC_GetHCLKFreq() / (i + 1))
#endif
{
i++;
if (i == 255)
{
LOG_E("QSPI init failed, QSPI frequency(%d) is too low.", cfg->max_hz);
return -RT_ERROR;
}
}
/* 80/(1+i) */
qspi_bus->QSPI_Handler.Init.ClockPrescaler = i;
if (!(cfg->mode & RT_SPI_CPOL))
{
/* QSPI MODE0 */
qspi_bus->QSPI_Handler.Init.ClockMode = QSPI_CLOCK_MODE_0;
}
else
{
/* QSPI MODE3 */
qspi_bus->QSPI_Handler.Init.ClockMode = QSPI_CLOCK_MODE_3;
}
/* flash size */
qspi_bus->QSPI_Handler.Init.FlashSize = POSITION_VAL(qspi_cfg->medium_size) - 1;
result = HAL_QSPI_Init(&qspi_bus->QSPI_Handler);
if (result == HAL_OK)
{
LOG_D("qspi init success!");
}
else
{
LOG_E("qspi init failed (%d)!", result);
}
#ifdef BSP_QSPI_USING_DMA
/* QSPI interrupts must be enabled when using the HAL_QSPI_Receive_DMA */
HAL_NVIC_SetPriority(QSPI_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(QSPI_IRQn);
HAL_NVIC_SetPriority(QSPI_DMA_IRQ, 0, 0);
HAL_NVIC_EnableIRQ(QSPI_DMA_IRQ);
/* init QSPI DMA */
if(QSPI_DMA_RCC == RCC_AHB1ENR_DMA1EN)
{
__HAL_RCC_DMA1_CLK_ENABLE();
}
else
{
__HAL_RCC_DMA2_CLK_ENABLE();
}
HAL_DMA_DeInit(qspi_bus->QSPI_Handler.hdma);
DMA_HandleTypeDef hdma_quadspi_config = QSPI_DMA_CONFIG;
qspi_bus->hdma_quadspi = hdma_quadspi_config;
if (HAL_DMA_Init(&qspi_bus->hdma_quadspi) != HAL_OK)
{
LOG_E("qspi dma init failed (%d)!", result);
}
__HAL_LINKDMA(&qspi_bus->QSPI_Handler, hdma, qspi_bus->hdma_quadspi);
#endif /* BSP_QSPI_USING_DMA */
return result;
}
static void qspi_send_cmd(struct stm32_qspi_bus *qspi_bus, struct rt_qspi_message *message)
{
RT_ASSERT(qspi_bus != RT_NULL);
RT_ASSERT(message != RT_NULL);
QSPI_CommandTypeDef Cmdhandler;
/* set QSPI cmd struct */
Cmdhandler.Instruction = message->instruction.content;
Cmdhandler.Address = message->address.content;
Cmdhandler.DummyCycles = message->dummy_cycles;
if (message->instruction.qspi_lines == 0)
{
Cmdhandler.InstructionMode = QSPI_INSTRUCTION_NONE;
}
else if (message->instruction.qspi_lines == 1)
{
Cmdhandler.InstructionMode = QSPI_INSTRUCTION_1_LINE;
}
else if (message->instruction.qspi_lines == 2)
{
Cmdhandler.InstructionMode = QSPI_INSTRUCTION_2_LINES;
}
else if (message->instruction.qspi_lines == 4)
{
Cmdhandler.InstructionMode = QSPI_INSTRUCTION_4_LINES;
}
if (message->address.qspi_lines == 0)
{
Cmdhandler.AddressMode = QSPI_ADDRESS_NONE;
}
else if (message->address.qspi_lines == 1)
{
Cmdhandler.AddressMode = QSPI_ADDRESS_1_LINE;
}
else if (message->address.qspi_lines == 2)
{
Cmdhandler.AddressMode = QSPI_ADDRESS_2_LINES;
}
else if (message->address.qspi_lines == 4)
{
Cmdhandler.AddressMode = QSPI_ADDRESS_4_LINES;
}
if (message->address.size == 24)
{
Cmdhandler.AddressSize = QSPI_ADDRESS_24_BITS;
}
else
{
Cmdhandler.AddressSize = QSPI_ADDRESS_32_BITS;
}
if (message->qspi_data_lines == 0)
{
Cmdhandler.DataMode = QSPI_DATA_NONE;
}
else if (message->qspi_data_lines == 1)
{
Cmdhandler.DataMode = QSPI_DATA_1_LINE;
}
else if (message->qspi_data_lines == 2)
{
Cmdhandler.DataMode = QSPI_DATA_2_LINES;
}
else if (message->qspi_data_lines == 4)
{
Cmdhandler.DataMode = QSPI_DATA_4_LINES;
}
Cmdhandler.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
Cmdhandler.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
Cmdhandler.DdrMode = QSPI_DDR_MODE_DISABLE;
Cmdhandler.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
Cmdhandler.NbData = message->parent.length;
HAL_QSPI_Command(&qspi_bus->QSPI_Handler, &Cmdhandler, 5000);
}
static rt_uint32_t qspixfer(struct rt_spi_device *device, struct rt_spi_message *message)
{
rt_size_t len = 0;
RT_ASSERT(device != RT_NULL);
RT_ASSERT(device->bus != RT_NULL);
struct rt_qspi_message *qspi_message = (struct rt_qspi_message *)message;
struct stm32_qspi_bus *qspi_bus = device->bus->parent.user_data;
#ifdef BSP_QSPI_USING_SOFTCS
struct stm32_hw_spi_cs *cs = device->parent.user_data;
#endif
const rt_uint8_t *sndb = message->send_buf;
rt_uint8_t *rcvb = message->recv_buf;
rt_int32_t length = message->length;
#ifdef BSP_QSPI_USING_SOFTCS
if (message->cs_take)
{
rt_pin_write(cs->pin, 0);
}
#endif
/* send data */
if (sndb)
{
qspi_send_cmd(qspi_bus, qspi_message);
if (qspi_message->parent.length != 0)
{
if (HAL_QSPI_Transmit(&qspi_bus->QSPI_Handler, (rt_uint8_t *)sndb, 5000) == HAL_OK)
{
len = length;
}
else
{
LOG_E("QSPI send data failed(%d)!", qspi_bus->QSPI_Handler.ErrorCode);
qspi_bus->QSPI_Handler.State = HAL_QSPI_STATE_READY;
goto __exit;
}
}
else
{
len = 1;
}
}
else if (rcvb)/* recv data */
{
qspi_send_cmd(qspi_bus, qspi_message);
#ifdef BSP_QSPI_USING_DMA
if (HAL_QSPI_Receive_DMA(&qspi_bus->QSPI_Handler, rcvb) == HAL_OK)
#else
if (HAL_QSPI_Receive(&qspi_bus->QSPI_Handler, rcvb, 5000) == HAL_OK)
#endif
{
len = length;
#ifdef BSP_QSPI_USING_DMA
while (qspi_bus->QSPI_Handler.RxXferCount != 0);
#endif
}
else
{
LOG_E("QSPI recv data failed(%d)!", qspi_bus->QSPI_Handler.ErrorCode);
qspi_bus->QSPI_Handler.State = HAL_QSPI_STATE_READY;
goto __exit;
}
}
__exit:
#ifdef BSP_QSPI_USING_SOFTCS
if (message->cs_release)
{
rt_pin_write(cs->pin, 1);
}
#endif
return len;
}
static rt_err_t qspi_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration)
{
RT_ASSERT(device != RT_NULL);
RT_ASSERT(configuration != RT_NULL);
struct rt_qspi_device *qspi_device = (struct rt_qspi_device *)device;
return stm32_qspi_init(qspi_device, &qspi_device->config);
}
static const struct rt_spi_ops stm32_qspi_ops =
{
.configure = qspi_configure,
.xfer = qspixfer,
};
static int stm32_qspi_register_bus(struct stm32_qspi_bus *qspi_bus, const char *name)
{
RT_ASSERT(qspi_bus != RT_NULL);
RT_ASSERT(name != RT_NULL);
_qspi_bus1.parent.user_data = qspi_bus;
return rt_qspi_bus_register(&_qspi_bus1, name, &stm32_qspi_ops);
}
/**
* @brief This function attach device to QSPI bus.
* @param device_name QSPI device name
* @param pin QSPI cs pin number
* @param data_line_width QSPI data lines width, such as 1, 2, 4
* @param enter_qspi_mode Callback function that lets FLASH enter QSPI mode
* @param exit_qspi_mode Callback function that lets FLASH exit QSPI mode
* @retval 0 : success
* -1 : failed
*/
rt_err_t stm32_qspi_bus_attach_device(const char *bus_name, const char *device_name, rt_uint32_t pin, rt_uint8_t data_line_width, void (*enter_qspi_mode)(), void (*exit_qspi_mode)())
{
struct rt_qspi_device *qspi_device = RT_NULL;
struct stm32_hw_spi_cs *cs_pin = RT_NULL;
rt_err_t result = RT_EOK;
RT_ASSERT(bus_name != RT_NULL);
RT_ASSERT(device_name != RT_NULL);
RT_ASSERT(data_line_width == 1 || data_line_width == 2 || data_line_width == 4);
qspi_device = (struct rt_qspi_device *)rt_malloc(sizeof(struct rt_qspi_device));
if (qspi_device == RT_NULL)
{
LOG_E("no memory, qspi bus attach device failed!");
result = RT_ENOMEM;
goto __exit;
}
cs_pin = (struct stm32_hw_spi_cs *)rt_malloc(sizeof(struct stm32_hw_spi_cs));
if (qspi_device == RT_NULL)
{
LOG_E("no memory, qspi bus attach device failed!");
result = RT_ENOMEM;
goto __exit;
}
qspi_device->enter_qspi_mode = enter_qspi_mode;
qspi_device->exit_qspi_mode = exit_qspi_mode;
qspi_device->config.qspi_dl_width = data_line_width;
cs_pin->pin = pin;
#ifdef BSP_QSPI_USING_SOFTCS
rt_pin_mode(pin, PIN_MODE_OUTPUT);
rt_pin_write(pin, 1);
#endif
result = rt_spi_bus_attach_device(&qspi_device->parent, device_name, bus_name, (void *)cs_pin);
__exit:
if (result != RT_EOK)
{
if (qspi_device)
{
rt_free(qspi_device);
}
if (cs_pin)
{
rt_free(cs_pin);
}
}
return result;
}
#ifdef BSP_QSPI_USING_DMA
void QSPI_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_QSPI_IRQHandler(&_stm32_qspi_bus.QSPI_Handler);
/* leave interrupt */
rt_interrupt_leave();
}
void QSPI_DMA_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_DMA_IRQHandler(&_stm32_qspi_bus.hdma_quadspi);
/* leave interrupt */
rt_interrupt_leave();
}
#endif /* BSP_QSPI_USING_DMA */
static int rt_hw_qspi_bus_init(void)
{
return stm32_qspi_register_bus(&_stm32_qspi_bus, "qspi1");
}
INIT_BOARD_EXPORT(rt_hw_qspi_bus_init);
#endif /* BSP_USING_QSPI */
#endif /* RT_USING_QSPI */
+306
View File
@@ -0,0 +1,306 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-04 balanceTWK first version
* 2020-10-14 Dozingfiretruck Porting for stm32wbxx
* 2021-02-05 Meco Man fix the problem of mixing local time and UTC time
* 2021-07-05 iysheng implement RTC framework V2.0
*/
#include "board.h"
#ifdef BSP_USING_ONCHIP_RTC
#include <sys/time.h>
#ifndef RTC_BKP_DR1
#define RTC_BKP_DR1 RT_NULL
#endif
//#define DRV_DEBUG
#define LOG_TAG "drv.rtc"
#include <drv_log.h>
#define BKUP_REG_DATA 0xA5A5
static RTC_HandleTypeDef RTC_Handler;
RT_WEAK uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister)
{
return (~BKUP_REG_DATA);
}
RT_WEAK void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister, uint32_t Data)
{
return;
}
static void get_rtc_timeval(struct timeval *tv)
{
RTC_TimeTypeDef RTC_TimeStruct = {0};
RTC_DateTypeDef RTC_DateStruct = {0};
struct tm tm_new = {0};
HAL_RTC_GetTime(&RTC_Handler, &RTC_TimeStruct, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&RTC_Handler, &RTC_DateStruct, RTC_FORMAT_BIN);
tm_new.tm_sec = RTC_TimeStruct.Seconds;
tm_new.tm_min = RTC_TimeStruct.Minutes;
tm_new.tm_hour = RTC_TimeStruct.Hours;
tm_new.tm_mday = RTC_DateStruct.Date;
tm_new.tm_mon = RTC_DateStruct.Month - 1;
tm_new.tm_year = RTC_DateStruct.Year + 100;
tv->tv_sec = timegm(&tm_new);
#if defined(SOC_SERIES_STM32H7)
tv->tv_usec = (255.0 - RTC_TimeStruct.SubSeconds * 1.0) / 256.0 * 1000.0 * 1000.0;
#endif
}
static rt_err_t set_rtc_time_stamp(time_t time_stamp)
{
RTC_TimeTypeDef RTC_TimeStruct = {0};
RTC_DateTypeDef RTC_DateStruct = {0};
struct tm tm = {0};
gmtime_r(&time_stamp, &tm);
if (tm.tm_year < 100)
{
return -RT_ERROR;
}
RTC_TimeStruct.Seconds = tm.tm_sec ;
RTC_TimeStruct.Minutes = tm.tm_min ;
RTC_TimeStruct.Hours = tm.tm_hour;
RTC_DateStruct.Date = tm.tm_mday;
RTC_DateStruct.Month = tm.tm_mon + 1 ;
RTC_DateStruct.Year = tm.tm_year - 100;
RTC_DateStruct.WeekDay = tm.tm_wday + 1;
if (HAL_RTC_SetTime(&RTC_Handler, &RTC_TimeStruct, RTC_FORMAT_BIN) != HAL_OK)
{
return -RT_ERROR;
}
if (HAL_RTC_SetDate(&RTC_Handler, &RTC_DateStruct, RTC_FORMAT_BIN) != HAL_OK)
{
return -RT_ERROR;
}
LOG_D("set rtc time.");
HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR1, BKUP_REG_DATA);
#ifdef SOC_SERIES_STM32F1
/* F1 series does't save year/month/date datas. so keep those datas to bkp reg */
HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR2, RTC_DateStruct.Year);
HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR3, RTC_DateStruct.Month);
HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR4, RTC_DateStruct.Date);
HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR5, RTC_DateStruct.WeekDay);
#endif
return RT_EOK;
}
#ifdef SOC_SERIES_STM32F1
/* update RTC_BKP_DRx*/
static void rt_rtc_f1_bkp_update(void)
{
RTC_DateTypeDef RTC_DateStruct = {0};
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_BKP_CLK_ENABLE();
RTC_DateStruct.Year = HAL_RTCEx_BKUPRead(&RTC_Handler, RTC_BKP_DR2);
RTC_DateStruct.Month = HAL_RTCEx_BKUPRead(&RTC_Handler, RTC_BKP_DR3);
RTC_DateStruct.Date = HAL_RTCEx_BKUPRead(&RTC_Handler, RTC_BKP_DR4);
RTC_DateStruct.WeekDay = HAL_RTCEx_BKUPRead(&RTC_Handler, RTC_BKP_DR5);
if (HAL_RTC_SetDate(&RTC_Handler, &RTC_DateStruct, RTC_FORMAT_BIN) != HAL_OK)
{
Error_Handler();
}
HAL_RTC_GetDate(&RTC_Handler, &RTC_DateStruct, RTC_FORMAT_BIN);
if (HAL_RTCEx_BKUPRead(&RTC_Handler, RTC_BKP_DR4) != RTC_DateStruct.Date)
{
HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR1, BKUP_REG_DATA);
HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR2, RTC_DateStruct.Year);
HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR3, RTC_DateStruct.Month);
HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR4, RTC_DateStruct.Date);
HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR5, RTC_DateStruct.WeekDay);
}
}
#endif
static rt_err_t rt_rtc_config(void)
{
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
HAL_PWR_EnableBkUpAccess();
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
#ifdef BSP_RTC_USING_LSI
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
#else
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
#endif
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
#if defined(SOC_SERIES_STM32WL)
__HAL_RCC_RTCAPB_CLK_ENABLE();
#endif
/* Enable RTC Clock */
__HAL_RCC_RTC_ENABLE();
RTC_Handler.Instance = RTC;
if (HAL_RTCEx_BKUPRead(&RTC_Handler, RTC_BKP_DR1) != BKUP_REG_DATA)
{
LOG_I("RTC hasn't been configured, please use <date> command to config.");
#if defined(SOC_SERIES_STM32F1)
RTC_Handler.Init.OutPut = RTC_OUTPUTSOURCE_NONE;
RTC_Handler.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
#elif defined(SOC_SERIES_STM32F0)
/* set the frequency division */
#ifdef BSP_RTC_USING_LSI
RTC_Handler.Init.AsynchPrediv = 0XA0;
RTC_Handler.Init.SynchPrediv = 0xFA;
#else
RTC_Handler.Init.AsynchPrediv = 0X7F;
RTC_Handler.Init.SynchPrediv = 0x0130;
#endif /* BSP_RTC_USING_LSI */
RTC_Handler.Init.HourFormat = RTC_HOURFORMAT_24;
RTC_Handler.Init.OutPut = RTC_OUTPUT_DISABLE;
RTC_Handler.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
RTC_Handler.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
#elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32H7) || defined (SOC_SERIES_STM32WB)
/* set the frequency division */
#ifdef BSP_RTC_USING_LSI
RTC_Handler.Init.AsynchPrediv = 0X7D;
#else
RTC_Handler.Init.AsynchPrediv = 0X7F;
#endif /* BSP_RTC_USING_LSI */
RTC_Handler.Init.SynchPrediv = 0XFF;
RTC_Handler.Init.HourFormat = RTC_HOURFORMAT_24;
RTC_Handler.Init.OutPut = RTC_OUTPUT_DISABLE;
RTC_Handler.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
RTC_Handler.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
#endif
if (HAL_RTC_Init(&RTC_Handler) != HAL_OK)
{
return -RT_ERROR;
}
}
#ifdef SOC_SERIES_STM32F1
else
{
/* F1 series need update by bkp reg datas */
rt_rtc_f1_bkp_update();
}
#endif
return RT_EOK;
}
static rt_err_t stm32_rtc_init(void)
{
#if !defined(SOC_SERIES_STM32H7) && !defined(SOC_SERIES_STM32WL) && !defined(SOC_SERIES_STM32WB)
__HAL_RCC_PWR_CLK_ENABLE();
#endif
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
#ifdef BSP_RTC_USING_LSI
#ifdef SOC_SERIES_STM32WB
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI1;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
#else
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
#endif
#else
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
#endif
HAL_RCC_OscConfig(&RCC_OscInitStruct);
if (rt_rtc_config() != RT_EOK)
{
LOG_E("rtc init failed.");
return -RT_ERROR;
}
return RT_EOK;
}
static rt_err_t stm32_rtc_get_secs(void *args)
{
struct timeval tv;
get_rtc_timeval(&tv);
*(rt_uint32_t *) args = tv.tv_sec;
LOG_D("RTC: get rtc_time %x", *(rt_uint32_t *)args);
return RT_EOK;
}
static rt_err_t stm32_rtc_set_secs(void *args)
{
rt_err_t result = RT_EOK;
if (set_rtc_time_stamp(*(rt_uint32_t *)args))
{
result = -RT_ERROR;
}
LOG_D("RTC: set rtc_time %x", *(rt_uint32_t *)args);
return result;
}
static rt_err_t stm32_rtc_get_timeval(void *args)
{
get_rtc_timeval((struct timeval *) args);
return RT_EOK;
}
static const struct rt_rtc_ops stm32_rtc_ops =
{
stm32_rtc_init,
stm32_rtc_get_secs,
stm32_rtc_set_secs,
RT_NULL,
RT_NULL,
stm32_rtc_get_timeval,
RT_NULL,
};
static rt_rtc_dev_t stm32_rtc_dev;
static int rt_hw_rtc_init(void)
{
rt_err_t result;
stm32_rtc_dev.ops = &stm32_rtc_ops;
result = rt_hw_rtc_register(&stm32_rtc_dev, "rtc", RT_DEVICE_FLAG_RDWR, RT_NULL);
if (result != RT_EOK)
{
LOG_E("rtc register err code: %d", result);
return result;
}
LOG_D("rtc init success");
return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_rtc_init);
#endif /* BSP_USING_ONCHIP_RTC */
+888
View File
@@ -0,0 +1,888 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-06-22 tyx first
* 2018-12-12 balanceTWK first version
* 2019-06-11 WillianChan Add SD card hot plug detection
* 2020-11-09 whj4674672 fix sdio non-aligned access problem
*/
#include "board.h"
#ifdef BSP_USING_SDIO
#include "drv_sdio.h"
#include "drv_config.h"
//#define DRV_DEBUG
#define LOG_TAG "drv.sdio"
#include <drv_log.h>
static struct stm32_sdio_config sdio_config = SDIO_BUS_CONFIG;
static struct stm32_sdio_class sdio_obj;
static struct rt_mmcsd_host *host;
#define SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS (100000)
#define RTHW_SDIO_LOCK(_sdio) rt_mutex_take(&_sdio->mutex, RT_WAITING_FOREVER)
#define RTHW_SDIO_UNLOCK(_sdio) rt_mutex_release(&_sdio->mutex);
struct sdio_pkg
{
struct rt_mmcsd_cmd *cmd;
void *buff;
rt_uint32_t flag;
};
struct rthw_sdio
{
struct rt_mmcsd_host *host;
struct stm32_sdio_des sdio_des;
struct rt_event event;
struct rt_mutex mutex;
struct sdio_pkg *pkg;
};
ALIGN(SDIO_ALIGN_LEN)
static rt_uint8_t cache_buf[SDIO_BUFF_SIZE];
static rt_uint32_t stm32_sdio_clk_get(struct stm32_sdio *hw_sdio)
{
return SDIO_CLOCK_FREQ;
}
/**
* @brief This function get order from sdio.
* @param data
* @retval sdio order
*/
static int get_order(rt_uint32_t data)
{
int order = 0;
switch (data)
{
case 1:
order = 0;
break;
case 2:
order = 1;
break;
case 4:
order = 2;
break;
case 8:
order = 3;
break;
case 16:
order = 4;
break;
case 32:
order = 5;
break;
case 64:
order = 6;
break;
case 128:
order = 7;
break;
case 256:
order = 8;
break;
case 512:
order = 9;
break;
case 1024:
order = 10;
break;
case 2048:
order = 11;
break;
case 4096:
order = 12;
break;
case 8192:
order = 13;
break;
case 16384:
order = 14;
break;
default :
order = 0;
break;
}
return order;
}
/**
* @brief This function wait sdio completed.
* @param sdio rthw_sdio
* @retval None
*/
static void rthw_sdio_wait_completed(struct rthw_sdio *sdio)
{
rt_uint32_t status;
struct rt_mmcsd_cmd *cmd = sdio->pkg->cmd;
struct rt_mmcsd_data *data = cmd->data;
struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio;
if (rt_event_recv(&sdio->event, 0xffffffff, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
rt_tick_from_millisecond(5000), &status) != RT_EOK)
{
LOG_E("wait completed timeout");
cmd->err = -RT_ETIMEOUT;
return;
}
if (sdio->pkg == RT_NULL)
{
return;
}
cmd->resp[0] = hw_sdio->resp1;
cmd->resp[1] = hw_sdio->resp2;
cmd->resp[2] = hw_sdio->resp3;
cmd->resp[3] = hw_sdio->resp4;
if (status & HW_SDIO_ERRORS)
{
if ((status & HW_SDIO_IT_CCRCFAIL) && (resp_type(cmd) & (RESP_R3 | RESP_R4)))
{
cmd->err = RT_EOK;
}
else
{
cmd->err = -RT_ERROR;
}
if (status & HW_SDIO_IT_CTIMEOUT)
{
cmd->err = -RT_ETIMEOUT;
}
if (status & HW_SDIO_IT_DCRCFAIL)
{
data->err = -RT_ERROR;
}
if (status & HW_SDIO_IT_DTIMEOUT)
{
data->err = -RT_ETIMEOUT;
}
if (cmd->err == RT_EOK)
{
LOG_D("sta:0x%08X [%08X %08X %08X %08X]", status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
}
else
{
LOG_D("err:0x%08x, %s%s%s%s%s%s%s cmd:%d arg:0x%08x rw:%c len:%d blksize:%d",
status,
status & HW_SDIO_IT_CCRCFAIL ? "CCRCFAIL " : "",
status & HW_SDIO_IT_DCRCFAIL ? "DCRCFAIL " : "",
status & HW_SDIO_IT_CTIMEOUT ? "CTIMEOUT " : "",
status & HW_SDIO_IT_DTIMEOUT ? "DTIMEOUT " : "",
status & HW_SDIO_IT_TXUNDERR ? "TXUNDERR " : "",
status & HW_SDIO_IT_RXOVERR ? "RXOVERR " : "",
status == 0 ? "NULL" : "",
cmd->cmd_code,
cmd->arg,
data ? (data->flags & DATA_DIR_WRITE ? 'w' : 'r') : '-',
data ? data->blks * data->blksize : 0,
data ? data->blksize : 0
);
}
}
else
{
cmd->err = RT_EOK;
LOG_D("sta:0x%08X [%08X %08X %08X %08X]", status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
}
}
/**
* @brief This function transfer data by dma.
* @param sdio rthw_sdio
* @param pkg sdio package
* @retval None
*/
static void rthw_sdio_transfer_by_dma(struct rthw_sdio *sdio, struct sdio_pkg *pkg)
{
struct rt_mmcsd_data *data;
int size;
void *buff;
struct stm32_sdio *hw_sdio;
if ((RT_NULL == pkg) || (RT_NULL == sdio))
{
LOG_E("rthw_sdio_transfer_by_dma invalid args");
return;
}
data = pkg->cmd->data;
if (RT_NULL == data)
{
LOG_E("rthw_sdio_transfer_by_dma invalid args");
return;
}
buff = pkg->buff;
if (RT_NULL == buff)
{
LOG_E("rthw_sdio_transfer_by_dma invalid args");
return;
}
hw_sdio = sdio->sdio_des.hw_sdio;
size = data->blks * data->blksize;
if (data->flags & DATA_DIR_WRITE)
{
sdio->sdio_des.txconfig((rt_uint32_t *)buff, (rt_uint32_t *)&hw_sdio->fifo, size);
hw_sdio->dctrl |= HW_SDIO_DMA_ENABLE;
}
else if (data->flags & DATA_DIR_READ)
{
sdio->sdio_des.rxconfig((rt_uint32_t *)&hw_sdio->fifo, (rt_uint32_t *)buff, size);
hw_sdio->dctrl |= HW_SDIO_DMA_ENABLE | HW_SDIO_DPSM_ENABLE;
}
}
/**
* @brief This function send command.
* @param sdio rthw_sdio
* @param pkg sdio package
* @retval None
*/
static void rthw_sdio_send_command(struct rthw_sdio *sdio, struct sdio_pkg *pkg)
{
struct rt_mmcsd_cmd *cmd = pkg->cmd;
struct rt_mmcsd_data *data = cmd->data;
struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio;
rt_uint32_t reg_cmd;
/* save pkg */
sdio->pkg = pkg;
LOG_D("CMD:%d ARG:0x%08x RES:%s%s%s%s%s%s%s%s%s rw:%c len:%d blksize:%d",
cmd->cmd_code,
cmd->arg,
resp_type(cmd) == RESP_NONE ? "NONE" : "",
resp_type(cmd) == RESP_R1 ? "R1" : "",
resp_type(cmd) == RESP_R1B ? "R1B" : "",
resp_type(cmd) == RESP_R2 ? "R2" : "",
resp_type(cmd) == RESP_R3 ? "R3" : "",
resp_type(cmd) == RESP_R4 ? "R4" : "",
resp_type(cmd) == RESP_R5 ? "R5" : "",
resp_type(cmd) == RESP_R6 ? "R6" : "",
resp_type(cmd) == RESP_R7 ? "R7" : "",
data ? (data->flags & DATA_DIR_WRITE ? 'w' : 'r') : '-',
data ? data->blks * data->blksize : 0,
data ? data->blksize : 0
);
/* config cmd reg */
reg_cmd = cmd->cmd_code | HW_SDIO_CPSM_ENABLE;
if (resp_type(cmd) == RESP_NONE)
reg_cmd |= HW_SDIO_RESPONSE_NO;
else if (resp_type(cmd) == RESP_R2)
reg_cmd |= HW_SDIO_RESPONSE_LONG;
else
reg_cmd |= HW_SDIO_RESPONSE_SHORT;
/* config data reg */
if (data != RT_NULL)
{
rt_uint32_t dir = 0;
rt_uint32_t size = data->blks * data->blksize;
int order;
hw_sdio->dctrl = 0;
hw_sdio->dtimer = HW_SDIO_DATATIMEOUT;
hw_sdio->dlen = size;
order = get_order(data->blksize);
dir = (data->flags & DATA_DIR_READ) ? HW_SDIO_TO_HOST : 0;
hw_sdio->dctrl = HW_SDIO_IO_ENABLE | (order << 4) | dir;
}
/* transfer config */
if (data != RT_NULL)
{
rthw_sdio_transfer_by_dma(sdio, pkg);
}
/* open irq */
hw_sdio->mask |= HW_SDIO_IT_CMDSENT | HW_SDIO_IT_CMDREND | HW_SDIO_ERRORS;
if (data != RT_NULL)
{
hw_sdio->mask |= HW_SDIO_IT_DATAEND;
}
/* send cmd */
hw_sdio->arg = cmd->arg;
hw_sdio->cmd = reg_cmd;
/* wait completed */
rthw_sdio_wait_completed(sdio);
/* Waiting for data to be sent to completion */
if (data != RT_NULL)
{
volatile rt_uint32_t count = SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS;
while (count && (hw_sdio->sta & (HW_SDIO_IT_TXACT | HW_SDIO_IT_RXACT)))
{
count--;
}
if ((count == 0) || (hw_sdio->sta & HW_SDIO_ERRORS))
{
cmd->err = -RT_ERROR;
}
}
/* close irq, keep sdio irq */
hw_sdio->mask = hw_sdio->mask & HW_SDIO_IT_SDIOIT ? HW_SDIO_IT_SDIOIT : 0x00;
/* clear pkg */
sdio->pkg = RT_NULL;
}
/**
* @brief This function send sdio request.
* @param host rt_mmcsd_host
* @param req request
* @retval None
*/
static void rthw_sdio_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
{
struct sdio_pkg pkg;
struct rthw_sdio *sdio = host->private_data;
struct rt_mmcsd_data *data;
RTHW_SDIO_LOCK(sdio);
if (req->cmd != RT_NULL)
{
rt_memset(&pkg, 0, sizeof(pkg));
data = req->cmd->data;
pkg.cmd = req->cmd;
if (data != RT_NULL)
{
rt_uint32_t size = data->blks * data->blksize;
RT_ASSERT(size <= SDIO_BUFF_SIZE);
pkg.buff = data->buf;
if ((rt_uint32_t)data->buf & (SDIO_ALIGN_LEN - 1))
{
pkg.buff = cache_buf;
if (data->flags & DATA_DIR_WRITE)
{
rt_memcpy(cache_buf, data->buf, size);
}
}
}
rthw_sdio_send_command(sdio, &pkg);
if ((data != RT_NULL) && (data->flags & DATA_DIR_READ) && ((rt_uint32_t)data->buf & (SDIO_ALIGN_LEN - 1)))
{
rt_memcpy(data->buf, cache_buf, data->blksize * data->blks);
}
}
if (req->stop != RT_NULL)
{
rt_memset(&pkg, 0, sizeof(pkg));
pkg.cmd = req->stop;
rthw_sdio_send_command(sdio, &pkg);
}
RTHW_SDIO_UNLOCK(sdio);
mmcsd_req_complete(sdio->host);
}
/**
* @brief This function config sdio.
* @param host rt_mmcsd_host
* @param io_cfg rt_mmcsd_io_cfg
* @retval None
*/
static void rthw_sdio_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg)
{
rt_uint32_t clkcr, div, clk_src;
rt_uint32_t clk = io_cfg->clock;
struct rthw_sdio *sdio = host->private_data;
struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio;
clk_src = sdio->sdio_des.clk_get(sdio->sdio_des.hw_sdio);
if (clk_src < 400 * 1000)
{
LOG_E("The clock rate is too low! rata:%d", clk_src);
return;
}
if (clk > host->freq_max) clk = host->freq_max;
if (clk > clk_src)
{
LOG_W("Setting rate is greater than clock source rate.");
clk = clk_src;
}
LOG_D("clk:%d width:%s%s%s power:%s%s%s",
clk,
io_cfg->bus_width == MMCSD_BUS_WIDTH_8 ? "8" : "",
io_cfg->bus_width == MMCSD_BUS_WIDTH_4 ? "4" : "",
io_cfg->bus_width == MMCSD_BUS_WIDTH_1 ? "1" : "",
io_cfg->power_mode == MMCSD_POWER_OFF ? "OFF" : "",
io_cfg->power_mode == MMCSD_POWER_UP ? "UP" : "",
io_cfg->power_mode == MMCSD_POWER_ON ? "ON" : ""
);
RTHW_SDIO_LOCK(sdio);
div = clk_src / clk;
if ((clk == 0) || (div == 0))
{
clkcr = 0;
}
else
{
if (div < 2)
{
div = 2;
}
else if (div > 0xFF)
{
div = 0xFF;
}
div -= 2;
clkcr = div | HW_SDIO_CLK_ENABLE;
}
if (io_cfg->bus_width == MMCSD_BUS_WIDTH_8)
{
clkcr |= HW_SDIO_BUSWIDE_8B;
}
else if (io_cfg->bus_width == MMCSD_BUS_WIDTH_4)
{
clkcr |= HW_SDIO_BUSWIDE_4B;
}
else
{
clkcr |= HW_SDIO_BUSWIDE_1B;
}
hw_sdio->clkcr = clkcr;
switch (io_cfg->power_mode)
{
case MMCSD_POWER_OFF:
hw_sdio->power = HW_SDIO_POWER_OFF;
break;
case MMCSD_POWER_UP:
hw_sdio->power = HW_SDIO_POWER_UP;
break;
case MMCSD_POWER_ON:
hw_sdio->power = HW_SDIO_POWER_ON;
break;
default:
LOG_W("unknown power_mode %d", io_cfg->power_mode);
break;
}
RTHW_SDIO_UNLOCK(sdio);
}
/**
* @brief This function update sdio interrupt.
* @param host rt_mmcsd_host
* @param enable
* @retval None
*/
void rthw_sdio_irq_update(struct rt_mmcsd_host *host, rt_int32_t enable)
{
struct rthw_sdio *sdio = host->private_data;
struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio;
if (enable)
{
LOG_D("enable sdio irq");
hw_sdio->mask |= HW_SDIO_IT_SDIOIT;
}
else
{
LOG_D("disable sdio irq");
hw_sdio->mask &= ~HW_SDIO_IT_SDIOIT;
}
}
/**
* @brief This function detect sdcard.
* @param host rt_mmcsd_host
* @retval 0x01
*/
static rt_int32_t rthw_sd_detect(struct rt_mmcsd_host *host)
{
LOG_D("try to detect device");
return 0x01;
}
/**
* @brief This function interrupt process function.
* @param host rt_mmcsd_host
* @retval None
*/
void rthw_sdio_irq_process(struct rt_mmcsd_host *host)
{
int complete = 0;
struct rthw_sdio *sdio = host->private_data;
struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio;
rt_uint32_t intstatus = hw_sdio->sta;
if (intstatus & HW_SDIO_ERRORS)
{
hw_sdio->icr = HW_SDIO_ERRORS;
complete = 1;
}
else
{
if (intstatus & HW_SDIO_IT_CMDREND)
{
hw_sdio->icr = HW_SDIO_IT_CMDREND;
if (sdio->pkg != RT_NULL)
{
if (!sdio->pkg->cmd->data)
{
complete = 1;
}
else if ((sdio->pkg->cmd->data->flags & DATA_DIR_WRITE))
{
hw_sdio->dctrl |= HW_SDIO_DPSM_ENABLE;
}
}
}
if (intstatus & HW_SDIO_IT_CMDSENT)
{
hw_sdio->icr = HW_SDIO_IT_CMDSENT;
if (resp_type(sdio->pkg->cmd) == RESP_NONE)
{
complete = 1;
}
}
if (intstatus & HW_SDIO_IT_DATAEND)
{
hw_sdio->icr = HW_SDIO_IT_DATAEND;
complete = 1;
}
}
if ((intstatus & HW_SDIO_IT_SDIOIT) && (hw_sdio->mask & HW_SDIO_IT_SDIOIT))
{
hw_sdio->icr = HW_SDIO_IT_SDIOIT;
sdio_irq_wakeup(host);
}
if (complete)
{
hw_sdio->mask &= ~HW_SDIO_ERRORS;
rt_event_send(&sdio->event, intstatus);
}
}
static const struct rt_mmcsd_host_ops ops =
{
rthw_sdio_request,
rthw_sdio_iocfg,
rthw_sd_detect,
rthw_sdio_irq_update,
};
/**
* @brief This function create mmcsd host.
* @param sdio_des stm32_sdio_des
* @retval rt_mmcsd_host
*/
struct rt_mmcsd_host *sdio_host_create(struct stm32_sdio_des *sdio_des)
{
struct rt_mmcsd_host *host;
struct rthw_sdio *sdio = RT_NULL;
if ((sdio_des == RT_NULL) || (sdio_des->txconfig == RT_NULL) || (sdio_des->rxconfig == RT_NULL))
{
LOG_E("L:%d F:%s %s %s %s",
(sdio_des == RT_NULL ? "sdio_des is NULL" : ""),
(sdio_des ? (sdio_des->txconfig ? "txconfig is NULL" : "") : ""),
(sdio_des ? (sdio_des->rxconfig ? "rxconfig is NULL" : "") : "")
);
return RT_NULL;
}
sdio = rt_malloc(sizeof(struct rthw_sdio));
if (sdio == RT_NULL)
{
LOG_E("L:%d F:%s malloc rthw_sdio fail");
return RT_NULL;
}
rt_memset(sdio, 0, sizeof(struct rthw_sdio));
host = mmcsd_alloc_host();
if (host == RT_NULL)
{
LOG_E("L:%d F:%s mmcsd alloc host fail");
rt_free(sdio);
return RT_NULL;
}
rt_memcpy(&sdio->sdio_des, sdio_des, sizeof(struct stm32_sdio_des));
sdio->sdio_des.hw_sdio = (sdio_des->hw_sdio == RT_NULL ? (struct stm32_sdio *)SDIO_BASE_ADDRESS : sdio_des->hw_sdio);
sdio->sdio_des.clk_get = (sdio_des->clk_get == RT_NULL ? stm32_sdio_clk_get : sdio_des->clk_get);
rt_event_init(&sdio->event, "sdio", RT_IPC_FLAG_FIFO);
rt_mutex_init(&sdio->mutex, "sdio", RT_IPC_FLAG_PRIO);
/* set host defautl attributes */
host->ops = &ops;
host->freq_min = 400 * 1000;
host->freq_max = SDIO_MAX_FREQ;
host->valid_ocr = 0X00FFFF80;/* The voltage range supported is 1.65v-3.6v */
#ifndef SDIO_USING_1_BIT
host->flags = MMCSD_BUSWIDTH_4 | MMCSD_MUTBLKWRITE | MMCSD_SUP_SDIO_IRQ;
#else
host->flags = MMCSD_MUTBLKWRITE | MMCSD_SUP_SDIO_IRQ;
#endif
host->max_seg_size = SDIO_BUFF_SIZE;
host->max_dma_segs = 1;
host->max_blk_size = 512;
host->max_blk_count = 512;
/* link up host and sdio */
sdio->host = host;
host->private_data = sdio;
rthw_sdio_irq_update(host, 1);
/* ready to change */
mmcsd_change(host);
return host;
}
/**
* @brief This function configures the DMATX.
* @param BufferSRC: pointer to the source buffer
* @param BufferSize: buffer size
* @retval None
*/
void SD_LowLevel_DMA_TxConfig(uint32_t *src, uint32_t *dst, uint32_t BufferSize)
{
#if defined(SOC_SERIES_STM32F1)
static uint32_t size = 0;
size += BufferSize * 4;
sdio_obj.cfg = &sdio_config;
sdio_obj.dma.handle_tx.Instance = sdio_config.dma_tx.Instance;
sdio_obj.dma.handle_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
sdio_obj.dma.handle_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
sdio_obj.dma.handle_tx.Init.MemInc = DMA_MINC_ENABLE;
sdio_obj.dma.handle_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
sdio_obj.dma.handle_tx.Init.PeriphInc = DMA_PINC_DISABLE;
sdio_obj.dma.handle_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
/* DMA_PFCTRL */
HAL_DMA_DeInit(&sdio_obj.dma.handle_tx);
HAL_DMA_Init(&sdio_obj.dma.handle_tx);
HAL_DMA_Start(&sdio_obj.dma.handle_tx, (uint32_t)src, (uint32_t)dst, BufferSize);
#elif defined(SOC_SERIES_STM32L4)
static uint32_t size = 0;
size += BufferSize * 4;
sdio_obj.cfg = &sdio_config;
sdio_obj.dma.handle_tx.Instance = sdio_config.dma_tx.Instance;
sdio_obj.dma.handle_tx.Init.Request = sdio_config.dma_tx.request;
sdio_obj.dma.handle_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
sdio_obj.dma.handle_tx.Init.PeriphInc = DMA_PINC_DISABLE;
sdio_obj.dma.handle_tx.Init.MemInc = DMA_MINC_ENABLE;
sdio_obj.dma.handle_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
sdio_obj.dma.handle_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
sdio_obj.dma.handle_tx.Init.Mode = DMA_NORMAL;
sdio_obj.dma.handle_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
HAL_DMA_DeInit(&sdio_obj.dma.handle_tx);
HAL_DMA_Init(&sdio_obj.dma.handle_tx);
HAL_DMA_Start(&sdio_obj.dma.handle_tx, (uint32_t)src, (uint32_t)dst, BufferSize);
#else
static uint32_t size = 0;
size += BufferSize * 4;
sdio_obj.cfg = &sdio_config;
sdio_obj.dma.handle_tx.Instance = sdio_config.dma_tx.Instance;
sdio_obj.dma.handle_tx.Init.Channel = sdio_config.dma_tx.channel;
sdio_obj.dma.handle_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
sdio_obj.dma.handle_tx.Init.PeriphInc = DMA_PINC_DISABLE;
sdio_obj.dma.handle_tx.Init.MemInc = DMA_MINC_ENABLE;
sdio_obj.dma.handle_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
sdio_obj.dma.handle_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
sdio_obj.dma.handle_tx.Init.Mode = DMA_PFCTRL;
sdio_obj.dma.handle_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
sdio_obj.dma.handle_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
sdio_obj.dma.handle_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
sdio_obj.dma.handle_tx.Init.MemBurst = DMA_MBURST_INC4;
sdio_obj.dma.handle_tx.Init.PeriphBurst = DMA_PBURST_INC4;
/* DMA_PFCTRL */
HAL_DMA_DeInit(&sdio_obj.dma.handle_tx);
HAL_DMA_Init(&sdio_obj.dma.handle_tx);
HAL_DMA_Start(&sdio_obj.dma.handle_tx, (uint32_t)src, (uint32_t)dst, BufferSize);
#endif
}
/**
* @brief This function configures the DMARX.
* @param BufferDST: pointer to the destination buffer
* @param BufferSize: buffer size
* @retval None
*/
void SD_LowLevel_DMA_RxConfig(uint32_t *src, uint32_t *dst, uint32_t BufferSize)
{
#if defined(SOC_SERIES_STM32F1)
sdio_obj.cfg = &sdio_config;
sdio_obj.dma.handle_rx.Instance = sdio_config.dma_tx.Instance;
sdio_obj.dma.handle_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
sdio_obj.dma.handle_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
sdio_obj.dma.handle_rx.Init.MemInc = DMA_MINC_ENABLE;
sdio_obj.dma.handle_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
sdio_obj.dma.handle_rx.Init.PeriphInc = DMA_PINC_DISABLE;
sdio_obj.dma.handle_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
HAL_DMA_DeInit(&sdio_obj.dma.handle_rx);
HAL_DMA_Init(&sdio_obj.dma.handle_rx);
HAL_DMA_Start(&sdio_obj.dma.handle_rx, (uint32_t)src, (uint32_t)dst, BufferSize);
#elif defined(SOC_SERIES_STM32L4)
sdio_obj.cfg = &sdio_config;
sdio_obj.dma.handle_rx.Instance = sdio_config.dma_tx.Instance;
sdio_obj.dma.handle_rx.Init.Request = sdio_config.dma_tx.request;
sdio_obj.dma.handle_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
sdio_obj.dma.handle_rx.Init.PeriphInc = DMA_PINC_DISABLE;
sdio_obj.dma.handle_rx.Init.MemInc = DMA_MINC_ENABLE;
sdio_obj.dma.handle_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
sdio_obj.dma.handle_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
sdio_obj.dma.handle_rx.Init.Mode = DMA_NORMAL;
sdio_obj.dma.handle_rx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_DeInit(&sdio_obj.dma.handle_rx);
HAL_DMA_Init(&sdio_obj.dma.handle_rx);
HAL_DMA_Start(&sdio_obj.dma.handle_rx, (uint32_t)src, (uint32_t)dst, BufferSize);
#else
sdio_obj.cfg = &sdio_config;
sdio_obj.dma.handle_rx.Instance = sdio_config.dma_tx.Instance;
sdio_obj.dma.handle_rx.Init.Channel = sdio_config.dma_tx.channel;
sdio_obj.dma.handle_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
sdio_obj.dma.handle_rx.Init.PeriphInc = DMA_PINC_DISABLE;
sdio_obj.dma.handle_rx.Init.MemInc = DMA_MINC_ENABLE;
sdio_obj.dma.handle_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
sdio_obj.dma.handle_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
sdio_obj.dma.handle_rx.Init.Mode = DMA_PFCTRL;
sdio_obj.dma.handle_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
sdio_obj.dma.handle_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
sdio_obj.dma.handle_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
sdio_obj.dma.handle_rx.Init.MemBurst = DMA_MBURST_INC4;
sdio_obj.dma.handle_rx.Init.PeriphBurst = DMA_PBURST_INC4;
HAL_DMA_DeInit(&sdio_obj.dma.handle_rx);
HAL_DMA_Init(&sdio_obj.dma.handle_rx);
HAL_DMA_Start(&sdio_obj.dma.handle_rx, (uint32_t)src, (uint32_t)dst, BufferSize);
#endif
}
/**
* @brief This function get stm32 sdio clock.
* @param hw_sdio: stm32_sdio
* @retval PCLK2Freq
*/
static rt_uint32_t stm32_sdio_clock_get(struct stm32_sdio *hw_sdio)
{
return HAL_RCC_GetPCLK2Freq();
}
static rt_err_t DMA_TxConfig(rt_uint32_t *src, rt_uint32_t *dst, int Size)
{
SD_LowLevel_DMA_TxConfig((uint32_t *)src, (uint32_t *)dst, Size / 4);
return RT_EOK;
}
static rt_err_t DMA_RxConfig(rt_uint32_t *src, rt_uint32_t *dst, int Size)
{
SD_LowLevel_DMA_RxConfig((uint32_t *)src, (uint32_t *)dst, Size / 4);
return RT_EOK;
}
void SDIO_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
/* Process All SDIO Interrupt Sources */
rthw_sdio_irq_process(host);
/* leave interrupt */
rt_interrupt_leave();
}
int rt_hw_sdio_init(void)
{
struct stm32_sdio_des sdio_des;
SD_HandleTypeDef hsd;
hsd.Instance = SDCARD_INSTANCE;
{
rt_uint32_t tmpreg = 0x00U;
#if defined(SOC_SERIES_STM32F1)
/* enable DMA clock && Delay after an RCC peripheral clock enabling*/
SET_BIT(RCC->AHBENR, sdio_config.dma_rx.dma_rcc);
tmpreg = READ_BIT(RCC->AHBENR, sdio_config.dma_rx.dma_rcc);
#elif defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F2)
SET_BIT(RCC->AHB1ENR, sdio_config.dma_rx.dma_rcc);
/* Delay after an RCC peripheral clock enabling */
tmpreg = READ_BIT(RCC->AHB1ENR, sdio_config.dma_rx.dma_rcc);
#endif
UNUSED(tmpreg); /* To avoid compiler warnings */
}
HAL_NVIC_SetPriority(SDIO_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(SDIO_IRQn);
HAL_SD_MspInit(&hsd);
sdio_des.clk_get = stm32_sdio_clock_get;
sdio_des.hw_sdio = (struct stm32_sdio *)SDCARD_INSTANCE;
sdio_des.rxconfig = DMA_RxConfig;
sdio_des.txconfig = DMA_TxConfig;
host = sdio_host_create(&sdio_des);
if (host == RT_NULL)
{
LOG_E("host create fail");
return -1;
}
return 0;
}
INIT_DEVICE_EXPORT(rt_hw_sdio_init);
void stm32_mmcsd_change(void)
{
mmcsd_change(host);
}
#endif
+264
View File
@@ -0,0 +1,264 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-04 zylx first version
*/
#include <board.h>
#ifdef BSP_USING_SDRAM
#include <sdram_port.h>
#define DRV_DEBUG
#define LOG_TAG "drv.sdram"
#include <drv_log.h>
static SDRAM_HandleTypeDef hsdram1;
static FMC_SDRAM_CommandTypeDef command;
#ifdef RT_USING_MEMHEAP_AS_HEAP
static struct rt_memheap system_heap;
#endif
/**
* @brief
* @param hsdram: SDRAM handle
* @param Command: Pointer to SDRAM command structure
* @retval None
*/
static void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
{
__IO uint32_t tmpmrd = 0;
uint32_t target_bank = 0;
#if SDRAM_TARGET_BANK == 1
target_bank = FMC_SDRAM_CMD_TARGET_BANK1;
#else
target_bank = FMC_SDRAM_CMD_TARGET_BANK2;
#endif
/* Configure a clock configuration enable command */
Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Command->CommandTarget = target_bank;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
/* Insert 100 ms delay */
/* interrupt is not enable, just to delay some time. */
for (tmpmrd = 0; tmpmrd < 0xffff; tmpmrd ++)
;
/* Configure a PALL (precharge all) command */
Command->CommandMode = FMC_SDRAM_CMD_PALL;
Command->CommandTarget = target_bank;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
/* Configure a Auto-Refresh command */
Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Command->CommandTarget = target_bank;
Command->AutoRefreshNumber = 8;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
/* Program the external memory mode register */
#if SDRAM_DATA_WIDTH == 8
tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
#elif SDRAM_DATA_WIDTH == 16
tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2 |
#else
tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_4 |
#endif
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
#if SDRAM_CAS_LATENCY == 3
SDRAM_MODEREG_CAS_LATENCY_3 |
#else
SDRAM_MODEREG_CAS_LATENCY_2 |
#endif
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
Command->CommandTarget = target_bank;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = tmpmrd;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
/* Set the device refresh counter */
HAL_SDRAM_ProgramRefreshRate(hsdram, SDRAM_REFRESH_COUNT);
}
static int SDRAM_Init(void)
{
int result = RT_EOK;
FMC_SDRAM_TimingTypeDef SDRAM_Timing;
/* SDRAM device configuration */
hsdram1.Instance = FMC_SDRAM_DEVICE;
SDRAM_Timing.LoadToActiveDelay = LOADTOACTIVEDELAY;
SDRAM_Timing.ExitSelfRefreshDelay = EXITSELFREFRESHDELAY;
SDRAM_Timing.SelfRefreshTime = SELFREFRESHTIME;
SDRAM_Timing.RowCycleDelay = ROWCYCLEDELAY;
SDRAM_Timing.WriteRecoveryTime = WRITERECOVERYTIME;
SDRAM_Timing.RPDelay = RPDELAY;
SDRAM_Timing.RCDDelay = RCDDELAY;
#if SDRAM_TARGET_BANK == 1
hsdram1.Init.SDBank = FMC_SDRAM_BANK1;
#else
hsdram1.Init.SDBank = FMC_SDRAM_BANK2;
#endif
#if SDRAM_COLUMN_BITS == 8
hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
#elif SDRAM_COLUMN_BITS == 9
hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9;
#elif SDRAM_COLUMN_BITS == 10
hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_10;
#else
hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_11;
#endif
#if SDRAM_ROW_BITS == 11
hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_11;
#elif SDRAM_ROW_BITS == 12
hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
#else
hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13;
#endif
#if SDRAM_DATA_WIDTH == 8
hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_8;
#elif SDRAM_DATA_WIDTH == 16
hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
#else
hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_32;
#endif
hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
#if SDRAM_CAS_LATENCY == 1
hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_1;
#elif SDRAM_CAS_LATENCY == 2
hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;
#else
hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
#endif
hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
#if SDCLOCK_PERIOD == 2
hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
#else
hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_3;
#endif
hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
#if SDRAM_RPIPE_DELAY == 0
hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
#elif SDRAM_RPIPE_DELAY == 1
hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_1;
#else
hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_2;
#endif
/* Initialize the SDRAM controller */
if (HAL_SDRAM_Init(&hsdram1, &SDRAM_Timing) != HAL_OK)
{
LOG_E("SDRAM init failed!");
result = -RT_ERROR;
}
else
{
/* Program the SDRAM external device */
SDRAM_Initialization_Sequence(&hsdram1, &command);
LOG_D("sdram init success, mapped at 0x%X, size is %d bytes, data width is %d", SDRAM_BANK_ADDR, SDRAM_SIZE, SDRAM_DATA_WIDTH);
#ifdef RT_USING_MEMHEAP_AS_HEAP
/* If RT_USING_MEMHEAP_AS_HEAP is enabled, SDRAM is initialized to the heap */
rt_memheap_init(&system_heap, "sdram", (void *)SDRAM_BANK_ADDR, SDRAM_SIZE);
#endif
}
return result;
}
INIT_BOARD_EXPORT(SDRAM_Init);
#ifdef DRV_DEBUG
#ifdef FINSH_USING_MSH
int sdram_test(void)
{
int i = 0;
uint32_t start_time = 0, time_cast = 0;
#if SDRAM_DATA_WIDTH == 8
char data_width = 1;
uint8_t data = 0;
#elif SDRAM_DATA_WIDTH == 16
char data_width = 2;
uint16_t data = 0;
#else
char data_width = 4;
uint32_t data = 0;
#endif
/* write data */
LOG_D("Writing the %ld bytes data, waiting....", SDRAM_SIZE);
start_time = rt_tick_get();
for (i = 0; i < SDRAM_SIZE / data_width; i++)
{
#if SDRAM_DATA_WIDTH == 8
*(__IO uint8_t *)(SDRAM_BANK_ADDR + i * data_width) = (uint8_t)(i % 100);
#elif SDRAM_DATA_WIDTH == 16
*(__IO uint16_t *)(SDRAM_BANK_ADDR + i * data_width) = (uint16_t)(i % 1000);
#else
*(__IO uint32_t *)(SDRAM_BANK_ADDR + i * data_width) = (uint32_t)(i % 1000);
#endif
}
time_cast = rt_tick_get() - start_time;
LOG_D("Write data success, total time: %d.%03dS.", time_cast / RT_TICK_PER_SECOND,
time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000));
/* read data */
LOG_D("start Reading and verifying data, waiting....");
for (i = 0; i < SDRAM_SIZE / data_width; i++)
{
#if SDRAM_DATA_WIDTH == 8
data = *(__IO uint8_t *)(SDRAM_BANK_ADDR + i * data_width);
if (data != i % 100)
{
LOG_E("SDRAM test failed!");
break;
}
#elif SDRAM_DATA_WIDTH == 16
data = *(__IO uint16_t *)(SDRAM_BANK_ADDR + i * data_width);
if (data != i % 1000)
{
LOG_E("SDRAM test failed!");
break;
}
#else
data = *(__IO uint32_t *)(SDRAM_BANK_ADDR + i * data_width);
if (data != i % 1000)
{
LOG_E("SDRAM test failed!");
break;
}
#endif
}
if (i >= SDRAM_SIZE / data_width)
{
LOG_D("SDRAM test success!");
}
return RT_EOK;
}
MSH_CMD_EXPORT(sdram_test, sdram test)
#endif /* FINSH_USING_MSH */
#endif /* DRV_DEBUG */
#endif /* BSP_USING_SDRAM */
+221
View File
@@ -0,0 +1,221 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-08 balanceTWK first version
*/
#include <board.h>
#ifdef RT_USING_I2C_BITOPS
#include "drv_soft_i2c.h"
#include "drv_config.h"
//#define DRV_DEBUG
#define LOG_TAG "drv.i2c"
#include <drv_log.h>
#if !defined(BSP_USING_I2C1) && !defined(BSP_USING_I2C2) && !defined(BSP_USING_I2C3) && !defined(BSP_USING_I2C4)
#error "Please define at least one BSP_USING_I2Cx"
/* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
#endif
static const struct stm32_soft_i2c_config soft_i2c_config[] =
{
#ifdef BSP_USING_I2C1
I2C1_BUS_CONFIG,
#endif
#ifdef BSP_USING_I2C2
I2C2_BUS_CONFIG,
#endif
#ifdef BSP_USING_I2C3
I2C3_BUS_CONFIG,
#endif
#ifdef BSP_USING_I2C4
I2C4_BUS_CONFIG,
#endif
};
static struct stm32_i2c i2c_obj[sizeof(soft_i2c_config) / sizeof(soft_i2c_config[0])];
/**
* This function initializes the i2c pin.
*
* @param Stm32 i2c dirver class.
*/
static void stm32_i2c_gpio_init(struct stm32_i2c *i2c)
{
struct stm32_soft_i2c_config* cfg = (struct stm32_soft_i2c_config*)i2c->ops.data;
rt_pin_mode(cfg->scl, PIN_MODE_OUTPUT_OD);
rt_pin_mode(cfg->sda, PIN_MODE_OUTPUT_OD);
rt_pin_write(cfg->scl, PIN_HIGH);
rt_pin_write(cfg->sda, PIN_HIGH);
}
/**
* This function sets the sda pin.
*
* @param Stm32 config class.
* @param The sda pin state.
*/
static void stm32_set_sda(void *data, rt_int32_t state)
{
struct stm32_soft_i2c_config* cfg = (struct stm32_soft_i2c_config*)data;
if (state)
{
rt_pin_write(cfg->sda, PIN_HIGH);
}
else
{
rt_pin_write(cfg->sda, PIN_LOW);
}
}
/**
* This function sets the scl pin.
*
* @param Stm32 config class.
* @param The scl pin state.
*/
static void stm32_set_scl(void *data, rt_int32_t state)
{
struct stm32_soft_i2c_config* cfg = (struct stm32_soft_i2c_config*)data;
if (state)
{
rt_pin_write(cfg->scl, PIN_HIGH);
}
else
{
rt_pin_write(cfg->scl, PIN_LOW);
}
}
/**
* This function gets the sda pin state.
*
* @param The sda pin state.
*/
static rt_int32_t stm32_get_sda(void *data)
{
struct stm32_soft_i2c_config* cfg = (struct stm32_soft_i2c_config*)data;
return rt_pin_read(cfg->sda);
}
/**
* This function gets the scl pin state.
*
* @param The scl pin state.
*/
static rt_int32_t stm32_get_scl(void *data)
{
struct stm32_soft_i2c_config* cfg = (struct stm32_soft_i2c_config*)data;
return rt_pin_read(cfg->scl);
}
/**
* The time delay function.
*
* @param microseconds.
*/
static void stm32_udelay(rt_uint32_t us)
{
rt_uint32_t ticks;
rt_uint32_t told, tnow, tcnt = 0;
rt_uint32_t reload = SysTick->LOAD;
ticks = us * reload / (1000000 / RT_TICK_PER_SECOND);
told = SysTick->VAL;
while (1)
{
tnow = SysTick->VAL;
if (tnow != told)
{
if (tnow < told)
{
tcnt += told - tnow;
}
else
{
tcnt += reload - tnow + told;
}
told = tnow;
if (tcnt >= ticks)
{
break;
}
}
}
}
static const struct rt_i2c_bit_ops stm32_bit_ops_default =
{
.data = RT_NULL,
.set_sda = stm32_set_sda,
.set_scl = stm32_set_scl,
.get_sda = stm32_get_sda,
.get_scl = stm32_get_scl,
.udelay = stm32_udelay,
.delay_us = 1,
.timeout = 100
};
/**
* if i2c is locked, this function will unlock it
*
* @param stm32 config class
*
* @return RT_EOK indicates successful unlock.
*/
static rt_err_t stm32_i2c_bus_unlock(const struct stm32_soft_i2c_config *cfg)
{
rt_int32_t i = 0;
if (PIN_LOW == rt_pin_read(cfg->sda))
{
while (i++ < 9)
{
rt_pin_write(cfg->scl, PIN_HIGH);
stm32_udelay(100);
rt_pin_write(cfg->scl, PIN_LOW);
stm32_udelay(100);
}
}
if (PIN_LOW == rt_pin_read(cfg->sda))
{
return -RT_ERROR;
}
return RT_EOK;
}
/* I2C initialization function */
int rt_hw_i2c_init(void)
{
rt_size_t obj_num = sizeof(i2c_obj) / sizeof(struct stm32_i2c);
rt_err_t result;
for (int i = 0; i < obj_num; i++)
{
i2c_obj[i].ops = stm32_bit_ops_default;
i2c_obj[i].ops.data = (void*)&soft_i2c_config[i];
i2c_obj[i].i2c2_bus.priv = &i2c_obj[i].ops;
stm32_i2c_gpio_init(&i2c_obj[i]);
result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c2_bus, soft_i2c_config[i].bus_name);
RT_ASSERT(result == RT_EOK);
stm32_i2c_bus_unlock(&soft_i2c_config[i]);
LOG_D("software simulation %s init done, pin scl: %d, pin sda %d",
soft_i2c_config[i].bus_name,
soft_i2c_config[i].scl,
soft_i2c_config[i].sda);
}
return RT_EOK;
}
INIT_BOARD_EXPORT(rt_hw_i2c_init);
#endif /* RT_USING_I2C */
+944
View File
@@ -0,0 +1,944 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-5 SummerGift first version
* 2018-12-11 greedyhao Porting for stm32f7xx
* 2019-01-03 zylx modify DMA initialization and spixfer function
* 2020-01-15 whj4674672 Porting for stm32h7xx
* 2020-06-18 thread-liu Porting for stm32mp1xx
* 2020-10-14 Dozingfiretruck Porting for stm32wbxx
*/
#include "board.h"
#ifdef RT_USING_SPI
#if defined(BSP_USING_SPI1) || defined(BSP_USING_SPI2) || defined(BSP_USING_SPI3) || defined(BSP_USING_SPI4) || defined(BSP_USING_SPI5) || defined(BSP_USING_SPI6)
#include "drv_spi.h"
#include "drv_config.h"
#include <string.h>
//#define DRV_DEBUG
#define LOG_TAG "drv.spi"
#include <drv_log.h>
enum
{
#ifdef BSP_USING_SPI1
SPI1_INDEX,
#endif
#ifdef BSP_USING_SPI2
SPI2_INDEX,
#endif
#ifdef BSP_USING_SPI3
SPI3_INDEX,
#endif
#ifdef BSP_USING_SPI4
SPI4_INDEX,
#endif
#ifdef BSP_USING_SPI5
SPI5_INDEX,
#endif
#ifdef BSP_USING_SPI6
SPI6_INDEX,
#endif
};
static struct stm32_spi_config spi_config[] =
{
#ifdef BSP_USING_SPI1
SPI1_BUS_CONFIG,
#endif
#ifdef BSP_USING_SPI2
SPI2_BUS_CONFIG,
#endif
#ifdef BSP_USING_SPI3
SPI3_BUS_CONFIG,
#endif
#ifdef BSP_USING_SPI4
SPI4_BUS_CONFIG,
#endif
#ifdef BSP_USING_SPI5
SPI5_BUS_CONFIG,
#endif
#ifdef BSP_USING_SPI6
SPI6_BUS_CONFIG,
#endif
};
static struct stm32_spi spi_bus_obj[sizeof(spi_config) / sizeof(spi_config[0])] = {0};
static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configuration *cfg)
{
RT_ASSERT(spi_drv != RT_NULL);
RT_ASSERT(cfg != RT_NULL);
SPI_HandleTypeDef *spi_handle = &spi_drv->handle;
if (cfg->mode & RT_SPI_SLAVE)
{
spi_handle->Init.Mode = SPI_MODE_SLAVE;
}
else
{
spi_handle->Init.Mode = SPI_MODE_MASTER;
}
if (cfg->mode & RT_SPI_3WIRE)
{
spi_handle->Init.Direction = SPI_DIRECTION_1LINE;
}
else
{
spi_handle->Init.Direction = SPI_DIRECTION_2LINES;
}
if (cfg->data_width == 8)
{
spi_handle->Init.DataSize = SPI_DATASIZE_8BIT;
spi_handle->TxXferSize = 8;
spi_handle->RxXferSize = 8;
}
else if (cfg->data_width == 16)
{
spi_handle->Init.DataSize = SPI_DATASIZE_16BIT;
}
else
{
return RT_EIO;
}
if (cfg->mode & RT_SPI_CPHA)
{
spi_handle->Init.CLKPhase = SPI_PHASE_2EDGE;
}
else
{
spi_handle->Init.CLKPhase = SPI_PHASE_1EDGE;
}
if (cfg->mode & RT_SPI_CPOL)
{
spi_handle->Init.CLKPolarity = SPI_POLARITY_HIGH;
}
else
{
spi_handle->Init.CLKPolarity = SPI_POLARITY_LOW;
}
if (cfg->mode & RT_SPI_NO_CS)
{
spi_handle->Init.NSS = SPI_NSS_HARD_OUTPUT;
}
else
{
spi_handle->Init.NSS = SPI_NSS_SOFT;
}
uint32_t SPI_APB_CLOCK;
#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)
SPI_APB_CLOCK = HAL_RCC_GetPCLK1Freq();
#elif defined(SOC_SERIES_STM32H7)
SPI_APB_CLOCK = HAL_RCC_GetSysClockFreq();
#else
SPI_APB_CLOCK = HAL_RCC_GetPCLK2Freq();
#endif
if (cfg->max_hz >= SPI_APB_CLOCK / 2)
{
spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
}
else if (cfg->max_hz >= SPI_APB_CLOCK / 4)
{
spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
}
else if (cfg->max_hz >= SPI_APB_CLOCK / 8)
{
spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
}
else if (cfg->max_hz >= SPI_APB_CLOCK / 16)
{
spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
}
else if (cfg->max_hz >= SPI_APB_CLOCK / 32)
{
spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
}
else if (cfg->max_hz >= SPI_APB_CLOCK / 64)
{
spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
}
else if (cfg->max_hz >= SPI_APB_CLOCK / 128)
{
spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
}
else
{
/* min prescaler 256 */
spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
}
LOG_D("sys freq: %d, pclk2 freq: %d, SPI limiting freq: %d, BaudRatePrescaler: %d",
#if defined(SOC_SERIES_STM32MP1)
HAL_RCC_GetSystemCoreClockFreq(),
#else
HAL_RCC_GetSysClockFreq(),
#endif
SPI_APB_CLOCK,
cfg->max_hz,
spi_handle->Init.BaudRatePrescaler);
if (cfg->mode & RT_SPI_MSB)
{
spi_handle->Init.FirstBit = SPI_FIRSTBIT_MSB;
}
else
{
spi_handle->Init.FirstBit = SPI_FIRSTBIT_LSB;
}
spi_handle->Init.TIMode = SPI_TIMODE_DISABLE;
spi_handle->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
spi_handle->State = HAL_SPI_STATE_RESET;
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32WB)
spi_handle->Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
#elif defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1)
spi_handle->Init.Mode = SPI_MODE_MASTER;
spi_handle->Init.NSS = SPI_NSS_SOFT;
spi_handle->Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
spi_handle->Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
spi_handle->Init.CRCPolynomial = 7;
spi_handle->Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
spi_handle->Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
spi_handle->Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
spi_handle->Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
spi_handle->Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
spi_handle->Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE;
spi_handle->Init.IOSwap = SPI_IO_SWAP_DISABLE;
spi_handle->Init.FifoThreshold = SPI_FIFO_THRESHOLD_08DATA;
#endif
if (HAL_SPI_Init(spi_handle) != HAL_OK)
{
return RT_EIO;
}
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) \
|| defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32WB)
SET_BIT(spi_handle->Instance->CR2, SPI_RXFIFO_THRESHOLD_HF);
#endif
/* DMA configuration */
if (spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG)
{
HAL_DMA_Init(&spi_drv->dma.handle_rx);
__HAL_LINKDMA(&spi_drv->handle, hdmarx, spi_drv->dma.handle_rx);
/* NVIC configuration for DMA transfer complete interrupt */
HAL_NVIC_SetPriority(spi_drv->config->dma_rx->dma_irq, 0, 0);
HAL_NVIC_EnableIRQ(spi_drv->config->dma_rx->dma_irq);
}
if (spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG)
{
HAL_DMA_Init(&spi_drv->dma.handle_tx);
__HAL_LINKDMA(&spi_drv->handle, hdmatx, spi_drv->dma.handle_tx);
/* NVIC configuration for DMA transfer complete interrupt */
HAL_NVIC_SetPriority(spi_drv->config->dma_tx->dma_irq, 0, 1);
HAL_NVIC_EnableIRQ(spi_drv->config->dma_tx->dma_irq);
}
if(spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG || spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG)
{
HAL_NVIC_SetPriority(spi_drv->config->irq_type, 2, 0);
HAL_NVIC_EnableIRQ(spi_drv->config->irq_type);
}
LOG_D("%s init done", spi_drv->config->bus_name);
return RT_EOK;
}
static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
{
HAL_StatusTypeDef state;
rt_size_t message_length, already_send_length;
rt_uint16_t send_length;
rt_uint8_t *recv_buf;
const rt_uint8_t *send_buf;
RT_ASSERT(device != RT_NULL);
RT_ASSERT(device->bus != RT_NULL);
RT_ASSERT(device->bus->parent.user_data != RT_NULL);
RT_ASSERT(message != RT_NULL);
struct stm32_spi *spi_drv = rt_container_of(device->bus, struct stm32_spi, spi_bus);
SPI_HandleTypeDef *spi_handle = &spi_drv->handle;
struct stm32_hw_spi_cs *cs = device->parent.user_data;
if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS))
{
if (device->config.mode & RT_SPI_CS_HIGH)
HAL_GPIO_WritePin(cs->GPIOx, cs->GPIO_Pin, GPIO_PIN_SET);
else
HAL_GPIO_WritePin(cs->GPIOx, cs->GPIO_Pin, GPIO_PIN_RESET);
}
LOG_D("%s transfer prepare and start", spi_drv->config->bus_name);
LOG_D("%s sendbuf: %X, recvbuf: %X, length: %d",
spi_drv->config->bus_name,
(uint32_t)message->send_buf,
(uint32_t)message->recv_buf, message->length);
message_length = message->length;
recv_buf = message->recv_buf;
send_buf = message->send_buf;
while (message_length)
{
/* the HAL library use uint16 to save the data length */
if (message_length > 65535)
{
send_length = 65535;
message_length = message_length - 65535;
}
else
{
send_length = message_length;
message_length = 0;
}
/* calculate the start address */
already_send_length = message->length - send_length - message_length;
send_buf = (rt_uint8_t *)message->send_buf + already_send_length;
recv_buf = (rt_uint8_t *)message->recv_buf + already_send_length;
/* start once data exchange in DMA mode */
if (message->send_buf && message->recv_buf)
{
if ((spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG) && (spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG))
{
state = HAL_SPI_TransmitReceive_DMA(spi_handle, (uint8_t *)send_buf, (uint8_t *)recv_buf, send_length);
}
else
{
state = HAL_SPI_TransmitReceive(spi_handle, (uint8_t *)send_buf, (uint8_t *)recv_buf, send_length, 1000);
}
}
else if (message->send_buf)
{
if (spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG)
{
state = HAL_SPI_Transmit_DMA(spi_handle, (uint8_t *)send_buf, send_length);
}
else
{
state = HAL_SPI_Transmit(spi_handle, (uint8_t *)send_buf, send_length, 1000);
}
if (message->cs_release && (device->config.mode & RT_SPI_3WIRE))
{
/* release the CS by disable SPI when using 3 wires SPI */
__HAL_SPI_DISABLE(spi_handle);
}
}
else
{
memset((uint8_t *)recv_buf, 0xff, send_length);
if (spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG)
{
state = HAL_SPI_Receive_DMA(spi_handle, (uint8_t *)recv_buf, send_length);
}
else
{
/* clear the old error flag */
__HAL_SPI_CLEAR_OVRFLAG(spi_handle);
state = HAL_SPI_Receive(spi_handle, (uint8_t *)recv_buf, send_length, 1000);
}
}
if (state != HAL_OK)
{
LOG_I("spi transfer error : %d", state);
message->length = 0;
spi_handle->State = HAL_SPI_STATE_READY;
}
else
{
LOG_D("%s transfer done", spi_drv->config->bus_name);
}
/* For simplicity reasons, this example is just waiting till the end of the
transfer, but application may perform other tasks while transfer operation
is ongoing. */
while (HAL_SPI_GetState(spi_handle) != HAL_SPI_STATE_READY);
}
if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS))
{
if (device->config.mode & RT_SPI_CS_HIGH)
HAL_GPIO_WritePin(cs->GPIOx, cs->GPIO_Pin, GPIO_PIN_RESET);
else
HAL_GPIO_WritePin(cs->GPIOx, cs->GPIO_Pin, GPIO_PIN_SET);
}
return message->length;
}
static rt_err_t spi_configure(struct rt_spi_device *device,
struct rt_spi_configuration *configuration)
{
RT_ASSERT(device != RT_NULL);
RT_ASSERT(configuration != RT_NULL);
struct stm32_spi *spi_drv = rt_container_of(device->bus, struct stm32_spi, spi_bus);
spi_drv->cfg = configuration;
return stm32_spi_init(spi_drv, configuration);
}
static const struct rt_spi_ops stm_spi_ops =
{
.configure = spi_configure,
.xfer = spixfer,
};
static int rt_hw_spi_bus_init(void)
{
rt_err_t result;
for (int i = 0; i < sizeof(spi_config) / sizeof(spi_config[0]); i++)
{
spi_bus_obj[i].config = &spi_config[i];
spi_bus_obj[i].spi_bus.parent.user_data = &spi_config[i];
spi_bus_obj[i].handle.Instance = spi_config[i].Instance;
if (spi_bus_obj[i].spi_dma_flag & SPI_USING_RX_DMA_FLAG)
{
/* Configure the DMA handler for Transmission process */
spi_bus_obj[i].dma.handle_rx.Instance = spi_config[i].dma_rx->Instance;
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
spi_bus_obj[i].dma.handle_rx.Init.Channel = spi_config[i].dma_rx->channel;
#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7)
spi_bus_obj[i].dma.handle_rx.Init.Request = spi_config[i].dma_rx->request;
#endif
spi_bus_obj[i].dma.handle_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
spi_bus_obj[i].dma.handle_rx.Init.PeriphInc = DMA_PINC_DISABLE;
spi_bus_obj[i].dma.handle_rx.Init.MemInc = DMA_MINC_ENABLE;
spi_bus_obj[i].dma.handle_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
spi_bus_obj[i].dma.handle_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
spi_bus_obj[i].dma.handle_rx.Init.Mode = DMA_NORMAL;
spi_bus_obj[i].dma.handle_rx.Init.Priority = DMA_PRIORITY_HIGH;
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7)
spi_bus_obj[i].dma.handle_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
spi_bus_obj[i].dma.handle_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
spi_bus_obj[i].dma.handle_rx.Init.MemBurst = DMA_MBURST_INC4;
spi_bus_obj[i].dma.handle_rx.Init.PeriphBurst = DMA_PBURST_INC4;
#endif
{
rt_uint32_t tmpreg = 0x00U;
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32F0)
/* enable DMA clock && Delay after an RCC peripheral clock enabling*/
SET_BIT(RCC->AHBENR, spi_config[i].dma_rx->dma_rcc);
tmpreg = READ_BIT(RCC->AHBENR, spi_config[i].dma_rx->dma_rcc);
#elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7)
SET_BIT(RCC->AHB1ENR, spi_config[i].dma_rx->dma_rcc);
/* Delay after an RCC peripheral clock enabling */
tmpreg = READ_BIT(RCC->AHB1ENR, spi_config[i].dma_rx->dma_rcc);
#elif defined(SOC_SERIES_STM32MP1)
__HAL_RCC_DMAMUX_CLK_ENABLE();
SET_BIT(RCC->MP_AHB2ENSETR, spi_config[i].dma_rx->dma_rcc);
tmpreg = READ_BIT(RCC->MP_AHB2ENSETR, spi_config[i].dma_rx->dma_rcc);
#endif
UNUSED(tmpreg); /* To avoid compiler warnings */
}
}
if (spi_bus_obj[i].spi_dma_flag & SPI_USING_TX_DMA_FLAG)
{
/* Configure the DMA handler for Transmission process */
spi_bus_obj[i].dma.handle_tx.Instance = spi_config[i].dma_tx->Instance;
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
spi_bus_obj[i].dma.handle_tx.Init.Channel = spi_config[i].dma_tx->channel;
#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7)
spi_bus_obj[i].dma.handle_tx.Init.Request = spi_config[i].dma_tx->request;
#endif
spi_bus_obj[i].dma.handle_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
spi_bus_obj[i].dma.handle_tx.Init.PeriphInc = DMA_PINC_DISABLE;
spi_bus_obj[i].dma.handle_tx.Init.MemInc = DMA_MINC_ENABLE;
spi_bus_obj[i].dma.handle_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
spi_bus_obj[i].dma.handle_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
spi_bus_obj[i].dma.handle_tx.Init.Mode = DMA_NORMAL;
spi_bus_obj[i].dma.handle_tx.Init.Priority = DMA_PRIORITY_LOW;
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7)
spi_bus_obj[i].dma.handle_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
spi_bus_obj[i].dma.handle_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
spi_bus_obj[i].dma.handle_tx.Init.MemBurst = DMA_MBURST_INC4;
spi_bus_obj[i].dma.handle_tx.Init.PeriphBurst = DMA_PBURST_INC4;
#endif
{
rt_uint32_t tmpreg = 0x00U;
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32F0)
/* enable DMA clock && Delay after an RCC peripheral clock enabling*/
SET_BIT(RCC->AHBENR, spi_config[i].dma_tx->dma_rcc);
tmpreg = READ_BIT(RCC->AHBENR, spi_config[i].dma_tx->dma_rcc);
#elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7)
SET_BIT(RCC->AHB1ENR, spi_config[i].dma_tx->dma_rcc);
/* Delay after an RCC peripheral clock enabling */
tmpreg = READ_BIT(RCC->AHB1ENR, spi_config[i].dma_tx->dma_rcc);
#elif defined(SOC_SERIES_STM32MP1)
__HAL_RCC_DMAMUX_CLK_ENABLE();
SET_BIT(RCC->MP_AHB2ENSETR, spi_config[i].dma_tx->dma_rcc);
tmpreg = READ_BIT(RCC->MP_AHB2ENSETR, spi_config[i].dma_tx->dma_rcc);
#endif
UNUSED(tmpreg); /* To avoid compiler warnings */
}
}
result = rt_spi_bus_register(&spi_bus_obj[i].spi_bus, spi_config[i].bus_name, &stm_spi_ops);
RT_ASSERT(result == RT_EOK);
LOG_D("%s bus init done", spi_config[i].bus_name);
}
return result;
}
/**
* Attach the spi device to SPI bus, this function must be used after initialization.
*/
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, GPIO_TypeDef *cs_gpiox, uint16_t cs_gpio_pin)
{
RT_ASSERT(bus_name != RT_NULL);
RT_ASSERT(device_name != RT_NULL);
rt_err_t result;
struct rt_spi_device *spi_device;
struct stm32_hw_spi_cs *cs_pin;
/* initialize the cs pin && select the slave*/
GPIO_InitTypeDef GPIO_Initure;
GPIO_Initure.Pin = cs_gpio_pin;
GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Initure.Pull = GPIO_PULLUP;
GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(cs_gpiox, &GPIO_Initure);
HAL_GPIO_WritePin(cs_gpiox, cs_gpio_pin, GPIO_PIN_SET);
/* attach the device to spi bus*/
spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
RT_ASSERT(spi_device != RT_NULL);
cs_pin = (struct stm32_hw_spi_cs *)rt_malloc(sizeof(struct stm32_hw_spi_cs));
RT_ASSERT(cs_pin != RT_NULL);
cs_pin->GPIOx = cs_gpiox;
cs_pin->GPIO_Pin = cs_gpio_pin;
result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
if (result != RT_EOK)
{
LOG_E("%s attach to %s faild, %d\n", device_name, bus_name, result);
}
RT_ASSERT(result == RT_EOK);
LOG_D("%s attach to %s done", device_name, bus_name);
return result;
}
#if defined(BSP_SPI1_TX_USING_DMA) || defined(BSP_SPI1_RX_USING_DMA)
void SPI1_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_SPI_IRQHandler(&spi_bus_obj[SPI1_INDEX].handle);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#if defined(BSP_USING_SPI1) && defined(BSP_SPI1_RX_USING_DMA)
/**
* @brief This function handles DMA Rx interrupt request.
* @param None
* @retval None
*/
void SPI1_DMA_RX_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_DMA_IRQHandler(&spi_bus_obj[SPI1_INDEX].dma.handle_rx);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#if defined(BSP_USING_SPI1) && defined(BSP_SPI1_TX_USING_DMA)
/**
* @brief This function handles DMA Tx interrupt request.
* @param None
* @retval None
*/
void SPI1_DMA_TX_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_DMA_IRQHandler(&spi_bus_obj[SPI1_INDEX].dma.handle_tx);
/* leave interrupt */
rt_interrupt_leave();
}
#endif /* defined(BSP_USING_SPI1) && defined(BSP_SPI_USING_DMA) */
#if defined(BSP_SPI2_TX_USING_DMA) || defined(BSP_SPI2_RX_USING_DMA)
void SPI2_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_SPI_IRQHandler(&spi_bus_obj[SPI2_INDEX].handle);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#if defined(BSP_USING_SPI2) && defined(BSP_SPI2_RX_USING_DMA)
/**
* @brief This function handles DMA Rx interrupt request.
* @param None
* @retval None
*/
void SPI2_DMA_RX_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_DMA_IRQHandler(&spi_bus_obj[SPI2_INDEX].dma.handle_rx);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#if defined(BSP_USING_SPI2) && defined(BSP_SPI2_TX_USING_DMA)
/**
* @brief This function handles DMA Tx interrupt request.
* @param None
* @retval None
*/
void SPI2_DMA_TX_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_DMA_IRQHandler(&spi_bus_obj[SPI2_INDEX].dma.handle_tx);
/* leave interrupt */
rt_interrupt_leave();
}
#endif /* defined(BSP_USING_SPI2) && defined(BSP_SPI_USING_DMA) */
#if defined(BSP_SPI3_TX_USING_DMA) || defined(BSP_SPI3_RX_USING_DMA)
void SPI3_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_SPI_IRQHandler(&spi_bus_obj[SPI3_INDEX].handle);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#if defined(BSP_USING_SPI3) && defined(BSP_SPI3_RX_USING_DMA)
/**
* @brief This function handles DMA Rx interrupt request.
* @param None
* @retval None
*/
void SPI3_DMA_RX_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_DMA_IRQHandler(&spi_bus_obj[SPI3_INDEX].dma.handle_rx);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#if defined(BSP_USING_SPI3) && defined(BSP_SPI3_TX_USING_DMA)
/**
* @brief This function handles DMA Tx interrupt request.
* @param None
* @retval None
*/
void SPI3_DMA_TX_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_DMA_IRQHandler(&spi_bus_obj[SPI3_INDEX].dma.handle_tx);
/* leave interrupt */
rt_interrupt_leave();
}
#endif /* defined(BSP_USING_SPI3) && defined(BSP_SPI_USING_DMA) */
#if defined(BSP_SPI4_TX_USING_DMA) || defined(BSP_SPI4_RX_USING_DMA)
void SPI4_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_SPI_IRQHandler(&spi_bus_obj[SPI4_INDEX].handle);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#if defined(BSP_USING_SPI4) && defined(BSP_SPI4_RX_USING_DMA)
/**
* @brief This function handles DMA Rx interrupt request.
* @param None
* @retval None
*/
void SPI4_DMA_RX_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_DMA_IRQHandler(&spi_bus_obj[SPI4_INDEX].dma.handle_rx);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#if defined(BSP_USING_SPI4) && defined(BSP_SPI4_TX_USING_DMA)
/**
* @brief This function handles DMA Tx interrupt request.
* @param None
* @retval None
*/
void SPI4_DMA_TX_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_DMA_IRQHandler(&spi_bus_obj[SPI4_INDEX].dma.handle_tx);
/* leave interrupt */
rt_interrupt_leave();
}
#endif /* defined(BSP_USING_SPI4) && defined(BSP_SPI_USING_DMA) */
#if defined(BSP_SPI5_TX_USING_DMA) || defined(BSP_SPI5_RX_USING_DMA)
void SPI5_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_SPI_IRQHandler(&spi_bus_obj[SPI5_INDEX].handle);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#if defined(BSP_USING_SPI5) && defined(BSP_SPI5_RX_USING_DMA)
/**
* @brief This function handles DMA Rx interrupt request.
* @param None
* @retval None
*/
void SPI5_DMA_RX_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_DMA_IRQHandler(&spi_bus_obj[SPI5_INDEX].dma.handle_rx);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#if defined(BSP_USING_SPI5) && defined(BSP_SPI5_TX_USING_DMA)
/**
* @brief This function handles DMA Tx interrupt request.
* @param None
* @retval None
*/
void SPI5_DMA_TX_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_DMA_IRQHandler(&spi_bus_obj[SPI5_INDEX].dma.handle_tx);
/* leave interrupt */
rt_interrupt_leave();
}
#endif /* defined(BSP_USING_SPI5) && defined(BSP_SPI_USING_DMA) */
#if defined(BSP_USING_SPI6) && defined(BSP_SPI6_RX_USING_DMA)
/**
* @brief This function handles DMA Rx interrupt request.
* @param None
* @retval None
*/
void SPI6_DMA_RX_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_DMA_IRQHandler(&spi_bus_obj[SPI6_INDEX].dma.handle_rx);
/* leave interrupt */
rt_interrupt_leave();
}
#endif
#if defined(BSP_USING_SPI6) && defined(BSP_SPI6_TX_USING_DMA)
/**
* @brief This function handles DMA Tx interrupt request.
* @param None
* @retval None
*/
void SPI6_DMA_TX_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_DMA_IRQHandler(&spi_bus_obj[SPI6_INDEX].dma.handle_tx);
/* leave interrupt */
rt_interrupt_leave();
}
#endif /* defined(BSP_USING_SPI6) && defined(BSP_SPI_USING_DMA) */
static void stm32_get_dma_info(void)
{
#ifdef BSP_SPI1_RX_USING_DMA
spi_bus_obj[SPI1_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG;
static struct dma_config spi1_dma_rx = SPI1_RX_DMA_CONFIG;
spi_config[SPI1_INDEX].dma_rx = &spi1_dma_rx;
#endif
#ifdef BSP_SPI1_TX_USING_DMA
spi_bus_obj[SPI1_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG;
static struct dma_config spi1_dma_tx = SPI1_TX_DMA_CONFIG;
spi_config[SPI1_INDEX].dma_tx = &spi1_dma_tx;
#endif
#ifdef BSP_SPI2_RX_USING_DMA
spi_bus_obj[SPI2_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG;
static struct dma_config spi2_dma_rx = SPI2_RX_DMA_CONFIG;
spi_config[SPI2_INDEX].dma_rx = &spi2_dma_rx;
#endif
#ifdef BSP_SPI2_TX_USING_DMA
spi_bus_obj[SPI2_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG;
static struct dma_config spi2_dma_tx = SPI2_TX_DMA_CONFIG;
spi_config[SPI2_INDEX].dma_tx = &spi2_dma_tx;
#endif
#ifdef BSP_SPI3_RX_USING_DMA
spi_bus_obj[SPI3_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG;
static struct dma_config spi3_dma_rx = SPI3_RX_DMA_CONFIG;
spi_config[SPI3_INDEX].dma_rx = &spi3_dma_rx;
#endif
#ifdef BSP_SPI3_TX_USING_DMA
spi_bus_obj[SPI3_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG;
static struct dma_config spi3_dma_tx = SPI3_TX_DMA_CONFIG;
spi_config[SPI3_INDEX].dma_tx = &spi3_dma_tx;
#endif
#ifdef BSP_SPI4_RX_USING_DMA
spi_bus_obj[SPI4_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG;
static struct dma_config spi4_dma_rx = SPI4_RX_DMA_CONFIG;
spi_config[SPI4_INDEX].dma_rx = &spi4_dma_rx;
#endif
#ifdef BSP_SPI4_TX_USING_DMA
spi_bus_obj[SPI4_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG;
static struct dma_config spi4_dma_tx = SPI4_TX_DMA_CONFIG;
spi_config[SPI4_INDEX].dma_tx = &spi4_dma_tx;
#endif
#ifdef BSP_SPI5_RX_USING_DMA
spi_bus_obj[SPI5_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG;
static struct dma_config spi5_dma_rx = SPI5_RX_DMA_CONFIG;
spi_config[SPI5_INDEX].dma_rx = &spi5_dma_rx;
#endif
#ifdef BSP_SPI5_TX_USING_DMA
spi_bus_obj[SPI5_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG;
static struct dma_config spi5_dma_tx = SPI5_TX_DMA_CONFIG;
spi_config[SPI5_INDEX].dma_tx = &spi5_dma_tx;
#endif
#ifdef BSP_SPI6_RX_USING_DMA
spi_bus_obj[SPI6_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG;
static struct dma_config spi6_dma_rx = SPI6_RX_DMA_CONFIG;
spi_config[SPI6_INDEX].dma_rx = &spi6_dma_rx;
#endif
#ifdef BSP_SPI6_TX_USING_DMA
spi_bus_obj[SPI6_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG;
static struct dma_config spi6_dma_tx = SPI6_TX_DMA_CONFIG;
spi_config[SPI6_INDEX].dma_tx = &spi6_dma_tx;
#endif
}
#if defined(SOC_SERIES_STM32F0)
void SPI1_DMA_RX_TX_IRQHandler(void)
{
#if defined(BSP_USING_SPI1) && defined(BSP_SPI1_TX_USING_DMA)
SPI1_DMA_TX_IRQHandler();
#endif
#if defined(BSP_USING_SPI1) && defined(BSP_SPI1_RX_USING_DMA)
SPI1_DMA_RX_IRQHandler();
#endif
}
void SPI2_DMA_RX_TX_IRQHandler(void)
{
#if defined(BSP_USING_SPI2) && defined(BSP_SPI2_TX_USING_DMA)
SPI2_DMA_TX_IRQHandler();
#endif
#if defined(BSP_USING_SPI2) && defined(BSP_SPI2_RX_USING_DMA)
SPI2_DMA_RX_IRQHandler();
#endif
}
#endif /* SOC_SERIES_STM32F0 */
int rt_hw_spi_init(void)
{
stm32_get_dma_info();
return rt_hw_spi_bus_init();
}
INIT_BOARD_EXPORT(rt_hw_spi_init);
#endif /* BSP_USING_SPI1 || BSP_USING_SPI2 || BSP_USING_SPI3 || BSP_USING_SPI4 || BSP_USING_SPI5 */
#endif /* RT_USING_SPI */
+1380
View File
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+280
View File
@@ -0,0 +1,280 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-04-10 ZYH first version
* 2019-10-27 flybreak Compatible with the HS
*/
#include "board.h"
#ifdef BSP_USING_USBDEVICE
#include <string.h>
#include <drv_config.h>
static PCD_HandleTypeDef _stm_pcd;
static struct udcd _stm_udc;
static struct ep_id _ep_pool[] =
{
{0x0, USB_EP_ATTR_CONTROL, USB_DIR_INOUT, 64, ID_ASSIGNED },
#ifdef BSP_USBD_EP_ISOC
{0x1, USB_EP_ATTR_ISOC, USB_DIR_IN, 64, ID_UNASSIGNED},
{0x1, USB_EP_ATTR_ISOC, USB_DIR_OUT, 64, ID_UNASSIGNED},
#else
{0x1, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
{0x1, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
#endif
{0x2, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED},
{0x2, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED},
{0x3, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
#if !defined(SOC_SERIES_STM32F1)
{0x3, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
#endif
{0xFF, USB_EP_ATTR_TYPE_MASK, USB_DIR_MASK, 0, ID_ASSIGNED },
};
void USBD_IRQ_HANDLER(void)
{
rt_interrupt_enter();
HAL_PCD_IRQHandler(&_stm_pcd);
/* leave interrupt */
rt_interrupt_leave();
}
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *pcd)
{
/* open ep0 OUT and IN */
HAL_PCD_EP_Open(pcd, 0x00, 0x40, EP_TYPE_CTRL);
HAL_PCD_EP_Open(pcd, 0x80, 0x40, EP_TYPE_CTRL);
rt_usbd_reset_handler(&_stm_udc);
}
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
{
rt_usbd_ep0_setup_handler(&_stm_udc, (struct urequest *)hpcd->Setup);
}
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{
if (epnum == 0)
{
rt_usbd_ep0_in_handler(&_stm_udc);
}
else
{
rt_usbd_ep_in_handler(&_stm_udc, 0x80 | epnum, hpcd->IN_ep[epnum].xfer_count);
}
}
void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
{
rt_usbd_connect_handler(&_stm_udc);
}
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
{
rt_usbd_sof_handler(&_stm_udc);
}
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
{
rt_usbd_disconnect_handler(&_stm_udc);
}
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{
if (epnum != 0)
{
rt_usbd_ep_out_handler(&_stm_udc, epnum, hpcd->OUT_ep[epnum].xfer_count);
}
else
{
rt_usbd_ep0_out_handler(&_stm_udc, hpcd->OUT_ep[0].xfer_count);
}
}
void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)
{
if (state == 1)
{
#if defined(SOC_SERIES_STM32F1)
rt_pin_mode(BSP_USB_CONNECT_PIN,PIN_MODE_OUTPUT);
rt_pin_write(BSP_USB_CONNECT_PIN, BSP_USB_PULL_UP_STATUS);
#endif
}
else
{
#if defined(SOC_SERIES_STM32F1)
rt_pin_mode(BSP_USB_CONNECT_PIN,PIN_MODE_OUTPUT);
rt_pin_write(BSP_USB_CONNECT_PIN, !BSP_USB_PULL_UP_STATUS);
#endif
}
}
static rt_err_t _ep_set_stall(rt_uint8_t address)
{
HAL_PCD_EP_SetStall(&_stm_pcd, address);
return RT_EOK;
}
static rt_err_t _ep_clear_stall(rt_uint8_t address)
{
HAL_PCD_EP_ClrStall(&_stm_pcd, address);
return RT_EOK;
}
static rt_err_t _set_address(rt_uint8_t address)
{
HAL_PCD_SetAddress(&_stm_pcd, address);
return RT_EOK;
}
static rt_err_t _set_config(rt_uint8_t address)
{
return RT_EOK;
}
static rt_err_t _ep_enable(uep_t ep)
{
RT_ASSERT(ep != RT_NULL);
RT_ASSERT(ep->ep_desc != RT_NULL);
HAL_PCD_EP_Open(&_stm_pcd, ep->ep_desc->bEndpointAddress,
ep->ep_desc->wMaxPacketSize, ep->ep_desc->bmAttributes);
return RT_EOK;
}
static rt_err_t _ep_disable(uep_t ep)
{
RT_ASSERT(ep != RT_NULL);
RT_ASSERT(ep->ep_desc != RT_NULL);
HAL_PCD_EP_Close(&_stm_pcd, ep->ep_desc->bEndpointAddress);
return RT_EOK;
}
static rt_size_t _ep_read(rt_uint8_t address, void *buffer)
{
rt_size_t size = 0;
RT_ASSERT(buffer != RT_NULL);
return size;
}
static rt_size_t _ep_read_prepare(rt_uint8_t address, void *buffer, rt_size_t size)
{
HAL_PCD_EP_Receive(&_stm_pcd, address, buffer, size);
return size;
}
static rt_size_t _ep_write(rt_uint8_t address, void *buffer, rt_size_t size)
{
HAL_PCD_EP_Transmit(&_stm_pcd, address, buffer, size);
return size;
}
static rt_err_t _ep0_send_status(void)
{
HAL_PCD_EP_Transmit(&_stm_pcd, 0x00, NULL, 0);
return RT_EOK;
}
static rt_err_t _suspend(void)
{
return RT_EOK;
}
static rt_err_t _wakeup(void)
{
return RT_EOK;
}
static rt_err_t _init(rt_device_t device)
{
PCD_HandleTypeDef *pcd;
/* Set LL Driver parameters */
pcd = (PCD_HandleTypeDef *)device->user_data;
pcd->Instance = USBD_INSTANCE;
memset(&pcd->Init, 0, sizeof pcd->Init);
pcd->Init.dev_endpoints = 8;
pcd->Init.speed = USBD_PCD_SPEED;
pcd->Init.ep0_mps = EP_MPS_64;
#if !defined(SOC_SERIES_STM32F1)
pcd->Init.phy_itface = USBD_PCD_PHY_MODULE;
#endif
/* Initialize LL Driver */
HAL_PCD_Init(pcd);
/* USB interrupt Init */
HAL_NVIC_SetPriority(USBD_IRQ_TYPE, 2, 0);
HAL_NVIC_EnableIRQ(USBD_IRQ_TYPE);
#if !defined(SOC_SERIES_STM32F1)
HAL_PCDEx_SetRxFiFo(pcd, 0x80);
HAL_PCDEx_SetTxFiFo(pcd, 0, 0x40);
HAL_PCDEx_SetTxFiFo(pcd, 1, 0x40);
HAL_PCDEx_SetTxFiFo(pcd, 2, 0x40);
HAL_PCDEx_SetTxFiFo(pcd, 3, 0x40);
#else
HAL_PCDEx_PMAConfig(pcd, 0x00, PCD_SNG_BUF, 0x18);
HAL_PCDEx_PMAConfig(pcd, 0x80, PCD_SNG_BUF, 0x58);
HAL_PCDEx_PMAConfig(pcd, 0x81, PCD_SNG_BUF, 0x98);
HAL_PCDEx_PMAConfig(pcd, 0x01, PCD_SNG_BUF, 0x118);
HAL_PCDEx_PMAConfig(pcd, 0x82, PCD_SNG_BUF, 0xD8);
HAL_PCDEx_PMAConfig(pcd, 0x02, PCD_SNG_BUF, 0x158);
HAL_PCDEx_PMAConfig(pcd, 0x83, PCD_SNG_BUF, 0x198);
#endif
HAL_PCD_Start(pcd);
return RT_EOK;
}
const static struct udcd_ops _udc_ops =
{
_set_address,
_set_config,
_ep_set_stall,
_ep_clear_stall,
_ep_enable,
_ep_disable,
_ep_read_prepare,
_ep_read,
_ep_write,
_ep0_send_status,
_suspend,
_wakeup,
};
#ifdef RT_USING_DEVICE_OPS
const static struct rt_device_ops _ops =
{
_init,
RT_NULL,
RT_NULL,
RT_NULL,
RT_NULL,
RT_NULL,
};
#endif
int stm_usbd_register(void)
{
rt_memset((void *)&_stm_udc, 0, sizeof(struct udcd));
_stm_udc.parent.type = RT_Device_Class_USBDevice;
#ifdef RT_USING_DEVICE_OPS
_stm_udc.parent.ops = &_ops;
#else
_stm_udc.parent.init = _init;
#endif
_stm_udc.parent.user_data = &_stm_pcd;
_stm_udc.ops = &_udc_ops;
/* Register endpoint infomation */
_stm_udc.ep_pool = _ep_pool;
_stm_udc.ep0.id = &_ep_pool[0];
#ifdef BSP_USBD_SPEED_HS
_stm_udc.device_is_hs = RT_TRUE;
#endif
rt_device_register((rt_device_t)&_stm_udc, "usbd", 0);
rt_usb_device_init();
return RT_EOK;
}
INIT_DEVICE_EXPORT(stm_usbd_register);
#endif
+258
View File
@@ -0,0 +1,258 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-10-30 ZYH the first version
* 2019-12-19 tyustli port to stm32 series
*/
#include "board.h"
#ifdef BSP_USING_USBHOST
#include "drv_usbh.h"
static HCD_HandleTypeDef stm32_hhcd_fs;
static struct rt_completion urb_completion;
static volatile rt_bool_t connect_status = RT_FALSE;
void OTG_FS_IRQHandler(void)
{
rt_interrupt_enter();
HAL_HCD_IRQHandler(&stm32_hhcd_fs);
rt_interrupt_leave();
}
void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
{
uhcd_t hcd = (uhcd_t)hhcd->pData;
if (!connect_status)
{
connect_status = RT_TRUE;
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb connected\n"));
rt_usbh_root_hub_connect_handler(hcd, OTG_FS_PORT, RT_FALSE);
}
}
void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
{
uhcd_t hcd = (uhcd_t)hhcd->pData;
if (connect_status)
{
connect_status = RT_FALSE;
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb disconnnect\n"));
rt_usbh_root_hub_disconnect_handler(hcd, OTG_FS_PORT);
}
}
void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
{
rt_completion_done(&urb_completion);
}
static rt_err_t drv_reset_port(rt_uint8_t port)
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("reset port\n"));
HAL_HCD_ResetPort(&stm32_hhcd_fs);
return RT_EOK;
}
static int drv_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes, int timeouts)
{
int timeout = timeouts;
while (1)
{
if (!connect_status)
{
return -1;
}
rt_completion_init(&urb_completion);
HAL_HCD_HC_SubmitRequest(&stm32_hhcd_fs,
pipe->pipe_index,
(pipe->ep.bEndpointAddress & 0x80) >> 7,
pipe->ep.bmAttributes,
token,
buffer,
nbytes,
0);
rt_completion_wait(&urb_completion, timeout);
rt_thread_mdelay(1);
if (HAL_HCD_HC_GetState(&stm32_hhcd_fs, pipe->pipe_index) == HC_NAK)
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("nak\n"));
if (pipe->ep.bmAttributes == USB_EP_ATTR_INT)
{
rt_thread_delay((pipe->ep.bInterval * RT_TICK_PER_SECOND / 1000) > 0 ? (pipe->ep.bInterval * RT_TICK_PER_SECOND / 1000) : 1);
}
HAL_HCD_HC_Halt(&stm32_hhcd_fs, pipe->pipe_index);
HAL_HCD_HC_Init(&stm32_hhcd_fs,
pipe->pipe_index,
pipe->ep.bEndpointAddress,
pipe->inst->address,
USB_OTG_SPEED_FULL,
pipe->ep.bmAttributes,
pipe->ep.wMaxPacketSize);
continue;
}
else if (HAL_HCD_HC_GetState(&stm32_hhcd_fs, pipe->pipe_index) == HC_STALL)
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("stall\n"));
pipe->status = UPIPE_STATUS_STALL;
if (pipe->callback != RT_NULL)
{
pipe->callback(pipe);
}
return -1;
}
else if (HAL_HCD_HC_GetState(&stm32_hhcd_fs, pipe->pipe_index) == URB_ERROR)
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("error\n"));
pipe->status = UPIPE_STATUS_ERROR;
if (pipe->callback != RT_NULL)
{
pipe->callback(pipe);
}
return -1;
}
else if(URB_DONE == HAL_HCD_HC_GetURBState(&stm32_hhcd_fs, pipe->pipe_index))
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("ok\n"));
pipe->status = UPIPE_STATUS_OK;
if (pipe->callback != RT_NULL)
{
pipe->callback(pipe);
}
size_t size = HAL_HCD_HC_GetXferCount(&stm32_hhcd_fs, pipe->pipe_index);
if (pipe->ep.bEndpointAddress & 0x80)
{
return size;
}
else if (pipe->ep.bEndpointAddress & 0x00)
{
return size;
}
return nbytes;
}
continue;
}
}
static rt_uint16_t pipe_index = 0;
static rt_uint8_t drv_get_free_pipe_index(void)
{
rt_uint8_t idx;
for (idx = 1; idx < 16; idx++)
{
if (!(pipe_index & (0x01 << idx)))
{
pipe_index |= (0x01 << idx);
return idx;
}
}
return 0xff;
}
static void drv_free_pipe_index(rt_uint8_t index)
{
pipe_index &= ~(0x01 << index);
}
static rt_err_t drv_open_pipe(upipe_t pipe)
{
pipe->pipe_index = drv_get_free_pipe_index();
HAL_HCD_HC_Init(&stm32_hhcd_fs,
pipe->pipe_index,
pipe->ep.bEndpointAddress,
pipe->inst->address,
USB_OTG_SPEED_FULL,
pipe->ep.bmAttributes,
pipe->ep.wMaxPacketSize);
/* Set DATA0 PID token*/
if (stm32_hhcd_fs.hc[pipe->pipe_index].ep_is_in)
{
stm32_hhcd_fs.hc[pipe->pipe_index].toggle_in = 0;
}
else
{
stm32_hhcd_fs.hc[pipe->pipe_index].toggle_out = 0;
}
return RT_EOK;
}
static rt_err_t drv_close_pipe(upipe_t pipe)
{
HAL_HCD_HC_Halt(&stm32_hhcd_fs, pipe->pipe_index);
drv_free_pipe_index(pipe->pipe_index);
return RT_EOK;
}
static struct uhcd_ops _uhcd_ops =
{
drv_reset_port,
drv_pipe_xfer,
drv_open_pipe,
drv_close_pipe,
};
static rt_err_t stm32_hcd_init(rt_device_t device)
{
HAL_StatusTypeDef state;
HCD_HandleTypeDef *hhcd = (HCD_HandleTypeDef *)device->user_data;
hhcd->Instance = USB_OTG_FS;
hhcd->Init.Host_channels = 8;
hhcd->Init.speed = HCD_SPEED_FULL;
hhcd->Init.dma_enable = DISABLE;
hhcd->Init.phy_itface = HCD_PHY_EMBEDDED;
hhcd->Init.Sof_enable = DISABLE;
state = HAL_HCD_Init(hhcd);
if (state != HAL_OK)
{
return -RT_ERROR;
}
HAL_HCD_Start(hhcd);
#ifdef USBH_USING_CONTROLLABLE_POWER
rt_pin_mode(USBH_POWER_PIN, PIN_MODE_OUTPUT);
rt_pin_write(USBH_POWER_PIN, PIN_LOW);
#endif
return RT_EOK;
}
int stm_usbh_register(void)
{
rt_err_t res = -RT_ERROR;
uhcd_t uhcd = (uhcd_t)rt_malloc(sizeof(struct uhcd));
if (uhcd == RT_NULL)
{
rt_kprintf("uhcd malloc failed\r\n");
return -RT_ERROR;
}
rt_memset((void *)uhcd, 0, sizeof(struct uhcd));
uhcd->parent.type = RT_Device_Class_USBHost;
uhcd->parent.init = stm32_hcd_init;
uhcd->parent.user_data = &stm32_hhcd_fs;
uhcd->ops = &_uhcd_ops;
uhcd->num_ports = OTG_FS_PORT;
stm32_hhcd_fs.pData = uhcd;
res = rt_device_register(&uhcd->parent, "usbh", RT_DEVICE_FLAG_DEACTIVATE);
if (res != RT_EOK)
{
rt_kprintf("register usb host failed res = %d\r\n", res);
return -RT_ERROR;
}
rt_usb_host_init("usbh");
return RT_EOK;
}
INIT_DEVICE_EXPORT(stm_usbh_register);
#endif
+131
View File
@@ -0,0 +1,131 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-07 balanceTWK first version
*/
#include <board.h>
#ifdef RT_USING_WDT
//#define DRV_DEBUG
#define LOG_TAG "drv.wdt"
#include <drv_log.h>
struct stm32_wdt_obj
{
rt_watchdog_t watchdog;
IWDG_HandleTypeDef hiwdg;
rt_uint16_t is_start;
};
static struct stm32_wdt_obj stm32_wdt;
static struct rt_watchdog_ops ops;
static rt_err_t wdt_init(rt_watchdog_t *wdt)
{
return RT_EOK;
}
static rt_err_t wdt_control(rt_watchdog_t *wdt, int cmd, void *arg)
{
switch (cmd)
{
/* feed the watchdog */
case RT_DEVICE_CTRL_WDT_KEEPALIVE:
if(HAL_IWDG_Refresh(&stm32_wdt.hiwdg) != HAL_OK)
{
LOG_E("watch dog keepalive fail.");
}
break;
/* set watchdog timeout */
case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
#if defined(LSI_VALUE)
if(LSI_VALUE)
{
stm32_wdt.hiwdg.Init.Reload = (*((rt_uint32_t*)arg)) * LSI_VALUE / 256 ;
}
else
{
LOG_E("Please define the value of LSI_VALUE!");
}
if(stm32_wdt.hiwdg.Init.Reload > 0xFFF)
{
LOG_E("wdg set timeout parameter too large, please less than %ds",0xFFF * 256 / LSI_VALUE);
return -RT_EINVAL;
}
#else
#error "Please define the value of LSI_VALUE!"
#endif
if(stm32_wdt.is_start)
{
if (HAL_IWDG_Init(&stm32_wdt.hiwdg) != HAL_OK)
{
LOG_E("wdg set timeout failed.");
return -RT_ERROR;
}
}
break;
case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:
#if defined(LSI_VALUE)
if(LSI_VALUE)
{
(*((rt_uint32_t*)arg)) = stm32_wdt.hiwdg.Init.Reload * 256 / LSI_VALUE;
}
else
{
LOG_E("Please define the value of LSI_VALUE!");
}
#else
#error "Please define the value of LSI_VALUE!"
#endif
break;
case RT_DEVICE_CTRL_WDT_START:
if (HAL_IWDG_Init(&stm32_wdt.hiwdg) != HAL_OK)
{
LOG_E("wdt start failed.");
return -RT_ERROR;
}
stm32_wdt.is_start = 1;
break;
default:
LOG_W("This command is not supported.");
return -RT_ERROR;
}
return RT_EOK;
}
int rt_wdt_init(void)
{
#if defined(SOC_SERIES_STM32H7)
stm32_wdt.hiwdg.Instance = IWDG1;
#else
stm32_wdt.hiwdg.Instance = IWDG;
#endif
stm32_wdt.hiwdg.Init.Prescaler = IWDG_PRESCALER_256;
stm32_wdt.hiwdg.Init.Reload = 0x00000FFF;
#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F7) \
|| defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32G0)
stm32_wdt.hiwdg.Init.Window = 0x00000FFF;
#endif
stm32_wdt.is_start = 0;
ops.init = &wdt_init;
ops.control = &wdt_control;
stm32_wdt.watchdog.ops = &ops;
/* register watchdog device */
if (rt_hw_watchdog_register(&stm32_wdt.watchdog, "wdt", RT_DEVICE_FLAG_DEACTIVATE, RT_NULL) != RT_EOK)
{
LOG_E("wdt device register failed.");
return -RT_ERROR;
}
LOG_D("wdt device register success.");
return RT_EOK;
}
INIT_BOARD_EXPORT(rt_wdt_init);
#endif /* RT_USING_WDT */
+87
View File
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-06 zylx first version
*/
#ifndef __ADC_CONFIG_H__
#define __ADC_CONFIG_H__
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BSP_USING_ADC1
#ifndef ADC1_CONFIG
#define ADC1_CONFIG \
{ \
.Instance = ADC1, \
.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4, \
.Init.Resolution = ADC_RESOLUTION_12B, \
.Init.DataAlign = ADC_DATAALIGN_RIGHT, \
.Init.ScanConvMode = DISABLE, \
.Init.EOCSelection = DISABLE, \
.Init.ContinuousConvMode = DISABLE, \
.Init.NbrOfConversion = 1, \
.Init.DiscontinuousConvMode = DISABLE, \
.Init.NbrOfDiscConversion = 0, \
.Init.ExternalTrigConv = ADC_SOFTWARE_START, \
.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE, \
.Init.DMAContinuousRequests = DISABLE, \
}
#endif /* ADC1_CONFIG */
#endif /* BSP_USING_ADC1 */
#ifdef BSP_USING_ADC2
#ifndef ADC2_CONFIG
#define ADC2_CONFIG \
{ \
.Instance = ADC2, \
.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4, \
.Init.Resolution = ADC_RESOLUTION_12B, \
.Init.DataAlign = ADC_DATAALIGN_RIGHT, \
.Init.ScanConvMode = DISABLE, \
.Init.EOCSelection = DISABLE, \
.Init.ContinuousConvMode = DISABLE, \
.Init.NbrOfConversion = 1, \
.Init.DiscontinuousConvMode = DISABLE, \
.Init.NbrOfDiscConversion = 0, \
.Init.ExternalTrigConv = ADC_SOFTWARE_START, \
.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE, \
.Init.DMAContinuousRequests = DISABLE, \
}
#endif /* ADC2_CONFIG */
#endif /* BSP_USING_ADC2 */
#ifdef BSP_USING_ADC3
#ifndef ADC3_CONFIG
#define ADC3_CONFIG \
{ \
.Instance = ADC3, \
.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4, \
.Init.Resolution = ADC_RESOLUTION_12B, \
.Init.DataAlign = ADC_DATAALIGN_RIGHT, \
.Init.ScanConvMode = DISABLE, \
.Init.EOCSelection = DISABLE, \
.Init.ContinuousConvMode = DISABLE, \
.Init.NbrOfConversion = 1, \
.Init.DiscontinuousConvMode = DISABLE, \
.Init.NbrOfDiscConversion = 0, \
.Init.ExternalTrigConv = ADC_SOFTWARE_START, \
.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE, \
.Init.DMAContinuousRequests = DISABLE, \
}
#endif /* ADC3_CONFIG */
#endif /* BSP_USING_ADC3 */
#ifdef __cplusplus
}
#endif
#endif /* __ADC_CONFIG_H__ */
+42
View File
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-06-16 thread-liu first version
*/
#ifndef __DAC_CONFIG_H__
#define __DAC_CONFIG_H__
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BSP_USING_DAC1
#ifndef DAC1_CONFIG
#define DAC1_CONFIG \
{ \
.Instance = DAC1, \
}
#endif /* DAC2_CONFIG */
#endif /* BSP_USING_DAC2 */
#ifdef BSP_USING_DAC2
#ifndef DAC2_CONFIG
#define DAC2_CONFIG \
{ \
.Instance = DAC2, \
}
#endif /* DAC2_CONFIG */
#endif /* BSP_USING_DAC2 */
#ifdef __cplusplus
}
#endif
#endif /* __DAC_CONFIG_H__ */
+284
View File
@@ -0,0 +1,284 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-01-02 zylx first version
* 2019-01-08 SummerGift clean up the code
*/
#ifndef __DMA_CONFIG_H__
#define __DMA_CONFIG_H__
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
/* DMA1 stream0 */
#if defined(BSP_SPI3_RX_USING_DMA) && !defined(SPI3_RX_DMA_INSTANCE)
#define SPI3_DMA_RX_IRQHandler DMA1_Stream0_IRQHandler
#define SPI3_RX_DMA_RCC RCC_AHB1ENR_DMA1EN
#define SPI3_RX_DMA_INSTANCE DMA1_Stream0
#define SPI3_RX_DMA_CHANNEL DMA_CHANNEL_0
#define SPI3_RX_DMA_IRQ DMA1_Stream0_IRQn
#elif defined(BSP_UART5_RX_USING_DMA) && !defined(UART5_RX_DMA_INSTANCE)
#define UART5_DMA_RX_IRQHandler DMA1_Stream0_IRQHandler
#define UART5_RX_DMA_RCC RCC_AHB1ENR_DMA1EN
#define UART5_RX_DMA_INSTANCE DMA1_Stream0
#define UART5_RX_DMA_CHANNEL DMA_CHANNEL_4
#define UART5_RX_DMA_IRQ DMA1_Stream0_IRQn
#elif defined(BSP_UART8_TX_USING_DMA) && !defined(UART8_TX_DMA_INSTANCE)
#define UART8_DMA_TX_IRQHandler DMA1_Stream0_IRQHandler
#define UART8_TX_DMA_RCC RCC_AHB1ENR_DMA1EN
#define UART8_TX_DMA_INSTANCE DMA1_Stream0
#define UART8_TX_DMA_CHANNEL DMA_CHANNEL_5
#define UART8_TX_DMA_IRQ DMA1_Stream0_IRQn
#endif
/* DMA1 stream1 */
#if defined(BSP_UART3_RX_USING_DMA) && !defined(UART3_RX_DMA_INSTANCE)
#define UART3_DMA_RX_IRQHandler DMA1_Stream1_IRQHandler
#define UART3_RX_DMA_RCC RCC_AHB1ENR_DMA1EN
#define UART3_RX_DMA_INSTANCE DMA1_Stream1
#define UART3_RX_DMA_CHANNEL DMA_CHANNEL_4
#define UART3_RX_DMA_IRQ DMA1_Stream1_IRQn
#elif defined(BSP_UART7_RX_USING_DMA) && !defined(UART7_RX_DMA_INSTANCE)
#define UART7_DMA_RX_IRQHandler DMA1_Stream1_IRQHandler
#define UART7_RX_DMA_RCC RCC_AHB1ENR_DMA1EN
#define UART7_RX_DMA_INSTANCE DMA1_Stream1
#define UART7_RX_DMA_CHANNEL DMA_CHANNEL_5
#define UART7_RX_DMA_IRQ DMA1_Stream1_IRQn
#endif
/* DMA1 stream2 */
#if defined(BSP_SPI3_RX_USING_DMA) && !defined(SPI3_RX_DMA_INSTANCE)
#define SPI3_DMA_RX_IRQHandler DMA1_Stream2_IRQHandler
#define SPI3_RX_DMA_RCC RCC_AHB1ENR_DMA1EN
#define SPI3_RX_DMA_INSTANCE DMA1_Stream2
#define SPI3_RX_DMA_CHANNEL DMA_CHANNEL_0
#define SPI3_RX_DMA_IRQ DMA1_Stream2_IRQn
#elif defined(BSP_UART4_RX_USING_DMA) && !defined(UART4_RX_DMA_INSTANCE)
#define UART4_DMA_RX_IRQHandler DMA1_Stream2_IRQHandler
#define UART4_RX_DMA_RCC RCC_AHB1ENR_DMA1EN
#define UART4_RX_DMA_INSTANCE DMA1_Stream2
#define UART4_RX_DMA_CHANNEL DMA_CHANNEL_4
#define UART4_RX_DMA_IRQ DMA1_Stream2_IRQn
#endif
/* DMA1 stream3 */
#if defined(BSP_SPI2_RX_USING_DMA) && !defined(SPI2_RX_DMA_INSTANCE)
#define SPI2_DMA_RX_IRQHandler DMA1_Stream3_IRQHandler
#define SPI2_RX_DMA_RCC RCC_AHB1ENR_DMA1EN
#define SPI2_RX_DMA_INSTANCE DMA1_Stream3
#define SPI2_RX_DMA_CHANNEL DMA_CHANNEL_0
#define SPI2_RX_DMA_IRQ DMA1_Stream3_IRQn
#elif defined(BSP_UART3_TX_USING_DMA) && !defined(UART3_TX_DMA_INSTANCE)
#define UART3_DMA_TX_IRQHandler DMA1_Stream3_IRQHandler
#define UART3_TX_DMA_RCC RCC_AHB1ENR_DMA1EN
#define UART3_TX_DMA_INSTANCE DMA1_Stream3
#define UART3_TX_DMA_CHANNEL DMA_CHANNEL_4
#define UART3_TX_DMA_IRQ DMA1_Stream3_IRQn
#elif defined(BSP_UART7_TX_USING_DMA) && !defined(UART7_TX_DMA_INSTANCE)
#define UART7_DMA_RX_IRQHandler DMA1_Stream3_IRQHandler
#define UART7_RX_DMA_RCC RCC_AHB1ENR_DMA1EN
#define UART7_RX_DMA_INSTANCE DMA1_Stream3
#define UART7_RX_DMA_CHANNEL DMA_CHANNEL_5
#define UART7_RX_DMA_IRQ DMA1_Stream3_IRQn
#endif
/* DMA1 stream4 */
#if defined(BSP_SPI2_TX_USING_DMA) && !defined(SPI2_TX_DMA_INSTANCE)
#define SPI2_DMA_TX_IRQHandler DMA1_Stream4_IRQHandler
#define SPI2_TX_DMA_RCC RCC_AHB1ENR_DMA1EN
#define SPI2_TX_DMA_INSTANCE DMA1_Stream4
#define SPI2_TX_DMA_CHANNEL DMA_CHANNEL_0
#define SPI2_TX_DMA_IRQ DMA1_Stream4_IRQn
#elif defined(BSP_UART4_TX_USING_DMA) && !defined(UART4_TX_DMA_INSTANCE)
#define UART4_DMA_TX_IRQHandler DMA1_Stream4_IRQHandler
#define UART4_TX_DMA_RCC RCC_AHB1ENR_DMA1EN
#define UART4_TX_DMA_INSTANCE DMA1_Stream4
#define UART4_TX_DMA_CHANNEL DMA_CHANNEL_4
#define UART4_TX_DMA_IRQ DMA1_Stream4_IRQn
#endif
/* DMA1 stream5 */
#if defined(BSP_SPI3_TX_USING_DMA) && !defined(SPI3_TX_DMA_INSTANCE)
#define SPI3_DMA_TX_IRQHandler DMA1_Stream5_IRQHandler
#define SPI3_TX_DMA_RCC RCC_AHB1ENR_DMA1EN
#define SPI3_TX_DMA_INSTANCE DMA1_Stream5
#define SPI3_TX_DMA_CHANNEL DMA_CHANNEL_0
#define SPI3_TX_DMA_IRQ DMA1_Stream5_IRQn
#elif defined(BSP_UART2_RX_USING_DMA) && !defined(UART2_RX_DMA_INSTANCE)
#define UART2_DMA_RX_IRQHandler DMA1_Stream5_IRQHandler
#define UART2_RX_DMA_RCC RCC_AHB1ENR_DMA1EN
#define UART2_RX_DMA_INSTANCE DMA1_Stream5
#define UART2_RX_DMA_CHANNEL DMA_CHANNEL_4
#define UART2_RX_DMA_IRQ DMA1_Stream5_IRQn
#endif
/* DMA1 stream6 */
#if defined(BSP_UART2_TX_USING_DMA) && !defined(UART2_TX_DMA_INSTANCE)
#define UART2_DMA_TX_IRQHandler DMA1_Stream6_IRQHandler
#define UART2_TX_DMA_RCC RCC_AHB1ENR_DMA1EN
#define UART2_TX_DMA_INSTANCE DMA1_Stream6
#define UART2_TX_DMA_CHANNEL DMA_CHANNEL_4
#define UART2_TX_DMA_IRQ DMA1_Stream6_IRQn
#elif defined(BSP_UART8_RX_USING_DMA) && !defined(UART8_RX_DMA_INSTANCE)
#define UART8_DMA_RX_IRQHandler DMA1_Stream6_IRQHandler
#define UART8_RX_DMA_RCC RCC_AHB1ENR_DMA1EN
#define UART8_RX_DMA_INSTANCE DMA1_Stream6
#define UART8_RX_DMA_CHANNEL DMA_CHANNEL_5
#define UART8_RX_DMA_IRQ DMA1_Stream6_IRQn
#endif
/* DMA1 stream7 */
#if defined(BSP_SPI3_TX_USING_DMA) && !defined(SPI3_TX_DMA_INSTANCE)
#define SPI3_DMA_TX_IRQHandler DMA1_Stream7_IRQHandler
#define SPI3_TX_DMA_RCC RCC_AHB1ENR_DMA1EN
#define SPI3_TX_DMA_INSTANCE DMA1_Stream7
#define SPI3_TX_DMA_CHANNEL DMA_CHANNEL_0
#define SPI3_TX_DMA_IRQ DMA1_Stream7_IRQn
#elif defined(BSP_UART5_TX_USING_DMA) && !defined(UART5_TX_DMA_INSTANCE)
#define UART5_DMA_TX_IRQHandler DMA1_Stream7_IRQHandler
#define UART5_TX_DMA_RCC RCC_AHB1ENR_DMA1EN
#define UART5_TX_DMA_INSTANCE DMA1_Stream7
#define UART5_TX_DMA_CHANNEL DMA_CHANNEL_4
#define UART5_TX_DMA_IRQ DMA1_Stream7_IRQn
#endif
/* DMA2 stream0 */
#if defined(BSP_SPI1_RX_USING_DMA) && !defined(SPI1_RX_DMA_INSTANCE)
#define SPI1_DMA_RX_IRQHandler DMA2_Stream0_IRQHandler
#define SPI1_RX_DMA_RCC RCC_AHB1ENR_DMA2EN
#define SPI1_RX_DMA_INSTANCE DMA2_Stream0
#define SPI1_RX_DMA_CHANNEL DMA_CHANNEL_3
#define SPI1_RX_DMA_IRQ DMA2_Stream0_IRQn
#elif defined(BSP_SPI4_RX_USING_DMA) && !defined(SPI4_RX_DMA_INSTANCE)
#define SPI4_DMA_RX_IRQHandler DMA2_Stream0_IRQHandler
#define SPI4_RX_DMA_RCC RCC_AHB1ENR_DMA2EN
#define SPI4_RX_DMA_INSTANCE DMA2_Stream0
#define SPI4_RX_DMA_CHANNEL DMA_CHANNEL_4
#define SPI4_RX_DMA_IRQ DMA2_Stream0_IRQn
#endif
/* DMA2 stream1 */
#if defined(BSP_SPI4_TX_USING_DMA) && !defined(SPI4_TX_DMA_INSTANCE)
#define SPI4_DMA_TX_IRQHandler DMA2_Stream1_IRQHandler
#define SPI4_TX_DMA_RCC RCC_AHB1ENR_DMA2EN
#define SPI4_TX_DMA_INSTANCE DMA2_Stream1
#define SPI4_TX_DMA_CHANNEL DMA_CHANNEL_4
#define SPI4_TX_DMA_IRQ DMA2_Stream1_IRQn
#elif defined(BSP_UART6_RX_USING_DMA) && !defined(UART6_RX_DMA_INSTANCE)
#define UART6_DMA_RX_IRQHandler DMA2_Stream1_IRQHandler
#define UART6_RX_DMA_RCC RCC_AHB1ENR_DMA2EN
#define UART6_RX_DMA_INSTANCE DMA2_Stream1
#define UART6_RX_DMA_CHANNEL DMA_CHANNEL_5
#define UART6_RX_DMA_IRQ DMA2_Stream1_IRQn
#endif
/* DMA2 stream2 */
#if defined(BSP_SPI1_RX_USING_DMA) && !defined(SPI1_RX_DMA_INSTANCE)
#define SPI1_DMA_RX_IRQHandler DMA2_Stream2_IRQHandler
#define SPI1_RX_DMA_RCC RCC_AHB1ENR_DMA2EN
#define SPI1_RX_DMA_INSTANCE DMA2_Stream2
#define SPI1_RX_DMA_CHANNEL DMA_CHANNEL_3
#define SPI1_RX_DMA_IRQ DMA2_Stream2_IRQn
#elif defined(BSP_UART1_RX_USING_DMA) && !defined(UART1_RX_DMA_INSTANCE)
#define UART1_DMA_RX_IRQHandler DMA2_Stream2_IRQHandler
#define UART1_RX_DMA_RCC RCC_AHB1ENR_DMA2EN
#define UART1_RX_DMA_INSTANCE DMA2_Stream2
#define UART1_RX_DMA_CHANNEL DMA_CHANNEL_4
#define UART1_RX_DMA_IRQ DMA2_Stream2_IRQn
#endif
/* DMA2 stream3 */
#if defined(BSP_SPI5_RX_USING_DMA) && !defined(SPI5_RX_DMA_INSTANCE)
#define SPI5_DMA_RX_IRQHandler DMA2_Stream3_IRQHandler
#define SPI5_RX_DMA_RCC RCC_AHB1ENR_DMA2EN
#define SPI5_RX_DMA_INSTANCE DMA2_Stream3
#define SPI5_RX_DMA_CHANNEL DMA_CHANNEL_2
#define SPI5_RX_DMA_IRQ DMA2_Stream3_IRQn
#elif defined(BSP_SPI1_TX_USING_DMA) && !defined(SPI1_TX_DMA_INSTANCE)
#define SPI1_DMA_TX_IRQHandler DMA2_Stream3_IRQHandler
#define SPI1_TX_DMA_RCC RCC_AHB1ENR_DMA2EN
#define SPI1_TX_DMA_INSTANCE DMA2_Stream3
#define SPI1_TX_DMA_CHANNEL DMA_CHANNEL_3
#define SPI1_TX_DMA_IRQ DMA2_Stream3_IRQn
#elif defined(BSP_SPI4_RX_USING_DMA) && !defined(SPI4_RX_DMA_INSTANCE)
#define SPI4_DMA_RX_IRQHandler DMA2_Stream3_IRQHandler
#define SPI4_RX_DMA_RCC RCC_AHB1ENR_DMA2EN
#define SPI4_RX_DMA_INSTANCE DMA2_Stream3
#define SPI4_RX_DMA_CHANNEL DMA_CHANNEL_5
#define SPI4_RX_DMA_IRQ DMA2_Stream3_IRQn
#endif
/* DMA2 stream4 */
#if defined(BSP_SPI5_TX_USING_DMA) && !defined(SPI5_TX_DMA_INSTANCE)
#define SPI5_DMA_TX_IRQHandler DMA2_Stream4_IRQHandler
#define SPI5_TX_DMA_RCC RCC_AHB1ENR_DMA2EN
#define SPI5_TX_DMA_INSTANCE DMA2_Stream4
#define SPI5_TX_DMA_CHANNEL DMA_CHANNEL_2
#define SPI5_TX_DMA_IRQ DMA2_Stream4_IRQn
#elif defined(BSP_SPI4_TX_USING_DMA) && !defined(SPI4_TX_DMA_INSTANCE)
#define SPI4_DMA_TX_IRQHandler DMA2_Stream4_IRQHandler
#define SPI4_TX_DMA_RCC RCC_AHB1ENR_DMA2EN
#define SPI4_TX_DMA_INSTANCE DMA2_Stream4
#define SPI4_TX_DMA_CHANNEL DMA_CHANNEL_5
#define SPI4_TX_DMA_IRQ DMA2_Stream4_IRQn
#endif
/* DMA2 stream5 */
#if defined(BSP_SPI1_TX_USING_DMA) && !defined(SPI1_TX_DMA_INSTANCE)
#define SPI1_DMA_TX_IRQHandler DMA2_Stream5_IRQHandler
#define SPI1_TX_DMA_RCC RCC_AHB1ENR_DMA2EN
#define SPI1_TX_DMA_INSTANCE DMA2_Stream5
#define SPI1_TX_DMA_CHANNEL DMA_CHANNEL_3
#define SPI1_TX_DMA_IRQ DMA2_Stream5_IRQn
#elif defined(BSP_UART1_RX_USING_DMA) && !defined(UART1_RX_DMA_INSTANCE)
#define UART1_DMA_RX_IRQHandler DMA2_Stream5_IRQHandler
#define UART1_RX_DMA_RCC RCC_AHB1ENR_DMA2EN
#define UART1_RX_DMA_INSTANCE DMA2_Stream5
#define UART1_RX_DMA_CHANNEL DMA_CHANNEL_4
#define UART1_RX_DMA_IRQ DMA2_Stream5_IRQn
#elif defined(BSP_SPI5_RX_USING_DMA) && !defined(SPI5_RX_DMA_INSTANCE)
#define SPI5_DMA_RX_IRQHandler DMA2_Stream5_IRQHandler
#define SPI5_RX_DMA_RCC RCC_AHB1ENR_DMA2EN
#define SPI5_RX_DMA_INSTANCE DMA2_Stream5
#define SPI5_RX_DMA_CHANNEL DMA_CHANNEL_7
#define SPI5_RX_DMA_IRQ DMA2_Stream5_IRQn
#endif
/* DMA2 stream6 */
#if defined(BSP_SPI5_TX_USING_DMA) && !defined(SPI5_TX_DMA_INSTANCE)
#define SPI5_DMA_TX_IRQHandler DMA2_Stream6_IRQHandler
#define SPI5_TX_DMA_RCC RCC_AHB1ENR_DMA2EN
#define SPI5_TX_DMA_INSTANCE DMA2_Stream6
#define SPI5_TX_DMA_CHANNEL DMA_CHANNEL_7
#define SPI5_TX_DMA_IRQ DMA2_Stream6_IRQn
#elif defined(BSP_UART6_TX_USING_DMA) && !defined(UART6_TX_DMA_INSTANCE)
#define UART6_DMA_TX_IRQHandler DMA2_Stream6_IRQHandler
#define UART6_TX_DMA_RCC RCC_AHB1ENR_DMA2EN
#define UART6_TX_DMA_INSTANCE DMA2_Stream6
#define UART6_TX_DMA_CHANNEL DMA_CHANNEL_5
#define UART6_TX_DMA_IRQ DMA2_Stream6_IRQn
#endif
/* DMA2 stream7 */
#if defined(BSP_UART1_TX_USING_DMA) && !defined(UART1_TX_DMA_INSTANCE)
#define UART1_DMA_TX_IRQHandler DMA2_Stream7_IRQHandler
#define UART1_TX_DMA_RCC RCC_AHB1ENR_DMA2EN
#define UART1_TX_DMA_INSTANCE DMA2_Stream7
#define UART1_TX_DMA_CHANNEL DMA_CHANNEL_4
#define UART1_TX_DMA_IRQ DMA2_Stream7_IRQn
#endif
#ifdef __cplusplus
}
#endif
#endif /* __DMA_CONFIG_H__ */
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-08-23 balanceTWK first version
*/
#ifndef __PULSE_ENCODER_CONFIG_H__
#define __PULSE_ENCODER_CONFIG_H__
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BSP_USING_PULSE_ENCODER1
#ifndef PULSE_ENCODER1_CONFIG
#define PULSE_ENCODER1_CONFIG \
{ \
.tim_handler.Instance = TIM1, \
.encoder_irqn = TIM1_UP_TIM10_IRQn, \
.name = "pulse1" \
}
#endif /* PULSE_ENCODER1_CONFIG */
#endif /* BSP_USING_PULSE_ENCODER1 */
#ifdef BSP_USING_PULSE_ENCODER2
#ifndef PULSE_ENCODER2_CONFIG
#define PULSE_ENCODER2_CONFIG \
{ \
.tim_handler.Instance = TIM2, \
.encoder_irqn = TIM2_IRQn, \
.name = "pulse2" \
}
#endif /* PULSE_ENCODER2_CONFIG */
#endif /* BSP_USING_PULSE_ENCODER2 */
#ifdef BSP_USING_PULSE_ENCODER3
#ifndef PULSE_ENCODER3_CONFIG
#define PULSE_ENCODER3_CONFIG \
{ \
.tim_handler.Instance = TIM3, \
.encoder_irqn = TIM3_IRQn, \
.name = "pulse3" \
}
#endif /* PULSE_ENCODER3_CONFIG */
#endif /* BSP_USING_PULSE_ENCODER3 */
#ifdef BSP_USING_PULSE_ENCODER4
#ifndef PULSE_ENCODER4_CONFIG
#define PULSE_ENCODER4_CONFIG \
{ \
.tim_handler.Instance = TIM4, \
.encoder_irqn = TIM4_IRQn, \
.name = "pulse4" \
}
#endif /* PULSE_ENCODER4_CONFIG */
#endif /* BSP_USING_PULSE_ENCODER4 */
#ifdef __cplusplus
}
#endif
#endif /* __PULSE_ENCODER_CONFIG_H__ */
+90
View File
@@ -0,0 +1,90 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-13 zylx first version
*/
#ifndef __PWM_CONFIG_H__
#define __PWM_CONFIG_H__
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BSP_USING_PWM2
#ifndef PWM2_CONFIG
#define PWM2_CONFIG \
{ \
.tim_handle.Instance = TIM2, \
.name = "pwm2", \
.channel = 0 \
}
#endif /* PWM2_CONFIG */
#endif /* BSP_USING_PWM2 */
#ifdef BSP_USING_PWM3
#ifndef PWM3_CONFIG
#define PWM3_CONFIG \
{ \
.tim_handle.Instance = TIM3, \
.name = "pwm3", \
.channel = 0 \
}
#endif /* PWM3_CONFIG */
#endif /* BSP_USING_PWM3 */
#ifdef BSP_USING_PWM4
#ifndef PWM4_CONFIG
#define PWM4_CONFIG \
{ \
.tim_handle.Instance = TIM4, \
.name = "pwm4", \
.channel = 0 \
}
#endif /* PWM4_CONFIG */
#endif /* BSP_USING_PWM4 */
#ifdef BSP_USING_PWM5
#ifndef PWM5_CONFIG
#define PWM5_CONFIG \
{ \
.tim_handle.Instance = TIM5, \
.name = "pwm5", \
.channel = 0 \
}
#endif /* PWM5_CONFIG */
#endif /* BSP_USING_PWM5 */
#ifdef BSP_USING_PWM9
#ifndef PWM9_CONFIG
#define PWM9_CONFIG \
{ \
.tim_handle.Instance = TIM9, \
.name = "pwm9", \
.channel = 0 \
}
#endif /* PWM9_CONFIG */
#endif /* BSP_USING_PWM9 */
#ifdef BSP_USING_PWM12
#ifndef PWM12_CONFIG
#define PWM12_CONFIG \
{ \
.tim_handle.Instance = TIM12, \
.name = "pwm12", \
.channel = 0 \
}
#endif /* PWM12_CONFIG */
#endif /* BSP_USING_PWM12 */
#ifdef __cplusplus
}
#endif
#endif /* __PWM_CONFIG_H__ */
+56
View File
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-22 zylx first version
*/
#ifndef __QSPI_CONFIG_H__
#define __QSPI_CONFIG_H__
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BSP_USING_QSPI
#ifndef QSPI_BUS_CONFIG
#define QSPI_BUS_CONFIG \
{ \
.Instance = QUADSPI, \
.Init.FifoThreshold = 4, \
.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE, \
.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_5_CYCLE, \
}
#endif /* QSPI_BUS_CONFIG */
#endif /* BSP_USING_QSPI */
#ifdef BSP_QSPI_USING_DMA
#ifndef QSPI_DMA_CONFIG
#define QSPI_DMA_CONFIG \
{ \
.Instance = QSPI_DMA_INSTANCE, \
.Init.Channel = QSPI_DMA_CHANNEL, \
.Init.Direction = DMA_PERIPH_TO_MEMORY, \
.Init.PeriphInc = DMA_PINC_DISABLE, \
.Init.MemInc = DMA_MINC_ENABLE, \
.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE, \
.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE, \
.Init.Mode = DMA_NORMAL, \
.Init.Priority = DMA_PRIORITY_LOW \
}
#endif /* QSPI_DMA_CONFIG */
#endif /* BSP_QSPI_USING_DMA */
#define QSPI_IRQn QUADSPI_IRQn
#define QSPI_IRQHandler QUADSPI_IRQHandler
#ifdef __cplusplus
}
#endif
#endif /* __QSPI_CONFIG_H__ */
+44
View File
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-13 BalanceTWK first version
*/
#ifndef __SDIO_CONFIG_H__
#define __SDIO_CONFIG_H__
#include <rtthread.h>
#include "stm32f4xx_hal.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BSP_USING_SDIO
#define SDIO_BUS_CONFIG \
{ \
.Instance = SDIO, \
.dma_rx.dma_rcc = RCC_AHB1ENR_DMA2EN, \
.dma_tx.dma_rcc = RCC_AHB1ENR_DMA2EN, \
.dma_rx.Instance = DMA2_Stream3, \
.dma_rx.channel = DMA_CHANNEL_4, \
.dma_rx.dma_irq = DMA2_Stream3_IRQn, \
.dma_tx.Instance = DMA2_Stream6, \
.dma_tx.channel = DMA_CHANNEL_4, \
.dma_tx.dma_irq = DMA2_Stream6_IRQn, \
}
#endif
#ifdef __cplusplus
}
#endif
#endif /*__SDIO_CONFIG_H__ */
+200
View File
@@ -0,0 +1,200 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-06 SummerGift first version
* 2019-01-03 zylx modify DMA support
*/
#ifndef __SPI_CONFIG_H__
#define __SPI_CONFIG_H__
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BSP_USING_SPI1
#ifndef SPI1_BUS_CONFIG
#define SPI1_BUS_CONFIG \
{ \
.Instance = SPI1, \
.bus_name = "spi1", \
.irq_type = SPI1_IRQn, \
}
#endif /* SPI1_BUS_CONFIG */
#endif /* BSP_USING_SPI1 */
#ifdef BSP_SPI1_TX_USING_DMA
#ifndef SPI1_TX_DMA_CONFIG
#define SPI1_TX_DMA_CONFIG \
{ \
.dma_rcc = SPI1_TX_DMA_RCC, \
.Instance = SPI1_TX_DMA_INSTANCE, \
.channel = SPI1_TX_DMA_CHANNEL, \
.dma_irq = SPI1_TX_DMA_IRQ, \
}
#endif /* SPI1_TX_DMA_CONFIG */
#endif /* BSP_SPI1_TX_USING_DMA */
#ifdef BSP_SPI1_RX_USING_DMA
#ifndef SPI1_RX_DMA_CONFIG
#define SPI1_RX_DMA_CONFIG \
{ \
.dma_rcc = SPI1_RX_DMA_RCC, \
.Instance = SPI1_RX_DMA_INSTANCE, \
.channel = SPI1_RX_DMA_CHANNEL, \
.dma_irq = SPI1_RX_DMA_IRQ, \
}
#endif /* SPI1_RX_DMA_CONFIG */
#endif /* BSP_SPI1_RX_USING_DMA */
#ifdef BSP_USING_SPI2
#ifndef SPI2_BUS_CONFIG
#define SPI2_BUS_CONFIG \
{ \
.Instance = SPI2, \
.bus_name = "spi2", \
.irq_type = SPI2_IRQn, \
}
#endif /* SPI2_BUS_CONFIG */
#endif /* BSP_USING_SPI2 */
#ifdef BSP_SPI2_TX_USING_DMA
#ifndef SPI2_TX_DMA_CONFIG
#define SPI2_TX_DMA_CONFIG \
{ \
.dma_rcc = SPI2_TX_DMA_RCC, \
.Instance = SPI2_TX_DMA_INSTANCE, \
.channel = SPI2_TX_DMA_CHANNEL, \
.dma_irq = SPI2_TX_DMA_IRQ, \
}
#endif /* SPI2_TX_DMA_CONFIG */
#endif /* BSP_SPI2_TX_USING_DMA */
#ifdef BSP_SPI2_RX_USING_DMA
#ifndef SPI2_RX_DMA_CONFIG
#define SPI2_RX_DMA_CONFIG \
{ \
.dma_rcc = SPI2_RX_DMA_RCC, \
.Instance = SPI2_RX_DMA_INSTANCE, \
.channel = SPI2_RX_DMA_CHANNEL, \
.dma_irq = SPI2_RX_DMA_IRQ, \
}
#endif /* SPI2_RX_DMA_CONFIG */
#endif /* BSP_SPI2_RX_USING_DMA */
#ifdef BSP_USING_SPI3
#ifndef SPI3_BUS_CONFIG
#define SPI3_BUS_CONFIG \
{ \
.Instance = SPI3, \
.bus_name = "spi3", \
.irq_type = SPI3_IRQn, \
}
#endif /* SPI3_BUS_CONFIG */
#endif /* BSP_USING_SPI3 */
#ifdef BSP_SPI3_TX_USING_DMA
#ifndef SPI3_TX_DMA_CONFIG
#define SPI3_TX_DMA_CONFIG \
{ \
.dma_rcc = SPI3_TX_DMA_RCC, \
.Instance = SPI3_TX_DMA_INSTANCE, \
.channel = SPI3_TX_DMA_CHANNEL, \
.dma_irq = SPI3_TX_DMA_IRQ, \
}
#endif /* SPI3_TX_DMA_CONFIG */
#endif /* BSP_SPI3_TX_USING_DMA */
#ifdef BSP_SPI3_RX_USING_DMA
#ifndef SPI3_RX_DMA_CONFIG
#define SPI3_RX_DMA_CONFIG \
{ \
.dma_rcc = SPI3_RX_DMA_RCC, \
.Instance = SPI3_RX_DMA_INSTANCE, \
.channel = SPI3_RX_DMA_CHANNEL, \
.dma_irq = SPI3_RX_DMA_IRQ, \
}
#endif /* SPI3_RX_DMA_CONFIG */
#endif /* BSP_SPI3_RX_USING_DMA */
#ifdef BSP_USING_SPI4
#ifndef SPI4_BUS_CONFIG
#define SPI4_BUS_CONFIG \
{ \
.Instance = SPI4, \
.bus_name = "spi4", \
.irq_type = SPI4_IRQn, \
}
#endif /* SPI4_BUS_CONFIG */
#endif /* BSP_USING_SPI4 */
#ifdef BSP_SPI4_TX_USING_DMA
#ifndef SPI4_TX_DMA_CONFIG
#define SPI4_TX_DMA_CONFIG \
{ \
.dma_rcc = SPI4_TX_DMA_RCC, \
.Instance = SPI4_TX_DMA_INSTANCE, \
.channel = SPI4_TX_DMA_CHANNEL, \
.dma_irq = SPI4_TX_DMA_IRQ, \
}
#endif /* SPI4_TX_DMA_CONFIG */
#endif /* BSP_SPI4_TX_USING_DMA */
#ifdef BSP_SPI4_RX_USING_DMA
#ifndef SPI4_RX_DMA_CONFIG
#define SPI4_RX_DMA_CONFIG \
{ \
.dma_rcc = SPI4_RX_DMA_RCC, \
.Instance = SPI4_RX_DMA_INSTANCE, \
.channel = SPI4_RX_DMA_CHANNEL, \
.dma_irq = SPI4_RX_DMA_IRQ, \
}
#endif /* SPI4_RX_DMA_CONFIG */
#endif /* BSP_SPI4_RX_USING_DMA */
#ifdef BSP_USING_SPI5
#ifndef SPI5_BUS_CONFIG
#define SPI5_BUS_CONFIG \
{ \
.Instance = SPI5, \
.bus_name = "spi5", \
.irq_type = SPI5_IRQn, \
}
#endif /* SPI5_BUS_CONFIG */
#endif /* BSP_USING_SPI5 */
#ifdef BSP_SPI5_TX_USING_DMA
#ifndef SPI5_TX_DMA_CONFIG
#define SPI5_TX_DMA_CONFIG \
{ \
.dma_rcc = SPI5_TX_DMA_RCC, \
.Instance = SPI5_TX_DMA_INSTANCE, \
.channel = SPI5_TX_DMA_CHANNEL, \
.dma_irq = SPI5_TX_DMA_IRQ, \
}
#endif /* SPI5_TX_DMA_CONFIG */
#endif /* BSP_SPI5_TX_USING_DMA */
#ifdef BSP_SPI5_RX_USING_DMA
#ifndef SPI5_RX_DMA_CONFIG
#define SPI5_RX_DMA_CONFIG \
{ \
.dma_rcc = SPI5_RX_DMA_RCC, \
.Instance = SPI5_RX_DMA_INSTANCE, \
.channel = SPI5_RX_DMA_CHANNEL, \
.dma_irq = SPI5_RX_DMA_IRQ, \
}
#endif /* SPI5_RX_DMA_CONFIG */
#endif /* BSP_SPI5_RX_USING_DMA */
#ifdef __cplusplus
}
#endif
#endif /*__SPI_CONFIG_H__ */
+78
View File
@@ -0,0 +1,78 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-11 zylx first version
*/
#ifndef __TIM_CONFIG_H__
#define __TIM_CONFIG_H__
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef TIM_DEV_INFO_CONFIG
#define TIM_DEV_INFO_CONFIG \
{ \
.maxfreq = 1000000, \
.minfreq = 3000, \
.maxcnt = 0xFFFF, \
.cntmode = HWTIMER_CNTMODE_UP, \
}
#endif /* TIM_DEV_INFO_CONFIG */
#ifdef BSP_USING_TIM3
#ifndef TIM3_CONFIG
#define TIM3_CONFIG \
{ \
.tim_handle.Instance = TIM3, \
.tim_irqn = TIM3_IRQn, \
.name = "timer3", \
}
#endif /* TIM3_CONFIG */
#endif /* BSP_USING_TIM3 */
#ifdef BSP_USING_TIM11
#ifndef TIM11_CONFIG
#define TIM11_CONFIG \
{ \
.tim_handle.Instance = TIM11, \
.tim_irqn = TIM1_TRG_COM_TIM11_IRQn, \
.name = "timer11", \
}
#endif /* TIM11_CONFIG */
#endif /* BSP_USING_TIM11 */
#ifdef BSP_USING_TIM13
#ifndef TIM13_CONFIG
#define TIM13_CONFIG \
{ \
.tim_handle.Instance = TIM13, \
.tim_irqn = TIM8_UP_TIM13_IRQn, \
.name = "timer13", \
}
#endif /* TIM13_CONFIG */
#endif /* BSP_USING_TIM13 */
#ifdef BSP_USING_TIM14
#ifndef TIM14_CONFIG
#define TIM14_CONFIG \
{ \
.tim_handle.Instance = TIM14, \
.tim_irqn = TIM8_TRG_COM_TIM14_IRQn, \
.name = "timer14", \
}
#endif /* TIM14_CONFIG */
#endif /* BSP_USING_TIM14 */
#ifdef __cplusplus
}
#endif
#endif /* __TIM_CONFIG_H__ */
+322
View File
@@ -0,0 +1,322 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-10-30 SummerGift first version
* 2019-01-03 zylx modify dma support
*/
#ifndef __UART_CONFIG_H__
#define __UART_CONFIG_H__
#include <rtthread.h>
#include <board.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(BSP_USING_UART1)
#ifndef UART1_CONFIG
#define UART1_CONFIG \
{ \
.name = "uart1", \
.Instance = USART1, \
.irq_type = USART1_IRQn, \
.tx_pin_name = BSP_UART1_TX_PIN, \
.rx_pin_name = BSP_UART1_RX_PIN, \
}
#endif /* UART1_CONFIG */
#if defined(BSP_UART1_RX_USING_DMA)
#ifndef UART1_DMA_RX_CONFIG
#define UART1_DMA_RX_CONFIG \
{ \
.Instance = UART1_RX_DMA_INSTANCE, \
.channel = UART1_RX_DMA_CHANNEL, \
.dma_rcc = UART1_RX_DMA_RCC, \
.dma_irq = UART1_RX_DMA_IRQ, \
}
#endif /* UART1_DMA_RX_CONFIG */
#endif /* BSP_UART1_RX_USING_DMA */
#if defined(BSP_UART1_TX_USING_DMA)
#ifndef UART1_DMA_TX_CONFIG
#define UART1_DMA_TX_CONFIG \
{ \
.Instance = UART1_TX_DMA_INSTANCE, \
.channel = UART1_TX_DMA_CHANNEL, \
.dma_rcc = UART1_TX_DMA_RCC, \
.dma_irq = UART1_TX_DMA_IRQ, \
}
#endif /* UART1_DMA_TX_CONFIG */
#endif /* BSP_UART1_TX_USING_DMA */
#endif /* BSP_USING_UART1 */
#if defined(BSP_USING_UART2)
#ifndef UART2_CONFIG
#define UART2_CONFIG \
{ \
.name = "uart2", \
.Instance = USART2, \
.irq_type = USART2_IRQn, \
.tx_pin_name = BSP_UART2_TX_PIN, \
.rx_pin_name = BSP_UART2_RX_PIN, \
}
#endif /* UART2_CONFIG */
#if defined(BSP_UART2_RX_USING_DMA)
#ifndef UART2_DMA_RX_CONFIG
#define UART2_DMA_RX_CONFIG \
{ \
.Instance = UART2_RX_DMA_INSTANCE, \
.channel = UART2_RX_DMA_CHANNEL, \
.dma_rcc = UART2_RX_DMA_RCC, \
.dma_irq = UART2_RX_DMA_IRQ, \
}
#endif /* UART2_DMA_RX_CONFIG */
#endif /* BSP_UART2_RX_USING_DMA */
#if defined(BSP_UART2_TX_USING_DMA)
#ifndef UART2_DMA_TX_CONFIG
#define UART2_DMA_TX_CONFIG \
{ \
.Instance = UART2_TX_DMA_INSTANCE, \
.channel = UART2_TX_DMA_CHANNEL, \
.dma_rcc = UART2_TX_DMA_RCC, \
.dma_irq = UART2_TX_DMA_IRQ, \
}
#endif /* UART2_DMA_TX_CONFIG */
#endif /* BSP_UART2_TX_USING_DMA */
#endif /* BSP_USING_UART2 */
#if defined(BSP_USING_UART3)
#ifndef UART3_CONFIG
#define UART3_CONFIG \
{ \
.name = "uart3", \
.Instance = USART3, \
.irq_type = USART3_IRQn, \
.tx_pin_name = BSP_UART3_TX_PIN, \
.rx_pin_name = BSP_UART3_RX_PIN, \
}
#endif /* UART3_CONFIG */
#if defined(BSP_UART3_RX_USING_DMA)
#ifndef UART3_DMA_RX_CONFIG
#define UART3_DMA_RX_CONFIG \
{ \
.Instance = UART3_RX_DMA_INSTANCE, \
.channel = UART3_RX_DMA_CHANNEL, \
.dma_rcc = UART3_RX_DMA_RCC, \
.dma_irq = UART3_RX_DMA_IRQ, \
}
#endif /* UART3_DMA_RX_CONFIG */
#endif /* BSP_UART3_RX_USING_DMA */
#if defined(BSP_UART3_TX_USING_DMA)
#ifndef UART3_DMA_TX_CONFIG
#define UART3_DMA_TX_CONFIG \
{ \
.Instance = UART3_TX_DMA_INSTANCE, \
.channel = UART3_TX_DMA_CHANNEL, \
.dma_rcc = UART3_TX_DMA_RCC, \
.dma_irq = UART3_TX_DMA_IRQ, \
}
#endif /* UART3_DMA_TX_CONFIG */
#endif /* BSP_UART3_TX_USING_DMA */
#endif /* BSP_USING_UART3 */
#if defined(BSP_USING_UART4)
#ifndef UART4_CONFIG
#define UART4_CONFIG \
{ \
.name = "uart4", \
.Instance = UART4, \
.irq_type = UART4_IRQn, \
.tx_pin_name = BSP_UART4_TX_PIN, \
.rx_pin_name = BSP_UART4_RX_PIN, \
}
#endif /* UART4_CONFIG */
#if defined(BSP_UART4_RX_USING_DMA)
#ifndef UART4_DMA_RX_CONFIG
#define UART4_DMA_RX_CONFIG \
{ \
.Instance = UART4_RX_DMA_INSTANCE, \
.channel = UART4_RX_DMA_CHANNEL, \
.dma_rcc = UART4_RX_DMA_RCC, \
.dma_irq = UART4_RX_DMA_IRQ, \
}
#endif /* UART4_DMA_RX_CONFIG */
#endif /* BSP_UART4_RX_USING_DMA */
#if defined(BSP_UART4_TX_USING_DMA)
#ifndef UART4_DMA_TX_CONFIG
#define UART4_DMA_TX_CONFIG \
{ \
.Instance = UART4_TX_DMA_INSTANCE, \
.channel = UART4_TX_DMA_CHANNEL, \
.dma_rcc = UART4_TX_DMA_RCC, \
.dma_irq = UART4_TX_DMA_IRQ, \
}
#endif /* UART4_DMA_TX_CONFIG */
#endif /* BSP_UART4_RX_USING_DMA */
#endif /* BSP_USING_UART4 */
#if defined(BSP_USING_UART5)
#ifndef UART5_CONFIG
#define UART5_CONFIG \
{ \
.name = "uart5", \
.Instance = UART5, \
.irq_type = UART5_IRQn, \
.tx_pin_name = BSP_UART5_TX_PIN, \
.rx_pin_name = BSP_UART5_RX_PIN, \
}
#endif /* UART5_CONFIG */
#if defined(BSP_UART5_RX_USING_DMA)
#ifndef UART5_DMA_RX_CONFIG
#define UART5_DMA_RX_CONFIG \
{ \
.Instance = UART5_RX_DMA_INSTANCE, \
.channel = UART5_RX_DMA_CHANNEL, \
.dma_rcc = UART5_RX_DMA_RCC, \
.dma_irq = UART5_RX_DMA_IRQ, \
}
#endif /* UART5_DMA_RX_CONFIG */
#endif /* BSP_UART5_RX_USING_DMA */
#if defined(BSP_UART5_TX_USING_DMA)
#ifndef UART5_DMA_TX_CONFIG
#define UART5_DMA_TX_CONFIG \
{ \
.Instance = UART5_TX_DMA_INSTANCE, \
.channel = UART5_TX_DMA_CHANNEL, \
.dma_rcc = UART5_TX_DMA_RCC, \
.dma_irq = UART5_TX_DMA_IRQ, \
}
#endif /* UART5_DMA_TX_CONFIG */
#endif /* BSP_UART5_TX_USING_DMA */
#endif /* BSP_USING_UART5 */
#if defined(BSP_USING_UART6)
#ifndef UART6_CONFIG
#define UART6_CONFIG \
{ \
.name = "uart6", \
.Instance = USART6, \
.irq_type = USART6_IRQn, \
.tx_pin_name = BSP_UART6_TX_PIN, \
.rx_pin_name = BSP_UART6_RX_PIN, \
}
#endif /* UART6_CONFIG */
#if defined(BSP_UART6_RX_USING_DMA)
#ifndef UART6_DMA_RX_CONFIG
#define UART6_DMA_RX_CONFIG \
{ \
.Instance = UART6_RX_DMA_INSTANCE, \
.channel = UART6_RX_DMA_CHANNEL, \
.dma_rcc = UART6_RX_DMA_RCC, \
.dma_irq = UART6_RX_DMA_IRQ, \
}
#endif /* UART6_DMA_RX_CONFIG */
#endif /* BSP_UART6_RX_USING_DMA */
#if defined(BSP_UART6_TX_USING_DMA)
#ifndef UART6_DMA_TX_CONFIG
#define UART6_DMA_TX_CONFIG \
{ \
.Instance = UART6_TX_DMA_INSTANCE, \
.channel = UART6_TX_DMA_CHANNEL, \
.dma_rcc = UART6_TX_DMA_RCC, \
.dma_irq = UART6_TX_DMA_IRQ, \
}
#endif /* UART6_DMA_TX_CONFIG */
#endif /* BSP_UART6_TX_USING_DMA */
#endif /* BSP_USING_UART6 */
#if defined(BSP_USING_UART7)
#ifndef UART7_CONFIG
#define UART7_CONFIG \
{ \
.name = "uart7", \
.Instance = UART7, \
.irq_type = UART7_IRQn, \
.tx_pin_name = BSP_UART7_TX_PIN, \
.rx_pin_name = BSP_UART7_RX_PIN, \
}
#endif /* UART7_CONFIG */
#if defined(BSP_UART7_RX_USING_DMA)
#ifndef UART7_DMA_RX_CONFIG
#define UART7_DMA_RX_CONFIG \
{ \
.Instance = UART7_RX_DMA_INSTANCE, \
.channel = UART7_RX_DMA_CHANNEL, \
.dma_rcc = UART7_RX_DMA_RCC, \
.dma_irq = UART7_RX_DMA_IRQ, \
}
#endif /* UART7_DMA_RX_CONFIG */
#endif /* BSP_UART7_RX_USING_DMA */
#if defined(BSP_UART7_TX_USING_DMA)
#ifndef UART7_DMA_TX_CONFIG
#define UART7_DMA_TX_CONFIG \
{ \
.Instance = UART7_TX_DMA_INSTANCE, \
.channel = UART7_TX_DMA_CHANNEL, \
.dma_rcc = UART7_TX_DMA_RCC, \
.dma_irq = UART7_TX_DMA_IRQ, \
}
#endif /* UART7_DMA_TX_CONFIG */
#endif /* BSP_UART7_TX_USING_DMA */
#endif /* BSP_USING_UART7 */
#if defined(BSP_USING_UART8)
#ifndef UART8_CONFIG
#define UART8_CONFIG \
{ \
.name = "uart8", \
.Instance = UART8, \
.irq_type = UART8_IRQn, \
.tx_pin_name = BSP_UART8_TX_PIN, \
.rx_pin_name = BSP_UART8_RX_PIN, \
}
#endif /* UART8_CONFIG */
#if defined(BSP_UART8_RX_USING_DMA)
#ifndef UART8_DMA_RX_CONFIG
#define UART8_DMA_RX_CONFIG \
{ \
.Instance = UART8_RX_DMA_INSTANCE, \
.channel = UART8_RX_DMA_CHANNEL, \
.dma_rcc = UART8_RX_DMA_RCC, \
.dma_irq = UART8_RX_DMA_IRQ, \
}
#endif /* UART8_DMA_RX_CONFIG */
#endif /* BSP_UART8_RX_USING_DMA */
#if defined(BSP_UART8_TX_USING_DMA)
#ifndef UART8_DMA_TX_CONFIG
#define UART8_DMA_TX_CONFIG \
{ \
.Instance = UART8_TX_DMA_INSTANCE, \
.channel = UART8_TX_DMA_CHANNEL, \
.dma_rcc = UART8_TX_DMA_RCC, \
.dma_irq = UART8_TX_DMA_IRQ, \
}
#endif /* UART8_DMA_TX_CONFIG */
#endif /* BSP_UART8_TX_USING_DMA */
#endif /* BSP_USING_UART8 */
#ifdef __cplusplus
}
#endif
#endif
+42
View File
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-04-10 ZYH first version
* 2019-10-27 flybreak Compatible with the HS
*/
#ifndef __USBD_CONFIG_H__
#define __USBD_CONFIG_H__
#include <rtconfig.h>
#ifdef BSP_USBD_TYPE_HS
#define USBD_IRQ_TYPE OTG_HS_IRQn
#define USBD_IRQ_HANDLER OTG_HS_IRQHandler
#define USBD_INSTANCE USB_OTG_HS
#else
#define USBD_IRQ_TYPE OTG_FS_IRQn
#define USBD_IRQ_HANDLER OTG_FS_IRQHandler
#define USBD_INSTANCE USB_OTG_FS
#endif
#ifdef BSP_USBD_SPEED_HS
#define USBD_PCD_SPEED PCD_SPEED_HIGH
#elif BSP_USBD_SPEED_HSINFS
#define USBD_PCD_SPEED PCD_SPEED_HIGH_IN_FULL
#else
#define USBD_PCD_SPEED PCD_SPEED_FULL
#endif
#ifdef BSP_USBD_PHY_ULPI
#define USBD_PCD_PHY_MODULE PCD_PHY_ULPI
#elif BSP_USBD_PHY_UTMI
#define USBD_PCD_PHY_MODULE PCD_PHY_UTMI
#else
#define USBD_PCD_PHY_MODULE PCD_PHY_EMBEDDED
#endif
#endif
+59
View File
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-08-05 Xeon Xu the first version
* 2019-01-22 YLZ port from stm324xx-HAL to bsp stm3210x-HAL
* 2019-01-26 YLZ redefine `struct stm32_drv_can` add member `Rx1Message`
* 2019-02-19 YLZ port to BSP [stm32]
* 2019-06-17 YLZ modify struct stm32_drv_can.
*/
#ifndef __DRV_CAN_H__
#define __DRV_CAN_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <board.h>
#include <rtdevice.h>
#include <rtthread.h>
#define BS1SHIFT 16
#define BS2SHIFT 20
#define RRESCLSHIFT 0
#define SJWSHIFT 24
#define BS1MASK ((0x0F) << BS1SHIFT )
#define BS2MASK ((0x07) << BS2SHIFT )
#define RRESCLMASK (0x3FF << RRESCLSHIFT )
#define SJWMASK (0x3 << SJWSHIFT )
struct stm32_baud_rate_tab
{
rt_uint32_t baud_rate;
rt_uint32_t config_data;
};
#define BAUD_DATA(TYPE,NO) ((can_baud_rate_tab[NO].config_data & TYPE##MASK))
/* stm32 can device */
struct stm32_can
{
char *name;
CAN_HandleTypeDef CanHandle;
CAN_FilterTypeDef FilterConfig;
struct rt_can_device device; /* inherit from can device */
};
int rt_hw_can_init(void);
#ifdef __cplusplus
}
#endif
#endif /*__DRV_CAN_H__ */
/************************** end of file ******************/
+66
View File
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-7 SummerGift first version
*/
#ifndef __DRV_COMMON_H__
#define __DRV_COMMON_H__
#include <rtthread.h>
#include <rthw.h>
#include <board.h>
#ifdef RT_USING_DEVICE
#include <rtdevice.h>
#endif
#ifdef __cplusplus
extern "C"
{
#endif
void _Error_Handler(char *s, int num);
#ifndef Error_Handler
#define Error_Handler() _Error_Handler(__FILE__, __LINE__)
#endif
#define DMA_NOT_AVAILABLE ((DMA_INSTANCE_TYPE *)0xFFFFFFFFU)
#define __STM32_PORT(port) GPIO##port##_BASE
#if defined(SOC_SERIES_STM32MP1)
#define GET_PIN(PORTx,PIN) (GPIO##PORTx == GPIOZ) ? (176 + PIN) : ((rt_base_t)((16 * ( ((rt_base_t)__STM32_PORT(PORTx) - (rt_base_t)GPIOA_BASE)/(0x1000UL) )) + PIN))
#else
#define GET_PIN(PORTx,PIN) (rt_base_t)((16 * ( ((rt_base_t)__STM32_PORT(PORTx) - (rt_base_t)GPIOA_BASE)/(0x0400UL) )) + PIN)
#endif
#define STM32_FLASH_START_ADRESS ROM_START
#define STM32_FLASH_SIZE ROM_SIZE
#define STM32_FLASH_END_ADDRESS ROM_END
#define STM32_SRAM1_SIZE RAM_SIZE
#define STM32_SRAM1_START RAM_START
#define STM32_SRAM1_END RAM_END
#if defined(__CC_ARM) || defined(__CLANG_ARM)
extern int Image$RW_IRAM1$ZI$Limit;
#define HEAP_BEGIN ((void *)&Image$RW_IRAM1$ZI$Limit)
#elif __ICCARM__
#pragma section="CSTACK"
#define HEAP_BEGIN (__segment_end("CSTACK"))
#else
extern int __bss_end;
#define HEAP_BEGIN ((void *)&__bss_end)
#endif
#define HEAP_END STM32_SRAM1_END
#ifdef __cplusplus
}
#endif
#endif
+167
View File
@@ -0,0 +1,167 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-10-30 SummerGift first version
* 2020-10-14 Dozingfiretruck Porting for stm32wbxx
*/
#ifndef __DRV_CONFIG_H__
#define __DRV_CONFIG_H__
#include <board.h>
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(SOC_SERIES_STM32F0)
#include "config/dma_config.h"
#include "config/uart_config.h"
#include "config/spi_config.h"
#include "config/tim_config.h"
#include "config/pwm_config.h"
#include "config/adc_config.h"
#elif defined(SOC_SERIES_STM32F1)
#include "config/dma_config.h"
#include "config/uart_config.h"
#include "config/spi_config.h"
#include "config/adc_config.h"
#include "config/tim_config.h"
#include "config/sdio_config.h"
#include "config/pwm_config.h"
#include "config/usbd_config.h"
#include "config/pulse_encoder_config.h"
#elif defined(SOC_SERIES_STM32F2)
#include "config/dma_config.h"
#include "config/uart_config.h"
#include "config/spi_config.h"
#include "config/adc_config.h"
#include "config/tim_config.h"
#include "config/sdio_config.h"
#include "config/pwm_config.h"
#elif defined(SOC_SERIES_STM32F3)
#include "config/uart_config.h"
#include "config/tim_config.h"
#include "config/pwm_config.h"
#include "config/dma_config.h"
#elif defined(SOC_SERIES_STM32F4)
#include "config/dma_config.h"
#include "config/uart_config.h"
#include "config/spi_config.h"
#include "config/qspi_config.h"
#include "config/usbd_config.h"
#include "config/adc_config.h"
#include "config/dac_config.h"
#include "config/tim_config.h"
#include "config/sdio_config.h"
#include "config/pwm_config.h"
#include "config/pulse_encoder_config.h"
#elif defined(SOC_SERIES_STM32F7)
#include "config/dma_config.h"
#include "config/uart_config.h"
#include "config/spi_config.h"
#include "config/qspi_config.h"
#include "config/adc_config.h"
#include "config/tim_config.h"
#include "config/sdio_config.h"
#include "config/pwm_config.h"
#elif defined(SOC_SERIES_STM32L0)
#include "config/dma_config.h"
#include "config/uart_config.h"
#elif defined(SOC_SERIES_STM32L4)
#include "config/dma_config.h"
#include "config/uart_config.h"
#include "config/spi_config.h"
#include "config/qspi_config.h"
#include "config/adc_config.h"
#include "config/dac_config.h"
#include "config/tim_config.h"
#include "config/sdio_config.h"
#include "config/pwm_config.h"
#include "config/usbd_config.h"
#elif defined(SOC_SERIES_STM32L5)
#include "config/dma_config.h"
#include "config/uart_config.h"
#include "config/spi_config.h"
#include "config/qspi_config.h"
#include "config/adc_config.h"
#include "config/dac_config.h"
#include "config/tim_config.h"
#include "config/sdio_config.h"
#include "config/pwm_config.h"
#include "config/usbd_config.h"
#elif defined(SOC_SERIES_STM32G0)
#include "config/dma_config.h"
#include "config/uart_config.h"
#include "config/spi_config.h"
#include "config/adc_config.h"
#include "config/tim_config.h"
#include "config/pwm_config.h"
#elif defined(SOC_SERIES_STM32G4)
#include "config/dma_config.h"
#include "config/uart_config.h"
#include "config/spi_config.h"
#include "config/qspi_config.h"
#include "config/usbd_config.h"
#include "config/adc_config.h"
#include "config/tim_config.h"
#include "config/sdio_config.h"
#include "config/pwm_config.h"
#include "config/pulse_encoder_config.h"
#elif defined(SOC_SERIES_STM32H7)
#include "config/dma_config.h"
#include "config/uart_config.h"
#include "config/spi_config.h"
#include "config/qspi_config.h"
#include "config/adc_config.h"
#include "config/dac_config.h"
#include "config/tim_config.h"
#include "config/sdio_config.h"
#include "config/pwm_config.h"
#include "config/usbd_config.h"
#elif defined(SOC_SERIES_STM32U5)
#include "config/dma_config.h"
#include "config/uart_config.h"
#include "config/spi_config.h"
#include "config/qspi_config.h"
#include "config/adc_config.h"
#include "config/dac_config.h"
#include "config/tim_config.h"
#include "config/sdio_config.h"
#include "config/pwm_config.h"
#include "config/usbd_config.h"
#elif defined(SOC_SERIES_STM32MP1)
#include "config/dma_config.h"
#include "config/uart_config.h"
#include "config/qspi_config.h"
#include "config/spi_config.h"
#include "config/adc_config.h"
#include "config/dac_config.h"
#include "config/tim_config.h"
#include "config/pwm_config.h"
#elif defined(SOC_SERIES_STM32WL)
#include "config/dma_config.h"
#include "config/uart_config.h"
#include "config/spi_config.h"
#include "config/tim_config.h"
#elif defined(SOC_SERIES_STM32WB)
#include "config/adc_config.h"
#include "config/dma_config.h"
#include "config/pwm_config.h"
#include "config/qspi_config.h"
#include "config/spi_config.h"
#include "config/tim_config.h"
#include "config/uart_config.h"
#include "config/usbd_config.h"
#endif
#ifdef __cplusplus
}
#endif
#endif
+16
View File
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2019 Winner Microelectronics Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-07-10 Ernest 1st version
*/
#ifndef __DRV_CRYPTO_H__
#define __DRV_CRYPTO_H__
int l4_hw_crypto_device_init(void);
#endif /* __DRV_CRYPTO_H__ */
+51
View File
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-10 SummerGift first version
* 2020-10-14 Dozingfiretruck Porting for stm32wbxx
*/
#ifndef __DRV_DMA_H_
#define __DRV_DMA_H_
#include <rtthread.h>
#include <board.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32L5)\
|| defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G0) \
|| defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB)|| defined(SOC_SERIES_STM32F3) \
|| defined(SOC_SERIES_STM32U5)
#define DMA_INSTANCE_TYPE DMA_Channel_TypeDef
#elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)\
|| defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1)
#define DMA_INSTANCE_TYPE DMA_Stream_TypeDef
#endif /* defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) */
struct dma_config {
DMA_INSTANCE_TYPE *Instance;
rt_uint32_t dma_rcc;
IRQn_Type dma_irq;
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)|| defined(SOC_SERIES_STM32F3)
rt_uint32_t channel;
#endif
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32G4)\
|| defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32L5)
rt_uint32_t request;
#endif
};
#ifdef __cplusplus
}
#endif
#endif /*__DRV_DMA_H_ */
+106
View File
@@ -0,0 +1,106 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-25 zylx first version
*/
#ifndef __DRV_ETH_H__
#define __DRV_ETH_H__
#include <rtthread.h>
#include <rthw.h>
#include <rtdevice.h>
#include <board.h>
/* The PHY basic control register */
#define PHY_BASIC_CONTROL_REG 0x00U
#define PHY_RESET_MASK (1<<15)
#define PHY_AUTO_NEGOTIATION_MASK (1<<12)
/* The PHY basic status register */
#define PHY_BASIC_STATUS_REG 0x01U
#define PHY_LINKED_STATUS_MASK (1<<2)
#define PHY_AUTONEGO_COMPLETE_MASK (1<<5)
/* The PHY ID one register */
#define PHY_ID1_REG 0x02U
/* The PHY ID two register */
#define PHY_ID2_REG 0x03U
/* The PHY auto-negotiate advertise register */
#define PHY_AUTONEG_ADVERTISE_REG 0x04U
#ifdef PHY_USING_LAN8720A
/* The PHY interrupt source flag register. */
#define PHY_INTERRUPT_FLAG_REG 0x1DU
/* The PHY interrupt mask register. */
#define PHY_INTERRUPT_MASK_REG 0x1EU
#define PHY_LINK_DOWN_MASK (1<<4)
#define PHY_AUTO_NEGO_COMPLETE_MASK (1<<6)
/* The PHY status register. */
#define PHY_Status_REG 0x1FU
#define PHY_10M_MASK (1<<2)
#define PHY_100M_MASK (1<<3)
#define PHY_FULL_DUPLEX_MASK (1<<4)
#define PHY_Status_SPEED_10M(sr) ((sr) & PHY_10M_MASK)
#define PHY_Status_SPEED_100M(sr) ((sr) & PHY_100M_MASK)
#define PHY_Status_FULL_DUPLEX(sr) ((sr) & PHY_FULL_DUPLEX_MASK)
#elif defined(PHY_USING_DM9161CEP)
#define PHY_Status_REG 0x11U
#define PHY_10M_MASK ((1<<12) || (1<<13))
#define PHY_100M_MASK ((1<<14) || (1<<15))
#define PHY_FULL_DUPLEX_MASK ((1<<15) || (1<<13))
#define PHY_Status_SPEED_10M(sr) ((sr) & PHY_10M_MASK)
#define PHY_Status_SPEED_100M(sr) ((sr) & PHY_100M_MASK)
#define PHY_Status_FULL_DUPLEX(sr) ((sr) & PHY_FULL_DUPLEX_MASK)
/* The PHY interrupt source flag register. */
#define PHY_INTERRUPT_FLAG_REG 0x15U
/* The PHY interrupt mask register. */
#define PHY_INTERRUPT_MASK_REG 0x15U
#define PHY_LINK_CHANGE_FLAG (1<<2)
#define PHY_LINK_CHANGE_MASK (1<<9)
#define PHY_INT_MASK 0
#elif defined(PHY_USING_DP83848C)
#define PHY_Status_REG 0x10U
#define PHY_10M_MASK (1<<1)
#define PHY_FULL_DUPLEX_MASK (1<<2)
#define PHY_Status_SPEED_10M(sr) ((sr) & PHY_10M_MASK)
#define PHY_Status_SPEED_100M(sr) (!PHY_Status_SPEED_10M(sr))
#define PHY_Status_FULL_DUPLEX(sr) ((sr) & PHY_FULL_DUPLEX_MASK)
/* The PHY interrupt source flag register. */
#define PHY_INTERRUPT_FLAG_REG 0x12U
#define PHY_LINK_CHANGE_FLAG (1<<13)
/* The PHY interrupt control register. */
#define PHY_INTERRUPT_CTRL_REG 0x11U
#define PHY_INTERRUPT_EN ((1<<0)|(1<<1))
/* The PHY interrupt mask register. */
#define PHY_INTERRUPT_MASK_REG 0x12U
#define PHY_INT_MASK (1<<5)
#endif
#ifdef PHY_USING_LAN8742A
/* The PHY interrupt source flag register. */
#define PHY_INTERRUPT_FLAG_REG 0x1DU
/* The PHY interrupt mask register. */
#define PHY_INTERRUPT_MASK_REG 0x1EU
#define PHY_LINK_DOWN_MASK (1<<4)
#define PHY_AUTO_NEGO_COMPLETE_MASK (1<<6)
/* The PHY status register. */
#define PHY_Status_REG 0x1FU
#define PHY_10M_MASK (1<<2)
#define PHY_100M_MASK (1<<3)
#define PHY_FULL_DUPLEX_MASK (1<<4)
#define PHY_Status_SPEED_10M(sr) ((sr) & PHY_10M_MASK)
#define PHY_Status_SPEED_100M(sr) ((sr) & PHY_100M_MASK)
#define PHY_Status_FULL_DUPLEX(sr) ((sr) & PHY_FULL_DUPLEX_MASK)
#endif /* PHY_USING_LAN8742A */
#endif /* __DRV_ETH_H__ */
+31
View File
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-5 SummerGift first version
*/
#ifndef __DRV_FLASH_H__
#define __DRV_FLASH_H__
#include <rtthread.h>
#include "rtdevice.h"
#include <rthw.h>
#include <drv_common.h>
#ifdef __cplusplus
extern "C" {
#endif
int stm32_flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size);
int stm32_flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size);
int stm32_flash_erase(rt_uint32_t addr, size_t size);
#ifdef __cplusplus
}
#endif
#endif /* __DRV_FLASH_H__ */
+27
View File
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-15 SummerGift first version
*/
/*
* NOTE: DO NOT include this file on the header file.
*/
#ifndef LOG_TAG
#define DBG_TAG "drv"
#else
#define DBG_TAG LOG_TAG
#endif /* LOG_TAG */
#ifdef DRV_DEBUG
#define DBG_LVL DBG_LOG
#else
#define DBG_LVL DBG_INFO
#endif /* DRV_DEBUG */
#include <rtdbg.h>
+23
View File
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-05-06 Zero-Free first version
*/
#ifndef __DRV_PMTIMER_H__
#define __DRV_PMTIMER_H__
#include <rtthread.h>
rt_uint32_t stm32l4_lptim_get_countfreq(void);
rt_uint32_t stm32l4_lptim_get_tick_max(void);
rt_uint32_t stm32l4_lptim_get_current_tick(void);
rt_err_t stm32l4_lptim_start(rt_uint32_t load);
void stm32l4_lptim_stop(void);
#endif /* __DRV_PMTIMER_H__ */
+26
View File
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-27 zylx first version
*/
#ifndef __DRV_QSPI_H__
#define __DRV_QSPI_H__
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
rt_err_t stm32_qspi_bus_attach_device(const char *bus_name, const char *device_name, rt_uint32_t pin, rt_uint8_t data_line_width, void (*enter_qspi_mode)(), void (*exit_qspi_mode)());
#ifdef __cplusplus
}
#endif
#endif /* __DRV_QSPI_H__ */
+196
View File
@@ -0,0 +1,196 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-13 BalanceTWK first version
* 2019-06-11 WillianChan Add SD card hot plug detection
*/
#ifndef _DRV_SDIO_H
#define _DRV_SDIO_H
#include <rtthread.h>
#include "rtdevice.h"
#include <rthw.h>
#include <drv_common.h>
#include "drv_dma.h"
#include <string.h>
#include <drivers/mmcsd_core.h>
#include <drivers/sdio.h>
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4)
#define SDCARD_INSTANCE_TYPE SDIO_TypeDef
#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F7)
#define SDCARD_INSTANCE_TYPE SDMMC_TypeDef
#endif /* defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F4) */
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4)
#define SDCARD_INSTANCE SDIO
#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F7)
#define SDCARD_INSTANCE SDMMC1
#endif /* defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F4) */
#define SDIO_BUFF_SIZE 4096
#define SDIO_ALIGN_LEN 32
#ifndef SDIO_MAX_FREQ
#define SDIO_MAX_FREQ (1000000)
#endif
#ifndef SDIO_BASE_ADDRESS
#define SDIO_BASE_ADDRESS (0x40012800U)
#endif
#ifndef SDIO_CLOCK_FREQ
#define SDIO_CLOCK_FREQ (48U * 1000 * 1000)
#endif
#ifndef SDIO_BUFF_SIZE
#define SDIO_BUFF_SIZE (4096)
#endif
#ifndef SDIO_ALIGN_LEN
#define SDIO_ALIGN_LEN (32)
#endif
#ifndef SDIO_MAX_FREQ
#define SDIO_MAX_FREQ (24 * 1000 * 1000)
#endif
#define HW_SDIO_IT_CCRCFAIL (0x01U << 0)
#define HW_SDIO_IT_DCRCFAIL (0x01U << 1)
#define HW_SDIO_IT_CTIMEOUT (0x01U << 2)
#define HW_SDIO_IT_DTIMEOUT (0x01U << 3)
#define HW_SDIO_IT_TXUNDERR (0x01U << 4)
#define HW_SDIO_IT_RXOVERR (0x01U << 5)
#define HW_SDIO_IT_CMDREND (0x01U << 6)
#define HW_SDIO_IT_CMDSENT (0x01U << 7)
#define HW_SDIO_IT_DATAEND (0x01U << 8)
#define HW_SDIO_IT_STBITERR (0x01U << 9)
#define HW_SDIO_IT_DBCKEND (0x01U << 10)
#define HW_SDIO_IT_CMDACT (0x01U << 11)
#define HW_SDIO_IT_TXACT (0x01U << 12)
#define HW_SDIO_IT_RXACT (0x01U << 13)
#define HW_SDIO_IT_TXFIFOHE (0x01U << 14)
#define HW_SDIO_IT_RXFIFOHF (0x01U << 15)
#define HW_SDIO_IT_TXFIFOF (0x01U << 16)
#define HW_SDIO_IT_RXFIFOF (0x01U << 17)
#define HW_SDIO_IT_TXFIFOE (0x01U << 18)
#define HW_SDIO_IT_RXFIFOE (0x01U << 19)
#define HW_SDIO_IT_TXDAVL (0x01U << 20)
#define HW_SDIO_IT_RXDAVL (0x01U << 21)
#define HW_SDIO_IT_SDIOIT (0x01U << 22)
#define HW_SDIO_ERRORS \
(HW_SDIO_IT_CCRCFAIL | HW_SDIO_IT_CTIMEOUT | \
HW_SDIO_IT_DCRCFAIL | HW_SDIO_IT_DTIMEOUT | \
HW_SDIO_IT_RXOVERR | HW_SDIO_IT_TXUNDERR)
#define HW_SDIO_POWER_OFF (0x00U)
#define HW_SDIO_POWER_UP (0x02U)
#define HW_SDIO_POWER_ON (0x03U)
#define HW_SDIO_FLOW_ENABLE (0x01U << 14)
#define HW_SDIO_BUSWIDE_1B (0x00U << 11)
#define HW_SDIO_BUSWIDE_4B (0x01U << 11)
#define HW_SDIO_BUSWIDE_8B (0x02U << 11)
#define HW_SDIO_BYPASS_ENABLE (0x01U << 10)
#define HW_SDIO_IDLE_ENABLE (0x01U << 9)
#define HW_SDIO_CLK_ENABLE (0x01U << 8)
#define HW_SDIO_SUSPEND_CMD (0x01U << 11)
#define HW_SDIO_CPSM_ENABLE (0x01U << 10)
#define HW_SDIO_WAIT_END (0x01U << 9)
#define HW_SDIO_WAIT_INT (0x01U << 8)
#define HW_SDIO_RESPONSE_NO (0x00U << 6)
#define HW_SDIO_RESPONSE_SHORT (0x01U << 6)
#define HW_SDIO_RESPONSE_LONG (0x03U << 6)
#define HW_SDIO_DATA_LEN_MASK (0x01FFFFFFU)
#define HW_SDIO_IO_ENABLE (0x01U << 11)
#define HW_SDIO_RWMOD_CK (0x01U << 10)
#define HW_SDIO_RWSTOP_ENABLE (0x01U << 9)
#define HW_SDIO_RWSTART_ENABLE (0x01U << 8)
#define HW_SDIO_DBLOCKSIZE_1 (0x00U << 4)
#define HW_SDIO_DBLOCKSIZE_2 (0x01U << 4)
#define HW_SDIO_DBLOCKSIZE_4 (0x02U << 4)
#define HW_SDIO_DBLOCKSIZE_8 (0x03U << 4)
#define HW_SDIO_DBLOCKSIZE_16 (0x04U << 4)
#define HW_SDIO_DBLOCKSIZE_32 (0x05U << 4)
#define HW_SDIO_DBLOCKSIZE_64 (0x06U << 4)
#define HW_SDIO_DBLOCKSIZE_128 (0x07U << 4)
#define HW_SDIO_DBLOCKSIZE_256 (0x08U << 4)
#define HW_SDIO_DBLOCKSIZE_512 (0x09U << 4)
#define HW_SDIO_DBLOCKSIZE_1024 (0x0AU << 4)
#define HW_SDIO_DBLOCKSIZE_2048 (0x0BU << 4)
#define HW_SDIO_DBLOCKSIZE_4096 (0x0CU << 4)
#define HW_SDIO_DBLOCKSIZE_8192 (0x0DU << 4)
#define HW_SDIO_DBLOCKSIZE_16384 (0x0EU << 4)
#define HW_SDIO_DMA_ENABLE (0x01U << 3)
#define HW_SDIO_STREAM_ENABLE (0x01U << 2)
#define HW_SDIO_TO_HOST (0x01U << 1)
#define HW_SDIO_DPSM_ENABLE (0x01U << 0)
#define HW_SDIO_DATATIMEOUT (0xF0000000U)
struct stm32_sdio
{
volatile rt_uint32_t power;
volatile rt_uint32_t clkcr;
volatile rt_uint32_t arg;
volatile rt_uint32_t cmd;
volatile rt_uint32_t respcmd;
volatile rt_uint32_t resp1;
volatile rt_uint32_t resp2;
volatile rt_uint32_t resp3;
volatile rt_uint32_t resp4;
volatile rt_uint32_t dtimer;
volatile rt_uint32_t dlen;
volatile rt_uint32_t dctrl;
volatile rt_uint32_t dcount;
volatile rt_uint32_t sta;
volatile rt_uint32_t icr;
volatile rt_uint32_t mask;
volatile rt_uint32_t reserved0[2];
volatile rt_uint32_t fifocnt;
volatile rt_uint32_t reserved1[13];
volatile rt_uint32_t fifo;
};
typedef rt_err_t (*dma_txconfig)(rt_uint32_t *src, rt_uint32_t *dst, int size);
typedef rt_err_t (*dma_rxconfig)(rt_uint32_t *src, rt_uint32_t *dst, int size);
typedef rt_uint32_t (*sdio_clk_get)(struct stm32_sdio *hw_sdio);
struct stm32_sdio_des
{
struct stm32_sdio *hw_sdio;
dma_txconfig txconfig;
dma_rxconfig rxconfig;
sdio_clk_get clk_get;
};
struct stm32_sdio_config
{
SDCARD_INSTANCE_TYPE *Instance;
struct dma_config dma_rx, dma_tx;
};
/* stm32 sdio dirver class */
struct stm32_sdio_class
{
struct stm32_sdio_des *des;
const struct stm32_sdio_config *cfg;
struct rt_mmcsd_host host;
struct
{
DMA_HandleTypeDef handle_rx;
DMA_HandleTypeDef handle_tx;
} dma;
};
extern void stm32_mmcsd_change(void);
#endif
+69
View File
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-08 balanceTWK first version
*/
#ifndef __DRV_I2C__
#define __DRV_I2C__
#include <rtthread.h>
#include <rthw.h>
#include <rtdevice.h>
/* stm32 config class */
struct stm32_soft_i2c_config
{
rt_uint8_t scl;
rt_uint8_t sda;
const char *bus_name;
};
/* stm32 i2c dirver class */
struct stm32_i2c
{
struct rt_i2c_bit_ops ops;
struct rt_i2c_bus_device i2c2_bus;
};
#ifdef BSP_USING_I2C1
#define I2C1_BUS_CONFIG \
{ \
.scl = BSP_I2C1_SCL_PIN, \
.sda = BSP_I2C1_SDA_PIN, \
.bus_name = "i2c1", \
}
#endif
#ifdef BSP_USING_I2C2
#define I2C2_BUS_CONFIG \
{ \
.scl = BSP_I2C2_SCL_PIN, \
.sda = BSP_I2C2_SDA_PIN, \
.bus_name = "i2c2", \
}
#endif
#ifdef BSP_USING_I2C3
#define I2C3_BUS_CONFIG \
{ \
.scl = BSP_I2C3_SCL_PIN, \
.sda = BSP_I2C3_SDA_PIN, \
.bus_name = "i2c3", \
}
#endif
#ifdef BSP_USING_I2C4
#define I2C4_BUS_CONFIG \
{ \
.scl = BSP_I2C4_SCL_PIN, \
.sda = BSP_I2C4_SDA_PIN, \
.bus_name = "i2c4", \
}
#endif
int rt_hw_i2c_init(void);
#endif
+71
View File
@@ -0,0 +1,71 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-5 SummerGift first version
*/
#ifndef __DRV_SPI_H__
#define __DRV_SPI_H__
#include <rtthread.h>
#include "rtdevice.h"
#include <rthw.h>
#include <drv_common.h>
#include "drv_dma.h"
#ifdef __cplusplus
extern "C" {
#endif
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, GPIO_TypeDef* cs_gpiox, uint16_t cs_gpio_pin);
#ifdef __cplusplus
}
#endif
struct stm32_hw_spi_cs
{
GPIO_TypeDef* GPIOx;
uint16_t GPIO_Pin;
};
struct stm32_spi_config
{
SPI_TypeDef *Instance;
char *bus_name;
IRQn_Type irq_type;
struct dma_config *dma_rx, *dma_tx;
};
struct stm32_spi_device
{
rt_uint32_t pin;
char *bus_name;
char *device_name;
};
#define SPI_USING_RX_DMA_FLAG (1<<0)
#define SPI_USING_TX_DMA_FLAG (1<<1)
/* stm32 spi dirver class */
struct stm32_spi
{
SPI_HandleTypeDef handle;
struct stm32_spi_config *config;
struct rt_spi_configuration *cfg;
struct
{
DMA_HandleTypeDef handle_rx;
DMA_HandleTypeDef handle_tx;
} dma;
rt_uint8_t spi_dma_flag;
struct rt_spi_bus spi_bus;
};
#endif /*__DRV_SPI_H__ */
+74
View File
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018.10.30 SummerGift first version
* 2019.03.05 whj4674672 add stm32h7
* 2020-10-14 Dozingfiretruck Porting for stm32wbxx
*/
#ifndef __DRV_USART_H__
#define __DRV_USART_H__
#include <rtthread.h>
#include "rtdevice.h"
#include <rthw.h>
#include <drv_common.h>
#include "drv_dma.h"
int rt_hw_usart_init(void);
#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) \
|| defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB)|| defined(SOC_SERIES_STM32F3)
#define DMA_INSTANCE_TYPE DMA_Channel_TypeDef
#elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) \
|| defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1)
#define DMA_INSTANCE_TYPE DMA_Stream_TypeDef
#endif /* defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) */
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32L5) || defined(SOC_SERIES_STM32WL) \
|| defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32G0) \
|| defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB)|| defined(SOC_SERIES_STM32F3) || defined(SOC_SERIES_STM32U5)
#define UART_INSTANCE_CLEAR_FUNCTION __HAL_UART_CLEAR_FLAG
#elif defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) \
|| defined(SOC_SERIES_STM32MP1)
#define UART_INSTANCE_CLEAR_FUNCTION __HAL_UART_CLEAR_IT
#endif
/* stm32 config class */
struct stm32_uart_config
{
const char *name;
USART_TypeDef *Instance;
IRQn_Type irq_type;
struct dma_config *dma_rx;
struct dma_config *dma_tx;
const char *tx_pin_name;
const char *rx_pin_name;
};
/* stm32 uart dirver class */
struct stm32_uart
{
UART_HandleTypeDef handle;
struct stm32_uart_config *config;
#ifdef RT_SERIAL_USING_DMA
struct
{
DMA_HandleTypeDef handle;
rt_size_t last_index;
} dma_rx;
struct
{
DMA_HandleTypeDef handle;
} dma_tx;
#endif
rt_uint16_t uart_dma_flag;
struct rt_serial_device serial;
};
#endif /* __DRV_USART_H__ */
+83
View File
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-06-01 KyleChan first version
*/
#ifndef __DRV_USART_V2_H__
#define __DRV_USART_V2_H__
#include <rtthread.h>
#include <rtdevice.h>
#include <rthw.h>
#include <drv_common.h>
#include <drv_dma.h>
#include <drv_config.h>
int rt_hw_usart_init(void);
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32F0) \
|| defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32H7) \
|| defined(SOC_SERIES_STM32G4)
#define UART_SET_TDR(__HANDLE__, __DATA__) ((__HANDLE__)->Instance->TDR = (__DATA__))
#define UART_GET_RDR(__HANDLE__, MASK) ((__HANDLE__)->Instance->RDR & MASK)
#else
#define UART_SET_TDR(__HANDLE__, __DATA__) ((__HANDLE__)->Instance->DR = (__DATA__))
#define UART_GET_RDR(__HANDLE__, MASK) ((__HANDLE__)->Instance->DR & MASK)
#endif
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F2) \
|| defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32G0) \
|| defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB)
#define UART_INSTANCE_CLEAR_FUNCTION __HAL_UART_CLEAR_FLAG
#elif defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) \
|| defined(SOC_SERIES_STM32MP1)
#define UART_INSTANCE_CLEAR_FUNCTION __HAL_UART_CLEAR_IT
#endif
#define UART_RX_DMA_IT_IDLE_FLAG 0x00
#define UART_RX_DMA_IT_HT_FLAG 0x01
#define UART_RX_DMA_IT_TC_FLAG 0x02
/* stm32 config class */
struct stm32_uart_config
{
const char *name;
USART_TypeDef *Instance;
IRQn_Type irq_type;
#ifdef RT_SERIAL_USING_DMA
struct dma_config *dma_rx;
struct dma_config *dma_tx;
#endif
};
/* stm32 uart dirver class */
struct stm32_uart
{
UART_HandleTypeDef handle;
struct stm32_uart_config *config;
#ifdef RT_SERIAL_USING_DMA
struct
{
DMA_HandleTypeDef handle;
rt_size_t remaining_cnt;
} dma_rx;
struct
{
DMA_HandleTypeDef handle;
} dma_tx;
#endif
rt_uint16_t uart_dma_flag;
struct rt_serial_device serial;
};
#endif /* __DRV_USART_H__ */
+21
View File
@@ -0,0 +1,21 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-12-12 ZYH the first version
* 2019-12-19 tyustli port to stm32 series
*/
#ifndef __DRV_USBH_H__
#define __DRV_USBH_H__
#include <rtthread.h>
#define OTG_FS_PORT 1
int stm_usbh_register(void);
#endif
/************* end of file ************/
+451
View File
@@ -0,0 +1,451 @@
/**
******************************************************************************
* @file stm32f4xx_hal_conf.h
* @brief HAL configuration file.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F4xx_HAL_CONF_H
#define __STM32F4xx_HAL_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* ########################## Module Selection ############################## */
/**
* @brief This is the list of modules to be used in the HAL driver
*/
#define HAL_MODULE_ENABLED
/* #define HAL_ADC_MODULE_ENABLED */
/* #define HAL_CRYP_MODULE_ENABLED */
/* #define HAL_CAN_MODULE_ENABLED */
/* #define HAL_CRC_MODULE_ENABLED */
/* #define HAL_CRYP_MODULE_ENABLED */
/* #define HAL_DAC_MODULE_ENABLED */
/* #define HAL_DCMI_MODULE_ENABLED */
/* #define HAL_DMA2D_MODULE_ENABLED */
/* #define HAL_ETH_MODULE_ENABLED */
/* #define HAL_NAND_MODULE_ENABLED */
/* #define HAL_NOR_MODULE_ENABLED */
/* #define HAL_PCCARD_MODULE_ENABLED */
/* #define HAL_SRAM_MODULE_ENABLED */
/* #define HAL_SDRAM_MODULE_ENABLED */
/* #define HAL_HASH_MODULE_ENABLED */
/* #define HAL_I2C_MODULE_ENABLED */
/* #define HAL_I2S_MODULE_ENABLED */
/* #define HAL_IWDG_MODULE_ENABLED */
/* #define HAL_LTDC_MODULE_ENABLED */
/* #define HAL_RNG_MODULE_ENABLED */
/* #define HAL_RTC_MODULE_ENABLED */
/* #define HAL_SAI_MODULE_ENABLED */
/* #define HAL_SD_MODULE_ENABLED */
/* #define HAL_MMC_MODULE_ENABLED */
/* #define HAL_SPI_MODULE_ENABLED */
/* #define HAL_TIM_MODULE_ENABLED */
#define HAL_UART_MODULE_ENABLED
/* #define HAL_USART_MODULE_ENABLED */
/* #define HAL_IRDA_MODULE_ENABLED */
/* #define HAL_SMARTCARD_MODULE_ENABLED */
/* #define HAL_WWDG_MODULE_ENABLED */
/* #define HAL_PCD_MODULE_ENABLED */
/* #define HAL_HCD_MODULE_ENABLED */
/* #define HAL_DSI_MODULE_ENABLED */
/* #define HAL_QSPI_MODULE_ENABLED */
/* #define HAL_QSPI_MODULE_ENABLED */
/* #define HAL_CEC_MODULE_ENABLED */
/* #define HAL_FMPI2C_MODULE_ENABLED */
/* #define HAL_SPDIFRX_MODULE_ENABLED */
/* #define HAL_DFSDM_MODULE_ENABLED */
/* #define HAL_LPTIM_MODULE_ENABLED */
/* #define HAL_EXTI_MODULE_ENABLED */
#define HAL_GPIO_MODULE_ENABLED
#define HAL_DMA_MODULE_ENABLED
#define HAL_RCC_MODULE_ENABLED
#define HAL_FLASH_MODULE_ENABLED
#define HAL_PWR_MODULE_ENABLED
#define HAL_CORTEX_MODULE_ENABLED
/* ########################## HSE/HSI Values adaptation ##################### */
/**
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSE is used as system clock source, directly or through the PLL).
*/
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSE_STARTUP_TIMEOUT)
#define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */
/**
* @brief Internal High Speed oscillator (HSI) value.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSI is used as system clock source, directly or through the PLL).
*/
#if !defined (HSI_VALUE)
#define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
/**
* @brief Internal Low Speed oscillator (LSI) value.
*/
#if !defined (LSI_VALUE)
#define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
The real value may vary depending on the variations
in voltage and temperature.*/
/**
* @brief External Low Speed oscillator (LSE) value.
*/
#if !defined (LSE_VALUE)
#define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */
#endif /* LSE_VALUE */
#if !defined (LSE_STARTUP_TIMEOUT)
#define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */
#endif /* LSE_STARTUP_TIMEOUT */
/**
* @brief External clock source for I2S peripheral
* This value is used by the I2S HAL module to compute the I2S clock source
* frequency, this source is inserted directly through I2S_CKIN pad.
*/
#if !defined (EXTERNAL_CLOCK_VALUE)
#define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the External audio frequency in Hz*/
#endif /* EXTERNAL_CLOCK_VALUE */
/* 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. */
/* ########################### System Configuration ######################### */
/**
* @brief This is the HAL system configuration section
*/
#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */
#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */
#define USE_RTOS 0U
#define PREFETCH_ENABLE 1U
#define INSTRUCTION_CACHE_ENABLE 1U
#define DATA_CACHE_ENABLE 1U
/* ########################## Assert Selection ############################## */
/**
* @brief Uncomment the line below to expanse the "assert_param" macro in the
* HAL drivers code
*/
/* #define USE_FULL_ASSERT 1U */
/* ################## Ethernet peripheral configuration ##################### */
/* Section 1 : Ethernet peripheral configuration */
/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
#define MAC_ADDR0 2U
#define MAC_ADDR1 0U
#define MAC_ADDR2 0U
#define MAC_ADDR3 0U
#define MAC_ADDR4 0U
#define MAC_ADDR5 0U
/* Definition of the Ethernet driver buffers size and count */
#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
#define ETH_RXBUFNB ((uint32_t)4U) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
#define ETH_TXBUFNB ((uint32_t)4U) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
/* Section 2: PHY configuration section */
/* DP83848_PHY_ADDRESS Address*/
#define DP83848_PHY_ADDRESS 0x01U
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
#define PHY_RESET_DELAY ((uint32_t)0x000000FFU)
/* PHY Configuration delay */
#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU)
#define PHY_READ_TO ((uint32_t)0x0000FFFFU)
#define PHY_WRITE_TO ((uint32_t)0x0000FFFFU)
/* Section 3: Common PHY Registers */
#define PHY_BCR ((uint16_t)0x0000U) /*!< Transceiver Basic Control Register */
#define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */
#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */
#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */
#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */
#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */
#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */
#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */
/* Section 4: Extended PHY Registers */
#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */
#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */
#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */
/* ################## SPI peripheral configuration ########################## */
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
* Activated: CRC code is present inside driver
* Deactivated: CRC code cleaned from driver
*/
#define USE_SPI_CRC 0U
/* Includes ------------------------------------------------------------------*/
/**
* @brief Include module's header file
*/
#ifdef HAL_RCC_MODULE_ENABLED
#include "stm32f4xx_hal_rcc.h"
#endif /* HAL_RCC_MODULE_ENABLED */
#ifdef HAL_EXTI_MODULE_ENABLED
#include "stm32f4xx_hal_exti.h"
#endif /* HAL_EXTI_MODULE_ENABLED */
#ifdef HAL_GPIO_MODULE_ENABLED
#include "stm32f4xx_hal_gpio.h"
#endif /* HAL_GPIO_MODULE_ENABLED */
#ifdef HAL_DMA_MODULE_ENABLED
#include "stm32f4xx_hal_dma.h"
#endif /* HAL_DMA_MODULE_ENABLED */
#ifdef HAL_CORTEX_MODULE_ENABLED
#include "stm32f4xx_hal_cortex.h"
#endif /* HAL_CORTEX_MODULE_ENABLED */
#ifdef HAL_ADC_MODULE_ENABLED
#include "stm32f4xx_hal_adc.h"
#endif /* HAL_ADC_MODULE_ENABLED */
#ifdef HAL_CAN_MODULE_ENABLED
#include "stm32f4xx_hal_can.h"
#endif /* HAL_CAN_MODULE_ENABLED */
#ifdef HAL_CRC_MODULE_ENABLED
#include "stm32f4xx_hal_crc.h"
#endif /* HAL_CRC_MODULE_ENABLED */
#ifdef HAL_CRYP_MODULE_ENABLED
#include "stm32f4xx_hal_cryp.h"
#endif /* HAL_CRYP_MODULE_ENABLED */
#ifdef HAL_DMA2D_MODULE_ENABLED
#include "stm32f4xx_hal_dma2d.h"
#endif /* HAL_DMA2D_MODULE_ENABLED */
#ifdef HAL_DAC_MODULE_ENABLED
#include "stm32f4xx_hal_dac.h"
#endif /* HAL_DAC_MODULE_ENABLED */
#ifdef HAL_DCMI_MODULE_ENABLED
#include "stm32f4xx_hal_dcmi.h"
#endif /* HAL_DCMI_MODULE_ENABLED */
#ifdef HAL_ETH_MODULE_ENABLED
#include "stm32f4xx_hal_eth.h"
#endif /* HAL_ETH_MODULE_ENABLED */
#ifdef HAL_FLASH_MODULE_ENABLED
#include "stm32f4xx_hal_flash.h"
#endif /* HAL_FLASH_MODULE_ENABLED */
#ifdef HAL_SRAM_MODULE_ENABLED
#include "stm32f4xx_hal_sram.h"
#endif /* HAL_SRAM_MODULE_ENABLED */
#ifdef HAL_NOR_MODULE_ENABLED
#include "stm32f4xx_hal_nor.h"
#endif /* HAL_NOR_MODULE_ENABLED */
#ifdef HAL_NAND_MODULE_ENABLED
#include "stm32f4xx_hal_nand.h"
#endif /* HAL_NAND_MODULE_ENABLED */
#ifdef HAL_PCCARD_MODULE_ENABLED
#include "stm32f4xx_hal_pccard.h"
#endif /* HAL_PCCARD_MODULE_ENABLED */
#ifdef HAL_SDRAM_MODULE_ENABLED
#include "stm32f4xx_hal_sdram.h"
#endif /* HAL_SDRAM_MODULE_ENABLED */
#ifdef HAL_HASH_MODULE_ENABLED
#include "stm32f4xx_hal_hash.h"
#endif /* HAL_HASH_MODULE_ENABLED */
#ifdef HAL_I2C_MODULE_ENABLED
#include "stm32f4xx_hal_i2c.h"
#endif /* HAL_I2C_MODULE_ENABLED */
#ifdef HAL_I2S_MODULE_ENABLED
#include "stm32f4xx_hal_i2s.h"
#endif /* HAL_I2S_MODULE_ENABLED */
#ifdef HAL_IWDG_MODULE_ENABLED
#include "stm32f4xx_hal_iwdg.h"
#endif /* HAL_IWDG_MODULE_ENABLED */
#ifdef HAL_LTDC_MODULE_ENABLED
#include "stm32f4xx_hal_ltdc.h"
#endif /* HAL_LTDC_MODULE_ENABLED */
#ifdef HAL_PWR_MODULE_ENABLED
#include "stm32f4xx_hal_pwr.h"
#endif /* HAL_PWR_MODULE_ENABLED */
#ifdef HAL_RNG_MODULE_ENABLED
#include "stm32f4xx_hal_rng.h"
#endif /* HAL_RNG_MODULE_ENABLED */
#ifdef HAL_RTC_MODULE_ENABLED
#include "stm32f4xx_hal_rtc.h"
#endif /* HAL_RTC_MODULE_ENABLED */
#ifdef HAL_SAI_MODULE_ENABLED
#include "stm32f4xx_hal_sai.h"
#endif /* HAL_SAI_MODULE_ENABLED */
#ifdef HAL_SD_MODULE_ENABLED
#include "stm32f4xx_hal_sd.h"
#endif /* HAL_SD_MODULE_ENABLED */
#ifdef HAL_MMC_MODULE_ENABLED
#include "stm32f4xx_hal_mmc.h"
#endif /* HAL_MMC_MODULE_ENABLED */
#ifdef HAL_SPI_MODULE_ENABLED
#include "stm32f4xx_hal_spi.h"
#endif /* HAL_SPI_MODULE_ENABLED */
#ifdef HAL_TIM_MODULE_ENABLED
#include "stm32f4xx_hal_tim.h"
#endif /* HAL_TIM_MODULE_ENABLED */
#ifdef HAL_UART_MODULE_ENABLED
#include "stm32f4xx_hal_uart.h"
#endif /* HAL_UART_MODULE_ENABLED */
#ifdef HAL_USART_MODULE_ENABLED
#include "stm32f4xx_hal_usart.h"
#endif /* HAL_USART_MODULE_ENABLED */
#ifdef HAL_IRDA_MODULE_ENABLED
#include "stm32f4xx_hal_irda.h"
#endif /* HAL_IRDA_MODULE_ENABLED */
#ifdef HAL_SMARTCARD_MODULE_ENABLED
#include "stm32f4xx_hal_smartcard.h"
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
#ifdef HAL_WWDG_MODULE_ENABLED
#include "stm32f4xx_hal_wwdg.h"
#endif /* HAL_WWDG_MODULE_ENABLED */
#ifdef HAL_PCD_MODULE_ENABLED
#include "stm32f4xx_hal_pcd.h"
#endif /* HAL_PCD_MODULE_ENABLED */
#ifdef HAL_HCD_MODULE_ENABLED
#include "stm32f4xx_hal_hcd.h"
#endif /* HAL_HCD_MODULE_ENABLED */
#ifdef HAL_DSI_MODULE_ENABLED
#include "stm32f4xx_hal_dsi.h"
#endif /* HAL_DSI_MODULE_ENABLED */
#ifdef HAL_QSPI_MODULE_ENABLED
#include "stm32f4xx_hal_qspi.h"
#endif /* HAL_QSPI_MODULE_ENABLED */
#ifdef HAL_CEC_MODULE_ENABLED
#include "stm32f4xx_hal_cec.h"
#endif /* HAL_CEC_MODULE_ENABLED */
#ifdef HAL_FMPI2C_MODULE_ENABLED
#include "stm32f4xx_hal_fmpi2c.h"
#endif /* HAL_FMPI2C_MODULE_ENABLED */
#ifdef HAL_SPDIFRX_MODULE_ENABLED
#include "stm32f4xx_hal_spdifrx.h"
#endif /* HAL_SPDIFRX_MODULE_ENABLED */
#ifdef HAL_DFSDM_MODULE_ENABLED
#include "stm32f4xx_hal_dfsdm.h"
#endif /* HAL_DFSDM_MODULE_ENABLED */
#ifdef HAL_LPTIM_MODULE_ENABLED
#include "stm32f4xx_hal_lptim.h"
#endif /* HAL_LPTIM_MODULE_ENABLED */
/* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT
/**
* @brief The assert_param macro is used for function's parameters check.
* @param expr: If expr is false, it calls assert_failed function
* which reports the name of the source file and the source
* line number of the call that failed.
* If expr is true, it returns no value.
* @retval None
*/
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
#ifdef __cplusplus
}
#endif
#endif /* __STM32F4xx_HAL_CONF_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/