first commit for chrg
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
if BSP_USING_USBD
|
||||
config BSP_USBD_TYPE_FS
|
||||
bool
|
||||
# "USB Full Speed (FS) Core"
|
||||
config BSP_USBD_TYPE_HS
|
||||
bool
|
||||
# "USB High Speed (HS) Core"
|
||||
|
||||
config BSP_USBD_SPEED_HS
|
||||
bool
|
||||
# "USB High Speed (HS) Mode"
|
||||
config BSP_USBD_SPEED_HSINFS
|
||||
bool
|
||||
# "USB High Speed (HS) Core in FS mode"
|
||||
|
||||
config BSP_USBD_PHY_EMBEDDED
|
||||
bool
|
||||
# "Using Embedded phy interface"
|
||||
config BSP_USBD_PHY_UTMI
|
||||
bool
|
||||
# "UTMI: USB 2.0 Transceiver Macrocell Interace"
|
||||
config BSP_USBD_PHY_ULPI
|
||||
bool
|
||||
# "ULPI: UTMI+ Low Pin Interface"
|
||||
endif
|
||||
|
||||
config BSP_USING_CRC
|
||||
bool "Enable CRC (CRC-32 0x04C11DB7 Polynomial)"
|
||||
select RT_USING_HWCRYPTO
|
||||
select RT_HWCRYPTO_USING_CRC
|
||||
# "Crypto device frame dose not support above 8-bits granularity"
|
||||
# "Reserve progress, running well, about 32-bits granularity, such as stm32f1, stm32f4"
|
||||
depends on (SOC_SERIES_STM32L4 || SOC_SERIES_STM32F0 || SOC_SERIES_STM32F7 || SOC_SERIES_STM32H7 || SOC_SERIES_STM32MP1)
|
||||
default n
|
||||
|
||||
config BSP_USING_RNG
|
||||
bool "Enable RNG (Random Number Generator)"
|
||||
select RT_USING_HWCRYPTO
|
||||
select RT_HWCRYPTO_USING_RNG
|
||||
depends on (SOC_SERIES_STM32L4 || SOC_SERIES_STM32F4 || SOC_SERIES_STM32F7 || \
|
||||
SOC_SERIES_STM32H7 || SOC_SERIES_STM32MP1)
|
||||
default n
|
||||
|
||||
config BSP_USING_HASH
|
||||
bool "Enable HASH (Hash House Harriers)"
|
||||
select RT_USING_HWCRYPTO
|
||||
select RT_HWCRYPTO_USING_HASH
|
||||
depends on (SOC_SERIES_STM32MP1)
|
||||
default n
|
||||
|
||||
config BSP_USING_CRYP
|
||||
bool "Enable CRYP (Encrypt And Decrypt Data)"
|
||||
select RT_USING_HWCRYPTO
|
||||
select RT_HWCRYPTO_USING_CRYP
|
||||
depends on (SOC_SERIES_STM32MP1)
|
||||
default n
|
||||
|
||||
config BSP_USING_UDID
|
||||
bool "Enable UDID (Unique Device Identifier)"
|
||||
select RT_USING_HWCRYPTO
|
||||
default n
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
Import('RTT_ROOT')
|
||||
Import('rtconfig')
|
||||
from building import *
|
||||
import os
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
group = []
|
||||
src = []
|
||||
path = [cwd]
|
||||
|
||||
if GetDepend(['RT_USING_PIN']):
|
||||
src += ['drv_gpio.c']
|
||||
|
||||
if GetDepend(['RT_USING_SERIAL']):
|
||||
if GetDepend(['RT_USING_SERIAL_V2']):
|
||||
src += ['drv_usart_v2.c']
|
||||
else:
|
||||
src += ['drv_usart.c']
|
||||
|
||||
if GetDepend(['BSP_USING_TIM']):
|
||||
src += ['drv_tim.c']
|
||||
|
||||
if GetDepend(['BSP_USING_PWM']):
|
||||
src += ['drv_pwm.c', 'drv_tim.c']
|
||||
|
||||
if GetDepend(['RT_USING_SPI']):
|
||||
src += ['drv_spi.c']
|
||||
|
||||
if GetDepend(['RT_USING_QSPI']):
|
||||
src += ['drv_qspi.c']
|
||||
|
||||
if GetDepend('RT_USING_SOFT_SPI'):
|
||||
src += ['drv_soft_spi.c']
|
||||
|
||||
if GetDepend(['RT_USING_I2C', 'RT_USING_I2C_BITOPS']):
|
||||
if GetDepend('BSP_USING_I2C1') or GetDepend('BSP_USING_I2C2') or GetDepend('BSP_USING_I2C3') or GetDepend('BSP_USING_I2C4'):
|
||||
src += ['drv_soft_i2c.c']
|
||||
|
||||
if GetDepend(['RT_USING_I2C']):
|
||||
if GetDepend('BSP_USING_HARD_I2C1') or GetDepend('BSP_USING_HARD_I2C2') or GetDepend('BSP_USING_HARD_I2C3') or GetDepend('BSP_USING_HARD_I2C4'):
|
||||
src += ['drv_hard_i2c.c']
|
||||
|
||||
if GetDepend(['BSP_USING_ETH', 'RT_USING_LWIP']) and not GetDepend(['SOC_STM32H750_ARTPI']):
|
||||
src += ['drv_eth.c']
|
||||
|
||||
if GetDepend(['RT_USING_ADC']):
|
||||
src += ['drv_adc.c']
|
||||
|
||||
if GetDepend(['RT_USING_DAC']):
|
||||
src += ['drv_dac.c']
|
||||
|
||||
if GetDepend(['RT_USING_CAN']):
|
||||
src += ['drv_can.c']
|
||||
|
||||
if GetDepend(['RT_USING_PM']):
|
||||
src += ['drv_pm.c']
|
||||
|
||||
if GetDepend(['BSP_USING_LPTIM']):
|
||||
src += ['drv_lptim.c']
|
||||
|
||||
if GetDepend('BSP_USING_SDRAM'):
|
||||
src += ['drv_sdram.c']
|
||||
|
||||
if GetDepend(['BSP_USING_NAND1']):
|
||||
src += ['drv_nand.c']
|
||||
|
||||
if GetDepend('BSP_USING_LCD'):
|
||||
src += ['drv_lcd.c']
|
||||
|
||||
if GetDepend('BSP_USING_LCD_MIPI'):
|
||||
src += ['drv_lcd_mipi.c']
|
||||
|
||||
if GetDepend('BSP_USING_ONCHIP_RTC'):
|
||||
src += ['drv_rtc.c']
|
||||
|
||||
if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32G0']):
|
||||
src += [os.path.join('drv_flash', 'drv_flash_g0.c')]
|
||||
|
||||
if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32F0']):
|
||||
src += [os.path.join('drv_flash', 'drv_flash_f0.c')]
|
||||
|
||||
if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32F1']):
|
||||
src += [os.path.join('drv_flash', 'drv_flash_f1.c')]
|
||||
|
||||
if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32F2']):
|
||||
src += [os.path.join('drv_flash', 'drv_flash_f2.c')]
|
||||
|
||||
if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32F4']):
|
||||
src += [os.path.join('drv_flash', 'drv_flash_f4.c')]
|
||||
|
||||
if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32F7']):
|
||||
src += [os.path.join('drv_flash', 'drv_flash_f7.c')]
|
||||
|
||||
if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32L1']):
|
||||
src += [os.path.join('drv_flash', 'drv_flash_l1.c')]
|
||||
|
||||
if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32L4']):
|
||||
src += [os.path.join('drv_flash', 'drv_flash_l4.c')]
|
||||
|
||||
if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32H7']):
|
||||
src += [os.path.join('drv_flash', 'drv_flash_h7.c')]
|
||||
|
||||
if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32WB']):
|
||||
src += [os.path.join('drv_flash', 'drv_flash_wb.c')]
|
||||
|
||||
if GetDepend('RT_USING_HWCRYPTO'):
|
||||
src += ['drv_crypto.c']
|
||||
|
||||
if GetDepend(['BSP_USING_WDT']):
|
||||
src += ['drv_wdt.c']
|
||||
|
||||
if GetDepend(['BSP_USING_SDIO']):
|
||||
if GetDepend('SOC_SERIES_STM32H7RS') or GetDepend('SOC_SERIES_STM32H7') or GetDepend('SOC_SERIES_STM32F7') or GetDepend('SOC_SERIES_STM32L4') or GetDepend('SOC_SERIES_STM32L5'):
|
||||
src += ['drv_sdmmc.c']
|
||||
else:
|
||||
src += ['drv_sdio.c']
|
||||
|
||||
if GetDepend(['BSP_USING_USBD']):
|
||||
src += ['drv_usbd.c']
|
||||
|
||||
if GetDepend(['BSP_USING_PULSE_ENCODER']):
|
||||
src += ['drv_pulse_encoder.c']
|
||||
|
||||
if GetDepend(['BSP_USING_USBH']):
|
||||
src += ['drv_usbh.c']
|
||||
|
||||
path += [os.path.join(cwd, 'config')]
|
||||
|
||||
if GetDepend('BSP_USING_ON_CHIP_FLASH'):
|
||||
path += [os.path.join(cwd, 'drv_flash')]
|
||||
|
||||
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)
|
||||
|
||||
Return('group')
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-12-07 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.DataAlign = ADC_DATAALIGN_RIGHT, \
|
||||
.Init.ScanConvMode = ADC_SCAN_DISABLE, \
|
||||
.Init.ContinuousConvMode = DISABLE, \
|
||||
.Init.NbrOfConversion = 1, \
|
||||
.Init.DiscontinuousConvMode = DISABLE, \
|
||||
.Init.NbrOfDiscConversion = 1, \
|
||||
.Init.ExternalTrigConv = ADC_SOFTWARE_START, \
|
||||
}
|
||||
#endif /* ADC1_CONFIG */
|
||||
#endif /* BSP_USING_ADC1 */
|
||||
|
||||
#ifdef BSP_USING_ADC2
|
||||
#ifndef ADC2_CONFIG
|
||||
#define ADC2_CONFIG \
|
||||
{ \
|
||||
.Instance = ADC2, \
|
||||
.Init.DataAlign = ADC_DATAALIGN_RIGHT, \
|
||||
.Init.ScanConvMode = ADC_SCAN_DISABLE, \
|
||||
.Init.ContinuousConvMode = DISABLE, \
|
||||
.Init.NbrOfConversion = 1, \
|
||||
.Init.DiscontinuousConvMode = DISABLE, \
|
||||
.Init.NbrOfDiscConversion = 1, \
|
||||
.Init.ExternalTrigConv = ADC_SOFTWARE_START, \
|
||||
}
|
||||
#endif /* ADC2_CONFIG */
|
||||
#endif /* BSP_USING_ADC2 */
|
||||
|
||||
#ifdef BSP_USING_ADC3
|
||||
#ifndef ADC3_CONFIG
|
||||
#define ADC3_CONFIG \
|
||||
{ \
|
||||
.Instance = ADC3, \
|
||||
.Init.DataAlign = ADC_DATAALIGN_RIGHT, \
|
||||
.Init.ScanConvMode = ADC_SCAN_DISABLE, \
|
||||
.Init.ContinuousConvMode = DISABLE, \
|
||||
.Init.NbrOfConversion = 1, \
|
||||
.Init.DiscontinuousConvMode = DISABLE, \
|
||||
.Init.NbrOfDiscConversion = 1, \
|
||||
.Init.ExternalTrigConv = ADC_SOFTWARE_START, \
|
||||
}
|
||||
#endif /* ADC3_CONFIG */
|
||||
#endif /* BSP_USING_ADC3 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ADC_CONFIG_H__ */
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-01-02 SummerGift 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 channel1 */
|
||||
#if defined(BSP_ADC1_USING_DMA) && !defined(ADC1_DMA_INSTANCE)
|
||||
#define ADC1_DMA_IRQHandler DMA1_Channel1_IRQHandler
|
||||
#define ADC1_DMA_RCC RCC_AHBENR_DMA1EN
|
||||
#define ADC1_DMA_INSTANCE DMA1_Channel1
|
||||
#define ADC1_DMA_IRQ DMA1_Channel1_IRQn
|
||||
#endif
|
||||
|
||||
/* DMA1 channel2 */
|
||||
#if defined(BSP_SPI1_RX_USING_DMA) && !defined(SPI1_RX_DMA_INSTANCE)
|
||||
#define SPI1_DMA_RX_IRQHandler DMA1_Channel2_IRQHandler
|
||||
#define SPI1_RX_DMA_RCC RCC_AHBENR_DMA1EN
|
||||
#define SPI1_RX_DMA_INSTANCE DMA1_Channel2
|
||||
#define SPI1_RX_DMA_IRQ DMA1_Channel2_IRQn
|
||||
#elif defined(BSP_UART3_TX_USING_DMA) && !defined(UART3_TX_DMA_INSTANCE)
|
||||
#define UART3_DMA_TX_IRQHandler DMA1_Channel2_IRQHandler
|
||||
#define UART3_TX_DMA_RCC RCC_AHBENR_DMA1EN
|
||||
#define UART3_TX_DMA_INSTANCE DMA1_Channel2
|
||||
#define UART3_TX_DMA_IRQ DMA1_Channel2_IRQn
|
||||
#endif
|
||||
|
||||
/* DMA1 channel3 */
|
||||
#if defined(BSP_SPI1_TX_USING_DMA) && !defined(SPI1_TX_DMA_INSTANCE)
|
||||
#define SPI1_DMA_TX_IRQHandler DMA1_Channel3_IRQHandler
|
||||
#define SPI1_TX_DMA_RCC RCC_AHBENR_DMA1EN
|
||||
#define SPI1_TX_DMA_INSTANCE DMA1_Channel3
|
||||
#define SPI1_TX_DMA_IRQ DMA1_Channel3_IRQn
|
||||
#elif defined(BSP_UART3_RX_USING_DMA) && !defined(UART3_RX_DMA_INSTANCE)
|
||||
#define UART3_DMA_RX_IRQHandler DMA1_Channel3_IRQHandler
|
||||
#define UART3_RX_DMA_RCC RCC_AHBENR_DMA1EN
|
||||
#define UART3_RX_DMA_INSTANCE DMA1_Channel3
|
||||
#define UART3_RX_DMA_IRQ DMA1_Channel3_IRQn
|
||||
#endif
|
||||
|
||||
/* DMA1 channel4 */
|
||||
#if defined(BSP_SPI2_RX_USING_DMA) && !defined(SPI2_RX_DMA_INSTANCE)
|
||||
#define SPI2_DMA_RX_IRQHandler DMA1_Channel4_IRQHandler
|
||||
#define SPI2_RX_DMA_RCC RCC_AHBENR_DMA1EN
|
||||
#define SPI2_RX_DMA_INSTANCE DMA1_Channel4
|
||||
#define SPI2_RX_DMA_IRQ DMA1_Channel4_IRQn
|
||||
#elif defined(BSP_UART1_TX_USING_DMA) && !defined(UART1_TX_DMA_INSTANCE)
|
||||
#define UART1_DMA_TX_IRQHandler DMA1_Channel4_IRQHandler
|
||||
#define UART1_TX_DMA_RCC RCC_AHBENR_DMA1EN
|
||||
#define UART1_TX_DMA_INSTANCE DMA1_Channel4
|
||||
#define UART1_TX_DMA_IRQ DMA1_Channel4_IRQn
|
||||
#elif defined(BSP_I2C2_TX_USING_DMA) && !defined(I2C2_TX_DMA_INSTANCE)
|
||||
#define I2C2_DMA_TX_IRQHandler DMA1_Channel4_IRQHandler
|
||||
#define I2C2_TX_DMA_RCC RCC_AHBENR_DMA1EN
|
||||
#define I2C2_TX_DMA_INSTANCE DMA1_Channel4
|
||||
#define I2C2_TX_DMA_IRQ DMA1_Channel4_IRQn
|
||||
#endif
|
||||
|
||||
/* DMA1 channel5 */
|
||||
#if defined(BSP_SPI2_TX_USING_DMA) && !defined(SPI2_TX_DMA_INSTANCE)
|
||||
#define SPI2_DMA_TX_IRQHandler DMA1_Channel5_IRQHandler
|
||||
#define SPI2_TX_DMA_RCC RCC_AHBENR_DMA1EN
|
||||
#define SPI2_TX_DMA_INSTANCE DMA1_Channel5
|
||||
#define SPI2_TX_DMA_IRQ DMA1_Channel5_IRQn
|
||||
#elif defined(BSP_UART1_RX_USING_DMA) && !defined(UART1_RX_DMA_INSTANCE)
|
||||
#define UART1_DMA_RX_IRQHandler DMA1_Channel5_IRQHandler
|
||||
#define UART1_RX_DMA_RCC RCC_AHBENR_DMA1EN
|
||||
#define UART1_RX_DMA_INSTANCE DMA1_Channel5
|
||||
#define UART1_RX_DMA_IRQ DMA1_Channel5_IRQn
|
||||
#elif defined(BSP_I2C2_RX_USING_DMA) && !defined(I2C2_RX_DMA_INSTANCE)
|
||||
#define I2C2_DMA_RX_IRQHandler DMA1_Channel5_IRQHandler
|
||||
#define I2C2_RX_DMA_RCC RCC_AHBENR_DMA1EN
|
||||
#define I2C2_RX_DMA_INSTANCE DMA1_Channel5
|
||||
#define I2C2_RX_DMA_IRQ DMA1_Channel5_IRQn
|
||||
#endif
|
||||
|
||||
/* DMA1 channel6 */
|
||||
#if defined(BSP_UART2_RX_USING_DMA) && !defined(UART2_RX_DMA_INSTANCE)
|
||||
#define UART2_DMA_RX_IRQHandler DMA1_Channel6_IRQHandler
|
||||
#define UART2_RX_DMA_RCC RCC_AHBENR_DMA1EN
|
||||
#define UART2_RX_DMA_INSTANCE DMA1_Channel6
|
||||
#define UART2_RX_DMA_IRQ DMA1_Channel6_IRQn
|
||||
#elif defined(BSP_I2C1_TX_USING_DMA) && !defined(I2C1_TX_DMA_INSTANCE)
|
||||
#define I2C1_DMA_TX_IRQHandler DMA1_Channel6_IRQHandler
|
||||
#define I2C1_TX_DMA_RCC RCC_AHBENR_DMA1EN
|
||||
#define I2C1_TX_DMA_INSTANCE DMA1_Channel6
|
||||
#define I2C1_TX_DMA_IRQ DMA1_Channel6_IRQn
|
||||
#endif
|
||||
|
||||
/* DMA1 channel7 */
|
||||
#if defined(BSP_UART2_TX_USING_DMA) && !defined(UART2_TX_DMA_INSTANCE)
|
||||
#define UART2_DMA_TX_IRQHandler DMA1_Channel7_IRQHandler
|
||||
#define UART2_TX_DMA_RCC RCC_AHBENR_DMA1EN
|
||||
#define UART2_TX_DMA_INSTANCE DMA1_Channel7
|
||||
#define UART2_TX_DMA_IRQ DMA1_Channel7_IRQn
|
||||
#elif defined(BSP_I2C1_RX_USING_DMA) && !defined(I2C1_RX_DMA_INSTANCE)
|
||||
#define I2C1_DMA_RX_IRQHandler DMA1_Channel7_IRQHandler
|
||||
#define I2C1_RX_DMA_RCC RCC_AHBENR_DMA1EN
|
||||
#define I2C1_RX_DMA_INSTANCE DMA1_Channel7
|
||||
#define I2C1_RX_DMA_IRQ DMA1_Channel7_IRQn
|
||||
#endif
|
||||
|
||||
/* DMA2 channel1 */
|
||||
#if defined(BSP_SPI3_RX_USING_DMA) && !defined(SPI3_RX_DMA_INSTANCE)
|
||||
#define SPI3_DMA_RX_IRQHandler DMA2_Channel1_IRQHandler
|
||||
#define SPI3_RX_DMA_RCC RCC_AHBENR_DMA2EN
|
||||
#define SPI3_RX_DMA_INSTANCE DMA2_Channel1
|
||||
#define SPI3_RX_DMA_IRQ DMA2_Channel1_IRQn
|
||||
#endif
|
||||
|
||||
/* DMA2 channel2 */
|
||||
#if defined(BSP_SPI3_TX_USING_DMA) && !defined(SPI3_TX_DMA_INSTANCE)
|
||||
#define SPI3_DMA_TX_IRQHandler DMA2_Channel2_IRQHandler
|
||||
#define SPI3_TX_DMA_RCC RCC_AHBENR_DMA2EN
|
||||
#define SPI3_TX_DMA_INSTANCE DMA2_Channel2
|
||||
#define SPI3_TX_DMA_IRQ DMA2_Channel2_IRQn
|
||||
#endif
|
||||
|
||||
/* DMA2 channel3 */
|
||||
#if defined(BSP_UART4_RX_USING_DMA) && !defined(UART4_RX_DMA_INSTANCE)
|
||||
#define UART4_DMA_RX_IRQHandler DMA2_Channel3_IRQHandler
|
||||
#define UART4_RX_DMA_RCC RCC_AHBENR_DMA2EN
|
||||
#define UART4_RX_DMA_INSTANCE DMA2_Channel3
|
||||
#define UART4_RX_DMA_IRQ DMA2_Channel3_IRQn
|
||||
#endif
|
||||
|
||||
/* DMA2 channel4 */
|
||||
#if defined(BSP_SDIO_TX_USING_DMA) && !defined(SDIO_TX_DMA_INSTANCE)
|
||||
#define SDIO_DMA_TX_IRQHandler DMA2_Channel4_5_IRQHandler
|
||||
#define SDIO_TX_DMA_RCC RCC_AHBENR_DMA2EN
|
||||
#define SDIO_TX_DMA_INSTANCE DMA2_Channel4
|
||||
#define SDIO_TX_DMA_IRQ DMA2_Channel4_5_IRQn
|
||||
#elif defined(BSP_SDIO_RX_USING_DMA) && !defined(SDIO_RX_DMA_INSTANCE)
|
||||
#define SDIO_DMA_RX_IRQHandler DMA2_Channel4_5_IRQHandler
|
||||
#define SDIO_RX_DMA_RCC RCC_AHBENR_DMA2EN
|
||||
#define SDIO_RX_DMA_INSTANCE DMA2_Channel4
|
||||
#define SDIO_RX_DMA_IRQ DMA2_Channel4_5_IRQn
|
||||
#endif
|
||||
|
||||
/* DMA2 channel5 */
|
||||
#if defined(BSP_ADC3_USING_DMA) && !defined(ADC3_DMA_INSTANCE)
|
||||
#define ADC3_DMA_IRQHandler DMA2_Channel4_5_IRQHandler
|
||||
#define ADC3_DMA_RCC RCC_AHBENR_DMA2EN
|
||||
#define ADC3_DMA_INSTANCE DMA2_Channel5
|
||||
#define ADC3_DMA_IRQ DMA2_Channel4_5_IRQn
|
||||
#elif defined(BSP_UART4_TX_USING_DMA) && !defined(UART4_TX_DMA_INSTANCE)
|
||||
#define UART4_DMA_TX_IRQHandler DMA2_Channel4_5_IRQHandler
|
||||
#define UART4_TX_DMA_RCC RCC_AHBENR_DMA2EN
|
||||
#define UART4_TX_DMA_INSTANCE DMA2_Channel5
|
||||
#define UART4_TX_DMA_IRQ DMA2_Channel4_5_IRQn
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __DMA_CONFIG_H__ */
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2024-02-06 Dyyt587 first version
|
||||
* 2024-04-23 Zeidan Add I2Cx_xx_DMA_CONFIG
|
||||
*/
|
||||
#ifndef __I2C_HARD_CONFIG_H__
|
||||
#define __I2C_HARD_CONFIG_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_HARD_I2C1
|
||||
#ifndef I2C1_BUS_CONFIG
|
||||
#define I2C1_BUS_CONFIG \
|
||||
{ \
|
||||
.Instance = I2C1, \
|
||||
.timeout=0x1000, \
|
||||
.name = "hwi2c1", \
|
||||
.evirq_type = I2C1_EV_IRQn, \
|
||||
.erirq_type = I2C1_ER_IRQn, \
|
||||
}
|
||||
#endif /* I2C1_BUS_CONFIG */
|
||||
#endif /* BSP_USING_HARD_I2C1 */
|
||||
|
||||
#ifdef BSP_I2C1_TX_USING_DMA
|
||||
#ifndef I2C1_TX_DMA_CONFIG
|
||||
#define I2C1_TX_DMA_CONFIG \
|
||||
{ \
|
||||
.dma_rcc = I2C1_TX_DMA_RCC, \
|
||||
.Instance = I2C1_TX_DMA_INSTANCE, \
|
||||
.dma_irq = I2C1_TX_DMA_IRQ, \
|
||||
}
|
||||
#endif /* I2C1_TX_DMA_CONFIG */
|
||||
#endif /* BSP_I2C1_TX_USING_DMA */
|
||||
|
||||
#ifdef BSP_I2C1_RX_USING_DMA
|
||||
#ifndef I2C1_RX_DMA_CONFIG
|
||||
#define I2C1_RX_DMA_CONFIG \
|
||||
{ \
|
||||
.dma_rcc = I2C1_RX_DMA_RCC, \
|
||||
.Instance = I2C1_RX_DMA_INSTANCE, \
|
||||
.dma_irq = I2C1_RX_DMA_IRQ, \
|
||||
}
|
||||
#endif /* I2C1_RX_DMA_CONFIG */
|
||||
#endif /* BSP_I2C1_RX_USING_DMA */
|
||||
|
||||
#ifdef BSP_USING_HARD_I2C2
|
||||
#ifndef I2C2_BUS_CONFIG
|
||||
#define I2C2_BUS_CONFIG \
|
||||
{ \
|
||||
.Instance = I2C2, \
|
||||
.timeout=0x1000, \
|
||||
.name = "hwi2c2", \
|
||||
.evirq_type = I2C2_EV_IRQn, \
|
||||
.erirq_type = I2C2_ER_IRQn, \
|
||||
}
|
||||
#endif /* I2C2_BUS_CONFIG */
|
||||
#endif /* BSP_USING_HARD_I2C2 */
|
||||
|
||||
#ifdef BSP_I2C2_TX_USING_DMA
|
||||
#ifndef I2C2_TX_DMA_CONFIG
|
||||
#define I2C2_TX_DMA_CONFIG \
|
||||
{ \
|
||||
.dma_rcc = I2C2_TX_DMA_RCC, \
|
||||
.Instance = I2C2_TX_DMA_INSTANCE, \
|
||||
.dma_irq = I2C2_TX_DMA_IRQ, \
|
||||
}
|
||||
#endif /* I2C2_TX_DMA_CONFIG */
|
||||
#endif /* BSP_I2C2_TX_USING_DMA */
|
||||
|
||||
#ifdef BSP_I2C2_RX_USING_DMA
|
||||
#ifndef I2C2_RX_DMA_CONFIG
|
||||
#define I2C2_RX_DMA_CONFIG \
|
||||
{ \
|
||||
.dma_rcc = I2C2_RX_DMA_RCC, \
|
||||
.Instance = I2C2_RX_DMA_INSTANCE, \
|
||||
.dma_irq = I2C2_RX_DMA_IRQ, \
|
||||
}
|
||||
#endif /* I2C2_RX_DMA_CONFIG */
|
||||
#endif /* BSP_I2C2_RX_USING_DMA */
|
||||
|
||||
#ifdef BSP_USING_HARD_I2C3
|
||||
#ifndef I2C3_BUS_CONFIG
|
||||
#define I2C3_BUS_CONFIG \
|
||||
{ \
|
||||
.Instance = I2C3, \
|
||||
.timeout=0x1000, \
|
||||
.name = "hwi2c3", \
|
||||
.evirq_type = I2C3_EV_IRQn, \
|
||||
.erirq_type = I2C3_ER_IRQn, \
|
||||
}
|
||||
#endif /* I2C3_BUS_CONFIG */
|
||||
#endif /* BSP_USING_HARD_I2C3 */
|
||||
|
||||
#ifdef BSP_I2C3_TX_USING_DMA
|
||||
#ifndef I2C3_TX_DMA_CONFIG
|
||||
#define I2C3_TX_DMA_CONFIG \
|
||||
{ \
|
||||
.dma_rcc = I2C3_TX_DMA_RCC, \
|
||||
.Instance = I2C3_TX_DMA_INSTANCE, \
|
||||
.dma_irq = I2C3_TX_DMA_IRQ, \
|
||||
}
|
||||
#endif /* I2C3_TX_DMA_CONFIG */
|
||||
#endif /* BSP_I2C3_TX_USING_DMA */
|
||||
|
||||
#ifdef BSP_I2C3_RX_USING_DMA
|
||||
#ifndef I2C3_RX_DMA_CONFIG
|
||||
#define I2C3_RX_DMA_CONFIG \
|
||||
{ \
|
||||
.dma_rcc = I2C3_RX_DMA_RCC, \
|
||||
.Instance = I2C3_RX_DMA_INSTANCE, \
|
||||
.dma_irq = I2C3_RX_DMA_IRQ, \
|
||||
}
|
||||
#endif /* I2C3_RX_DMA_CONFIG */
|
||||
#endif /* BSP_I2C3_RX_USING_DMA */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__I2C_HARD_CONFIG_H__ */
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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_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__ */
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-12-13 zylx first version
|
||||
* 2023-04-08 Wangyuqiang complete PWM defination
|
||||
*/
|
||||
|
||||
#ifndef __PWM_CONFIG_H__
|
||||
#define __PWM_CONFIG_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_PWM1
|
||||
#define PWM1_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM1, \
|
||||
.name = "pwm1", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM1 */
|
||||
|
||||
#ifdef BSP_USING_PWM2
|
||||
#define PWM2_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM2, \
|
||||
.name = "pwm2", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM2 */
|
||||
|
||||
#ifdef BSP_USING_PWM3
|
||||
#define PWM3_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM3, \
|
||||
.name = "pwm3", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM3 */
|
||||
|
||||
#ifdef BSP_USING_PWM4
|
||||
#define PWM4_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM4, \
|
||||
.name = "pwm4", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM4 */
|
||||
|
||||
#ifdef BSP_USING_PWM5
|
||||
#define PWM5_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM5, \
|
||||
.name = "pwm5", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM5 */
|
||||
|
||||
#ifdef BSP_USING_PWM6
|
||||
#define PWM6_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM6, \
|
||||
.name = "pwm6", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM6 */
|
||||
|
||||
#ifdef BSP_USING_PWM7
|
||||
#define PWM7_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM7, \
|
||||
.name = "pwm7", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM7 */
|
||||
|
||||
#ifdef BSP_USING_PWM8
|
||||
#define PWM8_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM8, \
|
||||
.name = "pwm8", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM8 */
|
||||
|
||||
#ifdef BSP_USING_PWM9
|
||||
#define PWM9_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM9, \
|
||||
.name = "pwm9", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM9 */
|
||||
|
||||
#ifdef BSP_USING_PWM10
|
||||
#define PWM10_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM10, \
|
||||
.name = "pwm10", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM10 */
|
||||
|
||||
#ifdef BSP_USING_PWM11
|
||||
#define PWM11_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM11, \
|
||||
.name = "pwm11", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM11 */
|
||||
|
||||
#ifdef BSP_USING_PWM12
|
||||
#define PWM12_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM12, \
|
||||
.name = "pwm12", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM12 */
|
||||
|
||||
#ifdef BSP_USING_PWM13
|
||||
#define PWM13_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM13, \
|
||||
.name = "pwm13", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM13 */
|
||||
|
||||
#ifdef BSP_USING_PWM14
|
||||
#define PWM14_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM14, \
|
||||
.name = "pwm14", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM14 */
|
||||
|
||||
#ifdef BSP_USING_PWM15
|
||||
#define PWM15_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM15, \
|
||||
.name = "pwm15", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM15 */
|
||||
|
||||
#ifdef BSP_USING_PWM16
|
||||
#define PWM16_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM16, \
|
||||
.name = "pwm16", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM16 */
|
||||
|
||||
#ifdef BSP_USING_PWM17
|
||||
#define PWM17_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM17, \
|
||||
.name = "pwm17", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM17 */
|
||||
|
||||
#ifdef BSP_USING_PWM18
|
||||
#define PWM18_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM18, \
|
||||
.name = "pwm18", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM18 */
|
||||
|
||||
#ifdef BSP_USING_PWM19
|
||||
#define PWM19_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM19, \
|
||||
.name = "pwm19", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM19 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __PWM_CONFIG_H__ */
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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 "stm32f1xx_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_SDIO
|
||||
#define SDIO_BUS_CONFIG \
|
||||
{ \
|
||||
.Instance = SDIO, \
|
||||
.dma_rx.dma_rcc = RCC_AHBENR_DMA2EN, \
|
||||
.dma_tx.dma_rcc = RCC_AHBENR_DMA2EN, \
|
||||
.dma_rx.Instance = DMA2_Channel4, \
|
||||
.dma_rx.dma_irq = DMA2_Channel4_IRQn, \
|
||||
.dma_tx.Instance = DMA2_Channel4, \
|
||||
.dma_tx.dma_irq = DMA2_Channel4_IRQn, \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__SDIO_CONFIG_H__ */
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-11-06 SummerGift first version
|
||||
* 2019-01-05 SummerGift 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, \
|
||||
.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, \
|
||||
.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, \
|
||||
.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, \
|
||||
.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, \
|
||||
.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, \
|
||||
.dma_irq = SPI3_RX_DMA_IRQ, \
|
||||
}
|
||||
#endif /* SPI3_RX_DMA_CONFIG */
|
||||
#endif /* BSP_SPI3_RX_USING_DMA */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__SPI_CONFIG_H__ */
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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 = 2000, \
|
||||
.maxcnt = 0xFFFF, \
|
||||
.cntmode = HWTIMER_CNTMODE_UP, \
|
||||
}
|
||||
#endif /* TIM_DEV_INFO_CONFIG */
|
||||
|
||||
#ifdef BSP_USING_TIM2
|
||||
#ifndef TIM2_CONFIG
|
||||
#define TIM2_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM2, \
|
||||
.tim_irqn = TIM2_IRQn, \
|
||||
.name = "timer2", \
|
||||
}
|
||||
#endif /* TIM2_CONFIG */
|
||||
#endif /* BSP_USING_TIM2 */
|
||||
|
||||
#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_TIM4
|
||||
#ifndef TIM4_CONFIG
|
||||
#define TIM4_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM4, \
|
||||
.tim_irqn = TIM4_IRQn, \
|
||||
.name = "timer4", \
|
||||
}
|
||||
#endif /* TIM4_CONFIG */
|
||||
#endif /* BSP_USING_TIM4 */
|
||||
|
||||
#ifdef BSP_USING_TIM5
|
||||
#ifndef TIM5_CONFIG
|
||||
#define TIM5_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM5, \
|
||||
.tim_irqn = TIM5_IRQn, \
|
||||
.name = "timer5", \
|
||||
}
|
||||
#endif /* TIM5_CONFIG */
|
||||
#endif /* BSP_USING_TIM5 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __TIM_CONFIG_H__ */
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-10-30 BalanceTWK first version
|
||||
* 2019-01-05 SummerGift modify DMA support
|
||||
*/
|
||||
|
||||
#ifndef __UART_CONFIG_H__
|
||||
#define __UART_CONFIG_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
#include "dma_config.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, \
|
||||
}
|
||||
#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, \
|
||||
.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, \
|
||||
.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, \
|
||||
}
|
||||
#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, \
|
||||
.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, \
|
||||
.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, \
|
||||
}
|
||||
#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, \
|
||||
.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, \
|
||||
.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, \
|
||||
}
|
||||
#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, \
|
||||
.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, \
|
||||
.dma_rcc = UART4_TX_DMA_RCC, \
|
||||
.dma_irq = UART4_TX_DMA_IRQ, \
|
||||
}
|
||||
#endif /* UART4_DMA_TX_CONFIG */
|
||||
#endif /* BSP_UART4_TX_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, \
|
||||
}
|
||||
#endif /* UART5_CONFIG */
|
||||
#endif /* BSP_USING_UART5 */
|
||||
|
||||
#if defined(BSP_UART5_RX_USING_DMA)
|
||||
#ifndef UART5_DMA_RX_CONFIG
|
||||
#define UART5_DMA_RX_CONFIG \
|
||||
{ \
|
||||
.Instance = DMA_NOT_AVAILABLE, \
|
||||
}
|
||||
#endif /* UART5_DMA_RX_CONFIG */
|
||||
#endif /* BSP_UART5_RX_USING_DMA */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-04-10 ZYH first version
|
||||
* 2019-07-29 Chinese66 change from f4 to f1
|
||||
*/
|
||||
#ifndef __USBD_CONFIG_H__
|
||||
#define __USBD_CONFIG_H__
|
||||
|
||||
#define USBD_IRQ_TYPE USB_LP_CAN1_RX0_IRQn
|
||||
#define USBD_IRQ_HANDLER USB_LP_CAN1_RX0_IRQHandler
|
||||
#define USBD_INSTANCE USB
|
||||
#define USBD_PCD_SPEED PCD_SPEED_FULL
|
||||
#define USBD_PCD_PHY_MODULE PCD_PHY_EMBEDDED
|
||||
|
||||
#ifndef BSP_USB_CONNECT_PIN
|
||||
#define BSP_USB_CONNECT_PIN -1
|
||||
#endif
|
||||
|
||||
#ifndef BSP_USB_PULL_UP_STATUS
|
||||
#define BSP_USB_PULL_UP_STATUS 1
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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__ */
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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__ */
|
||||
@@ -0,0 +1,464 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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_I2C1_RX_USING_DMA) && !defined(I2C1_RX_DMA_INSTANCE)
|
||||
#define I2C1_DMA_RX_IRQHandler DMA1_Stream0_IRQHandler
|
||||
#define I2C1_RX_DMA_RCC RCC_AHB1ENR_DMA1EN
|
||||
#define I2C1_RX_DMA_INSTANCE DMA1_Stream0
|
||||
#define I2C1_RX_DMA_CHANNEL DMA_CHANNEL_1
|
||||
#define I2C1_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_TX_USING_DMA) && !defined(UART7_TX_DMA_INSTANCE)
|
||||
#define UART7_DMA_TX_IRQHandler DMA1_Stream1_IRQHandler
|
||||
#define UART7_TX_DMA_RCC RCC_AHB1ENR_DMA1EN
|
||||
#define UART7_TX_DMA_INSTANCE DMA1_Stream1
|
||||
#define UART7_TX_DMA_CHANNEL DMA_CHANNEL_5
|
||||
#define UART7_TX_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_I2C3_RX_USING_DMA) && !defined(I2C3_RX_DMA_INSTANCE)
|
||||
#define I2C3_DMA_RX_IRQHandler DMA1_Stream2_IRQHandler
|
||||
#define I2C3_RX_DMA_RCC RCC_AHB1ENR_DMA1EN
|
||||
#define I2C3_RX_DMA_INSTANCE DMA1_Stream2
|
||||
#define I2C3_RX_DMA_CHANNEL DMA_CHANNEL_3
|
||||
#define I2C3_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
|
||||
#elif defined(BSP_I2C2_RX_USING_DMA) && !defined(I2C2_RX_DMA_INSTANCE)
|
||||
#define I2C2_DMA_RX_IRQHandler DMA1_Stream2_IRQHandler
|
||||
#define I2C2_RX_DMA_RCC RCC_AHB1ENR_DMA1EN
|
||||
#define I2C2_RX_DMA_INSTANCE DMA1_Stream2
|
||||
#define I2C2_RX_DMA_CHANNEL DMA_CHANNEL_7
|
||||
#define I2C2_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_RX_USING_DMA) && !defined(UART7_RX_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
|
||||
#elif defined(BSP_I2C2_RX_USING_DMA) && !defined(I2C2_RX_DMA_INSTANCE)
|
||||
#define I2C2_DMA_RX_IRQHandler DMA1_Stream3_IRQHandler
|
||||
#define I2C2_RX_DMA_RCC RCC_AHB1ENR_DMA1EN
|
||||
#define I2C2_RX_DMA_INSTANCE DMA1_Stream3
|
||||
#define I2C2_RX_DMA_CHANNEL DMA_CHANNEL_7
|
||||
#define I2C2_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_I2C3_TX_USING_DMA) && !defined(I2C3_TX_DMA_INSTANCE)
|
||||
#define I2C3_DMA_TX_IRQHandler DMA1_Stream4_IRQHandler
|
||||
#define I2C3_TX_DMA_RCC RCC_AHB1ENR_DMA1EN
|
||||
#define I2C3_TX_DMA_INSTANCE DMA1_Stream4
|
||||
#define I2C3_TX_DMA_CHANNEL DMA_CHANNEL_3
|
||||
#define I2C3_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
|
||||
#elif defined(BSP_UART3_TX_USING_DMA) && !defined(UART3_TX_DMA_INSTANCE)
|
||||
#define UART3_DMA_TX_IRQHandler DMA1_Stream4_IRQHandler
|
||||
#define UART3_TX_DMA_RCC RCC_AHB1ENR_DMA1EN
|
||||
#define UART3_TX_DMA_INSTANCE DMA1_Stream4
|
||||
#define UART3_TX_DMA_CHANNEL DMA_CHANNEL_7
|
||||
#define UART3_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_I2C1_RX_USING_DMA) && !defined(I2C1_RX_DMA_INSTANCE)
|
||||
#define I2C1_DMA_RX_IRQHandler DMA1_Stream5_IRQHandler
|
||||
#define I2C1_RX_DMA_RCC RCC_AHB1ENR_DMA1EN
|
||||
#define I2C1_RX_DMA_INSTANCE DMA1_Stream5
|
||||
#define I2C1_RX_DMA_CHANNEL DMA_CHANNEL_1
|
||||
#define I2C1_RX_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_I2C1_TX_USING_DMA) && !defined(I2C1_TX_DMA_INSTANCE)
|
||||
#define I2C1_DMA_TX_IRQHandler DMA1_Stream6_IRQHandler
|
||||
#define I2C1_TX_DMA_RCC RCC_AHB1ENR_DMA1EN
|
||||
#define I2C1_TX_DMA_INSTANCE DMA1_Stream6
|
||||
#define I2C1_TX_DMA_CHANNEL DMA_CHANNEL_1
|
||||
#define I2C1_TX_DMA_IRQ DMA1_Stream6_IRQn
|
||||
#elif 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_I2C1_TX_USING_DMA) && !defined(I2C1_TX_DMA_INSTANCE)
|
||||
#define I2C1_DMA_TX_IRQHandler DMA1_Stream7_IRQHandler
|
||||
#define I2C1_TX_DMA_RCC RCC_AHB1ENR_DMA1EN
|
||||
#define I2C1_TX_DMA_INSTANCE DMA1_Stream7
|
||||
#define I2C1_TX_DMA_CHANNEL DMA_CHANNEL_1
|
||||
#define I2C1_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
|
||||
#elif defined(BSP_I2C2_TX_USING_DMA) && !defined(I2C2_TX_DMA_INSTANCE)
|
||||
#define I2C2_DMA_TX_IRQHandler DMA1_Stream7_IRQHandler
|
||||
#define I2C2_TX_DMA_RCC RCC_AHB1ENR_DMA1EN
|
||||
#define I2C2_TX_DMA_INSTANCE DMA1_Stream7
|
||||
#define I2C2_TX_DMA_CHANNEL DMA_CHANNEL_7
|
||||
#define I2C2_TX_DMA_IRQ DMA1_Stream7_IRQn
|
||||
#endif
|
||||
|
||||
/* DMA2 stream0 */
|
||||
#if defined(BSP_ADC1_USING_DMA) && !defined(ADC1_DMA_INSTANCE)
|
||||
#define ADC1_DMA_IRQHandler DMA2_Stream0_IRQHandler
|
||||
#define ADC1_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define ADC1_DMA_INSTANCE DMA2_Stream0
|
||||
#define ADC1_DMA_CHANNEL DMA_CHANNEL_0
|
||||
#define ADC1_DMA_IRQ DMA2_Stream0_IRQn
|
||||
#elif defined(BSP_ADC3_USING_DMA) && !defined(ADC3_DMA_INSTANCE)
|
||||
#define ADC3_DMA_IRQHandler DMA2_Stream0_IRQHandler
|
||||
#define ADC3_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define ADC3_DMA_INSTANCE DMA2_Stream0
|
||||
#define ADC3_DMA_CHANNEL DMA_CHANNEL_2
|
||||
#define ADC3_DMA_IRQ DMA2_Stream0_IRQn
|
||||
#elif 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
|
||||
#elif defined(BSP_MEMTOMEM0_USING_DMA) && !defined(MEMTOMEM0_DMA_INSTANCE)
|
||||
#define MEMTOMEM0_DMA_IRQHandler DMA2_Stream0_IRQHandler
|
||||
#define MEMTOMEM0_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define MEMTOMEM0_DMA_INSTANCE DMA2_Stream0
|
||||
#define MEMTOMEM0_DMA_CHANNEL DMA_CHANNEL_7
|
||||
#define MEMTOMEM0_DMA_IRQ DMA2_Stream0_IRQn
|
||||
#endif
|
||||
|
||||
/* DMA2 stream1 */
|
||||
#if defined(BSP_ADC3_USING_DMA) && !defined(ADC3_DMA_INSTANCE)
|
||||
#define ADC3_DMA_IRQHandler DMA2_Stream1_IRQHandler
|
||||
#define ADC3_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define ADC3_DMA_INSTANCE DMA2_Stream1
|
||||
#define ADC3_DMA_CHANNEL DMA_CHANNEL_2
|
||||
#define ADC3_DMA_IRQ DMA2_Stream1_IRQn
|
||||
#elif defined(BSP_MEMTOMEM1_USING_DMA) && !defined(MEMTOMEM1_DMA_INSTANCE)
|
||||
#define MEMTOMEM1_DMA_IRQHandler DMA2_Stream1_IRQHandler
|
||||
#define MEMTOMEM1_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define MEMTOMEM1_DMA_INSTANCE DMA2_Stream1
|
||||
#define MEMTOMEM1_DMA_CHANNEL DMA_CHANNEL_3
|
||||
#define MEMTOMEM1_DMA_IRQ DMA2_Stream1_IRQn
|
||||
#elif 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_ADC2_USING_DMA) && !defined(ADC2_DMA_INSTANCE)
|
||||
#define ADC2_DMA_IRQHandler DMA2_Stream2_IRQHandler
|
||||
#define ADC2_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define ADC2_DMA_INSTANCE DMA2_Stream2
|
||||
#define ADC2_DMA_CHANNEL DMA_CHANNEL_1
|
||||
#define ADC2_DMA_IRQ DMA2_Stream2_IRQn
|
||||
#elif defined(BSP_MEMTOMEM2_USING_DMA) && !defined(MEMTOMEM2_DMA_INSTANCE)
|
||||
#define MEMTOMEM2_DMA_IRQHandler DMA2_Stream2_IRQHandler
|
||||
#define MEMTOMEM2_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define MEMTOMEM2_DMA_INSTANCE DMA2_Stream2
|
||||
#define MEMTOMEM2_DMA_CHANNEL DMA_CHANNEL_2
|
||||
#define MEMTOMEM2_DMA_IRQ DMA2_Stream2_IRQn
|
||||
#elif 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
|
||||
#elif defined(BSP_UART6_RX_USING_DMA) && !defined(UART6_RX_DMA_INSTANCE)
|
||||
#define UART6_DMA_RX_IRQHandler DMA2_Stream2_IRQHandler
|
||||
#define UART6_RX_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define UART6_RX_DMA_INSTANCE DMA2_Stream2
|
||||
#define UART6_RX_DMA_CHANNEL DMA_CHANNEL_5
|
||||
#define UART6_RX_DMA_IRQ DMA2_Stream2_IRQn
|
||||
#endif
|
||||
|
||||
/* DMA2 stream3 */
|
||||
#if defined(BSP_MEMTOMEM3_USING_DMA) && !defined(MEMTOMEM3_DMA_INSTANCE)
|
||||
#define MEMTOMEM3_DMA_IRQHandler DMA2_Stream3_IRQHandler
|
||||
#define MEMTOMEM3_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define MEMTOMEM3_DMA_INSTANCE DMA2_Stream3
|
||||
#define MEMTOMEM3_DMA_CHANNEL DMA_CHANNEL_0
|
||||
#define MEMTOMEM3_DMA_IRQ DMA2_Stream3_IRQn
|
||||
#elif defined(BSP_ADC2_USING_DMA) && !defined(ADC2_DMA_INSTANCE)
|
||||
#define ADC2_DMA_IRQHandler DMA2_Stream3_IRQHandler
|
||||
#define ADC2_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define ADC2_DMA_INSTANCE DMA2_Stream3
|
||||
#define ADC2_DMA_CHANNEL DMA_CHANNEL_1
|
||||
#define ADC2_DMA_IRQ DMA2_Stream3_IRQn
|
||||
#elif 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_SDIO_RX_USING_DMA) && !defined(SDIO_RX_DMA_INSTANCE)
|
||||
#define SDIO_DMA_RX_IRQHandler DMA2_Stream3_IRQHandler
|
||||
#define SDIO_RX_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define SDIO_RX_DMA_INSTANCE DMA2_Stream3
|
||||
#define SDIO_RX_DMA_CHANNEL DMA_CHANNEL_4
|
||||
#define SDIO_RX_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_ADC1_USING_DMA) && !defined(ADC1_DMA_INSTANCE)
|
||||
#define ADC1_DMA_IRQHandler DMA2_Stream4_IRQHandler
|
||||
#define ADC1_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define ADC1_DMA_INSTANCE DMA2_Stream4
|
||||
#define ADC1_DMA_CHANNEL DMA_CHANNEL_0
|
||||
#define ADC1_DMA_IRQ DMA2_Stream4_IRQn
|
||||
#elif 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_MEMTOMEM4_USING_DMA) && !defined(MEMTOMEM4_DMA_INSTANCE)
|
||||
#define MEMTOMEM4_DMA_IRQHandler DMA2_Stream4_IRQHandler
|
||||
#define MEMTOMEM4_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define MEMTOMEM4_DMA_INSTANCE DMA2_Stream4
|
||||
#define MEMTOMEM4_DMA_CHANNEL DMA_CHANNEL_4
|
||||
#define MEMTOMEM4_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_SPI6_TX_USING_DMA) && !defined(SPI6_TX_DMA_INSTANCE)
|
||||
#define SPI6_DMA_TX_IRQHandler DMA2_Stream5_IRQHandler
|
||||
#define SPI6_TX_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define SPI6_TX_DMA_INSTANCE DMA2_Stream5
|
||||
#define SPI6_TX_DMA_CHANNEL DMA_CHANNEL_1
|
||||
#define SPI6_TX_DMA_IRQ DMA2_Stream5_IRQn
|
||||
#elif 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_MEMTOMEM5_USING_DMA) && !defined(MEMTOMEM5_DMA_INSTANCE)
|
||||
#define MEMTOMEM5_DMA_IRQHandler DMA2_Stream5_IRQHandler
|
||||
#define MEMTOMEM5_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define MEMTOMEM5_DMA_INSTANCE DMA2_Stream5
|
||||
#define MEMTOMEM5_DMA_CHANNEL DMA_CHANNEL_5
|
||||
#define MEMTOMEM5_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_SPI6_RX_USING_DMA) && !defined(SPI6_RX_DMA_INSTANCE)
|
||||
#define SPI6_DMA_RX_IRQHandler DMA2_Stream6_IRQHandler
|
||||
#define SPI6_RX_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define SPI6_RX_DMA_INSTANCE DMA2_Stream6
|
||||
#define SPI6_RX_DMA_CHANNEL DMA_CHANNEL_1
|
||||
#define SPI6_RX_DMA_IRQ DMA2_Stream6_IRQn
|
||||
#elif defined(BSP_MEMTOMEM6_USING_DMA) && !defined(MEMTOMEM6_DMA_INSTANCE)
|
||||
#define MEMTOMEM6_DMA_IRQHandler DMA2_Stream6_IRQHandler
|
||||
#define MEMTOMEM6_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define MEMTOMEM6_DMA_INSTANCE DMA2_Stream6
|
||||
#define MEMTOMEM6_DMA_CHANNEL DMA_CHANNEL_3
|
||||
#define MEMTOMEM6_DMA_IRQ DMA2_Stream6_IRQn
|
||||
#elif defined(BSP_SDIO_TX_USING_DMA) && !defined(SDIO_TX_DMA_INSTANCE)
|
||||
#define SDIO_DMA_TX_IRQHandler DMA2_Stream6_IRQHandler
|
||||
#define SDIO_TX_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define SDIO_TX_DMA_INSTANCE DMA2_Stream6
|
||||
#define SDIO_TX_DMA_CHANNEL DMA_CHANNEL_4
|
||||
#define SDIO_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
|
||||
#elif 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
|
||||
#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
|
||||
#elif defined(BSP_UART6_TX_USING_DMA) && !defined(UART6_TX_DMA_INSTANCE)
|
||||
#define UART6_DMA_TX_IRQHandler DMA2_Stream7_IRQHandler
|
||||
#define UART6_TX_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define UART6_TX_DMA_INSTANCE DMA2_Stream7
|
||||
#define UART6_TX_DMA_CHANNEL DMA_CHANNEL_5
|
||||
#define UART6_TX_DMA_IRQ DMA2_Stream7_IRQn
|
||||
#elif defined(BSP_MEMTOMEM7_USING_DMA) && !defined(MEMTOMEM7_DMA_INSTANCE)
|
||||
#define MEMTOMEM7_DMA_IRQHandler DMA2_Stream7_IRQHandler
|
||||
#define MEMTOMEM7_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define MEMTOMEM7_DMA_INSTANCE DMA2_Stream7
|
||||
#define MEMTOMEM7_DMA_CHANNEL DMA_CHANNEL_6
|
||||
#define MEMTOMEM7_DMA_IRQ DMA2_Stream7_IRQn
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __DMA_CONFIG_H__ */
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2024-02-06 Dyyt587 first version
|
||||
* 2024-04-23 Zeidan Add I2Cx_xx_DMA_CONFIG
|
||||
*/
|
||||
#ifndef __I2C_HARD_CONFIG_H__
|
||||
#define __I2C_HARD_CONFIG_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_HARD_I2C1
|
||||
#ifndef I2C1_BUS_CONFIG
|
||||
#define I2C1_BUS_CONFIG \
|
||||
{ \
|
||||
.Instance = I2C1, \
|
||||
.timing=0x10707DBC, \
|
||||
.timeout=0x1000, \
|
||||
.name = "hwi2c1", \
|
||||
.evirq_type = I2C1_EV_IRQn, \
|
||||
.erirq_type = I2C1_ER_IRQn, \
|
||||
}
|
||||
#endif /* I2C1_BUS_CONFIG */
|
||||
#endif /* BSP_USING_HARD_I2C1 */
|
||||
|
||||
#ifdef BSP_I2C1_TX_USING_DMA
|
||||
#ifndef I2C1_TX_DMA_CONFIG
|
||||
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
|
||||
#define I2C1_TX_DMA_CONFIG \
|
||||
{ \
|
||||
.dma_rcc = I2C1_TX_DMA_RCC, \
|
||||
.Instance = I2C1_TX_DMA_INSTANCE, \
|
||||
.dma_irq = I2C1_TX_DMA_IRQ, \
|
||||
.channel = I2C1_TX_DMA_CHANNEL \
|
||||
}
|
||||
#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7)
|
||||
#define I2C1_TX_DMA_CONFIG \
|
||||
{ \
|
||||
.dma_rcc = I2C1_TX_DMA_RCC, \
|
||||
.Instance = I2C1_TX_DMA_INSTANCE, \
|
||||
.dma_irq = I2C1_TX_DMA_IRQ, \
|
||||
.request = DMA_REQUEST_I2C1_TX \
|
||||
}
|
||||
#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) */
|
||||
#endif /* I2C1_TX_DMA_CONFIG */
|
||||
#endif /* BSP_I2C1_TX_USING_DMA */
|
||||
|
||||
#ifdef BSP_I2C1_RX_USING_DMA
|
||||
#ifndef I2C1_RX_DMA_CONFIG
|
||||
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
|
||||
#define I2C1_RX_DMA_CONFIG \
|
||||
{ \
|
||||
.dma_rcc = I2C1_RX_DMA_RCC, \
|
||||
.Instance = I2C1_RX_DMA_INSTANCE, \
|
||||
.dma_irq = I2C1_RX_DMA_IRQ, \
|
||||
.channel = I2C1_RX_DMA_CHANNEL, \
|
||||
}
|
||||
#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7)
|
||||
#define I2C1_RX_DMA_CONFIG \
|
||||
{ \
|
||||
.dma_rcc = I2C1_RX_DMA_RCC, \
|
||||
.Instance = I2C1_RX_DMA_INSTANCE, \
|
||||
.dma_irq = I2C1_RX_DMA_IRQ, \
|
||||
.request = DMA_REQUEST_I2C1_RX \
|
||||
}
|
||||
#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) */
|
||||
#endif /* I2C1_RX_DMA_CONFIG */
|
||||
#endif /* BSP_I2C1_RX_USING_DMA */
|
||||
|
||||
#ifdef BSP_USING_HARD_I2C2
|
||||
#ifndef I2C2_BUS_CONFIG
|
||||
#define I2C2_BUS_CONFIG \
|
||||
{ \
|
||||
.Instance = I2C2, \
|
||||
.timing=0x10707DBC, \
|
||||
.timeout=0x1000, \
|
||||
.name = "hwi2c2", \
|
||||
.evirq_type = I2C2_EV_IRQn, \
|
||||
.erirq_type = I2C2_ER_IRQn, \
|
||||
}
|
||||
#endif /* I2C2_BUS_CONFIG */
|
||||
#endif /* BSP_USING_HARD_I2C2 */
|
||||
|
||||
#ifdef BSP_I2C2_TX_USING_DMA
|
||||
#ifndef I2C2_TX_DMA_CONFIG
|
||||
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
|
||||
#define I2C2_TX_DMA_CONFIG \
|
||||
{ \
|
||||
.dma_rcc = I2C2_TX_DMA_RCC, \
|
||||
.Instance = I2C2_TX_DMA_INSTANCE, \
|
||||
.dma_irq = I2C2_TX_DMA_IRQ, \
|
||||
.channel = I2C2_TX_DMA_CHANNEL, \
|
||||
}
|
||||
#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7)
|
||||
#define I2C2_TX_DMA_CONFIG \
|
||||
{ \
|
||||
.dma_rcc = I2C2_TX_DMA_RCC, \
|
||||
.Instance = I2C2_TX_DMA_INSTANCE, \
|
||||
.dma_irq = I2C2_TX_DMA_IRQ, \
|
||||
.request = DMA_REQUEST_I2C2_TX \
|
||||
}
|
||||
#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) */
|
||||
#endif /* I2C2_TX_DMA_CONFIG */
|
||||
#endif /* BSP_I2C2_TX_USING_DMA */
|
||||
|
||||
#ifdef BSP_I2C2_RX_USING_DMA
|
||||
#ifndef I2C2_RX_DMA_CONFIG
|
||||
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
|
||||
#define I2C2_RX_DMA_CONFIG \
|
||||
{ \
|
||||
.dma_rcc = I2C2_RX_DMA_RCC, \
|
||||
.Instance = I2C2_RX_DMA_INSTANCE, \
|
||||
.dma_irq = I2C2_RX_DMA_IRQ, \
|
||||
.channel = I2C2_RX_DMA_CHANNEL, \
|
||||
}
|
||||
#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7)
|
||||
#define I2C2_RX_DMA_CONFIG \
|
||||
{ \
|
||||
.dma_rcc = I2C2_RX_DMA_RCC, \
|
||||
.Instance = I2C2_RX_DMA_INSTANCE, \
|
||||
.dma_irq = I2C2_RX_DMA_IRQ, \
|
||||
.request = DMA_REQUEST_I2C2_RX \
|
||||
}
|
||||
#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) */
|
||||
#endif /* I2C2_RX_DMA_CONFIG */
|
||||
#endif /* BSP_I2C2_RX_USING_DMA */
|
||||
|
||||
#ifdef BSP_USING_HARD_I2C3
|
||||
#ifndef I2C3_BUS_CONFIG
|
||||
#define I2C3_BUS_CONFIG \
|
||||
{ \
|
||||
.Instance = I2C3, \
|
||||
.timing=0x10707DBC, \
|
||||
.timeout=0x1000, \
|
||||
.name = "hwi2c3", \
|
||||
.evirq_type = I2C3_EV_IRQn, \
|
||||
.erirq_type = I2C3_ER_IRQn, \
|
||||
}
|
||||
#endif /* I2C3_BUS_CONFIG */
|
||||
#endif /* BSP_USING_HARD_I2C3 */
|
||||
|
||||
#ifdef BSP_I2C3_TX_USING_DMA
|
||||
#ifndef I2C3_TX_DMA_CONFIG
|
||||
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
|
||||
#define I2C3_TX_DMA_CONFIG \
|
||||
{ \
|
||||
.dma_rcc = I2C3_TX_DMA_RCC, \
|
||||
.Instance = I2C3_TX_DMA_INSTANCE, \
|
||||
.dma_irq = I2C3_TX_DMA_IRQ, \
|
||||
.channel = I2C3_TX_DMA_CHANNEL, \
|
||||
}
|
||||
#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7)
|
||||
#define I2C3_TX_DMA_CONFIG \
|
||||
{ \
|
||||
.dma_rcc = I2C3_TX_DMA_RCC, \
|
||||
.Instance = I2C3_TX_DMA_INSTANCE, \
|
||||
.dma_irq = I2C3_TX_DMA_IRQ, \
|
||||
.request = DMA_REQUEST_I2C3_TX \
|
||||
}
|
||||
#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) */
|
||||
#endif /* I2C3_TX_DMA_CONFIG */
|
||||
#endif /* BSP_I2C3_TX_USING_DMA */
|
||||
|
||||
#ifdef BSP_I2C3_RX_USING_DMA
|
||||
#ifndef I2C3_RX_DMA_CONFIG
|
||||
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
|
||||
#define I2C3_RX_DMA_CONFIG \
|
||||
{ \
|
||||
.dma_rcc = I2C3_RX_DMA_RCC, \
|
||||
.Instance = I2C3_RX_DMA_INSTANCE, \
|
||||
.dma_irq = I2C3_RX_DMA_IRQ, \
|
||||
.channel = I2C3_RX_DMA_CHANNEL, \
|
||||
}
|
||||
#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7)
|
||||
#define I2C3_RX_DMA_CONFIG \
|
||||
{ \
|
||||
.dma_rcc = I2C3_RX_DMA_RCC, \
|
||||
.Instance = I2C3_RX_DMA_INSTANCE, \
|
||||
.dma_irq = I2C3_RX_DMA_IRQ, \
|
||||
.request = DMA_REQUEST_I2C3_RX \
|
||||
}
|
||||
#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) */
|
||||
#endif /* I2C3_RX_DMA_CONFIG */
|
||||
#endif /* BSP_I2C3_RX_USING_DMA */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__I2C_CONFIG_H__ */
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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__ */
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-12-13 zylx first version
|
||||
* 2023-04-08 Wangyuqiang complete PWM defination
|
||||
*/
|
||||
|
||||
#ifndef __PWM_CONFIG_H__
|
||||
#define __PWM_CONFIG_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_PWM1
|
||||
#define PWM1_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM1, \
|
||||
.name = "pwm1", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM1 */
|
||||
|
||||
#ifdef BSP_USING_PWM2
|
||||
#define PWM2_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM2, \
|
||||
.name = "pwm2", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM2 */
|
||||
|
||||
#ifdef BSP_USING_PWM3
|
||||
#define PWM3_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM3, \
|
||||
.name = "pwm3", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM3 */
|
||||
|
||||
#ifdef BSP_USING_PWM4
|
||||
#define PWM4_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM4, \
|
||||
.name = "pwm4", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM4 */
|
||||
|
||||
#ifdef BSP_USING_PWM5
|
||||
#define PWM5_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM5, \
|
||||
.name = "pwm5", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM5 */
|
||||
|
||||
#ifdef BSP_USING_PWM6
|
||||
#define PWM6_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM6, \
|
||||
.name = "pwm6", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM6 */
|
||||
|
||||
#ifdef BSP_USING_PWM7
|
||||
#define PWM7_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM7, \
|
||||
.name = "pwm7", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM7 */
|
||||
|
||||
#ifdef BSP_USING_PWM8
|
||||
#define PWM8_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM8, \
|
||||
.name = "pwm8", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM8 */
|
||||
|
||||
#ifdef BSP_USING_PWM9
|
||||
#define PWM9_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM9, \
|
||||
.name = "pwm9", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM9 */
|
||||
|
||||
#ifdef BSP_USING_PWM10
|
||||
#define PWM10_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM10, \
|
||||
.name = "pwm10", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM10 */
|
||||
|
||||
#ifdef BSP_USING_PWM11
|
||||
#define PWM11_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM11, \
|
||||
.name = "pwm11", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM11 */
|
||||
|
||||
#ifdef BSP_USING_PWM12
|
||||
#define PWM12_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM12, \
|
||||
.name = "pwm12", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM12 */
|
||||
|
||||
#ifdef BSP_USING_PWM13
|
||||
#define PWM13_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM13, \
|
||||
.name = "pwm13", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM13 */
|
||||
|
||||
#ifdef BSP_USING_PWM14
|
||||
#define PWM14_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM14, \
|
||||
.name = "pwm14", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM14 */
|
||||
|
||||
#ifdef BSP_USING_PWM15
|
||||
#define PWM15_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM15, \
|
||||
.name = "pwm15", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM15 */
|
||||
|
||||
#ifdef BSP_USING_PWM16
|
||||
#define PWM16_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM16, \
|
||||
.name = "pwm16", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM16 */
|
||||
|
||||
#ifdef BSP_USING_PWM17
|
||||
#define PWM17_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM17, \
|
||||
.name = "pwm17", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM17 */
|
||||
|
||||
#ifdef BSP_USING_PWM18
|
||||
#define PWM18_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM18, \
|
||||
.name = "pwm18", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM18 */
|
||||
|
||||
#ifdef BSP_USING_PWM19
|
||||
#define PWM19_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM19, \
|
||||
.name = "pwm19", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM19 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __PWM_CONFIG_H__ */
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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__ */
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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__ */
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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__ */
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-12-11 zylx first version
|
||||
* 2023-08-21 Donocean support all timers(except advanced timer)
|
||||
*/
|
||||
|
||||
#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_TIM2
|
||||
#ifndef TIM2_CONFIG
|
||||
#define TIM2_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM2, \
|
||||
.tim_irqn = TIM2_IRQn, \
|
||||
.name = "timer2", \
|
||||
}
|
||||
#endif /* TIM2_CONFIG */
|
||||
#endif /* BSP_USING_TIM2 */
|
||||
|
||||
#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_TIM4
|
||||
#ifndef TIM4_CONFIG
|
||||
#define TIM4_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM4, \
|
||||
.tim_irqn = TIM4_IRQn, \
|
||||
.name = "timer4", \
|
||||
}
|
||||
#endif /* TIM4_CONFIG */
|
||||
#endif /* BSP_USING_TIM4 */
|
||||
|
||||
#ifdef BSP_USING_TIM5
|
||||
#ifndef TIM5_CONFIG
|
||||
#define TIM5_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM5, \
|
||||
.tim_irqn = TIM5_IRQn, \
|
||||
.name = "timer5", \
|
||||
}
|
||||
#endif /* TIM5_CONFIG */
|
||||
#endif /* BSP_USING_TIM5 */
|
||||
|
||||
#ifdef BSP_USING_TIM6
|
||||
#ifndef TIM6_CONFIG
|
||||
#if defined(STM32F412Cx) || defined(STM32F412Rx) || defined(STM32F412Vx) || defined(STM32F412Zx)
|
||||
#define TIM6_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM6, \
|
||||
.tim_irqn = TIM6_IRQn, \
|
||||
.name = "timer6", \
|
||||
}
|
||||
#else
|
||||
#define TIM6_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM6, \
|
||||
.tim_irqn = TIM6_DAC_IRQn, \
|
||||
.name = "timer6", \
|
||||
}
|
||||
#endif /* defined(STM32F412Cx) || defined(STM32F412Rx) || defined(STM32F412Vx) || defined(STM32F412Zx) */
|
||||
#endif /* TIM6_CONFIG */
|
||||
#endif /* BSP_USING_TIM6 */
|
||||
|
||||
#ifdef BSP_USING_TIM7
|
||||
#ifndef TIM7_CONFIG
|
||||
#define TIM7_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM7, \
|
||||
.tim_irqn = TIM7_IRQn, \
|
||||
.name = "timer7", \
|
||||
}
|
||||
#endif /* TIM7_CONFIG */
|
||||
#endif /* BSP_USING_TIM7 */
|
||||
|
||||
#ifdef BSP_USING_TIM9
|
||||
#ifndef TIM9_CONFIG
|
||||
#define TIM9_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM9, \
|
||||
.tim_irqn = TIM1_BRK_TIM9_IRQn, \
|
||||
.name = "timer9", \
|
||||
}
|
||||
#endif /* TIM9_CONFIG */
|
||||
#endif /* BSP_USING_TIM9 */
|
||||
|
||||
#ifdef BSP_USING_TIM10
|
||||
#ifndef TIM10_CONFIG
|
||||
#define TIM10_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM10, \
|
||||
.tim_irqn = TIM1_UP_TIM10_IRQn, \
|
||||
.name = "timer10", \
|
||||
}
|
||||
#endif /* TIM10_CONFIG */
|
||||
#endif /* BSP_USING_TIM10 */
|
||||
|
||||
#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_TIM12
|
||||
#ifndef TIM12_CONFIG
|
||||
#define TIM12_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM12, \
|
||||
.tim_irqn = TIM8_BRK_TIM12_IRQn, \
|
||||
.name = "timer12", \
|
||||
}
|
||||
#endif /* TIM12_CONFIG */
|
||||
#endif /* BSP_USING_TIM12 */
|
||||
|
||||
#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__ */
|
||||
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(BSP_USING_UART1)
|
||||
#ifndef UART1_CONFIG
|
||||
#define UART1_CONFIG \
|
||||
{ \
|
||||
.name = "uart1", \
|
||||
.Instance = USART1, \
|
||||
.irq_type = USART1_IRQn, \
|
||||
}
|
||||
#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, \
|
||||
}
|
||||
#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, \
|
||||
}
|
||||
#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, \
|
||||
}
|
||||
#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, \
|
||||
}
|
||||
#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, \
|
||||
}
|
||||
#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, \
|
||||
}
|
||||
#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, \
|
||||
}
|
||||
#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
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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_16B, \
|
||||
.Init.ScanConvMode = ADC_SCAN_DISABLE, \
|
||||
.Init.EOCSelection = ADC_EOC_SINGLE_CONV, \
|
||||
.Init.LowPowerAutoWait = DISABLE, \
|
||||
.Init.ContinuousConvMode = DISABLE, \
|
||||
.Init.NbrOfConversion = 1, \
|
||||
.Init.DiscontinuousConvMode = DISABLE, \
|
||||
.Init.NbrOfDiscConversion = 1, \
|
||||
.Init.ExternalTrigConv = ADC_SOFTWARE_START, \
|
||||
.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE, \
|
||||
.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR, \
|
||||
.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN, \
|
||||
.Init.OversamplingMode = 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_16B, \
|
||||
.Init.ScanConvMode = ADC_SCAN_DISABLE, \
|
||||
.Init.EOCSelection = ADC_EOC_SINGLE_CONV, \
|
||||
.Init.LowPowerAutoWait = DISABLE, \
|
||||
.Init.ContinuousConvMode = DISABLE, \
|
||||
.Init.NbrOfConversion = 1, \
|
||||
.Init.DiscontinuousConvMode = DISABLE, \
|
||||
.Init.NbrOfDiscConversion = 1, \
|
||||
.Init.ExternalTrigConv = ADC_SOFTWARE_START, \
|
||||
.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE, \
|
||||
.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR, \
|
||||
.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN, \
|
||||
.Init.OversamplingMode = 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_16B, \
|
||||
.Init.ScanConvMode = ADC_SCAN_DISABLE, \
|
||||
.Init.EOCSelection = ADC_EOC_SINGLE_CONV, \
|
||||
.Init.LowPowerAutoWait = DISABLE, \
|
||||
.Init.ContinuousConvMode = DISABLE, \
|
||||
.Init.NbrOfConversion = 1, \
|
||||
.Init.DiscontinuousConvMode = DISABLE, \
|
||||
.Init.NbrOfDiscConversion = 1, \
|
||||
.Init.ExternalTrigConv = ADC_SOFTWARE_START, \
|
||||
.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE, \
|
||||
.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR, \
|
||||
.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN, \
|
||||
.Init.OversamplingMode = DISABLE, \
|
||||
}
|
||||
#endif /* ADC3_CONFIG */
|
||||
#endif /* BSP_USING_ADC3 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ADC_CONFIG_H__ */
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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__ */
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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
|
||||
* 2020-05-02 whj4674672 support stm32h7 dma1 and dma2
|
||||
*/
|
||||
|
||||
#ifndef __DMA_CONFIG_H__
|
||||
#define __DMA_CONFIG_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* DMA1 stream0 */
|
||||
#if defined(BSP_UART2_RX_USING_DMA) && !defined(UART2_RX_DMA_INSTANCE)
|
||||
#define UART2_DMA_RX_IRQHandler DMA1_Stream0_IRQHandler
|
||||
#define UART2_RX_DMA_RCC RCC_AHB1ENR_DMA1EN
|
||||
#define UART2_RX_DMA_INSTANCE DMA1_Stream0
|
||||
#define UART2_RX_DMA_REQUEST DMA_REQUEST_USART2_RX
|
||||
#define UART2_RX_DMA_IRQ DMA1_Stream0_IRQn
|
||||
#endif
|
||||
|
||||
/* DMA1 stream1 */
|
||||
#if defined(BSP_UART2_TX_USING_DMA) && !defined(UART2_TX_DMA_INSTANCE)
|
||||
#define UART2_DMA_TX_IRQHandler DMA1_Stream1_IRQHandler
|
||||
#define UART2_TX_DMA_RCC RCC_AHB1ENR_DMA1EN
|
||||
#define UART2_TX_DMA_INSTANCE DMA1_Stream1
|
||||
#define UART2_TX_DMA_REQUEST DMA_REQUEST_USART2_TX
|
||||
#define UART2_TX_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_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_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_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_IRQ DMA1_Stream5_IRQn
|
||||
#endif
|
||||
|
||||
/* DMA1 stream6 */
|
||||
|
||||
/* 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_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_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_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_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_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_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_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_IRQ DMA2_Stream6_IRQn
|
||||
#endif
|
||||
|
||||
/* DMA2 stream7 */
|
||||
#if defined(BSP_QSPI_USING_DMA) && !defined(QSPI_DMA_INSTANCE)
|
||||
#define QSPI_DMA_IRQHandler DMA2_Stream7_IRQHandler
|
||||
#define QSPI_DMA_RCC RCC_AHB1ENR_DMA2EN
|
||||
#define QSPI_DMA_INSTANCE DMA2_Stream7
|
||||
#define QSPI_DMA_IRQ DMA2_Stream7_IRQn
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __DMA_CONFIG_H__ */
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2024-07-11 wdfk-prog first version
|
||||
*/
|
||||
|
||||
#ifndef __LPTIM_CONFIG_H__
|
||||
#define __LPTIM_CONFIG_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef LPTIM_DEV_INFO_CONFIG
|
||||
#define LPTIM_DEV_INFO_CONFIG \
|
||||
{ \
|
||||
.maxfreq = 1000000, \
|
||||
.minfreq = 3000, \
|
||||
.maxcnt = 0xFFFF, \
|
||||
.cntmode = HWTIMER_CNTMODE_UP, \
|
||||
}
|
||||
#endif /* TIM_DEV_INFO_CONFIG */
|
||||
|
||||
#ifdef BSP_USING_LPTIM1
|
||||
#ifndef LPTIM1_CONFIG
|
||||
#define LPTIM1_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = LPTIM1, \
|
||||
.tim_irqn = LPTIM1_IRQn, \
|
||||
.name = "lptim1", \
|
||||
}
|
||||
#endif /* LPTIM1_CONFIG */
|
||||
#endif /* BSP_USING_LPTIM1 */
|
||||
|
||||
#ifdef BSP_USING_LPTIM2
|
||||
#ifndef LPTIM2_CONFIG
|
||||
#define LPTIM2_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = LPTIM2, \
|
||||
.tim_irqn = LPTIM2_IRQn, \
|
||||
.name = "lptim2", \
|
||||
}
|
||||
#endif /* LPTIM1_CONFIG */
|
||||
#endif /* BSP_USING_LPTIM1 */
|
||||
|
||||
#ifdef BSP_USING_LPTIM3
|
||||
#ifndef LPTIM3_CONFIG
|
||||
#define LPTIM3_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = LPTIM3, \
|
||||
.tim_irqn = LPTIM3_IRQn, \
|
||||
.name = "lptim3", \
|
||||
}
|
||||
#endif /* LPTIM3_CONFIG */
|
||||
#endif /* BSP_USING_LPTIM3 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LPTIM_CONFIG_H__ */
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-12-13 zylx first version
|
||||
* 2022-04-14 Miaowulue add PWM1
|
||||
* 2023-04-08 Wangyuqiang complete PWM defination
|
||||
*/
|
||||
|
||||
#ifndef __PWM_CONFIG_H__
|
||||
#define __PWM_CONFIG_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_PWM1
|
||||
#define PWM1_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM1, \
|
||||
.name = "pwm1", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM1 */
|
||||
|
||||
#ifdef BSP_USING_PWM2
|
||||
#define PWM2_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM2, \
|
||||
.name = "pwm2", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM2 */
|
||||
|
||||
#ifdef BSP_USING_PWM3
|
||||
#define PWM3_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM3, \
|
||||
.name = "pwm3", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM3 */
|
||||
|
||||
#ifdef BSP_USING_PWM4
|
||||
#define PWM4_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM4, \
|
||||
.name = "pwm4", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM4 */
|
||||
|
||||
#ifdef BSP_USING_PWM5
|
||||
#define PWM5_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM5, \
|
||||
.name = "pwm5", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM5 */
|
||||
|
||||
#ifdef BSP_USING_PWM6
|
||||
#define PWM6_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM6, \
|
||||
.name = "pwm6", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM6 */
|
||||
|
||||
#ifdef BSP_USING_PWM7
|
||||
#define PWM7_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM7, \
|
||||
.name = "pwm7", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM7 */
|
||||
|
||||
#ifdef BSP_USING_PWM8
|
||||
#define PWM8_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM8, \
|
||||
.name = "pwm8", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM8 */
|
||||
|
||||
#ifdef BSP_USING_PWM9
|
||||
#define PWM9_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM9, \
|
||||
.name = "pwm9", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM9 */
|
||||
|
||||
#ifdef BSP_USING_PWM10
|
||||
#define PWM10_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM10, \
|
||||
.name = "pwm10", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM10 */
|
||||
|
||||
#ifdef BSP_USING_PWM11
|
||||
#define PWM11_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM11, \
|
||||
.name = "pwm11", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM11 */
|
||||
|
||||
#ifdef BSP_USING_PWM12
|
||||
#define PWM12_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM12, \
|
||||
.name = "pwm12", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM12 */
|
||||
|
||||
#ifdef BSP_USING_PWM13
|
||||
#define PWM13_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM13, \
|
||||
.name = "pwm13", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM13 */
|
||||
|
||||
#ifdef BSP_USING_PWM14
|
||||
#define PWM14_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM14, \
|
||||
.name = "pwm14", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM14 */
|
||||
|
||||
#ifdef BSP_USING_PWM15
|
||||
#define PWM15_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM15, \
|
||||
.name = "pwm15", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM15 */
|
||||
|
||||
#ifdef BSP_USING_PWM16
|
||||
#define PWM16_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM16, \
|
||||
.name = "pwm16", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM16 */
|
||||
|
||||
#ifdef BSP_USING_PWM17
|
||||
#define PWM17_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM17, \
|
||||
.name = "pwm17", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM17 */
|
||||
|
||||
#ifdef BSP_USING_PWM18
|
||||
#define PWM18_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM18, \
|
||||
.name = "pwm18", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM18 */
|
||||
|
||||
#ifdef BSP_USING_PWM19
|
||||
#define PWM19_CONFIG \
|
||||
{ \
|
||||
.tim_handle.Instance = TIM19, \
|
||||
.name = "pwm19", \
|
||||
.channel = RT_NULL \
|
||||
}
|
||||
#endif /* BSP_USING_PWM19 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __PWM_CONFIG_H__ */
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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_4_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__ */
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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 "stm32h7xx_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_SDIO
|
||||
#define SDIO_BUS_CONFIG \
|
||||
{ \
|
||||
.Instance = SDMMC1, \
|
||||
.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__ */
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-11-06 SummerGift first version
|
||||
*/
|
||||
|
||||
#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, \
|
||||
.dma_irq = SPI1_TX_DMA_IRQ, \
|
||||
.request = DMA_REQUEST_SPI1_TX \
|
||||
}
|
||||
#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, \
|
||||
.dma_irq = SPI1_RX_DMA_IRQ, \
|
||||
.request = DMA_REQUEST_SPI1_RX \
|
||||
}
|
||||
#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, \
|
||||
.dma_irq = SPI2_TX_DMA_IRQ, \
|
||||
.request = DMA_REQUEST_SPI2_TX \
|
||||
}
|
||||
#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, \
|
||||
.dma_irq = SPI2_RX_DMA_IRQ, \
|
||||
.request = DMA_REQUEST_SPI2_RX \
|
||||
}
|
||||
#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, \
|
||||
.dma_irq = SPI3_TX_DMA_IRQ, \
|
||||
.request = DMA_REQUEST_SPI3_TX \
|
||||
}
|
||||
#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, \
|
||||
.dma_irq = SPI3_RX_DMA_IRQ, \
|
||||
.request = DMA_REQUEST_SPI3_RX \
|
||||
}
|
||||
#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, \
|
||||
.dma_irq = SPI4_TX_DMA_IRQ, \
|
||||
.request = DMA_REQUEST_SPI4_TX \
|
||||
}
|
||||
#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, \
|
||||
.dma_irq = SPI4_RX_DMA_IRQ, \
|
||||
.request = DMA_REQUEST_SPI4_RX \
|
||||
}
|
||||
#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, \
|
||||
.dma_irq = SPI5_TX_DMA_IRQ, \
|
||||
.request = DMA_REQUEST_SPI5_TX \
|
||||
}
|
||||
#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, \
|
||||
.dma_irq = SPI5_RX_DMA_IRQ, \
|
||||
.request = DMA_REQUEST_SPI5_RX \
|
||||
}
|
||||
#endif /* SPI5_RX_DMA_CONFIG */
|
||||
#endif /* BSP_SPI5_RX_USING_DMA */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__SPI_CONFIG_H__ */
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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_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__ */
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-10-30 SummerGift first version
|
||||
* 2019-01-05 zylx modify dma support
|
||||
* 2020-05-02 whj4674672 support stm32h7 uart dma
|
||||
*/
|
||||
|
||||
#ifndef __UART_CONFIG_H__
|
||||
#define __UART_CONFIG_H__
|
||||
|
||||
#include <rtthread.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, \
|
||||
}
|
||||
#endif /* UART1_CONFIG */
|
||||
#endif /* BSP_USING_UART1 */
|
||||
|
||||
#if defined(BSP_UART1_RX_USING_DMA)
|
||||
#ifndef UART1_DMA_RX_CONFIG
|
||||
#define UART1_DMA_RX_CONFIG \
|
||||
{ \
|
||||
.Instance = UART1_RX_DMA_INSTANCE, \
|
||||
.request = UART1_RX_DMA_REQUEST, \
|
||||
.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_USING_UART2)
|
||||
#ifndef UART2_CONFIG
|
||||
#define UART2_CONFIG \
|
||||
{ \
|
||||
.name = "uart2", \
|
||||
.Instance = USART2, \
|
||||
.irq_type = USART2_IRQn, \
|
||||
}
|
||||
#endif /* UART2_CONFIG */
|
||||
#endif /* BSP_USING_UART2 */
|
||||
|
||||
#if defined(BSP_UART2_RX_USING_DMA)
|
||||
#ifndef UART2_DMA_RX_CONFIG
|
||||
#define UART2_DMA_RX_CONFIG \
|
||||
{ \
|
||||
.Instance = UART2_RX_DMA_INSTANCE, \
|
||||
.request = UART2_RX_DMA_REQUEST, \
|
||||
.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, \
|
||||
.request = UART2_TX_DMA_REQUEST, \
|
||||
.dma_rcc = UART2_TX_DMA_RCC, \
|
||||
.dma_irq = UART2_TX_DMA_IRQ, \
|
||||
}
|
||||
#endif /* UART2_DMA_TX_CONFIG */
|
||||
#endif /* BSP_UART2_TX_USING_DMA */
|
||||
|
||||
#if defined(BSP_USING_UART3)
|
||||
#ifndef UART3_CONFIG
|
||||
#define UART3_CONFIG \
|
||||
{ \
|
||||
.name = "uart3", \
|
||||
.Instance = USART3, \
|
||||
.irq_type = USART3_IRQn, \
|
||||
}
|
||||
#endif /* UART3_CONFIG */
|
||||
#endif /* BSP_USING_UART3 */
|
||||
|
||||
#if defined(BSP_UART3_RX_USING_DMA)
|
||||
#ifndef UART3_DMA_RX_CONFIG
|
||||
#define UART3_DMA_RX_CONFIG \
|
||||
{ \
|
||||
.Instance = UART3_RX_DMA_INSTANCE, \
|
||||
.request = UART3_RX_DMA_REQUEST, \
|
||||
.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_USING_UART4)
|
||||
#ifndef UART4_CONFIG
|
||||
#define UART4_CONFIG \
|
||||
{ \
|
||||
.name = "uart4", \
|
||||
.Instance = UART4, \
|
||||
.irq_type = UART4_IRQn, \
|
||||
}
|
||||
#endif /* UART4_CONFIG */
|
||||
#endif /* BSP_USING_UART4 */
|
||||
|
||||
#if defined(BSP_UART4_RX_USING_DMA)
|
||||
#ifndef UART4_DMA_RX_CONFIG
|
||||
#define UART4_DMA_RX_CONFIG \
|
||||
{ \
|
||||
.Instance = UART4_RX_DMA_INSTANCE, \
|
||||
.request = UART4_RX_DMA_REQUEST, \
|
||||
.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_USING_UART5)
|
||||
#ifndef UART5_CONFIG
|
||||
#define UART5_CONFIG \
|
||||
{ \
|
||||
.name = "uart5", \
|
||||
.Instance = UART5, \
|
||||
.irq_type = UART5_IRQn, \
|
||||
}
|
||||
#endif /* UART5_CONFIG */
|
||||
#endif /* BSP_USING_UART5 */
|
||||
|
||||
#if defined(BSP_UART5_RX_USING_DMA)
|
||||
#ifndef UART5_DMA_RX_CONFIG
|
||||
#define UART5_DMA_RX_CONFIG \
|
||||
{ \
|
||||
.Instance = UART5_RX_DMA_INSTANCE, \
|
||||
.request = UART5_RX_DMA_REQUEST, \
|
||||
.dma_rcc = UART5_RX_DMA_RCC, \
|
||||
.dma_irq = UART5_RX_DMA_IRQ, \
|
||||
}
|
||||
#endif /* UART5_DMA_RX_CONFIG */
|
||||
#endif /* BSP_UART5_RX_USING_DMA */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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
|
||||
@@ -0,0 +1,393 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2025, 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
|
||||
* 2022-05-22 Stanley Lwin Add stm32_adc_get_vref
|
||||
* 2022-12-26 wdfk-prog Change the order of configuration channels and calibration functions
|
||||
*/
|
||||
|
||||
#include <board.h>
|
||||
#include <rtthread.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_get_channel(rt_int8_t rt_channel, uint32_t *stm32_channel)
|
||||
{
|
||||
switch (rt_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 /* ADC_CHANNEL_16 */
|
||||
case 17:
|
||||
*stm32_channel = ADC_CHANNEL_17;
|
||||
break;
|
||||
#ifdef ADC_CHANNEL_18
|
||||
case 18:
|
||||
*stm32_channel = ADC_CHANNEL_18;
|
||||
break;
|
||||
#endif /* ADC_CHANNEL_18 */
|
||||
#ifdef ADC_CHANNEL_19
|
||||
case 19:
|
||||
*stm32_channel = ADC_CHANNEL_19;
|
||||
break;
|
||||
#endif /* ADC_CHANNEL_19 */
|
||||
#ifdef ADC_CHANNEL_VREFINT
|
||||
case RT_ADC_INTERN_CH_VREF:
|
||||
*stm32_channel = ADC_CHANNEL_VREFINT;
|
||||
break;
|
||||
#endif /* ADC_CHANNEL_VREFINT */
|
||||
#ifdef ADC_CHANNEL_VBAT
|
||||
case RT_ADC_INTERN_CH_VBAT:
|
||||
*stm32_channel = ADC_CHANNEL_VBAT;
|
||||
break;
|
||||
#endif /* ADC_CHANNEL_VBAT */
|
||||
#ifdef ADC_CHANNEL_TEMPSENSOR
|
||||
case RT_ADC_INTERN_CH_TEMPER:
|
||||
*stm32_channel = ADC_CHANNEL_TEMPSENSOR;
|
||||
break;
|
||||
#endif /* ADC_CHANNEL_TEMPSENSOR */
|
||||
default:
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t stm32_adc_enabled(struct rt_adc_device *device, rt_int8_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)
|
||||
{
|
||||
ADC_ChannelConfTypeDef ADC_ChanConf;
|
||||
rt_memset(&ADC_ChanConf, 0, sizeof(ADC_ChanConf));
|
||||
|
||||
if(stm32_adc_get_channel(channel, &ADC_ChanConf.Channel) != RT_EOK)
|
||||
{
|
||||
LOG_E("ADC channel illegal: %d", channel);
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
#if defined(SOC_SERIES_STM32MP1) || defined (SOC_SERIES_STM32H7) || defined (SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32U5)
|
||||
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_810CYCLES_5;
|
||||
#elif defined(SOC_SERIES_STM32U5)
|
||||
ADC_ChanConf.SamplingTime = ADC_SAMPLETIME_814CYCLES;
|
||||
#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) || defined(SOC_SERIES_STM32U5)
|
||||
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
|
||||
|
||||
/* enable the analog power domain before configuring channel */
|
||||
#if defined(SOC_SERIES_STM32U5)
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
HAL_PWREx_EnableVddA();
|
||||
#endif /* defined(SOC_SERIES_STM32U5) */
|
||||
|
||||
if(HAL_ADC_ConfigChannel(stm32_adc_handler, &ADC_ChanConf) != HAL_OK)
|
||||
{
|
||||
LOG_E("Failed to configure ADC channel %d", channel);
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
/* 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) || defined(SOC_SERIES_STM32U5)
|
||||
/* 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
|
||||
}
|
||||
else
|
||||
{
|
||||
if (HAL_ADC_Stop(stm32_adc_handler) != HAL_OK)
|
||||
{
|
||||
LOG_E("Stop ADC conversion failed!\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_uint8_t stm32_adc_get_resolution(struct rt_adc_device *device)
|
||||
{
|
||||
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F3)
|
||||
return 12;
|
||||
#else
|
||||
ADC_HandleTypeDef *stm32_adc_handler = device->parent.user_data;
|
||||
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
|
||||
switch(stm32_adc_handler->Init.Resolution)
|
||||
{
|
||||
#ifdef SOC_SERIES_STM32H7
|
||||
case ADC_RESOLUTION_16B:
|
||||
return 16;
|
||||
#endif /* SOC_SERIES_STM32H7 */
|
||||
#if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32U5)
|
||||
case ADC_RESOLUTION_14B:
|
||||
return 14;
|
||||
#endif /* defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32U5) */
|
||||
case ADC_RESOLUTION_12B:
|
||||
return 12;
|
||||
case ADC_RESOLUTION_10B:
|
||||
return 10;
|
||||
case ADC_RESOLUTION_8B:
|
||||
return 8;
|
||||
#if defined(SOC_SERIES_STM32H7) && (ADC_VER_V5_V90) || defined(SOC_SERIES_STM32U5)
|
||||
case ADC_RESOLUTION_6B:
|
||||
return 6;
|
||||
#endif /* defined(SOC_SERIES_STM32H7) && (ADC_VER_V5_V90) || defined(SOC_SERIES_STM32U5) */
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#endif /* defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F3) */
|
||||
}
|
||||
|
||||
static rt_err_t stm32_adc_get_value(struct rt_adc_device *device, rt_int8_t channel, rt_uint32_t *value)
|
||||
{
|
||||
ADC_HandleTypeDef *stm32_adc_handler;
|
||||
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
RT_ASSERT(value != RT_NULL);
|
||||
|
||||
stm32_adc_handler = device->parent.user_data;
|
||||
|
||||
if (HAL_ADC_Start(stm32_adc_handler) != HAL_OK)
|
||||
{
|
||||
LOG_E("Start ADC conversion error!\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
/* Wait for the ADC to convert */
|
||||
if (HAL_ADC_PollForConversion(stm32_adc_handler, 100) != RT_EOK)
|
||||
{
|
||||
LOG_E("ADC conversion error!\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
/* get ADC value */
|
||||
*value = (rt_uint32_t)HAL_ADC_GetValue(stm32_adc_handler);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_int16_t stm32_adc_get_vref (struct rt_adc_device *device)
|
||||
{
|
||||
rt_uint16_t vref_mv;
|
||||
#ifdef __LL_ADC_CALC_VREFANALOG_VOLTAGE
|
||||
rt_err_t ret;
|
||||
rt_uint32_t vref_value;
|
||||
|
||||
ADC_HandleTypeDef *stm32_adc_handler = device->parent.user_data;
|
||||
|
||||
ret = stm32_adc_enabled(device, RT_ADC_INTERN_CH_VREF, RT_TRUE);
|
||||
if (ret != RT_EOK)
|
||||
return 0;
|
||||
ret = stm32_adc_get_value(device, RT_ADC_INTERN_CH_VREF, &vref_value);
|
||||
if (ret != RT_EOK)
|
||||
return 0;
|
||||
ret = stm32_adc_enabled(device, RT_ADC_INTERN_CH_VREF, RT_FALSE);
|
||||
if (ret != RT_EOK)
|
||||
return 0;
|
||||
|
||||
#ifdef SOC_SERIES_STM32U5
|
||||
vref_mv = __LL_ADC_CALC_VREFANALOG_VOLTAGE(stm32_adc_handler->Instance, vref_value, stm32_adc_handler->Init.Resolution);
|
||||
#else
|
||||
vref_mv = __LL_ADC_CALC_VREFANALOG_VOLTAGE(vref_value, stm32_adc_handler->Init.Resolution);
|
||||
#endif
|
||||
|
||||
#else
|
||||
vref_mv = 3300;
|
||||
#endif /* __LL_ADC_CALC_VREFANALOG_VOLTAGE */
|
||||
return vref_mv;
|
||||
}
|
||||
|
||||
static const struct rt_adc_ops stm_adc_ops =
|
||||
{
|
||||
.enabled = stm32_adc_enabled,
|
||||
.convert = stm32_adc_get_value,
|
||||
.get_resolution = stm32_adc_get_resolution,
|
||||
.get_vref = stm32_adc_get_vref,
|
||||
};
|
||||
|
||||
static int stm32_adc_init(void)
|
||||
{
|
||||
int result = RT_EOK;
|
||||
/* save adc name */
|
||||
char name_buf[5] = {'a', 'd', 'c', '0', 0};
|
||||
rt_uint32_t 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 */
|
||||
@@ -0,0 +1,977 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2024 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-02-19 YLZ add support EXTID RTR Frame. modify send, recv functions.
|
||||
* fix bug.port to BSP [stm32]
|
||||
* 2019-03-27 YLZ support double can channels, support stm32F4xx (only Legacy mode).
|
||||
* 2019-06-17 YLZ port to new STM32F1xx HAL V1.1.3.
|
||||
* 2021-02-02 YuZhe XU fix bug in filter config
|
||||
* 2021-8-25 SVCHAO The baud rate is configured according to the different APB1 frequencies.
|
||||
f4-series only.
|
||||
*/
|
||||
|
||||
#include "drv_can.h"
|
||||
|
||||
#ifdef BSP_USING_CAN
|
||||
|
||||
#define LOG_TAG "drv_can"
|
||||
#include <drv_log.h>
|
||||
|
||||
/* attention !!! baud calculation example: Tclk / ((ss + bs1 + bs2) * brp) = 36 / ((1 + 8 + 3) * 3) = 1MHz*/
|
||||
#if defined (SOC_SERIES_STM32F1)/* APB1 36MHz(max) */
|
||||
static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
|
||||
{
|
||||
{CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 3)},
|
||||
{CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_5TQ | CAN_BS2_3TQ | 5)},
|
||||
{CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 6)},
|
||||
{CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 12)},
|
||||
{CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 24)},
|
||||
{CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 30)},
|
||||
{CAN50kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 60)},
|
||||
{CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 150)},
|
||||
{CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 300)}
|
||||
};
|
||||
#elif defined (SOC_SERIES_STM32F4) /* 42MHz or 45MHz */
|
||||
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) ||\
|
||||
defined(STM32F401xC) || defined(STM32F401xE) /* 42MHz(max) */
|
||||
static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
|
||||
{
|
||||
{CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 3)},
|
||||
{CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_4TQ | 4)},
|
||||
{CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 6)},
|
||||
{CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 12)},
|
||||
{CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 24)},
|
||||
{CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 30)},
|
||||
{CAN50kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 60)},
|
||||
{CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 150)},
|
||||
{CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 300)}
|
||||
};
|
||||
#else /* APB1 45MHz(max) */
|
||||
static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
|
||||
{
|
||||
#ifdef BSP_USING_CAN168M
|
||||
{CAN1MBaud, (CAN_SJW_1TQ | CAN_BS1_3TQ | CAN_BS2_3TQ | 6)},
|
||||
#else
|
||||
{CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 3)},
|
||||
#endif
|
||||
{CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_5TQ | 4)},
|
||||
{CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 6)},
|
||||
{CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 12)},
|
||||
{CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 24)},
|
||||
{CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 30)},
|
||||
{CAN50kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 60)},
|
||||
{CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 150)},
|
||||
{CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 300)}
|
||||
};
|
||||
#endif
|
||||
#elif defined (SOC_SERIES_STM32F7)/* APB1 54MHz(max) */
|
||||
static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
|
||||
{
|
||||
{CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 3)},
|
||||
{CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_7TQ | 4)},
|
||||
{CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 6)},
|
||||
{CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 12)},
|
||||
{CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 24)},
|
||||
{CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 30)},
|
||||
{CAN50kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 60)},
|
||||
{CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 150)},
|
||||
{CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 300)}
|
||||
};
|
||||
#elif defined (SOC_SERIES_STM32L4)/* APB1 80MHz(max) */
|
||||
static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
|
||||
{
|
||||
{CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_5TQ | CAN_BS2_2TQ | 10)},
|
||||
{CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_14TQ | CAN_BS2_5TQ | 5)},
|
||||
{CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_7TQ | CAN_BS2_2TQ | 16)},
|
||||
{CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_13TQ | CAN_BS2_2TQ | 20)},
|
||||
{CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_13TQ | CAN_BS2_2TQ | 40)},
|
||||
{CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_13TQ | CAN_BS2_2TQ | 50)},
|
||||
{CAN50kBaud, (CAN_SJW_2TQ | CAN_BS1_13TQ | CAN_BS2_2TQ | 100)},
|
||||
{CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_13TQ | CAN_BS2_2TQ | 250)},
|
||||
{CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_13TQ | CAN_BS2_2TQ | 500)}
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_CAN1
|
||||
static struct stm32_can drv_can1 =
|
||||
{
|
||||
.name = "can1",
|
||||
.CanHandle.Instance = CAN1,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_CAN2
|
||||
static struct stm32_can drv_can2 =
|
||||
{
|
||||
"can2",
|
||||
.CanHandle.Instance = CAN2,
|
||||
};
|
||||
#endif
|
||||
|
||||
static rt_uint32_t get_can_baud_index(rt_uint32_t baud)
|
||||
{
|
||||
rt_uint32_t len, index;
|
||||
|
||||
len = sizeof(can_baud_rate_tab) / sizeof(can_baud_rate_tab[0]);
|
||||
for (index = 0; index < len; index++)
|
||||
{
|
||||
if (can_baud_rate_tab[index].baud_rate == baud)
|
||||
return index;
|
||||
}
|
||||
|
||||
return 0; /* default baud is CAN1MBaud */
|
||||
}
|
||||
|
||||
static rt_err_t _can_config(struct rt_can_device *can, struct can_configure *cfg)
|
||||
{
|
||||
struct stm32_can *drv_can;
|
||||
rt_uint32_t baud_index;
|
||||
|
||||
RT_ASSERT(can);
|
||||
RT_ASSERT(cfg);
|
||||
drv_can = (struct stm32_can *)can->parent.user_data;
|
||||
RT_ASSERT(drv_can);
|
||||
|
||||
drv_can->CanHandle.Init.TimeTriggeredMode = DISABLE;
|
||||
drv_can->CanHandle.Init.AutoBusOff = ENABLE;
|
||||
drv_can->CanHandle.Init.AutoWakeUp = DISABLE;
|
||||
drv_can->CanHandle.Init.AutoRetransmission = DISABLE;
|
||||
drv_can->CanHandle.Init.ReceiveFifoLocked = DISABLE;
|
||||
drv_can->CanHandle.Init.TransmitFifoPriority = ENABLE;
|
||||
|
||||
switch (cfg->mode)
|
||||
{
|
||||
case RT_CAN_MODE_NORMAL:
|
||||
drv_can->CanHandle.Init.Mode = CAN_MODE_NORMAL;
|
||||
break;
|
||||
case RT_CAN_MODE_LISTEN:
|
||||
drv_can->CanHandle.Init.Mode = CAN_MODE_SILENT;
|
||||
break;
|
||||
case RT_CAN_MODE_LOOPBACK:
|
||||
drv_can->CanHandle.Init.Mode = CAN_MODE_LOOPBACK;
|
||||
break;
|
||||
case RT_CAN_MODE_LOOPBACKANLISTEN:
|
||||
drv_can->CanHandle.Init.Mode = CAN_MODE_SILENT_LOOPBACK;
|
||||
break;
|
||||
}
|
||||
|
||||
baud_index = get_can_baud_index(cfg->baud_rate);
|
||||
drv_can->CanHandle.Init.SyncJumpWidth = BAUD_DATA(SJW, baud_index);
|
||||
drv_can->CanHandle.Init.TimeSeg1 = BAUD_DATA(BS1, baud_index);
|
||||
drv_can->CanHandle.Init.TimeSeg2 = BAUD_DATA(BS2, baud_index);
|
||||
drv_can->CanHandle.Init.Prescaler = BAUD_DATA(RRESCL, baud_index);
|
||||
/* init can */
|
||||
if (HAL_CAN_Init(&drv_can->CanHandle) != HAL_OK)
|
||||
{
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
/* default filter config */
|
||||
HAL_CAN_ConfigFilter(&drv_can->CanHandle, &drv_can->FilterConfig);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
|
||||
{
|
||||
rt_uint32_t argval;
|
||||
struct stm32_can *drv_can;
|
||||
struct rt_can_filter_config *filter_cfg;
|
||||
|
||||
RT_ASSERT(can != RT_NULL);
|
||||
drv_can = (struct stm32_can *)can->parent.user_data;
|
||||
RT_ASSERT(drv_can != RT_NULL);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case RT_DEVICE_CTRL_CLR_INT:
|
||||
argval = (rt_uint32_t) arg;
|
||||
if (argval == RT_DEVICE_FLAG_INT_RX)
|
||||
{
|
||||
if (CAN1 == drv_can->CanHandle.Instance)
|
||||
{
|
||||
HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);
|
||||
HAL_NVIC_DisableIRQ(CAN1_RX1_IRQn);
|
||||
}
|
||||
#ifdef CAN2
|
||||
if (CAN2 == drv_can->CanHandle.Instance)
|
||||
{
|
||||
HAL_NVIC_DisableIRQ(CAN2_RX0_IRQn);
|
||||
HAL_NVIC_DisableIRQ(CAN2_RX1_IRQn);
|
||||
}
|
||||
#endif
|
||||
__HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO0_MSG_PENDING);
|
||||
__HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO0_FULL);
|
||||
__HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO0_OVERRUN);
|
||||
__HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO1_MSG_PENDING);
|
||||
__HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO1_FULL);
|
||||
__HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO1_OVERRUN);
|
||||
}
|
||||
else if (argval == RT_DEVICE_FLAG_INT_TX)
|
||||
{
|
||||
if (CAN1 == drv_can->CanHandle.Instance)
|
||||
{
|
||||
HAL_NVIC_DisableIRQ(CAN1_TX_IRQn);
|
||||
}
|
||||
#ifdef CAN2
|
||||
if (CAN2 == drv_can->CanHandle.Instance)
|
||||
{
|
||||
HAL_NVIC_DisableIRQ(CAN2_TX_IRQn);
|
||||
}
|
||||
#endif
|
||||
__HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_TX_MAILBOX_EMPTY);
|
||||
}
|
||||
else if (argval == RT_DEVICE_CAN_INT_ERR)
|
||||
{
|
||||
if (CAN1 == drv_can->CanHandle.Instance)
|
||||
{
|
||||
NVIC_DisableIRQ(CAN1_SCE_IRQn);
|
||||
}
|
||||
#ifdef CAN2
|
||||
if (CAN2 == drv_can->CanHandle.Instance)
|
||||
{
|
||||
NVIC_DisableIRQ(CAN2_SCE_IRQn);
|
||||
}
|
||||
#endif
|
||||
__HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_ERROR_WARNING);
|
||||
__HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_ERROR_PASSIVE);
|
||||
__HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_BUSOFF);
|
||||
__HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_LAST_ERROR_CODE);
|
||||
__HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_ERROR);
|
||||
}
|
||||
break;
|
||||
case RT_DEVICE_CTRL_SET_INT:
|
||||
argval = (rt_uint32_t) arg;
|
||||
if (argval == RT_DEVICE_FLAG_INT_RX)
|
||||
{
|
||||
__HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO0_MSG_PENDING);
|
||||
__HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO0_FULL);
|
||||
__HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO0_OVERRUN);
|
||||
__HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO1_MSG_PENDING);
|
||||
__HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO1_FULL);
|
||||
__HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO1_OVERRUN);
|
||||
|
||||
if (CAN1 == drv_can->CanHandle.Instance)
|
||||
{
|
||||
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
|
||||
HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
|
||||
}
|
||||
#ifdef CAN2
|
||||
if (CAN2 == drv_can->CanHandle.Instance)
|
||||
{
|
||||
HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn);
|
||||
HAL_NVIC_SetPriority(CAN2_RX1_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(CAN2_RX1_IRQn);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (argval == RT_DEVICE_FLAG_INT_TX)
|
||||
{
|
||||
__HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_TX_MAILBOX_EMPTY);
|
||||
|
||||
if (CAN1 == drv_can->CanHandle.Instance)
|
||||
{
|
||||
HAL_NVIC_SetPriority(CAN1_TX_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(CAN1_TX_IRQn);
|
||||
}
|
||||
#ifdef CAN2
|
||||
if (CAN2 == drv_can->CanHandle.Instance)
|
||||
{
|
||||
HAL_NVIC_SetPriority(CAN2_TX_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(CAN2_TX_IRQn);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (argval == RT_DEVICE_CAN_INT_ERR)
|
||||
{
|
||||
__HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_ERROR_WARNING);
|
||||
__HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_ERROR_PASSIVE);
|
||||
__HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_BUSOFF);
|
||||
__HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_LAST_ERROR_CODE);
|
||||
__HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_ERROR);
|
||||
|
||||
if (CAN1 == drv_can->CanHandle.Instance)
|
||||
{
|
||||
HAL_NVIC_SetPriority(CAN1_SCE_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
|
||||
}
|
||||
#ifdef CAN2
|
||||
if (CAN2 == drv_can->CanHandle.Instance)
|
||||
{
|
||||
HAL_NVIC_SetPriority(CAN2_SCE_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(CAN2_SCE_IRQn);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case RT_CAN_CMD_SET_FILTER:
|
||||
{
|
||||
rt_uint32_t id_h = 0;
|
||||
rt_uint32_t id_l = 0;
|
||||
rt_uint32_t mask_h = 0;
|
||||
rt_uint32_t mask_l = 0;
|
||||
rt_uint32_t mask_l_tail = 0; /*CAN_FxR2 bit [2:0]*/
|
||||
|
||||
if (RT_NULL == arg)
|
||||
{
|
||||
/* default filter config */
|
||||
HAL_CAN_ConfigFilter(&drv_can->CanHandle, &drv_can->FilterConfig);
|
||||
}
|
||||
else
|
||||
{
|
||||
filter_cfg = (struct rt_can_filter_config *)arg;
|
||||
/* get default filter */
|
||||
for (int i = 0; i < filter_cfg->count; i++)
|
||||
{
|
||||
if (filter_cfg->items[i].hdr_bank == -1)
|
||||
{
|
||||
/* use default filter bank settings */
|
||||
if (rt_strcmp(drv_can->name, "can1") == 0)
|
||||
{
|
||||
/* can1 banks 0~13 */
|
||||
drv_can->FilterConfig.FilterBank = i;
|
||||
}
|
||||
else if (rt_strcmp(drv_can->name, "can2") == 0)
|
||||
{
|
||||
/* can2 banks 14~27 */
|
||||
drv_can->FilterConfig.FilterBank = i + 14;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* use user-defined filter bank settings */
|
||||
drv_can->FilterConfig.FilterBank = filter_cfg->items[i].hdr_bank;
|
||||
}
|
||||
/**
|
||||
* ID | CAN_FxR1[31:24] | CAN_FxR1[23:16] | CAN_FxR1[15:8] | CAN_FxR1[7:0] |
|
||||
* MASK | CAN_FxR2[31:24] | CAN_FxR2[23:16] | CAN_FxR2[15:8] | CAN_FxR2[7:0] |
|
||||
* STD ID | STID[10:3] | STDID[2:0] |<- 21bit ->|
|
||||
* EXT ID | EXTID[28:21] | EXTID[20:13] | EXTID[12:5] | EXTID[4:0] IDE RTR 0|
|
||||
* @note the 32bit STD ID must << 21 to fill CAN_FxR1[31:21] and EXT ID must << 3,
|
||||
* -> but the id bit of struct rt_can_filter_item is 29,
|
||||
* -> so STD id << 18 and EXT id Don't need << 3, when get the high 16bit.
|
||||
* -> FilterIdHigh : (((STDid << 18) or (EXT id)) >> 13) & 0xFFFF,
|
||||
* -> FilterIdLow: ((STDid << 18) or (EXT id << 3)) & 0xFFFF.
|
||||
* @note the mask bit of struct rt_can_filter_item is 32,
|
||||
* -> FilterMaskIdHigh: (((STD mask << 21) or (EXT mask <<3)) >> 16) & 0xFFFF
|
||||
* -> FilterMaskIdLow: ((STD mask << 21) or (EXT mask <<3)) & 0xFFFF
|
||||
*/
|
||||
if (filter_cfg->items[i].mode == CAN_FILTERMODE_IDMASK)
|
||||
{
|
||||
/* make sure the CAN_FxR1[2:0](IDE RTR) work */
|
||||
mask_l_tail = 0x06;
|
||||
}
|
||||
else if (filter_cfg->items[i].mode == CAN_FILTERMODE_IDLIST)
|
||||
{
|
||||
/* same as CAN_FxR1 */
|
||||
mask_l_tail = (filter_cfg->items[i].ide << 2) |
|
||||
(filter_cfg->items[i].rtr << 1);
|
||||
}
|
||||
if (filter_cfg->items[i].ide == RT_CAN_STDID)
|
||||
{
|
||||
id_h = ((filter_cfg->items[i].id << 18) >> 13) & 0xFFFF;
|
||||
id_l = ((filter_cfg->items[i].id << 18) |
|
||||
(filter_cfg->items[i].ide << 2) |
|
||||
(filter_cfg->items[i].rtr << 1)) & 0xFFFF;
|
||||
mask_h = ((filter_cfg->items[i].mask << 21) >> 16) & 0xFFFF;
|
||||
mask_l = ((filter_cfg->items[i].mask << 21) | mask_l_tail) & 0xFFFF;
|
||||
}
|
||||
else if (filter_cfg->items[i].ide == RT_CAN_EXTID)
|
||||
{
|
||||
id_h = (filter_cfg->items[i].id >> 13) & 0xFFFF;
|
||||
id_l = ((filter_cfg->items[i].id << 3) |
|
||||
(filter_cfg->items[i].ide << 2) |
|
||||
(filter_cfg->items[i].rtr << 1)) & 0xFFFF;
|
||||
mask_h = ((filter_cfg->items[i].mask << 3) >> 16) & 0xFFFF;
|
||||
mask_l = ((filter_cfg->items[i].mask << 3) | mask_l_tail) & 0xFFFF;
|
||||
}
|
||||
drv_can->FilterConfig.FilterIdHigh = id_h;
|
||||
drv_can->FilterConfig.FilterIdLow = id_l;
|
||||
drv_can->FilterConfig.FilterMaskIdHigh = mask_h;
|
||||
drv_can->FilterConfig.FilterMaskIdLow = mask_l;
|
||||
|
||||
drv_can->FilterConfig.FilterMode = filter_cfg->items[i].mode;
|
||||
drv_can->FilterConfig.FilterFIFOAssignment = filter_cfg->items[i].rxfifo;/*rxfifo = CAN_RX_FIFO0/CAN_RX_FIFO1*/
|
||||
/* Filter conf */
|
||||
HAL_CAN_ConfigFilter(&drv_can->CanHandle, &drv_can->FilterConfig);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RT_CAN_CMD_SET_MODE:
|
||||
argval = (rt_uint32_t) arg;
|
||||
if (argval != RT_CAN_MODE_NORMAL &&
|
||||
argval != RT_CAN_MODE_LISTEN &&
|
||||
argval != RT_CAN_MODE_LOOPBACK &&
|
||||
argval != RT_CAN_MODE_LOOPBACKANLISTEN)
|
||||
{
|
||||
return -RT_ERROR;
|
||||
}
|
||||
if (argval != drv_can->device.config.mode)
|
||||
{
|
||||
drv_can->device.config.mode = argval;
|
||||
return _can_config(&drv_can->device, &drv_can->device.config);
|
||||
}
|
||||
break;
|
||||
case RT_CAN_CMD_SET_BAUD:
|
||||
argval = (rt_uint32_t) arg;
|
||||
if (argval != CAN1MBaud &&
|
||||
argval != CAN800kBaud &&
|
||||
argval != CAN500kBaud &&
|
||||
argval != CAN250kBaud &&
|
||||
argval != CAN125kBaud &&
|
||||
argval != CAN100kBaud &&
|
||||
argval != CAN50kBaud &&
|
||||
argval != CAN20kBaud &&
|
||||
argval != CAN10kBaud)
|
||||
{
|
||||
return -RT_ERROR;
|
||||
}
|
||||
if (argval != drv_can->device.config.baud_rate)
|
||||
{
|
||||
drv_can->device.config.baud_rate = argval;
|
||||
return _can_config(&drv_can->device, &drv_can->device.config);
|
||||
}
|
||||
break;
|
||||
case RT_CAN_CMD_SET_PRIV:
|
||||
argval = (rt_uint32_t) arg;
|
||||
if (argval != RT_CAN_MODE_PRIV &&
|
||||
argval != RT_CAN_MODE_NOPRIV)
|
||||
{
|
||||
return -RT_ERROR;
|
||||
}
|
||||
if (argval != drv_can->device.config.privmode)
|
||||
{
|
||||
drv_can->device.config.privmode = argval;
|
||||
return _can_config(&drv_can->device, &drv_can->device.config);
|
||||
}
|
||||
break;
|
||||
case RT_CAN_CMD_GET_STATUS:
|
||||
{
|
||||
rt_uint32_t errtype;
|
||||
errtype = drv_can->CanHandle.Instance->ESR;
|
||||
drv_can->device.status.rcverrcnt = errtype >> 24;
|
||||
drv_can->device.status.snderrcnt = (errtype >> 16 & 0xFF);
|
||||
drv_can->device.status.lasterrtype = errtype & 0x70;
|
||||
drv_can->device.status.errcode = errtype & 0x07;
|
||||
|
||||
rt_memcpy(arg, &drv_can->device.status, sizeof(drv_can->device.status));
|
||||
break;
|
||||
}
|
||||
case RT_CAN_CMD_START:
|
||||
argval = (rt_uint32_t) arg;
|
||||
if (argval == 0)
|
||||
{
|
||||
HAL_CAN_Stop(&drv_can->CanHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
HAL_CAN_Start(&drv_can->CanHandle);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static int _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num)
|
||||
{
|
||||
CAN_HandleTypeDef *hcan;
|
||||
hcan = &((struct stm32_can *) can->parent.user_data)->CanHandle;
|
||||
struct rt_can_msg *pmsg = (struct rt_can_msg *) buf;
|
||||
CAN_TxHeaderTypeDef txheader = {0};
|
||||
HAL_CAN_StateTypeDef state = hcan->State;
|
||||
|
||||
/* Check the parameters */
|
||||
RT_ASSERT(IS_CAN_DLC(pmsg->len));
|
||||
|
||||
if ((state == HAL_CAN_STATE_READY) ||
|
||||
(state == HAL_CAN_STATE_LISTENING))
|
||||
{
|
||||
/*check select mailbox is empty */
|
||||
switch (1 << box_num)
|
||||
{
|
||||
case CAN_TX_MAILBOX0:
|
||||
if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0) != SET)
|
||||
{
|
||||
/* Return function status */
|
||||
return -RT_ERROR;
|
||||
}
|
||||
break;
|
||||
case CAN_TX_MAILBOX1:
|
||||
if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1) != SET)
|
||||
{
|
||||
/* Return function status */
|
||||
return -RT_ERROR;
|
||||
}
|
||||
break;
|
||||
case CAN_TX_MAILBOX2:
|
||||
if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2) != SET)
|
||||
{
|
||||
/* Return function status */
|
||||
return -RT_ERROR;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
RT_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (RT_CAN_STDID == pmsg->ide)
|
||||
{
|
||||
txheader.IDE = CAN_ID_STD;
|
||||
RT_ASSERT(IS_CAN_STDID(pmsg->id));
|
||||
txheader.StdId = pmsg->id;
|
||||
}
|
||||
else
|
||||
{
|
||||
txheader.IDE = CAN_ID_EXT;
|
||||
RT_ASSERT(IS_CAN_EXTID(pmsg->id));
|
||||
txheader.ExtId = pmsg->id;
|
||||
}
|
||||
|
||||
if (RT_CAN_DTR == pmsg->rtr)
|
||||
{
|
||||
txheader.RTR = CAN_RTR_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
txheader.RTR = CAN_RTR_REMOTE;
|
||||
}
|
||||
/* clear TIR */
|
||||
hcan->Instance->sTxMailBox[box_num].TIR &= CAN_TI0R_TXRQ;
|
||||
/* Set up the Id */
|
||||
if (RT_CAN_STDID == pmsg->ide)
|
||||
{
|
||||
hcan->Instance->sTxMailBox[box_num].TIR |= (txheader.StdId << CAN_TI0R_STID_Pos) | txheader.RTR;
|
||||
}
|
||||
else
|
||||
{
|
||||
hcan->Instance->sTxMailBox[box_num].TIR |= (txheader.ExtId << CAN_TI0R_EXID_Pos) | txheader.IDE | txheader.RTR;
|
||||
}
|
||||
/* Set up the DLC */
|
||||
hcan->Instance->sTxMailBox[box_num].TDTR = pmsg->len & 0x0FU;
|
||||
/* Set up the data field */
|
||||
WRITE_REG(hcan->Instance->sTxMailBox[box_num].TDHR,
|
||||
((uint32_t)pmsg->data[7] << CAN_TDH0R_DATA7_Pos) |
|
||||
((uint32_t)pmsg->data[6] << CAN_TDH0R_DATA6_Pos) |
|
||||
((uint32_t)pmsg->data[5] << CAN_TDH0R_DATA5_Pos) |
|
||||
((uint32_t)pmsg->data[4] << CAN_TDH0R_DATA4_Pos));
|
||||
WRITE_REG(hcan->Instance->sTxMailBox[box_num].TDLR,
|
||||
((uint32_t)pmsg->data[3] << CAN_TDL0R_DATA3_Pos) |
|
||||
((uint32_t)pmsg->data[2] << CAN_TDL0R_DATA2_Pos) |
|
||||
((uint32_t)pmsg->data[1] << CAN_TDL0R_DATA1_Pos) |
|
||||
((uint32_t)pmsg->data[0] << CAN_TDL0R_DATA0_Pos));
|
||||
/* Request transmission */
|
||||
SET_BIT(hcan->Instance->sTxMailBox[box_num].TIR, CAN_TI0R_TXRQ);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update error code */
|
||||
hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
|
||||
|
||||
return -RT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
static int _can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
CAN_HandleTypeDef *hcan;
|
||||
struct rt_can_msg *pmsg;
|
||||
CAN_RxHeaderTypeDef rxheader = {0};
|
||||
|
||||
RT_ASSERT(can);
|
||||
|
||||
hcan = &((struct stm32_can *)can->parent.user_data)->CanHandle;
|
||||
pmsg = (struct rt_can_msg *) buf;
|
||||
|
||||
/* get data */
|
||||
status = HAL_CAN_GetRxMessage(hcan, fifo, &rxheader, pmsg->data);
|
||||
if (HAL_OK != status)
|
||||
return -RT_ERROR;
|
||||
/* get id */
|
||||
if (CAN_ID_STD == rxheader.IDE)
|
||||
{
|
||||
pmsg->ide = RT_CAN_STDID;
|
||||
pmsg->id = rxheader.StdId;
|
||||
}
|
||||
else
|
||||
{
|
||||
pmsg->ide = RT_CAN_EXTID;
|
||||
pmsg->id = rxheader.ExtId;
|
||||
}
|
||||
/* get type */
|
||||
if (CAN_RTR_DATA == rxheader.RTR)
|
||||
{
|
||||
pmsg->rtr = RT_CAN_DTR;
|
||||
}
|
||||
else
|
||||
{
|
||||
pmsg->rtr = RT_CAN_RTR;
|
||||
}
|
||||
/*get rxfifo = CAN_RX_FIFO0/CAN_RX_FIFO1*/
|
||||
pmsg->rxfifo = fifo;
|
||||
|
||||
/* get len */
|
||||
pmsg->len = rxheader.DLC;
|
||||
/* get hdr_index */
|
||||
if (hcan->Instance == CAN1)
|
||||
{
|
||||
pmsg->hdr_index = rxheader.FilterMatchIndex;
|
||||
}
|
||||
#ifdef CAN2
|
||||
else if (hcan->Instance == CAN2)
|
||||
{
|
||||
pmsg->hdr_index = rxheader.FilterMatchIndex;
|
||||
}
|
||||
#endif
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
|
||||
static const struct rt_can_ops _can_ops =
|
||||
{
|
||||
_can_config,
|
||||
_can_control,
|
||||
_can_sendmsg,
|
||||
_can_recvmsg,
|
||||
};
|
||||
|
||||
static void _can_rx_isr(struct rt_can_device *can, rt_uint32_t fifo)
|
||||
{
|
||||
CAN_HandleTypeDef *hcan;
|
||||
RT_ASSERT(can);
|
||||
hcan = &((struct stm32_can *) can->parent.user_data)->CanHandle;
|
||||
|
||||
switch (fifo)
|
||||
{
|
||||
case CAN_RX_FIFO0:
|
||||
/* save to user list */
|
||||
if (HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO0) && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_RX_FIFO0_MSG_PENDING))
|
||||
{
|
||||
rt_hw_can_isr(can, RT_CAN_EVENT_RX_IND | fifo << 8);
|
||||
}
|
||||
/* Check FULL flag for FIFO0 */
|
||||
if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FF0) && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_RX_FIFO0_FULL))
|
||||
{
|
||||
/* Clear FIFO0 FULL Flag */
|
||||
__HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF0);
|
||||
}
|
||||
|
||||
/* Check Overrun flag for FIFO0 */
|
||||
if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV0) && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_RX_FIFO0_OVERRUN))
|
||||
{
|
||||
/* Clear FIFO0 Overrun Flag */
|
||||
__HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
|
||||
rt_hw_can_isr(can, RT_CAN_EVENT_RXOF_IND | fifo << 8);
|
||||
}
|
||||
break;
|
||||
case CAN_RX_FIFO1:
|
||||
/* save to user list */
|
||||
if (HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO1) && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_RX_FIFO1_MSG_PENDING))
|
||||
{
|
||||
rt_hw_can_isr(can, RT_CAN_EVENT_RX_IND | fifo << 8);
|
||||
}
|
||||
/* Check FULL flag for FIFO1 */
|
||||
if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FF1) && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_RX_FIFO1_FULL))
|
||||
{
|
||||
/* Clear FIFO1 FULL Flag */
|
||||
__HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF1);
|
||||
}
|
||||
|
||||
/* Check Overrun flag for FIFO1 */
|
||||
if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV1) && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_RX_FIFO1_OVERRUN))
|
||||
{
|
||||
/* Clear FIFO1 Overrun Flag */
|
||||
__HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
|
||||
rt_hw_can_isr(can, RT_CAN_EVENT_RXOF_IND | fifo << 8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void _can_check_tx_complete(struct rt_can_device *can)
|
||||
{
|
||||
CAN_HandleTypeDef *hcan;
|
||||
RT_ASSERT(can);
|
||||
hcan = &((struct stm32_can *) can->parent.user_data)->CanHandle;
|
||||
|
||||
if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP0))
|
||||
{
|
||||
if (!__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK0))
|
||||
{
|
||||
rt_hw_can_isr(can, RT_CAN_EVENT_TX_FAIL | 0 << 8);
|
||||
}
|
||||
SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP0);
|
||||
}
|
||||
|
||||
if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP1))
|
||||
{
|
||||
if (!__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK1))
|
||||
{
|
||||
rt_hw_can_isr(can, RT_CAN_EVENT_TX_FAIL | 1 << 8);
|
||||
}
|
||||
SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP1);
|
||||
}
|
||||
|
||||
if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP2))
|
||||
{
|
||||
if (!__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK2))
|
||||
{
|
||||
rt_hw_can_isr(can, RT_CAN_EVENT_TX_FAIL | 2 << 8);
|
||||
}
|
||||
SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP2);
|
||||
}
|
||||
|
||||
if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TERR0))/*IF AutoRetransmission = ENABLE,ACK ERR handler*/
|
||||
{
|
||||
SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ0);/*Abort the send request, trigger the TX interrupt,release completion quantity*/
|
||||
}
|
||||
|
||||
if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TERR1))
|
||||
{
|
||||
SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ1);
|
||||
}
|
||||
|
||||
if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TERR2))
|
||||
{
|
||||
SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ2);
|
||||
}
|
||||
}
|
||||
|
||||
static void _can_sce_isr(struct rt_can_device *can)
|
||||
{
|
||||
CAN_HandleTypeDef *hcan;
|
||||
RT_ASSERT(can);
|
||||
hcan = &((struct stm32_can *) can->parent.user_data)->CanHandle;
|
||||
rt_uint32_t errtype = hcan->Instance->ESR;
|
||||
|
||||
switch ((errtype & 0x70) >> 4)
|
||||
{
|
||||
case RT_CAN_BUS_BIT_PAD_ERR:
|
||||
can->status.bitpaderrcnt++;
|
||||
break;
|
||||
case RT_CAN_BUS_FORMAT_ERR:
|
||||
can->status.formaterrcnt++;
|
||||
break;
|
||||
case RT_CAN_BUS_ACK_ERR:/* attention !!! test ack err's unit is transmit unit */
|
||||
can->status.ackerrcnt++;
|
||||
break;
|
||||
case RT_CAN_BUS_IMPLICIT_BIT_ERR:
|
||||
case RT_CAN_BUS_EXPLICIT_BIT_ERR:
|
||||
can->status.biterrcnt++;
|
||||
break;
|
||||
case RT_CAN_BUS_CRC_ERR:
|
||||
can->status.crcerrcnt++;
|
||||
break;
|
||||
}
|
||||
_can_check_tx_complete(can);
|
||||
|
||||
can->status.lasterrtype = errtype & 0x70;
|
||||
can->status.rcverrcnt = errtype >> 24;
|
||||
can->status.snderrcnt = (errtype >> 16 & 0xFF);
|
||||
can->status.errcode = errtype & 0x07;
|
||||
hcan->Instance->MSR |= CAN_MSR_ERRI;
|
||||
}
|
||||
|
||||
static void _can_tx_isr(struct rt_can_device *can)
|
||||
{
|
||||
CAN_HandleTypeDef *hcan;
|
||||
RT_ASSERT(can);
|
||||
hcan = &((struct stm32_can *) can->parent.user_data)->CanHandle;
|
||||
|
||||
if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP0))
|
||||
{
|
||||
if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK0))
|
||||
{
|
||||
rt_hw_can_isr(can, RT_CAN_EVENT_TX_DONE | 0 << 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_hw_can_isr(can, RT_CAN_EVENT_TX_FAIL | 0 << 8);
|
||||
}
|
||||
/* Write 0 to Clear transmission status flag RQCPx */
|
||||
SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP0);
|
||||
}
|
||||
else if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP1))
|
||||
{
|
||||
if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK1))
|
||||
{
|
||||
rt_hw_can_isr(can, RT_CAN_EVENT_TX_DONE | 1 << 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_hw_can_isr(can, RT_CAN_EVENT_TX_FAIL | 1 << 8);
|
||||
}
|
||||
/* Write 0 to Clear transmission status flag RQCPx */
|
||||
SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP1);
|
||||
}
|
||||
else if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP2))
|
||||
{
|
||||
if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK2))
|
||||
{
|
||||
rt_hw_can_isr(can, RT_CAN_EVENT_TX_DONE | 2 << 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_hw_can_isr(can, RT_CAN_EVENT_TX_FAIL | 2 << 8);
|
||||
}
|
||||
/* Write 0 to Clear transmission status flag RQCPx */
|
||||
SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP2);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BSP_USING_CAN1
|
||||
/**
|
||||
* @brief This function handles CAN1 TX interrupts. transmit fifo0/1/2 is empty can trigger this interrupt
|
||||
*/
|
||||
void CAN1_TX_IRQHandler(void)
|
||||
{
|
||||
rt_interrupt_enter();
|
||||
_can_tx_isr(&drv_can1.device);
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles CAN1 RX0 interrupts.
|
||||
*/
|
||||
void CAN1_RX0_IRQHandler(void)
|
||||
{
|
||||
rt_interrupt_enter();
|
||||
_can_rx_isr(&drv_can1.device, CAN_RX_FIFO0);
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles CAN1 RX1 interrupts.
|
||||
*/
|
||||
void CAN1_RX1_IRQHandler(void)
|
||||
{
|
||||
rt_interrupt_enter();
|
||||
_can_rx_isr(&drv_can1.device, CAN_RX_FIFO1);
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles CAN1 SCE interrupts.
|
||||
*/
|
||||
void CAN1_SCE_IRQHandler(void)
|
||||
{
|
||||
rt_interrupt_enter();
|
||||
_can_sce_isr(&drv_can1.device);
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif /* BSP_USING_CAN1 */
|
||||
|
||||
#ifdef BSP_USING_CAN2
|
||||
/**
|
||||
* @brief This function handles CAN2 TX interrupts.
|
||||
*/
|
||||
void CAN2_TX_IRQHandler(void)
|
||||
{
|
||||
rt_interrupt_enter();
|
||||
_can_tx_isr(&drv_can2.device);
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles CAN2 RX0 interrupts.
|
||||
*/
|
||||
void CAN2_RX0_IRQHandler(void)
|
||||
{
|
||||
rt_interrupt_enter();
|
||||
_can_rx_isr(&drv_can2.device, CAN_RX_FIFO0);
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles CAN2 RX1 interrupts.
|
||||
*/
|
||||
void CAN2_RX1_IRQHandler(void)
|
||||
{
|
||||
rt_interrupt_enter();
|
||||
_can_rx_isr(&drv_can2.device, CAN_RX_FIFO1);
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles CAN2 SCE interrupts.
|
||||
*/
|
||||
void CAN2_SCE_IRQHandler(void)
|
||||
{
|
||||
rt_interrupt_enter();
|
||||
_can_sce_isr(&drv_can2.device);
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif /* BSP_USING_CAN2 */
|
||||
|
||||
int rt_hw_can_init(void)
|
||||
{
|
||||
struct can_configure config = CANDEFAULTCONFIG;
|
||||
config.privmode = RT_CAN_MODE_NOPRIV;
|
||||
config.ticks = 50;
|
||||
#ifdef RT_CAN_USING_HDR
|
||||
config.maxhdr = 14;
|
||||
#ifdef CAN2
|
||||
config.maxhdr = 28;
|
||||
#endif
|
||||
#endif
|
||||
/* config default filter */
|
||||
CAN_FilterTypeDef filterConf = {0};
|
||||
filterConf.FilterIdHigh = 0x0000;
|
||||
filterConf.FilterIdLow = 0x0000;
|
||||
filterConf.FilterMaskIdHigh = 0x0000;
|
||||
filterConf.FilterMaskIdLow = 0x0000;
|
||||
filterConf.FilterFIFOAssignment = CAN_FILTER_FIFO0;
|
||||
filterConf.FilterBank = 0;
|
||||
filterConf.FilterMode = CAN_FILTERMODE_IDMASK;
|
||||
filterConf.FilterScale = CAN_FILTERSCALE_32BIT;
|
||||
filterConf.FilterActivation = ENABLE;
|
||||
filterConf.SlaveStartFilterBank = 14;
|
||||
|
||||
#ifdef BSP_USING_CAN1
|
||||
filterConf.FilterBank = 0;
|
||||
|
||||
drv_can1.FilterConfig = filterConf;
|
||||
drv_can1.device.config = config;
|
||||
/* register CAN1 device */
|
||||
rt_hw_can_register(&drv_can1.device,
|
||||
drv_can1.name,
|
||||
&_can_ops,
|
||||
&drv_can1);
|
||||
#endif /* BSP_USING_CAN1 */
|
||||
|
||||
#ifdef BSP_USING_CAN2
|
||||
filterConf.FilterBank = filterConf.SlaveStartFilterBank;
|
||||
|
||||
drv_can2.FilterConfig = filterConf;
|
||||
drv_can2.device.config = config;
|
||||
/* register CAN2 device */
|
||||
rt_hw_can_register(&drv_can2.device,
|
||||
drv_can2.name,
|
||||
&_can_ops,
|
||||
&drv_can2);
|
||||
#endif /* BSP_USING_CAN2 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INIT_BOARD_EXPORT(rt_hw_can_init);
|
||||
|
||||
#endif /* BSP_USING_CAN */
|
||||
|
||||
/************************** end of file ******************/
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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>
|
||||
|
||||
#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 ******************/
|
||||
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2024 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 <rtdevice.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(SOC_SERIES_STM32F0)
|
||||
#include "f0/dma_config.h"
|
||||
#include "f0/uart_config.h"
|
||||
#include "f0/spi_config.h"
|
||||
#include "f0/tim_config.h"
|
||||
#include "f0/pwm_config.h"
|
||||
#include "f0/adc_config.h"
|
||||
#elif defined(SOC_SERIES_STM32F1)
|
||||
#include "f1/dma_config.h"
|
||||
#include "f1/uart_config.h"
|
||||
#include "f1/spi_config.h"
|
||||
#include "f1/adc_config.h"
|
||||
#include "f1/tim_config.h"
|
||||
#include "f1/sdio_config.h"
|
||||
#include "f1/pwm_config.h"
|
||||
#include "f1/usbd_config.h"
|
||||
#include "f1/i2c_hard_config.h"
|
||||
#include "f1/pulse_encoder_config.h"
|
||||
#elif defined(SOC_SERIES_STM32F2)
|
||||
#include "f2/dma_config.h"
|
||||
#include "f2/uart_config.h"
|
||||
#include "f2/spi_config.h"
|
||||
#include "f2/adc_config.h"
|
||||
#include "f2/tim_config.h"
|
||||
#include "f2/sdio_config.h"
|
||||
#include "f2/pwm_config.h"
|
||||
#elif defined(SOC_SERIES_STM32F3)
|
||||
#include "f3/uart_config.h"
|
||||
#include "f3/tim_config.h"
|
||||
#include "f3/pwm_config.h"
|
||||
#include "f3/dma_config.h"
|
||||
#elif defined(SOC_SERIES_STM32F4)
|
||||
#include "f4/dma_config.h"
|
||||
#include "f4/uart_config.h"
|
||||
#include "f4/spi_config.h"
|
||||
#include "f4/qspi_config.h"
|
||||
#include "f4/usbd_config.h"
|
||||
#include "f4/adc_config.h"
|
||||
#include "f4/dac_config.h"
|
||||
#include "f4/tim_config.h"
|
||||
#include "f4/sdio_config.h"
|
||||
#include "f4/pwm_config.h"
|
||||
#include "f4/i2c_hard_config.h"
|
||||
#include "f4/pulse_encoder_config.h"
|
||||
#elif defined(SOC_SERIES_STM32F7)
|
||||
#include "f7/dma_config.h"
|
||||
#include "f7/uart_config.h"
|
||||
#include "f7/spi_config.h"
|
||||
#include "f7/qspi_config.h"
|
||||
#include "f7/adc_config.h"
|
||||
#include "f7/tim_config.h"
|
||||
#include "f7/sdio_config.h"
|
||||
#include "f7/pwm_config.h"
|
||||
#elif defined(SOC_SERIES_STM32L0)
|
||||
#include "l0/dma_config.h"
|
||||
#include "l0/uart_config.h"
|
||||
#elif defined(SOC_SERIES_STM32L4)
|
||||
#include "l4/dma_config.h"
|
||||
#include "l4/uart_config.h"
|
||||
#include "l4/spi_config.h"
|
||||
#include "l4/qspi_config.h"
|
||||
#include "l4/adc_config.h"
|
||||
#include "l4/dac_config.h"
|
||||
#include "l4/tim_config.h"
|
||||
#include "l4/sdio_config.h"
|
||||
#include "l4/pwm_config.h"
|
||||
#include "l4/usbd_config.h"
|
||||
#elif defined(SOC_SERIES_STM32L5)
|
||||
#include "l5/dma_config.h"
|
||||
#include "l5/uart_config.h"
|
||||
#include "l5/spi_config.h"
|
||||
#include "l5/qspi_config.h"
|
||||
#include "l5/adc_config.h"
|
||||
#include "l5/dac_config.h"
|
||||
#include "l5/tim_config.h"
|
||||
#include "l5/sdio_config.h"
|
||||
#include "l5/pwm_config.h"
|
||||
#include "l5/usbd_config.h"
|
||||
#elif defined(SOC_SERIES_STM32G0)
|
||||
#include "g0/dma_config.h"
|
||||
#include "g0/uart_config.h"
|
||||
#include "g0/spi_config.h"
|
||||
#include "g0/adc_config.h"
|
||||
#include "g0/tim_config.h"
|
||||
#include "g0/pwm_config.h"
|
||||
#elif defined(SOC_SERIES_STM32G4)
|
||||
#include "g4/dma_config.h"
|
||||
#include "g4/uart_config.h"
|
||||
#include "g4/spi_config.h"
|
||||
#include "g4/qspi_config.h"
|
||||
#include "g4/usbd_config.h"
|
||||
#include "g4/adc_config.h"
|
||||
#include "g4/tim_config.h"
|
||||
#include "g4/sdio_config.h"
|
||||
#include "g4/pwm_config.h"
|
||||
#include "g4/pulse_encoder_config.h"
|
||||
#elif defined(SOC_SERIES_STM32H7)
|
||||
#include "h7/dma_config.h"
|
||||
#include "h7/uart_config.h"
|
||||
#include "h7/spi_config.h"
|
||||
#include "h7/qspi_config.h"
|
||||
#include "h7/adc_config.h"
|
||||
#include "h7/dac_config.h"
|
||||
#include "h7/tim_config.h"
|
||||
#include "h7/lptim_config.h"
|
||||
#include "h7/sdio_config.h"
|
||||
#include "h7/pwm_config.h"
|
||||
#include "h7/usbd_config.h"
|
||||
|
||||
#elif defined(SOC_SERIES_STM32H7RS)
|
||||
#include "h7/dma_config.h"
|
||||
#include "h7/uart_config.h"
|
||||
#include "h7/spi_config.h"
|
||||
#include "h7/adc_config.h"
|
||||
#include "h7/dac_config.h"
|
||||
#include "h7/tim_config.h"
|
||||
#include "h7/pwm_config.h"
|
||||
#include "h7/usbd_config.h"
|
||||
|
||||
#elif defined(SOC_SERIES_STM32U5)
|
||||
#include "u5/dma_config.h"
|
||||
#include "u5/uart_config.h"
|
||||
#include "u5/spi_config.h"
|
||||
#include "u5/qspi_config.h"
|
||||
#include "u5/adc_config.h"
|
||||
#include "u5/dac_config.h"
|
||||
#include "u5/tim_config.h"
|
||||
#include "u5/sdio_config.h"
|
||||
#include "u5/pwm_config.h"
|
||||
#include "u5/usbd_config.h"
|
||||
#elif defined(SOC_SERIES_STM32H5)
|
||||
#include "h5/uart_config.h"
|
||||
#include "h5/pwm_config.h"
|
||||
#include "h5/adc_config.h"
|
||||
#elif defined(SOC_SERIES_STM32MP1)
|
||||
#include "mp1/dma_config.h"
|
||||
#include "mp1/uart_config.h"
|
||||
#include "mp1/qspi_config.h"
|
||||
#include "mp1/spi_config.h"
|
||||
#include "mp1/adc_config.h"
|
||||
#include "mp1/dac_config.h"
|
||||
#include "mp1/tim_config.h"
|
||||
#include "mp1/pwm_config.h"
|
||||
#elif defined(SOC_SERIES_STM32WL)
|
||||
#include "wl/dma_config.h"
|
||||
#include "wl/uart_config.h"
|
||||
#include "wl/spi_config.h"
|
||||
#include "wl/tim_config.h"
|
||||
#elif defined(SOC_SERIES_STM32WB)
|
||||
#include "wb/adc_config.h"
|
||||
#include "wb/dma_config.h"
|
||||
#include "wb/pwm_config.h"
|
||||
#include "wb/qspi_config.h"
|
||||
#include "wb/spi_config.h"
|
||||
#include "wb/tim_config.h"
|
||||
#include "wb/uart_config.h"
|
||||
#include "wb/usbd_config.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,740 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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 <rtdevice.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "drv_crypto.h"
|
||||
#include <board.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:
|
||||
{
|
||||
__HAL_RCC_RNG_CLK_ENABLE();
|
||||
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);
|
||||
@@ -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__ */
|
||||
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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>
|
||||
#include <rtthread.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_uint8_t stm32_dac_get_resolution(struct rt_dac_device *device)
|
||||
{
|
||||
DAC_HandleTypeDef *stm32_dac_handler;
|
||||
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
|
||||
stm32_dac_handler = device->parent.user_data;
|
||||
(void)stm32_dac_handler;
|
||||
|
||||
/* Only has supported DAC_ALIGN_12B_R, so it will return 12 bits */
|
||||
return 12;
|
||||
}
|
||||
|
||||
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,
|
||||
.get_resolution = stm32_dac_get_resolution,
|
||||
};
|
||||
|
||||
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 */
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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) || defined(SOC_SERIES_STM32H5) || defined(SOC_SERIES_STM32H7RS)
|
||||
#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_ */
|
||||
@@ -0,0 +1,669 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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 "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
|
||||
|
||||
#undef PHY_FULL_DUPLEX
|
||||
#define PHY_LINK (1 << 0)
|
||||
#define PHY_100M (1 << 1)
|
||||
#define PHY_FULL_DUPLEX (1 << 2)
|
||||
|
||||
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_ssize_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_ssize_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");
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
#ifdef PHY_USING_YT8512C
|
||||
if (temp != 0xFFFF)
|
||||
#else
|
||||
if (temp != 0xFFFF && temp != 0x00)
|
||||
#endif /* PHY_USING_YT8512C */
|
||||
{
|
||||
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);
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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
|
||||
|
||||
#if defined(PHY_USING_LAN8720A) || defined(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)
|
||||
|
||||
#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)
|
||||
|
||||
#elif defined(PHY_USING_YT8512C)
|
||||
/* The PHY interrupt source flag register. */
|
||||
#define PHY_INTERRUPT_FLAG_REG 0x13U
|
||||
/* The PHY interrupt mask register. */
|
||||
#define PHY_INTERRUPT_MASK_REG 0x12U
|
||||
/* The PHY auto nego and link change mask. */
|
||||
#define PHY_INT_MASK (1<<15)|(3<<10)
|
||||
/* The PHY status register. */
|
||||
#define PHY_Status_REG 0x11U
|
||||
#define PHY_100M_MASK (1<<14)
|
||||
#define PHY_FULL_DUPLEX_MASK (1<<13)
|
||||
#define PHY_Status_SPEED_10M(sr) (!PHY_Status_SPEED_100M(sr))
|
||||
#define PHY_Status_SPEED_100M(sr) ((sr) & PHY_100M_MASK)
|
||||
#define PHY_Status_FULL_DUPLEX(sr) ((sr) & PHY_FULL_DUPLEX_MASK)
|
||||
#endif /* defined(PHY_USING_LAN8720A) || defined(PHY_USING_LAN8742A) */
|
||||
|
||||
#endif /* __DRV_ETH_H__ */
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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__ */
|
||||
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-12-5 SummerGift first version
|
||||
* 2020-03-05 redoc support stm32f103vg
|
||||
*
|
||||
*/
|
||||
|
||||
#include <rtconfig.h>
|
||||
#include <rtdef.h>
|
||||
|
||||
#ifdef BSP_USING_ON_CHIP_FLASH
|
||||
#include "drv_config.h"
|
||||
#include "drv_flash.h"
|
||||
#include <board.h>
|
||||
|
||||
#if defined(RT_USING_FAL)
|
||||
#include "fal.h"
|
||||
#endif
|
||||
|
||||
//#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.flash"
|
||||
#include <drv_log.h>
|
||||
|
||||
/**
|
||||
* @brief Gets the page of a given address
|
||||
* @param Addr: Address of the FLASH Memory
|
||||
* @retval The page of a given address
|
||||
*/
|
||||
static uint32_t GetPage(uint32_t addr)
|
||||
{
|
||||
uint32_t page = 0;
|
||||
page = RT_ALIGN_DOWN(addr, FLASH_PAGE_SIZE);
|
||||
return page;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 -RT_EINVAL;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (addr % 4 != 0)
|
||||
{
|
||||
LOG_E("write addr must be 4-byte alignment");
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
if ((end_addr) > STM32_FLASH_END_ADDRESS)
|
||||
{
|
||||
LOG_E("write outrange flash size! addr is (0x%p)", (void *)(addr + size));
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
while (addr < end_addr)
|
||||
{
|
||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr, *((rt_uint32_t *)buf)) == HAL_OK)
|
||||
{
|
||||
if (*(rt_uint32_t *)addr != *(rt_uint32_t *)buf)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
break;
|
||||
}
|
||||
addr += 4;
|
||||
buf += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
if (result != RT_EOK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erase data on flash with bank.
|
||||
* @note This operation is irreversible.
|
||||
* @note This operation's units is different which on many chips.
|
||||
*
|
||||
* @param bank flash bank
|
||||
* @param addr flash address
|
||||
* @param size erase bytes size
|
||||
*
|
||||
* @return result
|
||||
*/
|
||||
int stm32_flash_erase_bank(uint32_t bank, rt_uint32_t addr, size_t size)
|
||||
{
|
||||
rt_err_t result = RT_EOK;
|
||||
uint32_t PAGEError = 0;
|
||||
|
||||
/*Variable used for Erase procedure*/
|
||||
FLASH_EraseInitTypeDef EraseInitStruct;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
/* Fill EraseInit structure*/
|
||||
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInitStruct.PageAddress = GetPage(addr);
|
||||
EraseInitStruct.NbPages = (size + FLASH_PAGE_SIZE - 1) / FLASH_PAGE_SIZE;
|
||||
EraseInitStruct.Banks = bank;
|
||||
|
||||
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
#if defined(FLASH_BANK2_END)
|
||||
rt_err_t result = RT_EOK;
|
||||
rt_uint32_t addr_bank1 = 0;
|
||||
rt_uint32_t size_bank1 = 0;
|
||||
rt_uint32_t addr_bank2 = 0;
|
||||
rt_uint32_t size_bank2 = 0;
|
||||
|
||||
if((addr + size) <= FLASH_BANK1_END)
|
||||
{
|
||||
addr_bank1 = addr;
|
||||
size_bank1 = size;
|
||||
size_bank2 = 0;
|
||||
}
|
||||
else if(addr > FLASH_BANK1_END)
|
||||
{
|
||||
size_bank1 = 0;
|
||||
addr_bank2 = addr;
|
||||
size_bank2 = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
addr_bank1 = addr;
|
||||
size_bank1 = FLASH_BANK1_END + 1 - addr_bank1;
|
||||
addr_bank2 = FLASH_BANK1_END + 1;
|
||||
size_bank2 = addr + size - (FLASH_BANK1_END + 1);
|
||||
}
|
||||
|
||||
if(size_bank1)
|
||||
{
|
||||
LOG_D("bank1: addr (0x%p), size %d", (void *)addr_bank1, size_bank1);
|
||||
if(size_bank1 != stm32_flash_erase_bank(FLASH_BANK_1, addr_bank1, size_bank1))
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
}
|
||||
|
||||
if(size_bank2)
|
||||
{
|
||||
LOG_D("bank2: addr (0x%p), size %d", (void *)addr_bank2, size_bank2);
|
||||
if(size_bank2 != stm32_flash_erase_bank(FLASH_BANK_2, addr_bank2, size_bank2))
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
}
|
||||
|
||||
__exit:
|
||||
if(result != RT_EOK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return size_bank1 + size_bank2;
|
||||
#else
|
||||
return stm32_flash_erase_bank(FLASH_BANK_1, addr, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if defined(RT_USING_FAL)
|
||||
|
||||
static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size);
|
||||
static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size);
|
||||
static int fal_flash_erase(long offset, size_t size);
|
||||
|
||||
const struct fal_flash_dev stm32_onchip_flash = { "onchip_flash", STM32_FLASH_START_ADRESS, STM32_FLASH_SIZE, FLASH_PAGE_SIZE, {NULL, fal_flash_read, fal_flash_write, fal_flash_erase} };
|
||||
|
||||
static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size)
|
||||
{
|
||||
return stm32_flash_read(stm32_onchip_flash.addr + offset, buf, size);
|
||||
}
|
||||
|
||||
static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size)
|
||||
{
|
||||
return stm32_flash_write(stm32_onchip_flash.addr + offset, buf, size);
|
||||
}
|
||||
|
||||
static int fal_flash_erase(long offset, size_t size)
|
||||
{
|
||||
return stm32_flash_erase(stm32_onchip_flash.addr + offset, size);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* BSP_USING_ON_CHIP_FLASH */
|
||||
@@ -0,0 +1,464 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-12-5 SummerGift first version
|
||||
*/
|
||||
|
||||
#include <rtconfig.h>
|
||||
#include <rtdef.h>
|
||||
|
||||
#ifdef BSP_USING_ON_CHIP_FLASH
|
||||
#include "drv_config.h"
|
||||
#include "drv_flash.h"
|
||||
#include <board.h>
|
||||
|
||||
#if defined(RT_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)
|
||||
|
||||
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,
|
||||
},
|
||||
8,
|
||||
{},
|
||||
};
|
||||
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,
|
||||
},
|
||||
8,
|
||||
{},
|
||||
};
|
||||
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,
|
||||
},
|
||||
8,
|
||||
{},
|
||||
};
|
||||
|
||||
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 */
|
||||
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-12-5 SummerGift first version
|
||||
* 2019-3-2 jinsheng add Macro judgment
|
||||
* 2020-1-6 duminmin support single bank mode
|
||||
* 2020-5-17 yufanyufan77 support support H7
|
||||
* 2021-3-3 zhuyf233 fix some bugs
|
||||
*/
|
||||
|
||||
#include <rtconfig.h>
|
||||
#include <rtdef.h>
|
||||
|
||||
#ifdef BSP_USING_ON_CHIP_FLASH
|
||||
#include "drv_config.h"
|
||||
#include "drv_flash.h"
|
||||
#include <board.h>
|
||||
|
||||
#if defined(RT_USING_FAL)
|
||||
#include "fal.h"
|
||||
#endif
|
||||
|
||||
//#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.flash"
|
||||
#include <drv_log.h>
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @retval The length of bytes that have been read
|
||||
*/
|
||||
int stm32_flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if ((addr + size - 1) > FLASH_END)
|
||||
{
|
||||
LOG_E("read outrange flash size! addr is (0x%p)", (void *)(addr + size));
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
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 The length of bytes that have been written
|
||||
*/
|
||||
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 - 1, write_addr;
|
||||
rt_uint32_t write_granularity = FLASH_NB_32BITWORD_IN_FLASHWORD * 4;
|
||||
rt_uint32_t write_size = write_granularity;
|
||||
rt_uint8_t write_buffer[32] = {0};
|
||||
|
||||
if ((end_addr) > FLASH_END)
|
||||
{
|
||||
LOG_E("write outrange flash size! addr is (0x%p)", (void *)(addr + size));
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
if(addr % 32 != 0)
|
||||
{
|
||||
LOG_E("write addr must be 32-byte alignment");
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
if (size < 1)
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
write_addr = (uint32_t)buf;
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR);
|
||||
while (addr < end_addr)
|
||||
{
|
||||
if(end_addr - addr + 1 < write_granularity)
|
||||
{
|
||||
write_size = end_addr - addr + 1;
|
||||
for(size_t i = 0; i < write_size; i++)
|
||||
{
|
||||
write_buffer[i] = *((uint8_t *)(write_addr + i));
|
||||
}
|
||||
write_addr = (uint32_t)((rt_uint32_t *)write_buffer);
|
||||
}
|
||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, addr, write_addr) == HAL_OK)
|
||||
{
|
||||
for(rt_uint8_t i = 0; i < write_size; i++)
|
||||
{
|
||||
if (*(rt_uint8_t *)(addr + i) != *(rt_uint8_t *)(write_addr + i))
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
}
|
||||
addr += write_granularity;
|
||||
write_addr += write_granularity;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
}
|
||||
|
||||
__exit:
|
||||
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 SECTORError = 0;
|
||||
|
||||
if ((addr + size - 1) > FLASH_END)
|
||||
{
|
||||
LOG_E("ERROR: erase outrange flash size! addr is (0x%p)\n", (void *)(addr + size));
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
rt_uint32_t addr_bank1 = 0;
|
||||
rt_uint32_t size_bank1 = 0;
|
||||
#ifdef FLASH_BANK_2
|
||||
rt_uint32_t addr_bank2 = 0;
|
||||
rt_uint32_t size_bank2 = 0;
|
||||
#endif
|
||||
|
||||
if((addr + size) < FLASH_BANK2_BASE)
|
||||
{
|
||||
addr_bank1 = addr;
|
||||
size_bank1 = size;
|
||||
#ifdef FLASH_BANK_2
|
||||
size_bank2 = 0;
|
||||
#endif
|
||||
}
|
||||
else if(addr >= FLASH_BANK2_BASE)
|
||||
{
|
||||
size_bank1 = 0;
|
||||
#ifdef FLASH_BANK_2
|
||||
addr_bank2 = addr;
|
||||
size_bank2 = size;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
addr_bank1 = addr;
|
||||
size_bank1 = FLASH_BANK2_BASE - addr_bank1;
|
||||
#ifdef FLASH_BANK_2
|
||||
addr_bank2 = FLASH_BANK2_BASE;
|
||||
size_bank2 = addr + size - FLASH_BANK2_BASE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*Variable used for Erase procedure*/
|
||||
FLASH_EraseInitTypeDef EraseInitStruct;
|
||||
/* Unlock the Flash to enable the flash control register access */
|
||||
HAL_FLASH_Unlock();
|
||||
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
|
||||
EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
|
||||
SCB_DisableDCache();
|
||||
|
||||
if(size_bank1)
|
||||
{
|
||||
EraseInitStruct.Sector = (addr_bank1 - FLASH_BANK1_BASE) / FLASH_SECTOR_SIZE;
|
||||
EraseInitStruct.NbSectors = (addr_bank1 + size_bank1 -1 - FLASH_BANK1_BASE) / FLASH_SECTOR_SIZE - EraseInitStruct.Sector + 1;
|
||||
EraseInitStruct.Banks = FLASH_BANK_1;
|
||||
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FLASH_BANK_2
|
||||
if(size_bank2)
|
||||
{
|
||||
EraseInitStruct.Sector = (addr_bank2 - FLASH_BANK2_BASE) / FLASH_SECTOR_SIZE;
|
||||
EraseInitStruct.NbSectors = (addr_bank2 + size_bank2 -1 - FLASH_BANK2_BASE) / FLASH_SECTOR_SIZE - EraseInitStruct.Sector + 1;
|
||||
EraseInitStruct.Banks = FLASH_BANK_2;
|
||||
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK)
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
__exit:
|
||||
|
||||
SCB_EnableDCache();
|
||||
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)
|
||||
static int fal_flash_read_128k(long offset, 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_128k(long offset, size_t size);
|
||||
const struct fal_flash_dev stm32_onchip_flash_128k = { "onchip_flash_128k", STM32_FLASH_START_ADRESS, FLASH_SIZE_GRANULARITY_128K, (128 * 1024), {NULL, fal_flash_read_128k, fal_flash_write_128k, fal_flash_erase_128k} };
|
||||
|
||||
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_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_128k(long offset, size_t size)
|
||||
{
|
||||
return stm32_flash_erase(stm32_onchip_flash_128k.addr + offset, size);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* BSP_USING_ON_CHIP_FLASH */
|
||||
@@ -0,0 +1,831 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2025, 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>
|
||||
#include "drv_gpio.h"
|
||||
|
||||
#ifdef BSP_USING_GPIO
|
||||
|
||||
#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 16u
|
||||
#elif defined(GPIOP)
|
||||
#define __STM32_PORT_MAX 15u
|
||||
#elif defined(GPIOO)
|
||||
#define __STM32_PORT_MAX 14u
|
||||
#elif defined(GPION)
|
||||
#define __STM32_PORT_MAX 13u
|
||||
#elif defined(GPIOM)
|
||||
#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
|
||||
|
||||
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) \
|
||||
|| defined(SOC_SERIES_STM32H5) || defined(SOC_SERIES_STM32H7RS)
|
||||
{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]))
|
||||
|
||||
/* e.g. PE.7 */
|
||||
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))
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
if ((name[0] != 'P') || (name[2] != '.'))
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((name[1] >= 'A') && (name[1] <= 'Z'))
|
||||
{
|
||||
hw_port_num = (int)(name[1] - 'A');
|
||||
}
|
||||
else
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
out:
|
||||
rt_kprintf("Px.y x:A~Z y:0-15, e.g. PA.0\n");
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
static void stm32_pin_write(rt_device_t dev, rt_base_t pin, rt_uint8_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 rt_ssize_t stm32_pin_read(rt_device_t dev, rt_base_t pin)
|
||||
{
|
||||
GPIO_TypeDef *gpio_port;
|
||||
uint16_t gpio_pin;
|
||||
GPIO_PinState state = GPIO_PIN_RESET;
|
||||
|
||||
if (PIN_PORT(pin) < PIN_STPORT_MAX)
|
||||
{
|
||||
gpio_port = PIN_STPORT(pin);
|
||||
gpio_pin = PIN_STPIN(pin);
|
||||
state = HAL_GPIO_ReadPin(gpio_port, gpio_pin);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
return (state == GPIO_PIN_RESET) ? PIN_LOW : PIN_HIGH;
|
||||
}
|
||||
|
||||
static void stm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_uint8_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.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_int32_t i;
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (((rt_uint32_t)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 >= (rt_int32_t)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_base_t pin,
|
||||
rt_uint8_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 >= (rt_int32_t)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_base_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 >= (rt_int32_t)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_uint8_t enabled)
|
||||
{
|
||||
const struct pin_irq_map *irqmap;
|
||||
rt_base_t level;
|
||||
rt_int32_t irqindex = -1;
|
||||
|
||||
if (PIN_PORT(pin) >= PIN_STPORT_MAX)
|
||||
{
|
||||
return -RT_ENOSYS;
|
||||
}
|
||||
|
||||
if (enabled == PIN_IRQ_ENABLE)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
irqindex = bit2bitno(PIN_STPIN(pin));
|
||||
if (irqindex < 0 || irqindex >= (rt_int32_t)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;
|
||||
}
|
||||
static const 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_NULL,
|
||||
};
|
||||
|
||||
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) || defined(SOC_SERIES_STM32U5)
|
||||
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) || defined(SOC_SERIES_STM32H7RS)
|
||||
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
|
||||
|
||||
#if defined(__HAL_RCC_GPIOM_CLK_ENABLE)
|
||||
__HAL_RCC_GPIOM_CLK_ENABLE();
|
||||
#endif
|
||||
|
||||
#if defined(__HAL_RCC_GPION_CLK_ENABLE)
|
||||
__HAL_RCC_GPION_CLK_ENABLE();
|
||||
#endif
|
||||
|
||||
#if defined(__HAL_RCC_GPIOO_CLK_ENABLE)
|
||||
__HAL_RCC_GPIOO_CLK_ENABLE();
|
||||
#endif
|
||||
|
||||
#if defined(__HAL_RCC_GPIOP_CLK_ENABLE)
|
||||
__HAL_RCC_GPIOP_CLK_ENABLE();
|
||||
#endif
|
||||
|
||||
return rt_device_pin_register("pin", &_stm32_pin_ops, RT_NULL);
|
||||
}
|
||||
|
||||
#endif /* BSP_USING_GPIO */
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-11-06 balanceTWK first version
|
||||
* 2020-06-16 thread-liu add stm32mp1
|
||||
* 2020-09-01 thread-liu add GPIOZ
|
||||
* 2020-09-18 geniusgogo optimization design pin-index algorithm
|
||||
*/
|
||||
|
||||
#ifndef __DRV_GPIO_H__
|
||||
#define __DRV_GPIO_H__
|
||||
|
||||
#include <rtdevice.h>
|
||||
#include <board.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
struct pin_irq_map
|
||||
{
|
||||
rt_uint16_t pinbit;
|
||||
IRQn_Type irqno;
|
||||
};
|
||||
|
||||
int rt_hw_pin_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __DRV_GPIO_H__ */
|
||||
|
||||
@@ -0,0 +1,721 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2024-02-17 Dyyt587 first version
|
||||
* 2024-04-23 Zeidan fix bugs, test on STM32F429IGTx
|
||||
* 2024-12-10 zzk597 add support for STM32F1 series
|
||||
*/
|
||||
|
||||
#include "drv_hard_i2c.h"
|
||||
|
||||
/* not fully support for I2C4 */
|
||||
#if defined(BSP_USING_HARD_I2C1) || defined(BSP_USING_HARD_I2C2) || defined(BSP_USING_HARD_I2C3)
|
||||
|
||||
//#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.i2c.hw"
|
||||
#include <drv_log.h>
|
||||
|
||||
enum
|
||||
{
|
||||
#ifdef BSP_USING_HARD_I2C1
|
||||
I2C1_INDEX,
|
||||
#endif /* BSP_USING_HARD_I2C1 */
|
||||
#ifdef BSP_USING_HARD_I2C2
|
||||
I2C2_INDEX,
|
||||
#endif /* BSP_USING_HARD_I2C2 */
|
||||
#ifdef BSP_USING_HARD_I2C3
|
||||
I2C3_INDEX,
|
||||
#endif /* BSP_USING_HARD_I2C3 */
|
||||
};
|
||||
|
||||
static struct stm32_i2c_config i2c_config[] =
|
||||
{
|
||||
#ifdef BSP_USING_HARD_I2C1
|
||||
I2C1_BUS_CONFIG,
|
||||
#endif /* BSP_USING_HARD_I2C1 */
|
||||
#ifdef BSP_USING_HARD_I2C2
|
||||
I2C2_BUS_CONFIG,
|
||||
#endif /* BSP_USING_HARD_I2C2 */
|
||||
#ifdef BSP_USING_HARD_I2C3
|
||||
I2C3_BUS_CONFIG,
|
||||
#endif /* BSP_USING_HARD_I2C3 */
|
||||
};
|
||||
|
||||
static struct stm32_i2c i2c_objs[sizeof(i2c_config) / sizeof(i2c_config[0])] = {0};
|
||||
|
||||
static rt_err_t stm32_i2c_init(struct stm32_i2c *i2c_drv)
|
||||
{
|
||||
RT_ASSERT(i2c_drv != RT_NULL);
|
||||
|
||||
I2C_HandleTypeDef *i2c_handle = &i2c_drv->handle;
|
||||
struct stm32_i2c_config *cfg = i2c_drv->config;
|
||||
|
||||
rt_memset(i2c_handle, 0, sizeof(I2C_HandleTypeDef));
|
||||
|
||||
i2c_handle->Instance = cfg->Instance;
|
||||
#if defined(SOC_SERIES_STM32H7)
|
||||
i2c_handle->Init.Timing = cfg->timing;
|
||||
#endif /* defined(SOC_SERIES_STM32H7) */
|
||||
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F4)
|
||||
i2c_handle->Init.ClockSpeed = 100000;
|
||||
i2c_handle->Init.DutyCycle = I2C_DUTYCYCLE_2;
|
||||
#endif /* defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F4) */
|
||||
i2c_handle->Init.OwnAddress1 = 0;
|
||||
i2c_handle->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
|
||||
i2c_handle->Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
|
||||
i2c_handle->Init.OwnAddress2 = 0;
|
||||
i2c_handle->Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
|
||||
i2c_handle->Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
|
||||
if (HAL_I2C_DeInit(i2c_handle) != HAL_OK)
|
||||
{
|
||||
return -RT_EFAULT;
|
||||
}
|
||||
|
||||
if (HAL_I2C_Init(i2c_handle) != HAL_OK)
|
||||
{
|
||||
return -RT_EFAULT;
|
||||
}
|
||||
#if defined(SOC_SERIES_STM32H7)
|
||||
/* Configure Analogue filter */
|
||||
if (HAL_I2CEx_ConfigAnalogFilter(i2c_handle, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
|
||||
{
|
||||
return -RT_EFAULT;
|
||||
}
|
||||
|
||||
/* Configure Digital filter */
|
||||
if (HAL_I2CEx_ConfigDigitalFilter(i2c_handle, 0) != HAL_OK)
|
||||
{
|
||||
return -RT_EFAULT;
|
||||
}
|
||||
#endif /* defined(SOC_SERIES_STM32H7) */
|
||||
/* I2C2 DMA Init */
|
||||
if (i2c_drv->i2c_dma_flag & I2C_USING_RX_DMA_FLAG)
|
||||
{
|
||||
HAL_DMA_Init(&i2c_drv->dma.handle_rx);
|
||||
|
||||
__HAL_LINKDMA(&i2c_drv->handle, hdmarx, i2c_drv->dma.handle_rx);
|
||||
|
||||
/* NVIC configuration for DMA transfer complete interrupt */
|
||||
HAL_NVIC_SetPriority(i2c_drv->config->dma_rx->dma_irq, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(i2c_drv->config->dma_rx->dma_irq);
|
||||
}
|
||||
|
||||
if (i2c_drv->i2c_dma_flag & I2C_USING_TX_DMA_FLAG)
|
||||
{
|
||||
HAL_DMA_Init(&i2c_drv->dma.handle_tx);
|
||||
|
||||
__HAL_LINKDMA(&i2c_drv->handle, hdmatx, i2c_drv->dma.handle_tx);
|
||||
|
||||
/* NVIC configuration for DMA transfer complete interrupt */
|
||||
HAL_NVIC_SetPriority(i2c_drv->config->dma_tx->dma_irq, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(i2c_drv->config->dma_tx->dma_irq);
|
||||
}
|
||||
|
||||
/* In the data transfer function stm32_i2c_master_xfer(), the IT transfer function
|
||||
HAL_I2C_Master_Seq_Transmit_IT() is used when DMA is not used, so the IT interrupt
|
||||
must be enable anyway, regardless of the DMA configuration, otherwise
|
||||
the rt_completion_wait() will always timeout. */
|
||||
HAL_NVIC_SetPriority(i2c_drv->config->evirq_type, 2, 0);
|
||||
HAL_NVIC_EnableIRQ(i2c_drv->config->evirq_type);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t stm32_i2c_configure(struct rt_i2c_bus_device *bus)
|
||||
{
|
||||
RT_ASSERT(RT_NULL != bus);
|
||||
struct stm32_i2c *i2c_drv = rt_container_of(bus, struct stm32_i2c, i2c_bus);
|
||||
|
||||
return stm32_i2c_init(i2c_drv);
|
||||
}
|
||||
/**
|
||||
* @brief Hardware I2C driver transfer
|
||||
*
|
||||
* @param bus Device bus
|
||||
* @param msgs Data to be transferred
|
||||
* @param num Number of data
|
||||
* @return rt_ssize_t Transfer status
|
||||
*/
|
||||
static rt_ssize_t stm32_i2c_master_xfer(struct rt_i2c_bus_device *bus,
|
||||
struct rt_i2c_msg msgs[],
|
||||
rt_uint32_t num)
|
||||
{
|
||||
/* for stm32 dma may more stability */
|
||||
#define DMA_TRANS_MIN_LEN 2 /* only buffer length >= DMA_TRANS_MIN_LEN will use DMA mode */
|
||||
#define TRANS_TIMEOUT_PERSEC 8 /* per ms will trans nums bytes */
|
||||
|
||||
rt_int32_t i, ret;
|
||||
struct rt_i2c_msg *msg = msgs;
|
||||
struct rt_i2c_msg *next_msg = 0;
|
||||
struct stm32_i2c *i2c_obj;
|
||||
uint32_t mode = 0;
|
||||
uint8_t next_flag = 0;
|
||||
struct rt_completion *completion;
|
||||
rt_uint32_t timeout;
|
||||
|
||||
if (num == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
RT_ASSERT((msgs != RT_NULL) && (bus != RT_NULL));
|
||||
|
||||
i2c_obj = rt_container_of(bus, struct stm32_i2c, i2c_bus);
|
||||
completion = &i2c_obj->completion;
|
||||
I2C_HandleTypeDef *handle = &i2c_obj->handle;
|
||||
|
||||
LOG_D("xfer start %d mags", num);
|
||||
for (i = 0; i < (num - 1); i++)
|
||||
{
|
||||
mode = 0;
|
||||
msg = &msgs[i];
|
||||
LOG_D("xfer msgs[%d] addr=0x%2x buf=0x%x len= 0x%x flags= 0x%x", i, msg->addr, msg->buf, msg->len, msg->flags);
|
||||
next_msg = &msgs[i + 1];
|
||||
next_flag = next_msg->flags;
|
||||
timeout = msg->len/TRANS_TIMEOUT_PERSEC + 5;
|
||||
if (next_flag & RT_I2C_NO_START)
|
||||
{
|
||||
if ((next_flag & RT_I2C_RD) == (msg->flags & RT_I2C_RD))
|
||||
{ /* The same mode, can use no start */
|
||||
mode = I2C_FIRST_AND_NEXT_FRAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not allowed to use no start, sending address is required when changing direction, user setting error */
|
||||
LOG_W("user set flags error msg[%d] flags RT_I2C_NO_START has canceled", i + 1);
|
||||
mode = I2C_LAST_FRAME_NO_STOP;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mode = I2C_LAST_FRAME_NO_STOP;
|
||||
}
|
||||
|
||||
if (msg->flags & RT_I2C_RD)
|
||||
{
|
||||
LOG_D("xfer rec msgs[%d] hal mode = %s", i, mode == I2C_FIRST_AND_NEXT_FRAME ? "I2C_FIRST_AND_NEXT_FRAME" : mode == I2C_LAST_FRAME_NO_STOP ? "I2C_FIRST_FRAME/I2C_LAST_FRAME_NO_STOP"
|
||||
: mode == I2C_LAST_FRAME ? "I2C_LAST_FRAME"
|
||||
: "nuknown mode");
|
||||
if ((i2c_obj->i2c_dma_flag & I2C_USING_RX_DMA_FLAG) && (msg->len >= DMA_TRANS_MIN_LEN))
|
||||
{
|
||||
ret = HAL_I2C_Master_Seq_Receive_DMA(handle, (msg->addr<<1), msg->buf, msg->len, mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = HAL_I2C_Master_Seq_Receive_IT(handle, (msg->addr<<1), msg->buf, msg->len, mode);
|
||||
}
|
||||
if (ret != RT_EOK)
|
||||
{
|
||||
LOG_E("[%s:%d]I2C Read error(%d)!\n", __func__, __LINE__, ret);
|
||||
goto out;
|
||||
}
|
||||
if (rt_completion_wait(completion, timeout) != RT_EOK)
|
||||
{
|
||||
LOG_D("receive time out");
|
||||
goto out;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D("xfer trans msgs[%d] hal mode = %s", i, mode == I2C_FIRST_AND_NEXT_FRAME ? "I2C_FIRST_AND_NEXT_FRAME" : mode == I2C_LAST_FRAME_NO_STOP ? "I2C_FIRST_FRAME/I2C_LAST_FRAME_NO_STOP"
|
||||
: mode == I2C_LAST_FRAME ? "I2C_LAST_FRAME"
|
||||
: "nuknown mode");
|
||||
if ((i2c_obj->i2c_dma_flag & I2C_USING_TX_DMA_FLAG) && (msg->len >= DMA_TRANS_MIN_LEN))
|
||||
{
|
||||
ret = HAL_I2C_Master_Seq_Transmit_DMA(handle, (msg->addr<<1), msg->buf, msg->len, mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = HAL_I2C_Master_Seq_Transmit_IT(handle, (msg->addr<<1), msg->buf, msg->len, mode);
|
||||
}
|
||||
if (ret != RT_EOK)
|
||||
{
|
||||
LOG_D("[%s:%d]I2C Write error(%d)!\n", __func__, __LINE__, ret);
|
||||
goto out;
|
||||
}
|
||||
if (rt_completion_wait(completion, timeout) != RT_EOK)
|
||||
{
|
||||
LOG_D("transmit time out");
|
||||
goto out;
|
||||
|
||||
}
|
||||
}
|
||||
LOG_D("xfer next msgs[%d] addr=0x%2x buf= 0x%x len= 0x%x flags = 0x%x\r\n", i + 1, next_msg->addr, next_msg->buf, next_msg->len, next_msg->flags);
|
||||
}
|
||||
/* last msg */
|
||||
msg = &msgs[i];
|
||||
timeout = msg->len/TRANS_TIMEOUT_PERSEC + 5;
|
||||
if (msg->flags & RT_I2C_NO_STOP)
|
||||
mode = I2C_LAST_FRAME_NO_STOP;
|
||||
else
|
||||
mode = I2C_LAST_FRAME;
|
||||
LOG_D("xfer last msgs[%d] addr=0x%2x buf= 0x%x len= 0x%x flags = 0x%x", i, msg->addr, msg->buf, msg->len, msg->flags);
|
||||
if (msg->flags & RT_I2C_RD)
|
||||
{
|
||||
LOG_D("xfer rec msgs[%d] hal mode=%s", i, mode == I2C_FIRST_AND_NEXT_FRAME ? "I2C_FIRST_AND_NEXT_FRAME" : mode == I2C_LAST_FRAME_NO_STOP ? "I2C_FIRST_FRAME/I2C_LAST_FRAME_NO_STOP"
|
||||
: mode == I2C_LAST_FRAME ? "I2C_LAST_FRAME"
|
||||
: "nuknown mode");
|
||||
if ((i2c_obj->i2c_dma_flag & I2C_USING_RX_DMA_FLAG) && (msg->len >= DMA_TRANS_MIN_LEN))
|
||||
{
|
||||
ret = HAL_I2C_Master_Seq_Receive_DMA(handle, (msg->addr<<1), msg->buf, msg->len, mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = HAL_I2C_Master_Seq_Receive_IT(handle,(msg->addr<<1), msg->buf, msg->len, mode);
|
||||
}
|
||||
if (ret != RT_EOK)
|
||||
{
|
||||
LOG_D("[%s:%d]I2C Read error(%d)!\n", __func__, __LINE__, ret);
|
||||
goto out;
|
||||
}
|
||||
if (rt_completion_wait(completion, timeout) != RT_EOK)
|
||||
{
|
||||
LOG_D("receive time out");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D("xfer trans msgs[%d] hal mode = %s", i, mode == I2C_FIRST_AND_NEXT_FRAME ? "I2C_FIRST_AND_NEXT_FRAME" : mode == I2C_LAST_FRAME ? "I2C_LAST_FRAME"
|
||||
: mode == I2C_LAST_FRAME_NO_STOP ? "I2C_FIRST_FRAME/I2C_LAST_FRAME_NO_STOP"
|
||||
: "nuknown mode");
|
||||
if ((i2c_obj->i2c_dma_flag & I2C_USING_TX_DMA_FLAG) && (msg->len >= DMA_TRANS_MIN_LEN))
|
||||
{
|
||||
ret = HAL_I2C_Master_Seq_Transmit_DMA(handle, (msg->addr<<1), msg->buf, msg->len, mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = HAL_I2C_Master_Seq_Transmit_IT(handle, (msg->addr<<1), msg->buf, msg->len, mode);
|
||||
}
|
||||
if (ret != RT_EOK)
|
||||
{
|
||||
LOG_D("[%s:%d]I2C Write error(%d)!\n", __func__, __LINE__, ret);
|
||||
goto out;
|
||||
}
|
||||
if (rt_completion_wait(completion, timeout) != RT_EOK)
|
||||
{
|
||||
LOG_D("transmit time out");
|
||||
goto out;
|
||||
|
||||
}
|
||||
}
|
||||
ret = num;
|
||||
LOG_D("xfer end %d mags\r\n", num);
|
||||
return ret;
|
||||
|
||||
out:
|
||||
if (handle->ErrorCode == HAL_I2C_ERROR_AF)
|
||||
{
|
||||
LOG_D("I2C NACK Error now stoped");
|
||||
/* Send stop signal to prevent bus lock-up */
|
||||
#if defined(SOC_SERIES_STM32H7)
|
||||
handle->Instance->CR1 |= I2C_IT_STOPI;
|
||||
#endif /* defined(SOC_SERIES_STM32H7) */
|
||||
}
|
||||
if (handle->ErrorCode == HAL_I2C_ERROR_BERR)
|
||||
{
|
||||
LOG_D("I2C BUS Error now stoped");
|
||||
handle->Instance->CR1 |= I2C_CR1_STOP;
|
||||
ret=i-1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct rt_i2c_bus_device_ops stm32_i2c_ops =
|
||||
{
|
||||
.master_xfer = stm32_i2c_master_xfer,
|
||||
RT_NULL,
|
||||
RT_NULL
|
||||
};
|
||||
|
||||
int RT_hw_i2c_bus_init(void)
|
||||
{
|
||||
int ret = -RT_ERROR;
|
||||
rt_size_t obj_num = sizeof(i2c_objs) / sizeof(i2c_objs[0]);
|
||||
|
||||
for (int i = 0; i < obj_num; i++)
|
||||
{
|
||||
i2c_objs[i].i2c_bus.ops = &stm32_i2c_ops;
|
||||
i2c_objs[i].config = &i2c_config[i];
|
||||
i2c_objs[i].i2c_bus.timeout = i2c_config[i].timeout;
|
||||
|
||||
if ((i2c_objs[i].i2c_dma_flag & I2C_USING_RX_DMA_FLAG))
|
||||
{
|
||||
i2c_objs[i].dma.handle_rx.Instance = i2c_config[i].dma_rx->Instance;
|
||||
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
|
||||
i2c_objs[i].dma.handle_rx.Init.Channel = i2c_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)
|
||||
i2c_objs[i].dma.handle_rx.Init.Request = i2c_config[i].dma_rx->request;
|
||||
#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) */
|
||||
#ifndef SOC_SERIES_STM32U5
|
||||
i2c_objs[i].dma.handle_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
i2c_objs[i].dma.handle_rx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
i2c_objs[i].dma.handle_rx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
i2c_objs[i].dma.handle_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
i2c_objs[i].dma.handle_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
i2c_objs[i].dma.handle_rx.Init.Mode = DMA_NORMAL;
|
||||
i2c_objs[i].dma.handle_rx.Init.Priority = DMA_PRIORITY_LOW;
|
||||
#endif
|
||||
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7)
|
||||
i2c_objs[i].dma.handle_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
||||
i2c_objs[i].dma.handle_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
|
||||
i2c_objs[i].dma.handle_tx.Init.MemBurst = DMA_MBURST_INC4;
|
||||
i2c_objs[i].dma.handle_tx.Init.PeriphBurst = DMA_PBURST_INC4;
|
||||
#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) */
|
||||
{
|
||||
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, i2c_config[i].dma_rx->dma_rcc);
|
||||
tmpreg = READ_BIT(RCC->AHBENR, i2c_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, i2c_config[i].dma_rx->dma_rcc);
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmpreg = READ_BIT(RCC->AHB1ENR, i2c_config[i].dma_rx->dma_rcc);
|
||||
#elif defined(SOC_SERIES_STM32MP1)
|
||||
__HAL_RCC_DMAMUX_CLK_ENABLE();
|
||||
SET_BIT(RCC->MP_AHB2ENSETR, i2c_config[i].dma_rx->dma_rcc);
|
||||
tmpreg = READ_BIT(RCC->MP_AHB2ENSETR, i2c_config[i].dma_rx->dma_rcc);
|
||||
#endif /* defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32F0) */
|
||||
UNUSED(tmpreg); /* To avoid compiler warnings */
|
||||
}
|
||||
}
|
||||
|
||||
if (i2c_objs[i].i2c_dma_flag & I2C_USING_TX_DMA_FLAG)
|
||||
{
|
||||
i2c_objs[i].dma.handle_tx.Instance = i2c_config[i].dma_tx->Instance;
|
||||
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
|
||||
i2c_objs[i].dma.handle_tx.Init.Channel = i2c_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)
|
||||
i2c_objs[i].dma.handle_tx.Init.Request = i2c_config[i].dma_tx->request;
|
||||
#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) */
|
||||
#ifndef SOC_SERIES_STM32U5
|
||||
i2c_objs[i].dma.handle_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
i2c_objs[i].dma.handle_tx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
i2c_objs[i].dma.handle_tx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
i2c_objs[i].dma.handle_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
i2c_objs[i].dma.handle_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
i2c_objs[i].dma.handle_tx.Init.Mode = DMA_NORMAL;
|
||||
i2c_objs[i].dma.handle_tx.Init.Priority = DMA_PRIORITY_LOW;
|
||||
#endif
|
||||
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7)
|
||||
|
||||
i2c_objs[i].dma.handle_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
||||
i2c_objs[i].dma.handle_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
|
||||
i2c_objs[i].dma.handle_tx.Init.MemBurst = DMA_MBURST_INC4;
|
||||
i2c_objs[i].dma.handle_tx.Init.PeriphBurst = DMA_PBURST_INC4;
|
||||
#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) */
|
||||
{
|
||||
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, i2c_config[i].dma_tx->dma_rcc);
|
||||
tmpreg = READ_BIT(RCC->AHBENR, i2c_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, i2c_config[i].dma_tx->dma_rcc);
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmpreg = READ_BIT(RCC->AHB1ENR, i2c_config[i].dma_tx->dma_rcc);
|
||||
#elif defined(SOC_SERIES_STM32MP1)
|
||||
__HAL_RCC_DMAMUX_CLK_ENABLE();
|
||||
SET_BIT(RCC->MP_AHB2ENSETR, i2c_config[i].dma_tx->dma_rcc);
|
||||
tmpreg = READ_BIT(RCC->MP_AHB2ENSETR, i2c_config[i].dma_tx->dma_rcc);
|
||||
#endif /* defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32F0) */
|
||||
UNUSED(tmpreg); /* To avoid compiler warnings */
|
||||
}
|
||||
}
|
||||
|
||||
rt_completion_init(&i2c_objs[i].completion);
|
||||
stm32_i2c_configure(&i2c_objs[i].i2c_bus);
|
||||
ret = rt_i2c_bus_device_register(&i2c_objs[i].i2c_bus, i2c_objs[i].config->name);
|
||||
RT_ASSERT(ret == RT_EOK);
|
||||
LOG_D("%s bus init done", i2c_config[i].name);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void stm32_get_dma_info(void)
|
||||
{
|
||||
#ifdef BSP_I2C1_RX_USING_DMA
|
||||
i2c_objs[I2C1_INDEX].i2c_dma_flag |= I2C_USING_RX_DMA_FLAG;
|
||||
static struct dma_config I2C1_dma_rx = I2C1_RX_DMA_CONFIG;
|
||||
i2c_config[I2C1_INDEX].dma_rx = &I2C1_dma_rx;
|
||||
#endif /* BSP_I2C1_RX_USING_DMA */
|
||||
#ifdef BSP_I2C1_TX_USING_DMA
|
||||
i2c_objs[I2C1_INDEX].i2c_dma_flag |= I2C_USING_TX_DMA_FLAG;
|
||||
static struct dma_config I2C1_dma_tx = I2C1_TX_DMA_CONFIG;
|
||||
i2c_config[I2C1_INDEX].dma_tx = &I2C1_dma_tx;
|
||||
#endif /* BSP_I2C1_TX_USING_DMA */
|
||||
|
||||
#ifdef BSP_I2C2_RX_USING_DMA
|
||||
i2c_objs[I2C2_INDEX].i2c_dma_flag |= I2C_USING_RX_DMA_FLAG;
|
||||
static struct dma_config I2C2_dma_rx = I2C2_RX_DMA_CONFIG;
|
||||
i2c_config[I2C2_INDEX].dma_rx = &I2C2_dma_rx;
|
||||
#endif /* BSP_I2C2_RX_USING_DMA */
|
||||
#ifdef BSP_I2C2_TX_USING_DMA
|
||||
i2c_objs[I2C2_INDEX].i2c_dma_flag |= I2C_USING_TX_DMA_FLAG;
|
||||
static struct dma_config I2C2_dma_tx = I2C2_TX_DMA_CONFIG;
|
||||
i2c_config[I2C2_INDEX].dma_tx = &I2C2_dma_tx;
|
||||
#endif /* BSP_I2C2_TX_USING_DMA */
|
||||
|
||||
#ifdef BSP_I2C3_RX_USING_DMA
|
||||
i2c_objs[I2C3_INDEX].i2c_dma_flag |= I2C_USING_RX_DMA_FLAG;
|
||||
static struct dma_config I2C3_dma_rx = I2C3_RX_DMA_CONFIG;
|
||||
i2c_config[I2C3_INDEX].dma_rx = &I2C3_dma_rx;
|
||||
#endif /* BSP_I2C3_RX_USING_DMA */
|
||||
#ifdef BSP_I2C3_TX_USING_DMA
|
||||
i2c_objs[I2C3_INDEX].i2c_dma_flag |= I2C_USING_TX_DMA_FLAG;
|
||||
static struct dma_config I2C3_dma_tx = I2C3_TX_DMA_CONFIG;
|
||||
i2c_config[I2C3_INDEX].dma_tx = &I2C3_dma_tx;
|
||||
#endif /* BSP_I2C3_TX_USING_DMA */
|
||||
}
|
||||
|
||||
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
struct stm32_i2c *i2c_drv = rt_container_of(hi2c, struct stm32_i2c, handle);
|
||||
rt_completion_done(&i2c_drv->completion);
|
||||
}
|
||||
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
struct stm32_i2c *i2c_drv = rt_container_of(hi2c, struct stm32_i2c, handle);
|
||||
rt_completion_done(&i2c_drv->completion);
|
||||
}
|
||||
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
#if defined(SOC_SERIES_STM32H7)
|
||||
/* Send stop signal to prevent bus lock-up */
|
||||
if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
|
||||
{
|
||||
LOG_D("I2C NACK Error now stoped");
|
||||
hi2c->Instance->CR1 |= I2C_IT_STOPI;
|
||||
}
|
||||
if (hi2c->ErrorCode == HAL_I2C_ERROR_BERR)
|
||||
{
|
||||
LOG_D("I2C BUS Error now stoped");
|
||||
hi2c->Instance->CR1 |= I2C_IT_STOPI;
|
||||
}
|
||||
#endif /* defined(SOC_SERIES_STM32H7) */
|
||||
|
||||
}
|
||||
#ifdef BSP_USING_HARD_I2C1
|
||||
/**
|
||||
* @brief This function handles I2C2 event interrupt.
|
||||
*/
|
||||
void I2C1_EV_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN I2C2_EV_IRQn 0 */
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
/* USER CODE END I2C2_EV_IRQn 0 */
|
||||
HAL_I2C_EV_IRQHandler(&i2c_objs[I2C1_INDEX].handle);
|
||||
/* USER CODE BEGIN I2C2_EV_IRQn 1 */
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
/* USER CODE END I2C2_EV_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles I2C2 error interrupt.
|
||||
*/
|
||||
void I2C1_ER_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN I2C2_ER_IRQn 0 */
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
/* USER CODE END I2C2_ER_IRQn 0 */
|
||||
HAL_I2C_ER_IRQHandler(&i2c_objs[I2C1_INDEX].handle);
|
||||
/* USER CODE BEGIN I2C2_ER_IRQn 1 */
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
/* USER CODE END I2C2_ER_IRQn 1 */
|
||||
}
|
||||
#endif /* BSP_USING_HARD_I2C1 */
|
||||
|
||||
#ifdef BSP_USING_HARD_I2C2
|
||||
/**
|
||||
* @brief This function handles I2C2 event interrupt.
|
||||
*/
|
||||
void I2C2_EV_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN I2C2_EV_IRQn 0 */
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
/* USER CODE END I2C2_EV_IRQn 0 */
|
||||
HAL_I2C_EV_IRQHandler(&i2c_objs[I2C2_INDEX].handle);
|
||||
/* USER CODE BEGIN I2C2_EV_IRQn 1 */
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
/* USER CODE END I2C2_EV_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles I2C2 error interrupt.
|
||||
*/
|
||||
void I2C2_ER_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN I2C2_ER_IRQn 0 */
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
/* USER CODE END I2C2_ER_IRQn 0 */
|
||||
HAL_I2C_ER_IRQHandler(&i2c_objs[I2C2_INDEX].handle);
|
||||
/* USER CODE BEGIN I2C2_ER_IRQn 1 */
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
/* USER CODE END I2C2_ER_IRQn 1 */
|
||||
}
|
||||
#endif /* BSP_USING_HARD_I2C2 */
|
||||
|
||||
#ifdef BSP_USING_HARD_I2C3
|
||||
/**
|
||||
* @brief This function handles I2C2 event interrupt.
|
||||
*/
|
||||
void I2C3_EV_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN I2C2_EV_IRQn 0 */
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
/* USER CODE END I2C2_EV_IRQn 0 */
|
||||
HAL_I2C_EV_IRQHandler(&i2c_objs[I2C3_INDEX].handle);
|
||||
/* USER CODE BEGIN I2C2_EV_IRQn 1 */
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
/* USER CODE END I2C2_EV_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles I2C2 error interrupt.
|
||||
*/
|
||||
void I2C3_ER_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN I2C2_ER_IRQn 0 */
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
/* USER CODE END I2C2_ER_IRQn 0 */
|
||||
HAL_I2C_ER_IRQHandler(&i2c_objs[I2C3_INDEX].handle);
|
||||
/* USER CODE BEGIN I2C2_ER_IRQn 1 */
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
/* USER CODE END I2C2_ER_IRQn 1 */
|
||||
}
|
||||
#endif /* BSP_USING_HARD_I2C3 */
|
||||
|
||||
#if defined(BSP_USING_HARD_I2C1) && defined(BSP_I2C1_RX_USING_DMA)
|
||||
/**
|
||||
* @brief This function handles DMA Rx interrupt request.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void I2C1_DMA_RX_IRQHandler(void)
|
||||
{
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
|
||||
HAL_DMA_IRQHandler(&i2c_objs[I2C1_INDEX].dma.handle_rx);
|
||||
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif /* defined(BSP_USING_HARD_I2C1) && defined(BSP_I2C1_RX_USING_DMA) */
|
||||
|
||||
#if defined(BSP_USING_HARD_I2C1) && defined(BSP_I2C1_TX_USING_DMA)
|
||||
/**
|
||||
* @brief This function handles DMA Rx interrupt request.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void I2C1_DMA_TX_IRQHandler(void)
|
||||
{
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
|
||||
HAL_DMA_IRQHandler(&i2c_objs[I2C1_INDEX].dma.handle_tx);
|
||||
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif /* defined(BSP_USING_HARD_I2C1) && defined(BSP_I2C1_TX_USING_DMA) */
|
||||
|
||||
#if defined(BSP_USING_HARD_I2C2) && defined(BSP_I2C2_RX_USING_DMA)
|
||||
/**
|
||||
* @brief This function handles DMA Rx interrupt request.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void I2C2_DMA_RX_IRQHandler(void)
|
||||
{
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
|
||||
HAL_DMA_IRQHandler(&i2c_objs[I2C2_INDEX].dma.handle_rx);
|
||||
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif /* defined(BSP_USING_HARD_I2C2) && defined(BSP_I2C2_RX_USING_DMA) */
|
||||
|
||||
#if defined(BSP_USING_HARD_I2C2) && defined(BSP_I2C2_TX_USING_DMA)
|
||||
/**
|
||||
* @brief This function handles DMA Rx interrupt request.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void I2C2_DMA_TX_IRQHandler(void)
|
||||
{
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
|
||||
HAL_DMA_IRQHandler(&i2c_objs[I2C2_INDEX].dma.handle_tx);
|
||||
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif /* defined(BSP_USING_HARD_I2C2) && defined(BSP_I2C2_TX_USING_DMA) */
|
||||
|
||||
#if defined(BSP_USING_HARD_I2C3) && defined(BSP_I2C3_RX_USING_DMA)
|
||||
/**
|
||||
* @brief This function handles DMA Rx interrupt request.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void I2C3_DMA_RX_IRQHandler(void)
|
||||
{
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
|
||||
HAL_DMA_IRQHandler(&i2c_objs[I2C3_INDEX].dma.handle_rx);
|
||||
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif /* defined(BSP_USING_HARD_I2C3) && defined(BSP_I2C3_RX_USING_DMA) */
|
||||
|
||||
#if defined(BSP_USING_HARD_I2C3) && defined(BSP_I2C3_TX_USING_DMA)
|
||||
/**
|
||||
* @brief This function handles DMA Rx interrupt request.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void I2C3_DMA_TX_IRQHandler(void)
|
||||
{
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
|
||||
HAL_DMA_IRQHandler(&i2c_objs[I2C3_INDEX].dma.handle_tx);
|
||||
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif /* defined(BSP_USING_HARD_I2C3) && defined(BSP_I2C3_TX_USING_DMA) */
|
||||
|
||||
int rt_hw_hw_i2c_init(void)
|
||||
{
|
||||
stm32_get_dma_info();
|
||||
return RT_hw_i2c_bus_init();
|
||||
}
|
||||
INIT_BOARD_EXPORT(rt_hw_hw_i2c_init);
|
||||
|
||||
#endif /* defined(BSP_USING_HARD_I2C1) || defined(BSP_USING_HARD_I2C2) || defined(BSP_USING_HARD_I2C3) */
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2024-02-17 Dyyt587 first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_HARD_I2C_H__
|
||||
#define __DRV_HARD_I2C_H__
|
||||
|
||||
#include <drv_common.h>
|
||||
#include "drv_dma.h"
|
||||
#include "drv_config.h"
|
||||
#include <ipc/completion.h>
|
||||
|
||||
/* C binding of definitions if building with C++ compiler */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct stm32_i2c_config
|
||||
{
|
||||
const char *name;
|
||||
I2C_TypeDef *Instance;
|
||||
rt_uint32_t timing;
|
||||
rt_uint32_t timeout;
|
||||
IRQn_Type evirq_type;
|
||||
IRQn_Type erirq_type;
|
||||
struct dma_config *dma_rx;
|
||||
struct dma_config *dma_tx;
|
||||
};
|
||||
|
||||
struct stm32_i2c
|
||||
{
|
||||
I2C_HandleTypeDef handle;
|
||||
struct stm32_i2c_config *config;
|
||||
struct
|
||||
{
|
||||
DMA_HandleTypeDef handle_rx;
|
||||
DMA_HandleTypeDef handle_tx;
|
||||
} dma;
|
||||
rt_uint8_t i2c_dma_flag;
|
||||
struct rt_i2c_bus_device i2c_bus;
|
||||
struct rt_completion completion;
|
||||
};
|
||||
|
||||
#define I2C_USING_TX_DMA_FLAG (1U)
|
||||
#define I2C_USING_RX_DMA_FLAG (1U << 1)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __DRV_I2C_H__ */
|
||||
@@ -0,0 +1,456 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2025 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 <rtdevice.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)
|
||||
|
||||
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;
|
||||
}
|
||||
#ifndef ART_PI_TouchGFX_LIB
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
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
|
||||
{
|
||||
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 = 0;
|
||||
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_align(LCD_BUF_SIZE, LCD_BUF_SIZE);
|
||||
_lcd.back_buf = rt_malloc_align(LCD_BUF_SIZE, LCD_BUF_SIZE);
|
||||
_lcd.front_buf = rt_malloc_align(LCD_BUF_SIZE, 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;
|
||||
#ifndef ART_PI_TouchGFX_LIB
|
||||
device->control = drv_lcd_control;
|
||||
#endif
|
||||
#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);
|
||||
|
||||
#ifndef ART_PI_TouchGFX_LIB
|
||||
#ifdef DRV_DEBUG
|
||||
#ifdef FINSH_USING_MSH
|
||||
static void lcd_thread(void *arg)
|
||||
{
|
||||
struct drv_lcd_device *lcd = (struct drv_lcd_device *)arg;
|
||||
while (1)
|
||||
{
|
||||
if (lcd->lcd_info.pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
rt_device_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;
|
||||
}
|
||||
rt_device_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;
|
||||
}
|
||||
}
|
||||
else if (lcd->lcd_info.pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB888)
|
||||
{
|
||||
/* red */
|
||||
for (int i = 0; i < LCD_BUF_SIZE / 3; i++)
|
||||
{
|
||||
lcd->lcd_info.framebuffer[3 * i] = 0x00;
|
||||
lcd->lcd_info.framebuffer[3 * i + 1] = 0x00;
|
||||
lcd->lcd_info.framebuffer[3 * i + 2] = 0xff;
|
||||
}
|
||||
rt_device_control(&lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
|
||||
rt_thread_mdelay(1000);
|
||||
/* green */
|
||||
for (int i = 0; i < LCD_BUF_SIZE / 3; i++)
|
||||
{
|
||||
lcd->lcd_info.framebuffer[3 * i] = 0x00;
|
||||
lcd->lcd_info.framebuffer[3 * i + 1] = 0xff;
|
||||
lcd->lcd_info.framebuffer[3 * i + 2] = 0x00;
|
||||
}
|
||||
rt_device_control(&lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
|
||||
rt_thread_mdelay(1000);
|
||||
/* blue */
|
||||
for (int i = 0; i < LCD_BUF_SIZE / 3; i++)
|
||||
{
|
||||
lcd->lcd_info.framebuffer[3 * i] = 0xff;
|
||||
lcd->lcd_info.framebuffer[3 * i + 1] = 0x00;
|
||||
lcd->lcd_info.framebuffer[3 * i + 2] = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
rt_device_control(&lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
|
||||
rt_thread_mdelay(1000);
|
||||
}
|
||||
}
|
||||
int lcd_test(void)
|
||||
{
|
||||
struct drv_lcd_device *lcd;
|
||||
lcd = (struct drv_lcd_device *)rt_device_find("lcd");
|
||||
if(lcd == RT_NULL)
|
||||
{
|
||||
LOG_E("Failed to find LCD device!\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
const char *thread_name = "lcd_test";
|
||||
rt_thread_t thread = rt_thread_create(thread_name, lcd_thread, lcd, 256, RT_THREAD_PRIORITY_MAX - 1, 10);
|
||||
if (thread != RT_NULL)
|
||||
{
|
||||
rt_thread_startup(thread);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("%s created failed.", thread_name);
|
||||
return -RT_ERROR;
|
||||
}
|
||||
return RT_EOK;
|
||||
}
|
||||
MSH_CMD_EXPORT(lcd_test, Create thread test lcd);
|
||||
#endif /* FINSH_USING_MSH */
|
||||
#endif /* DRV_DEBUG */
|
||||
#endif /* BSP_USING_LCD */
|
||||
#endif
|
||||
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-05-23 WillianChan first version
|
||||
*/
|
||||
|
||||
#include <board.h>
|
||||
#include <rtconfig.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 */
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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>
|
||||
@@ -0,0 +1,320 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-05-06 Zero-Free first version
|
||||
* 2024-07-04 wdfk-prog lptimer is register with hwtimer, only supports pm calls,the timer function is not supported
|
||||
*/
|
||||
|
||||
#include <board.h>
|
||||
#include <drv_lptim.h>
|
||||
#include <rtdevice.h>
|
||||
#include "drv_config.h"
|
||||
|
||||
/*#define DRV_DEBUG*/
|
||||
#define LOG_TAG "drv.lptim"
|
||||
#include <drv_log.h>
|
||||
|
||||
#ifdef BSP_USING_LPTIM
|
||||
|
||||
#define LPTIM_REG_MAX_VALUE (0xFFFF)
|
||||
|
||||
enum
|
||||
{
|
||||
#ifdef BSP_USING_LPTIM1
|
||||
LPTIM1_INDEX,
|
||||
#endif
|
||||
#ifdef BSP_USING_LPTIM2
|
||||
LPTIM2_INDEX,
|
||||
#endif
|
||||
#ifdef BSP_USING_LPTIM3
|
||||
LPTIM3_INDEX,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct stm32_hw_lptimer
|
||||
{
|
||||
rt_hwtimer_t time_device;
|
||||
LPTIM_HandleTypeDef tim_handle;
|
||||
IRQn_Type tim_irqn;
|
||||
char *name;
|
||||
};
|
||||
|
||||
static struct stm32_hw_lptimer stm32_hw_lptimer_obj[] =
|
||||
{
|
||||
#ifdef BSP_USING_LPTIM1
|
||||
LPTIM1_CONFIG,
|
||||
#endif
|
||||
#ifdef BSP_USING_LPTIM2
|
||||
LPTIM2_CONFIG,
|
||||
#endif
|
||||
#ifdef BSP_USING_LPTIM3
|
||||
LPTIM3_CONFIG,
|
||||
#endif
|
||||
};
|
||||
|
||||
static const struct rt_hwtimer_info _info = LPTIM_DEV_INFO_CONFIG;
|
||||
|
||||
static void timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
|
||||
{
|
||||
if(timer == RT_NULL)
|
||||
{
|
||||
LOG_E("init timer is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
if (state)
|
||||
{
|
||||
struct stm32_hw_lptimer *tim_device = rt_container_of(timer, struct stm32_hw_lptimer, time_device);
|
||||
LPTIM_HandleTypeDef *tim = (LPTIM_HandleTypeDef *)timer->parent.user_data;
|
||||
|
||||
if(tim_device == RT_NULL)
|
||||
{
|
||||
LOG_E("start tim_device is NULL");
|
||||
return;
|
||||
}
|
||||
if(tim == RT_NULL)
|
||||
{
|
||||
LOG_E("start %s LPTIM_Handle is NULL", tim_device->name);
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
tim->Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
|
||||
tim->Init.Clock.Prescaler = LPTIM_PRESCALER_DIV32;
|
||||
tim->Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
|
||||
tim->Init.OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH;
|
||||
tim->Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
|
||||
tim->Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
|
||||
|
||||
HAL_StatusTypeDef ret = HAL_LPTIM_Init(tim);
|
||||
if (ret != HAL_OK)
|
||||
{
|
||||
LOG_E("%s init failed %d", tim_device->name, ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
NVIC_ClearPendingIRQ(LPTIM1_IRQn);
|
||||
NVIC_SetPriority(LPTIM1_IRQn, 0);
|
||||
NVIC_EnableIRQ(LPTIM1_IRQn);
|
||||
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)
|
||||
{
|
||||
if(timer == RT_NULL)
|
||||
{
|
||||
LOG_E("start timer is NULL");
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
struct stm32_hw_lptimer *tim_device = rt_container_of(timer, struct stm32_hw_lptimer, time_device);
|
||||
LPTIM_HandleTypeDef *tim = (LPTIM_HandleTypeDef *)timer->parent.user_data;
|
||||
|
||||
if(tim_device == RT_NULL)
|
||||
{
|
||||
LOG_E("start tim_device is NULL");
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
if(tim == RT_NULL)
|
||||
{
|
||||
LOG_E("start %s LPTIM_Handle is NULL", tim_device->name);
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef ret = HAL_LPTIM_TimeOut_Start_IT(tim, LPTIM_REG_MAX_VALUE, t);
|
||||
if(ret != HAL_OK)
|
||||
{
|
||||
LOG_E("start %s failed %d", tim_device->name, ret);
|
||||
return -RT_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D("start %s success", tim_device->name);
|
||||
return RT_EOK;
|
||||
}
|
||||
}
|
||||
|
||||
static void timer_stop(rt_hwtimer_t *timer)
|
||||
{
|
||||
if(timer == RT_NULL)
|
||||
{
|
||||
LOG_E("stop timer is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
struct stm32_hw_lptimer *tim_device = rt_container_of(timer, struct stm32_hw_lptimer, time_device);
|
||||
LPTIM_HandleTypeDef *tim = (LPTIM_HandleTypeDef *)timer->parent.user_data;
|
||||
|
||||
if(tim_device == RT_NULL)
|
||||
{
|
||||
LOG_E("stop tim_device is NULL");
|
||||
return;
|
||||
}
|
||||
if(tim == RT_NULL)
|
||||
{
|
||||
LOG_E("stop %s LPTIM_Handle is NULL", tim_device->name);
|
||||
return;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef ret = HAL_LPTIM_TimeOut_Stop_IT(tim);
|
||||
if(ret != HAL_OK)
|
||||
{
|
||||
LOG_E("stop %s failed %d", tim_device->name, ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D("stop %s success", tim_device->name);
|
||||
}
|
||||
}
|
||||
|
||||
static rt_uint32_t timer_get_freq(LPTIM_HandleTypeDef *tim)
|
||||
{
|
||||
/*No calculation is performed. The default initial configuration is 1000hz*/
|
||||
return 1000;
|
||||
}
|
||||
|
||||
|
||||
static rt_uint32_t timer_counter_get(rt_hwtimer_t *timer)
|
||||
{
|
||||
LPTIM_HandleTypeDef *tim = (LPTIM_HandleTypeDef *)timer->parent.user_data;
|
||||
return HAL_LPTIM_ReadCounter(tim);
|
||||
}
|
||||
|
||||
static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
|
||||
{
|
||||
if(timer == RT_NULL)
|
||||
{
|
||||
LOG_E("start timer is NULL");
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
struct stm32_hw_lptimer *tim_device = rt_container_of(timer, struct stm32_hw_lptimer, time_device);
|
||||
LPTIM_HandleTypeDef *tim = (LPTIM_HandleTypeDef *)timer->parent.user_data;
|
||||
|
||||
if(tim_device == RT_NULL)
|
||||
{
|
||||
LOG_E("start tim_device is NULL");
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
if(tim == RT_NULL)
|
||||
{
|
||||
LOG_E("start %s LPTIM_Handle is NULL", tim_device->name);
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
rt_err_t result = RT_EOK;
|
||||
switch (cmd)
|
||||
{
|
||||
case DRV_HW_LPTIMER_CTRL_GET_TICK_MAX:
|
||||
{
|
||||
*(rt_uint32_t *)arg = LPTIM_REG_MAX_VALUE;
|
||||
break;
|
||||
}
|
||||
case DRV_HW_LPTIMER_CTRL_GET_FREQ:
|
||||
{
|
||||
*(rt_uint32_t *)arg = timer_get_freq(tim);
|
||||
break;
|
||||
}
|
||||
case DRV_HW_LPTIMER_CTRL_START:
|
||||
{
|
||||
timer_start(timer, *(rt_uint32_t *)arg, HWTIMER_MODE_ONESHOT);
|
||||
break;
|
||||
}
|
||||
case DRV_HW_LPTIMER_CTRL_GET_COUNT:
|
||||
{
|
||||
*(rt_uint32_t *)arg = timer_counter_get(timer);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
result = -RT_ENOSYS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef BSP_USING_LPTIM1
|
||||
void LPTIM1_IRQHandler(void)
|
||||
{
|
||||
rt_interrupt_enter();
|
||||
HAL_LPTIM_IRQHandler(&stm32_hw_lptimer_obj[LPTIM1_INDEX].tim_handle);
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_LPTIM2
|
||||
void LPTIM2_IRQHandler(void)
|
||||
{
|
||||
rt_interrupt_enter();
|
||||
HAL_LPTIM_IRQHandler(&stm32_hw_lptimer_obj[LPTIM2_INDEX].tim_handle);
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_LPTIM3
|
||||
void LPTIM3_IRQHandler(void)
|
||||
{
|
||||
rt_interrupt_enter();
|
||||
HAL_LPTIM_IRQHandler(&stm32_hw_lptimer_obj[LPTIM3_INDEX].tim_handle);
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct rt_hwtimer_ops _ops =
|
||||
{
|
||||
.init = timer_init,
|
||||
.start = timer_start,
|
||||
.stop = timer_stop,
|
||||
.count_get = timer_counter_get,
|
||||
.control = timer_ctrl,
|
||||
};
|
||||
|
||||
/**
|
||||
* This function initialize the lptim
|
||||
*/
|
||||
static int stm32_hw_lptim_init(void)
|
||||
{
|
||||
int i = 0;
|
||||
int result = RT_EOK;
|
||||
|
||||
for (i = 0; i < sizeof(stm32_hw_lptimer_obj) / sizeof(stm32_hw_lptimer_obj[0]); i++)
|
||||
{
|
||||
stm32_hw_lptimer_obj[i].time_device.info = &_info;
|
||||
stm32_hw_lptimer_obj[i].time_device.ops = &_ops;
|
||||
if (rt_device_hwtimer_register(&stm32_hw_lptimer_obj[i].time_device, stm32_hw_lptimer_obj[i].name, &stm32_hw_lptimer_obj[i].tim_handle) == RT_EOK)
|
||||
{
|
||||
LOG_D("%s register success", stm32_hw_lptimer_obj[i].name);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("%s register failed", stm32_hw_lptimer_obj[i].name);
|
||||
result = -RT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
INIT_BOARD_EXPORT(stm32_hw_lptim_init);
|
||||
#endif /* BSP_USING_LPTIM */
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-05-06 Zero-Free first version
|
||||
* 2024-07-04 wdfk-prog lptimer is register with hwtimer, only supports pm calls,the timer function is not supported
|
||||
*/
|
||||
|
||||
#ifndef __DRV_PMTIMER_H__
|
||||
#define __DRV_PMTIMER_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
/* 0x20 - 0x3F udevice control commands*/
|
||||
typedef enum
|
||||
{
|
||||
DRV_HW_LPTIMER_CTRL_GET_TICK_MAX = 0x20, /* get the maximum tick value*/
|
||||
DRV_HW_LPTIMER_CTRL_GET_FREQ = 0X21, /* get the timer frequency*/
|
||||
DRV_HW_LPTIMER_CTRL_START = 0X22, /* set the timeout value*/
|
||||
DRV_HW_LPTIMER_CTRL_GET_COUNT = 0X23, /* get the current count value*/
|
||||
} drv_hw_lptimer_ctrl_t;
|
||||
|
||||
#endif /* __DRV_PMTIMER_H__ */
|
||||
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-09-28 mingmiaojing first version
|
||||
*/
|
||||
|
||||
#include <rtconfig.h>
|
||||
#ifdef BSP_USING_NAND1
|
||||
#include <board.h>
|
||||
#include "drv_nand.h"
|
||||
#include "drv_config.h"
|
||||
|
||||
#include <lpm.h>
|
||||
|
||||
#define NAND_PAGE_SIZE ((uint16_t)2048)
|
||||
#define NAND1_RW_TEST
|
||||
#ifndef RT_FIOGETXIPADDR
|
||||
#define RT_FIOGETXIPADDR 0x52540001U
|
||||
#endif
|
||||
|
||||
struct rt_device _hw_nand1;
|
||||
NAND_HandleTypeDef hnand1;
|
||||
|
||||
/* FSMC initialization function */
|
||||
static void rt_nand_init(void)
|
||||
{
|
||||
/* USER CODE BEGIN FSMC_Init 0 */
|
||||
|
||||
/* USER CODE END FSMC_Init 0 */
|
||||
|
||||
FSMC_NAND_PCC_TimingTypeDef ComSpaceTiming = {0};
|
||||
FSMC_NAND_PCC_TimingTypeDef AttSpaceTiming = {0};
|
||||
|
||||
/* USER CODE BEGIN FSMC_Init 1 */
|
||||
|
||||
/* USER CODE END FSMC_Init 1 */
|
||||
|
||||
/** Perform the NAND1 memory initialization sequence
|
||||
*/
|
||||
hnand1.Instance = FSMC_NAND_DEVICE;
|
||||
/* hnand1.Init */
|
||||
hnand1.Init.NandBank = FSMC_NAND_BANK2;
|
||||
hnand1.Init.Waitfeature = FSMC_NAND_PCC_WAIT_FEATURE_ENABLE;
|
||||
hnand1.Init.MemoryDataWidth = FSMC_NAND_PCC_MEM_BUS_WIDTH_8;
|
||||
hnand1.Init.EccComputation = FSMC_NAND_ECC_ENABLE;
|
||||
hnand1.Init.ECCPageSize = FSMC_NAND_ECC_PAGE_SIZE_512BYTE;
|
||||
hnand1.Init.TCLRSetupTime = 0;
|
||||
hnand1.Init.TARSetupTime = 0;
|
||||
/* hnand1.Config */
|
||||
hnand1.Config.PageSize = NAND_PAGE_SIZE;
|
||||
hnand1.Config.SpareAreaSize = 64;
|
||||
hnand1.Config.BlockSize = 64;
|
||||
hnand1.Config.BlockNbr = 1024;
|
||||
hnand1.Config.PlaneNbr = 1;
|
||||
hnand1.Config.PlaneSize = 1024;
|
||||
hnand1.Config.ExtraCommandEnable = DISABLE;
|
||||
/* ComSpaceTiming */
|
||||
ComSpaceTiming.SetupTime = 4;
|
||||
ComSpaceTiming.WaitSetupTime = 3;
|
||||
ComSpaceTiming.HoldSetupTime = 2;
|
||||
ComSpaceTiming.HiZSetupTime = 4;
|
||||
/* AttSpaceTiming */
|
||||
AttSpaceTiming.SetupTime = 4;
|
||||
AttSpaceTiming.WaitSetupTime = 3;
|
||||
AttSpaceTiming.HoldSetupTime = 2;
|
||||
AttSpaceTiming.HiZSetupTime = 4;
|
||||
|
||||
if (HAL_NAND_Init(&hnand1, &ComSpaceTiming, &AttSpaceTiming) != HAL_OK)
|
||||
{
|
||||
Error_Handler( );
|
||||
}
|
||||
|
||||
/** Disconnect NADV
|
||||
*/
|
||||
|
||||
__HAL_AFIO_FSMCNADV_DISCONNECTED();
|
||||
|
||||
/* USER CODE BEGIN FSMC_Init 2 */
|
||||
|
||||
/* USER CODE END FSMC_Init 2 */
|
||||
}
|
||||
|
||||
rt_err_t rt_nand_open(rt_device_t dev, rt_uint16_t oflag)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t rt_nand_control(rt_device_t dev, int cmd, void *args)
|
||||
{
|
||||
if(RT_DEVICE_CTRL_BLK_GETGEOME == cmd)
|
||||
{
|
||||
struct rt_device_blk_geometry *geometry = (struct rt_device_blk_geometry *)args;
|
||||
geometry->bytes_per_sector = 2048;
|
||||
geometry->sector_count = 64 * 1024;
|
||||
geometry->block_size = 2048 * 64;
|
||||
return RT_EOK;
|
||||
}
|
||||
else if(RT_FIOGETXIPADDR == cmd)
|
||||
{
|
||||
uint32_t *start_addr = (uint32_t *)args;
|
||||
*start_addr = 0;
|
||||
return RT_EOK;
|
||||
}
|
||||
else if(RT_DEVICE_CTRL_BLK_ERASE == cmd)
|
||||
{
|
||||
uint32_t *blk = (uint32_t *)args;
|
||||
NAND_AddressTypeDef Addr;
|
||||
Addr.Plane = 0x00;
|
||||
Addr.Block = *blk;
|
||||
Addr.Page = 0x00;
|
||||
HAL_NAND_Erase_Block(&hnand1,&Addr);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
/*pos: sector offset size: page count*/
|
||||
rt_ssize_t rt_nand_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
|
||||
{
|
||||
uint32_t page_cnt = size;
|
||||
NAND_AddressTypeDef ReadAddr;
|
||||
ReadAddr.Page = pos%64;
|
||||
ReadAddr.Plane = 0;
|
||||
ReadAddr.Block = pos/64;
|
||||
HAL_NAND_Read_Page(&hnand1, &ReadAddr, (uint8_t *)buffer, page_cnt);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_ssize_t rt_nand_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
|
||||
{
|
||||
uint32_t page_cnt = size;
|
||||
NAND_AddressTypeDef WriteAddr;
|
||||
WriteAddr.Page = pos%64;
|
||||
WriteAddr.Plane = 0;
|
||||
WriteAddr.Block = pos/64;
|
||||
HAL_NAND_Write_Page(&hnand1, &WriteAddr, (uint8_t *)buffer, page_cnt);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static int stm32_nand1_init(void)
|
||||
{
|
||||
NAND_IDTypeDef NAND_ID;
|
||||
rt_nand_init();
|
||||
HAL_NAND_Read_ID(&hnand1, &NAND_ID);
|
||||
rt_kprintf("Nand Flash ID = 0x%02X,0x%02X,0x%02X,0x%02X",
|
||||
NAND_ID.Maker_Id, NAND_ID.Device_Id,
|
||||
NAND_ID.Third_Id, NAND_ID.Fourth_Id);
|
||||
|
||||
#ifdef NAND1_RW_TEST
|
||||
uint32_t i = 0;
|
||||
static uint8_t TxBuffer [NAND_PAGE_SIZE];
|
||||
static uint8_t RxBuffer [NAND_PAGE_SIZE];
|
||||
NAND_AddressTypeDef WriteReadAddr;
|
||||
|
||||
WriteReadAddr.Plane = 0x00;
|
||||
WriteReadAddr.Block = 0x00;
|
||||
WriteReadAddr.Page = 0x00;
|
||||
|
||||
/* Erase the NAND first Block */
|
||||
for(i = 0; i < 64; i++)
|
||||
{
|
||||
WriteReadAddr.Block = i;
|
||||
HAL_NAND_Erase_Block(&hnand1,&WriteReadAddr);
|
||||
}
|
||||
|
||||
// /* Fill the buffer to send */
|
||||
// for (i = 0; i < NAND_PAGE_SIZE; i++ )
|
||||
// {
|
||||
// TxBuffer[i] = i;
|
||||
// }
|
||||
//
|
||||
// /* Write data to FMC NAND memory */
|
||||
// HAL_NAND_Write_Page(&hnand1, &WriteReadAddr, TxBuffer, 1);
|
||||
// rt_kprintf("\r\nWritten to the number:\r\n");
|
||||
// for(i = 0; i < 2048; i++)
|
||||
// {
|
||||
// rt_kprintf("0x%02X \t",TxBuffer[i]);
|
||||
// }
|
||||
// rt_kprintf("\n");
|
||||
// HAL_Delay(100);
|
||||
/* Read data from FMC NAND memory */
|
||||
WriteReadAddr.Block = 0;
|
||||
HAL_NAND_Read_Page(&hnand1, &WriteReadAddr, RxBuffer, 1);
|
||||
rt_kprintf("\r\nRead receive: \r\n");
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
rt_kprintf("0x%02X \t",RxBuffer[i]);
|
||||
}
|
||||
rt_kprintf("\n");
|
||||
#endif
|
||||
|
||||
//_hw_nand1.ops = &_hw_nand1;
|
||||
_hw_nand1.type = RT_Device_Class_MTD;
|
||||
_hw_nand1.init = RT_NULL;//rt_nand_init
|
||||
_hw_nand1.open = rt_nand_open;
|
||||
_hw_nand1.close = RT_NULL;
|
||||
_hw_nand1.read = rt_nand_read;
|
||||
_hw_nand1.write = rt_nand_write;
|
||||
_hw_nand1.control = rt_nand_control;
|
||||
_hw_nand1.user_data = RT_NULL;
|
||||
|
||||
rt_device_register(&_hw_nand1,"nand1", RT_DEVICE_FLAG_RDWR);
|
||||
|
||||
rt_kprintf("nand1 init done\n");
|
||||
|
||||
lpm_init();
|
||||
lpm_dev_blk_append(&_hw_nand1);
|
||||
return 0;
|
||||
}
|
||||
INIT_BOARD_EXPORT(stm32_nand1_init);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-09-28 mingmiaojing first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_GPIO_H__
|
||||
#define __DRV_GPIO_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int rt_hw_nand_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __DRV_GPIO_H__ */
|
||||
|
||||
@@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-05-06 Zero-Free first version
|
||||
* 2024-07-04 wdfk-prog lptimer is supported
|
||||
*/
|
||||
|
||||
#include <board.h>
|
||||
#include <drv_lptim.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
/*#define DRV_DEBUG*/
|
||||
#define LOG_TAG "drv.pm"
|
||||
#include <drv_log.h>
|
||||
|
||||
#ifdef RT_USING_PM
|
||||
|
||||
#ifndef BSP_USING_PM_TIMER
|
||||
/*
|
||||
! Using LPTIM timer, the maximum sleep time is 65535, less than 1 min. Use RTC alarm timers for longer periods.
|
||||
! For example: packages can be used :https://packages.rt-thread.org/detail.html?package=multi_rtimer
|
||||
*/
|
||||
#ifdef BSP_USING_LPTIM1
|
||||
#define BSP_USING_PM_TIMER "lptim1"
|
||||
#elif BSP_USING_LPTIM2
|
||||
#define BSP_USING_PM_TIMER "lptim2"
|
||||
#elif BSP_USING_LPTIM3
|
||||
#define BSP_USING_PM_TIMER "lptim3"
|
||||
#else
|
||||
#error "Please define BSP_USING_PM_TIMER"
|
||||
#endif
|
||||
|
||||
static rt_device_t timer = RT_NULL;
|
||||
|
||||
/* Re-configure the system clock */
|
||||
rt_weak void SystemClock_ReConfig(uint8_t run_mode)
|
||||
{
|
||||
/*todo add your code here*/
|
||||
}
|
||||
|
||||
rt_weak void stm32_pm_device_run(struct rt_pm *pm, uint8_t mode)
|
||||
{
|
||||
/*todo add your code here*/
|
||||
}
|
||||
|
||||
/**
|
||||
* 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:
|
||||
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:
|
||||
#if defined(SOC_SERIES_STM32L4)
|
||||
/* Enter STOP 2 mode */
|
||||
HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
|
||||
/* Re-configure the system clock */
|
||||
SystemClock_ReConfig(pm->run_mode);
|
||||
#endif /* defined(SOC_SERIES_STM32L4) */
|
||||
break;
|
||||
|
||||
case PM_SLEEP_MODE_STANDBY:
|
||||
/* Enter STANDBY mode */
|
||||
HAL_PWR_EnterSTANDBYMode();
|
||||
break;
|
||||
|
||||
case PM_SLEEP_MODE_SHUTDOWN:
|
||||
#if defined(SOC_SERIES_STM32L4)
|
||||
/* Enter SHUTDOWNN mode */
|
||||
HAL_PWREx_EnterSHUTDOWNMode();
|
||||
#endif /* defined(SOC_SERIES_STM32L4) */
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function caculate the PM tick from OS tick
|
||||
*
|
||||
* @param tick OS tick
|
||||
*
|
||||
* @return the PM tick
|
||||
*/
|
||||
static rt_tick_t stm32_pm_tick_from_os_tick(rt_tick_t tick)
|
||||
{
|
||||
rt_uint32_t freq = 0;
|
||||
rt_err_t ret = rt_device_control(timer, DRV_HW_LPTIMER_CTRL_GET_FREQ, &freq);
|
||||
if(ret != RT_EOK)
|
||||
{
|
||||
LOG_E("Get PM timer %s frequency failed %d", timer->parent.name, ret);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D("Get PM timer %s frequency %d", timer->parent.name, freq);
|
||||
}
|
||||
|
||||
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 stm32_os_tick_from_pm_tick(rt_uint32_t tick)
|
||||
{
|
||||
static rt_uint32_t os_tick_remain = 0;
|
||||
rt_tick_t os_tick = 0;
|
||||
rt_uint32_t freq = 0;
|
||||
|
||||
rt_err_t ret = rt_device_control(timer, DRV_HW_LPTIMER_CTRL_GET_FREQ, &freq);
|
||||
if(ret != RT_EOK)
|
||||
{
|
||||
LOG_E("Get PM timer %s frequency failed %d", timer->parent.name, ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
os_tick = (tick * RT_TICK_PER_SECOND + os_tick_remain) / freq;
|
||||
|
||||
os_tick_remain += (tick * RT_TICK_PER_SECOND);
|
||||
os_tick_remain %= freq;
|
||||
|
||||
return os_tick;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
RT_ASSERT(timer != RT_NULL);
|
||||
|
||||
if (timeout != RT_TICK_MAX)
|
||||
{
|
||||
rt_uint32_t max_tick = 0;
|
||||
rt_err_t ret = rt_device_control(timer, DRV_HW_LPTIMER_CTRL_GET_TICK_MAX, &max_tick);
|
||||
if(ret != RT_EOK)
|
||||
{
|
||||
LOG_E("Get PM timer %s max tick failed %d", timer->parent.name, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convert OS Tick to pmtimer timeout value */
|
||||
timeout = stm32_pm_tick_from_os_tick(timeout);
|
||||
|
||||
if (timeout > max_tick)
|
||||
{
|
||||
timeout = max_tick;
|
||||
}
|
||||
|
||||
/* Enter PM_TIMER_MODE */
|
||||
ret = rt_device_control(timer, DRV_HW_LPTIMER_CTRL_START, &timeout);
|
||||
if(ret != RT_EOK)
|
||||
{
|
||||
LOG_E("Get PM timer %s max tick failed %d", timer->parent.name, ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
rt_device_control(timer, HWTIMER_CTRL_STOP, RT_NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
rt_err_t ret = rt_device_control(timer, DRV_HW_LPTIMER_CTRL_GET_COUNT, &timer_tick);
|
||||
|
||||
if(ret != RT_EOK)
|
||||
{
|
||||
LOG_E("Get PM timer %s count failed %d", timer->parent.name, ret);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return stm32_os_tick_from_pm_tick(timer_tick);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct rt_pm_ops _ops =
|
||||
{
|
||||
sleep,
|
||||
stm32_pm_device_run,
|
||||
pm_timer_start,
|
||||
pm_timer_stop,
|
||||
pm_timer_get_tick
|
||||
};
|
||||
|
||||
/**
|
||||
* This function initialize the power manager
|
||||
*/
|
||||
int drv_pm_hw_init(void)
|
||||
{
|
||||
rt_uint8_t timer_mask = 0;
|
||||
|
||||
/* Enable Power Clock */
|
||||
#if !defined(SOC_SERIES_STM32H7) && !defined(SOC_SERIES_STM32WL) && !defined(SOC_SERIES_STM32WB)
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
#ifdef SOC_SERIES_STM32F1
|
||||
__HAL_RCC_BKP_CLK_ENABLE();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* initialize timer mask */
|
||||
timer_mask = 1UL << PM_SLEEP_MODE_DEEP;
|
||||
|
||||
/* initialize system pm module */
|
||||
rt_system_pm_init(&_ops, timer_mask, RT_NULL);
|
||||
|
||||
timer = rt_device_find(BSP_USING_PM_TIMER);
|
||||
|
||||
if(timer == RT_NULL)
|
||||
{
|
||||
LOG_E("Can't find PM timer device");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
return rt_device_init(timer);
|
||||
}
|
||||
}
|
||||
|
||||
INIT_CORE_EXPORT(drv_pm_hw_init);
|
||||
#endif /* RT_USING_PM */
|
||||
@@ -0,0 +1,306 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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 + 1));
|
||||
}
|
||||
|
||||
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_ENABLE_IT(&stm32_device->tim_handler, TIM_IT_UPDATE);
|
||||
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_DISABLE_IT(&stm32_device->tim_handler, TIM_IT_UPDATE);
|
||||
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
|
||||
@@ -0,0 +1,653 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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>
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef BSP_USING_PWM
|
||||
#include "drv_config.h"
|
||||
#include "drv_tim.h"
|
||||
#include <drivers/dev_pwm.h>
|
||||
|
||||
//#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.pwm"
|
||||
#include <drv_log.h>
|
||||
|
||||
#define MAX_PERIOD 65535
|
||||
#define MIN_PERIOD 1
|
||||
#define MIN_PULSE 1
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
static rt_uint64_t tim_clock_get(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
rt_uint32_t pclk1_doubler, pclk2_doubler;
|
||||
rt_uint64_t tim_clock;
|
||||
|
||||
stm32_tim_pclkx_doubler_get(&pclk1_doubler, &pclk2_doubler);
|
||||
|
||||
/* Some series may only have APBPERIPH_BASE, don't have HAL_RCC_GetPCLK2Freq */
|
||||
#if defined(APBPERIPH_BASE)
|
||||
tim_clock = (rt_uint32_t)(HAL_RCC_GetPCLK1Freq() * pclk1_doubler);
|
||||
#elif defined(APB1PERIPH_BASE) || defined(APB2PERIPH_BASE)
|
||||
if ((rt_uint32_t)htim->Instance >= APB2PERIPH_BASE)
|
||||
{
|
||||
tim_clock = (rt_uint32_t)(HAL_RCC_GetPCLK2Freq() * pclk2_doubler);
|
||||
}
|
||||
else
|
||||
{
|
||||
tim_clock = (rt_uint32_t)(HAL_RCC_GetPCLK1Freq() * pclk1_doubler);
|
||||
}
|
||||
#endif
|
||||
|
||||
return tim_clock;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
tim_clock = tim_clock_get(htim);
|
||||
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;
|
||||
/* Converts the channel number to the channel number of Hal library */
|
||||
rt_uint32_t channel = 0x04 * (configuration->channel - 1);
|
||||
|
||||
tim_clock = tim_clock_get(htim);
|
||||
/* Convert nanosecond to frequency and duty cycle. 1s = 1 * 1000 * 1000 * 1000 ns */
|
||||
tim_clock /= 1000000UL;
|
||||
period = (rt_uint64_t)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 = (rt_uint64_t)configuration->pulse * tim_clock / psc / 1000ULL;
|
||||
if (pulse < MIN_PULSE)
|
||||
{
|
||||
pulse = MIN_PULSE;
|
||||
}
|
||||
/*To determine user input, output high level is required*/
|
||||
else if (pulse >= period)
|
||||
{
|
||||
pulse = period + 1;
|
||||
}
|
||||
__HAL_TIM_SET_COMPARE(htim, channel, pulse - 1);
|
||||
|
||||
/* If you want the PWM setting to take effect immediately,
|
||||
please uncommon the following code, but it will cause the last PWM cycle not complete. */
|
||||
//__HAL_TIM_SET_COUNTER(htim, 0);
|
||||
|
||||
//HAL_TIM_GenerateEvent(htim, TIM_EVENTSOURCE_UPDATE); /* Update frequency value */
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t drv_pwm_set_period(TIM_HandleTypeDef *htim, struct rt_pwm_configuration *configuration)
|
||||
{
|
||||
rt_uint32_t period;
|
||||
rt_uint64_t tim_clock, psc;
|
||||
|
||||
tim_clock = tim_clock_get(htim);
|
||||
/* Convert nanosecond to frequency and duty cycle. 1s = 1 * 1000 * 1000 * 1000 ns */
|
||||
tim_clock /= 1000000UL;
|
||||
period = (rt_uint64_t)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);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t drv_pwm_set_pulse(TIM_HandleTypeDef *htim, struct rt_pwm_configuration *configuration)
|
||||
{
|
||||
rt_uint32_t period, pulse;
|
||||
rt_uint64_t tim_clock;
|
||||
/* Converts the channel number to the channel number of Hal library */
|
||||
rt_uint32_t channel = 0x04 * (configuration->channel - 1);
|
||||
|
||||
tim_clock = tim_clock_get(htim);
|
||||
/* Convert nanosecond to frequency and duty cycle. 1s = 1 * 1000 * 1000 * 1000 ns */
|
||||
tim_clock /= 1000000UL;
|
||||
|
||||
period = (__HAL_TIM_GET_AUTORELOAD(htim) + 1) * (htim->Instance->PSC + 1) * 1000UL / tim_clock;
|
||||
pulse = (rt_uint64_t)configuration->pulse * (__HAL_TIM_GET_AUTORELOAD(htim) + 1) / period;
|
||||
|
||||
if (pulse < MIN_PULSE)
|
||||
{
|
||||
pulse = MIN_PULSE;
|
||||
}
|
||||
else if (pulse > period)
|
||||
{
|
||||
pulse = period;
|
||||
}
|
||||
__HAL_TIM_SET_COMPARE(htim, channel, pulse - 1);
|
||||
|
||||
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 PWM_CMD_ENABLE:
|
||||
return drv_pwm_enable(htim, configuration, RT_TRUE);
|
||||
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_SET_PERIOD:
|
||||
return drv_pwm_set_period(htim, configuration);
|
||||
case PWM_CMD_SET_PULSE:
|
||||
return drv_pwm_set_pulse(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 = 1;
|
||||
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;
|
||||
}
|
||||
|
||||
stm32_tim_enable_clock(tim);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (HAL_TIM_PWM_Init(tim) != HAL_OK)
|
||||
{
|
||||
LOG_E("%s pwm init failed", device->name);
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if(IS_TIM_MASTER_INSTANCE(tim->Instance))
|
||||
{
|
||||
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 */
|
||||
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
|
||||
HAL_TIM_MspPostInit(tim);
|
||||
|
||||
/* enable update request source */
|
||||
__HAL_TIM_URS_ENABLE(tim);
|
||||
|
||||
__exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
static void stm32_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_PWM10_CH1
|
||||
stm32_pwm_obj[PWM10_INDEX].channel |= 1 << 0;
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM11_CH1
|
||||
stm32_pwm_obj[PWM11_INDEX].channel |= 1 << 0;
|
||||
#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_PWM13_CH1
|
||||
stm32_pwm_obj[PWM13_INDEX].channel |= 1 << 0;
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM14_CH1
|
||||
stm32_pwm_obj[PWM14_INDEX].channel |= 1 << 0;
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM15_CH1
|
||||
stm32_pwm_obj[PWM15_INDEX].channel |= 1 << 0;
|
||||
#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;
|
||||
|
||||
stm32_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 /* BSP_USING_PWM */
|
||||
@@ -0,0 +1,379 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-11-27 zylx first version
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
#include "drv_qspi.h"
|
||||
#include "drv_config.h"
|
||||
|
||||
#ifdef RT_USING_QSPI
|
||||
|
||||
#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.qspi"
|
||||
#include <drv_log.h>
|
||||
|
||||
#if defined(BSP_USING_QSPI)
|
||||
|
||||
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_ssize_t qspixfer(struct rt_spi_device *device, struct rt_spi_message *message)
|
||||
{
|
||||
rt_ssize_t result = 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;
|
||||
|
||||
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 && (device->cs_pin != PIN_NONE))
|
||||
{
|
||||
rt_pin_write(device->cs_pin, PIN_LOW);
|
||||
}
|
||||
#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)
|
||||
{
|
||||
result = length;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("QSPI send data failed(%d)!", qspi_bus->QSPI_Handler.ErrorCode);
|
||||
qspi_bus->QSPI_Handler.State = HAL_QSPI_STATE_READY;
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = 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
|
||||
{
|
||||
result = 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;
|
||||
result = -RT_ERROR;
|
||||
goto __exit;
|
||||
}
|
||||
}
|
||||
|
||||
__exit:
|
||||
#ifdef BSP_QSPI_USING_SOFTCS
|
||||
if (message->cs_release && (device->cs_pin != PIN_NONE))
|
||||
{
|
||||
rt_pin_write(device->cs_pin, PIN_HIGH);
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
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 cs_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 rt_hw_qspi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin, rt_uint8_t data_line_width, void (*enter_qspi_mode)(), void (*exit_qspi_mode)())
|
||||
{
|
||||
struct rt_qspi_device *qspi_device = 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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
#ifdef BSP_QSPI_USING_SOFTCS
|
||||
result = rt_spi_bus_attach_device_cspin(&qspi_device->parent, device_name, bus_name, cs_pin, RT_NULL);
|
||||
#else
|
||||
result = rt_spi_bus_attach_device_cspin(&qspi_device->parent, device_name, bus_name, PIN_NONE, RT_NULL);
|
||||
#endif /* BSP_QSPI_USING_SOFTCS */
|
||||
|
||||
__exit:
|
||||
if (result != RT_EOK)
|
||||
{
|
||||
if (qspi_device)
|
||||
{
|
||||
rt_free(qspi_device);
|
||||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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 rt_hw_qspi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin, rt_uint8_t data_line_width, void (*enter_qspi_mode)(), void (*exit_qspi_mode)());
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __DRV_QSPI_H__ */
|
||||
@@ -0,0 +1,440 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2024 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
|
||||
* 2025-06-05 RCSN add local time conversion for get timeval and set stamp
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
#include <sys/time.h>
|
||||
#include <rtdevice.h>
|
||||
#include <drv_common.h>
|
||||
|
||||
#ifdef BSP_USING_ONCHIP_RTC
|
||||
|
||||
#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
|
||||
|
||||
struct rtc_device_object
|
||||
{
|
||||
rt_rtc_dev_t rtc_dev;
|
||||
#ifdef RT_USING_ALARM
|
||||
struct rt_rtc_wkalarm wkalarm;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef RT_USING_ALARM
|
||||
static rt_err_t rtc_alarm_time_set(struct rtc_device_object* p_dev);
|
||||
static int rt_rtc_alarm_init(void);
|
||||
static RTC_AlarmTypeDef Alarm_InitStruct = { 0 };
|
||||
#endif
|
||||
|
||||
static struct rtc_device_object rtc_device;
|
||||
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 rt_err_t stm32_rtc_get_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;
|
||||
|
||||
#ifdef RT_ALARM_USING_LOCAL_TIME
|
||||
tv->tv_sec = mktime(&tm_new);
|
||||
#else
|
||||
tv->tv_sec = timegm(&tm_new);
|
||||
#endif
|
||||
#if defined(SOC_SERIES_STM32H7)
|
||||
tv->tv_usec = (255.0 - RTC_TimeStruct.SubSeconds * 1.0) / 256.0 * 1000.0 * 1000.0;
|
||||
#endif
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
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};
|
||||
#ifdef RT_ALARM_USING_LOCAL_TIME
|
||||
localtime_r(&time_stamp,&tm);
|
||||
#else
|
||||
gmtime_r(&time_stamp, &tm);
|
||||
#endif
|
||||
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();
|
||||
|
||||
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;
|
||||
#if defined(BSP_RTC_USING_LSI)
|
||||
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
|
||||
#elif defined(BSP_RTC_USING_LSE)
|
||||
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
|
||||
#else
|
||||
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV32;
|
||||
#endif
|
||||
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
|
||||
|
||||
#if defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G0)
|
||||
__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_STM32L0) \
|
||||
|| defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32H7) || defined (SOC_SERIES_STM32WB) \
|
||||
|| defined(SOC_SERIES_STM32G0)
|
||||
|
||||
/* 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;
|
||||
#else
|
||||
#warning "This series doesn't support yet!"
|
||||
#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();
|
||||
#ifdef SOC_SERIES_STM32F1
|
||||
__HAL_RCC_BKP_CLK_ENABLE();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(BSP_RTC_USING_LSI) || defined(BSP_RTC_USING_LSE)
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
|
||||
#ifdef BSP_RTC_USING_LSI
|
||||
#ifdef SOC_SERIES_STM32WB
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI1;
|
||||
#else
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
|
||||
#endif
|
||||
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
|
||||
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
|
||||
#else
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
|
||||
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
|
||||
RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
|
||||
#endif
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
|
||||
HAL_RCC_OscConfig(&RCC_OscInitStruct);
|
||||
#endif
|
||||
|
||||
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(time_t *sec)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
stm32_rtc_get_timeval(&tv);
|
||||
*(time_t *) sec = tv.tv_sec;
|
||||
LOG_D("RTC: get rtc_time %d", *sec);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t stm32_rtc_set_secs(time_t *sec)
|
||||
{
|
||||
rt_err_t result = RT_EOK;
|
||||
|
||||
if (set_rtc_time_stamp(*sec))
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
}
|
||||
LOG_D("RTC: set rtc_time %d", *sec);
|
||||
#ifdef RT_USING_ALARM
|
||||
rt_alarm_update(&rtc_device.rtc_dev.parent, 1);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
static rt_err_t stm32_rtc_get_alarm(struct rt_rtc_wkalarm *alarm)
|
||||
{
|
||||
#ifdef RT_USING_ALARM
|
||||
*alarm = rtc_device.wkalarm;
|
||||
LOG_D("GET_ALARM %d:%d:%d",rtc_device.wkalarm.tm_hour,
|
||||
rtc_device.wkalarm.tm_min,rtc_device.wkalarm.tm_sec);
|
||||
return RT_EOK;
|
||||
#else
|
||||
return -RT_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
static rt_err_t stm32_rtc_set_alarm(struct rt_rtc_wkalarm *alarm)
|
||||
{
|
||||
#ifdef RT_USING_ALARM
|
||||
LOG_D("RT_DEVICE_CTRL_RTC_SET_ALARM");
|
||||
if (alarm != RT_NULL)
|
||||
{
|
||||
rtc_device.wkalarm.enable = alarm->enable;
|
||||
rtc_device.wkalarm.tm_hour = alarm->tm_hour;
|
||||
rtc_device.wkalarm.tm_min = alarm->tm_min;
|
||||
rtc_device.wkalarm.tm_sec = alarm->tm_sec;
|
||||
/* must include the year, month, and day */
|
||||
/* as the alarm in RT_ALARM_ONESHOT mode compares the current timestamp with the alarm timestamp */
|
||||
rtc_device.wkalarm.tm_year = alarm->tm_year;
|
||||
rtc_device.wkalarm.tm_mon = alarm->tm_mon;
|
||||
rtc_device.wkalarm.tm_mday = alarm->tm_mday;
|
||||
rtc_alarm_time_set(&rtc_device);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("RT_DEVICE_CTRL_RTC_SET_ALARM error!!");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
LOG_D("SET_ALARM %d:%d:%d",alarm->tm_hour,
|
||||
alarm->tm_min, alarm->tm_sec);
|
||||
return RT_EOK;
|
||||
#else
|
||||
return -RT_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
static const struct rt_rtc_ops stm32_rtc_ops =
|
||||
{
|
||||
stm32_rtc_init,
|
||||
stm32_rtc_get_secs,
|
||||
stm32_rtc_set_secs,
|
||||
stm32_rtc_get_alarm,
|
||||
stm32_rtc_set_alarm,
|
||||
stm32_rtc_get_timeval,
|
||||
RT_NULL,
|
||||
};
|
||||
|
||||
#ifdef RT_USING_ALARM
|
||||
void rt_rtc_alarm_enable(void)
|
||||
{
|
||||
HAL_RTC_SetAlarm_IT(&RTC_Handler,&Alarm_InitStruct,RTC_FORMAT_BIN);
|
||||
HAL_RTC_GetAlarm(&RTC_Handler,&Alarm_InitStruct,RTC_ALARM_A,RTC_FORMAT_BIN);
|
||||
LOG_D("alarm read:%d:%d:%d", Alarm_InitStruct.AlarmTime.Hours,
|
||||
Alarm_InitStruct.AlarmTime.Minutes,
|
||||
Alarm_InitStruct.AlarmTime.Seconds);
|
||||
HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 0x02, 0);
|
||||
HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
|
||||
}
|
||||
|
||||
void rt_rtc_alarm_disable(void)
|
||||
{
|
||||
HAL_RTC_DeactivateAlarm(&RTC_Handler, RTC_ALARM_A);
|
||||
HAL_NVIC_DisableIRQ(RTC_Alarm_IRQn);
|
||||
}
|
||||
|
||||
static int rt_rtc_alarm_init(void)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t rtc_alarm_time_set(struct rtc_device_object* p_dev)
|
||||
{
|
||||
if (p_dev->wkalarm.enable)
|
||||
{
|
||||
Alarm_InitStruct.Alarm = RTC_ALARM_A;
|
||||
Alarm_InitStruct.AlarmTime.Hours = p_dev->wkalarm.tm_hour;
|
||||
Alarm_InitStruct.AlarmTime.Minutes = p_dev->wkalarm.tm_min;
|
||||
Alarm_InitStruct.AlarmTime.Seconds = p_dev->wkalarm.tm_sec;
|
||||
#ifndef SOC_SERIES_STM32F1
|
||||
Alarm_InitStruct.AlarmDateWeekDay = RTC_WEEKDAY_MONDAY;
|
||||
Alarm_InitStruct.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_WEEKDAY;
|
||||
Alarm_InitStruct.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
|
||||
Alarm_InitStruct.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_NONE;
|
||||
Alarm_InitStruct.AlarmTime.TimeFormat = RTC_HOURFORMAT12_AM;
|
||||
#endif /* SOC_SERIES_STM32F1 */
|
||||
LOG_D("alarm set:%d:%d:%d", Alarm_InitStruct.AlarmTime.Hours,
|
||||
Alarm_InitStruct.AlarmTime.Minutes,
|
||||
Alarm_InitStruct.AlarmTime.Seconds);
|
||||
rt_rtc_alarm_enable();
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
/*LOG_D("rtc alarm isr.\n");*/
|
||||
rt_alarm_update(&rtc_device.rtc_dev.parent, 1);
|
||||
}
|
||||
|
||||
void RTC_Alarm_IRQHandler(void)
|
||||
{
|
||||
rt_interrupt_enter();
|
||||
HAL_RTC_AlarmIRQHandler(&RTC_Handler);
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif
|
||||
|
||||
static int rt_hw_rtc_init(void)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
rtc_device.rtc_dev.ops = &stm32_rtc_ops;
|
||||
result = rt_hw_rtc_register(&rtc_device.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");
|
||||
|
||||
#ifdef RT_USING_ALARM
|
||||
rt_rtc_alarm_init();
|
||||
#endif
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
INIT_BOARD_EXPORT(rt_hw_rtc_init);
|
||||
#endif /* BSP_USING_ONCHIP_RTC */
|
||||
@@ -0,0 +1,888 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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"
|
||||
#include "drv_sdio.h"
|
||||
#include "drv_config.h"
|
||||
|
||||
#ifdef BSP_USING_SDIO
|
||||
|
||||
//#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;
|
||||
};
|
||||
|
||||
rt_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
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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/dev_mmcsd_core.h>
|
||||
#include <drivers/dev_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_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
|
||||
@@ -0,0 +1,735 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-05-23 liuduanfei first version
|
||||
* 2020-08-25 wanghaijing add sdmmmc2
|
||||
* 2023-03-26 wdfk-prog Distinguish between SDMMC and SDIO drivers
|
||||
*/
|
||||
#include "board.h"
|
||||
|
||||
#ifdef RT_USING_SDIO
|
||||
|
||||
#if !defined(BSP_USING_SDIO1) && !defined(BSP_USING_SDIO2)
|
||||
#error "Please define at least one BSP_USING_SDIOx"
|
||||
#endif
|
||||
|
||||
#include "drv_sdmmc.h"
|
||||
|
||||
#define DBG_TAG "drv.sdmmc"
|
||||
#ifdef DRV_DEBUG
|
||||
#define DBG_LVL DBG_LOG
|
||||
#else
|
||||
#define DBG_LVL DBG_INFO
|
||||
#endif /* DRV_DEBUG */
|
||||
#include <rtdbg.h>
|
||||
|
||||
static struct stm32_sdio_class sdio_obj;
|
||||
static struct rt_mmcsd_host *host1;
|
||||
static struct rt_mmcsd_host *host2;
|
||||
|
||||
#define SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS (1000000)
|
||||
|
||||
#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;
|
||||
};
|
||||
|
||||
rt_align(SDIO_ALIGN_LEN)
|
||||
static rt_uint8_t cache_buf[SDIO_BUFF_SIZE];
|
||||
|
||||
/**
|
||||
* @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 cmd 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;
|
||||
SD_TypeDef *hsd = sdio->sdio_des.hw_sdio.Instance;
|
||||
|
||||
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 cmd completed timeout");
|
||||
cmd->err = -RT_ETIMEOUT;
|
||||
return;
|
||||
}
|
||||
|
||||
if (sdio->pkg == RT_NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
/* Get Card Specific Data */
|
||||
cmd->resp[0] = hsd->RESP1;
|
||||
if (resp_type(cmd) == RESP_R2)
|
||||
{
|
||||
cmd->resp[1] = hsd->RESP2;
|
||||
cmd->resp[2] = hsd->RESP3;
|
||||
cmd->resp[3] = hsd->RESP4;
|
||||
}
|
||||
/* Check for error conditions */
|
||||
if (status & SDIO_ERRORS)
|
||||
{
|
||||
if ((status & SDMMC_STA_CCRCFAIL) && (resp_type(cmd) & (RESP_R3 | RESP_R4)))
|
||||
{
|
||||
cmd->err = RT_EOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd->err = -RT_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd->err = RT_EOK;
|
||||
}
|
||||
|
||||
if (status & SDMMC_IT_CTIMEOUT)
|
||||
{
|
||||
cmd->err = -RT_ETIMEOUT;
|
||||
}
|
||||
if (status & SDMMC_IT_DCRCFAIL)
|
||||
{
|
||||
data->err = -RT_ERROR;
|
||||
}
|
||||
|
||||
if (status & SDMMC_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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
SD_TypeDef *hsd = sdio->sdio_des.hw_sdio.Instance;
|
||||
rt_uint32_t reg_cmd;
|
||||
|
||||
rt_event_control(&sdio->event, RT_IPC_CMD_RESET, RT_NULL);
|
||||
/* 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\n",
|
||||
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
|
||||
);
|
||||
|
||||
/* open irq */
|
||||
__HAL_SD_ENABLE_IT(&sdio->sdio_des.hw_sdio, SDIO_MASKR_ALL);
|
||||
reg_cmd = cmd->cmd_code | SDMMC_CMD_CPSMEN;
|
||||
|
||||
/* data pre configuration */
|
||||
if (data != RT_NULL)
|
||||
{
|
||||
SCB_CleanInvalidateDCache();
|
||||
|
||||
reg_cmd |= SDMMC_CMD_CMDTRANS;
|
||||
__HAL_SD_DISABLE_IT(&sdio->sdio_des.hw_sdio, SDMMC_MASK_CMDRENDIE | SDMMC_MASK_CMDSENTIE);
|
||||
hsd->DTIMER = HW_SDIO_DATATIMEOUT;
|
||||
hsd->DLEN = data->blks * data->blksize;
|
||||
hsd->DCTRL = (get_order(data->blksize) << 4) | (data->flags & DATA_DIR_READ ? SDMMC_DCTRL_DTDIR : 0);
|
||||
#ifndef SOC_SERIES_STM32H7RS
|
||||
hsd->IDMABASE0 = (rt_uint32_t)cache_buf;
|
||||
#else
|
||||
hsd->IDMABASER = (rt_uint32_t)cache_buf;
|
||||
#endif
|
||||
hsd->IDMACTRL = SDMMC_IDMA_IDMAEN;
|
||||
}
|
||||
/* config cmd reg */
|
||||
if (resp_type(cmd) == RESP_NONE)
|
||||
reg_cmd |= SDMMC_RESPONSE_NO;
|
||||
else if (resp_type(cmd) == RESP_R2)
|
||||
reg_cmd |= SDMMC_RESPONSE_LONG;
|
||||
else
|
||||
reg_cmd |= SDMMC_RESPONSE_SHORT;
|
||||
|
||||
hsd->ARG = cmd->arg;
|
||||
hsd->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 && (hsd->STA & SDMMC_STA_DPSMACT))
|
||||
{
|
||||
count--;
|
||||
}
|
||||
|
||||
if ((count == 0) || (hsd->STA & SDIO_ERRORS))
|
||||
{
|
||||
cmd->err = -RT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* data post configuration */
|
||||
if (data != RT_NULL)
|
||||
{
|
||||
if (data->flags & DATA_DIR_READ)
|
||||
{
|
||||
rt_memcpy(data->buf, cache_buf, data->blks * data->blksize);
|
||||
SCB_CleanInvalidateDCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function send sdio request.
|
||||
* @param sdio rthw_sdio
|
||||
* @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);
|
||||
|
||||
if (data->flags & DATA_DIR_WRITE)
|
||||
{
|
||||
rt_memcpy(cache_buf, data->buf, size);
|
||||
}
|
||||
}
|
||||
|
||||
rthw_sdio_send_command(sdio, &pkg);
|
||||
}
|
||||
|
||||
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 temp, clk_src;
|
||||
rt_uint32_t clk = io_cfg->clock;
|
||||
struct rthw_sdio *sdio = host->private_data;
|
||||
SD_HandleTypeDef *hsd = &sdio->sdio_des.hw_sdio;
|
||||
SDMMC_InitTypeDef Init = {0};
|
||||
rt_uint32_t sdmmc_clk = sdio->sdio_des.clk_get();
|
||||
|
||||
if (sdmmc_clk < 400 * 1000)
|
||||
{
|
||||
LOG_E("The clock rate is too low! rata:%d", sdmmc_clk);
|
||||
return;
|
||||
}
|
||||
|
||||
if (clk > host->freq_max)
|
||||
clk = host->freq_max;
|
||||
|
||||
if (clk > sdmmc_clk)
|
||||
{
|
||||
LOG_W("Setting rate is greater than clock source rate.");
|
||||
clk = sdmmc_clk;
|
||||
}
|
||||
|
||||
LOG_D("clk:%dK width:%s%s%s power:%s%s%s",
|
||||
clk / 1000,
|
||||
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" : ""
|
||||
);
|
||||
|
||||
if (sdmmc_clk != 0U)
|
||||
{
|
||||
hsd->Init.ClockDiv = sdmmc_clk / (2U * SD_INIT_FREQ);
|
||||
/* Configure the SDMMC peripheral */
|
||||
Init.ClockEdge = hsd->Init.ClockEdge;
|
||||
Init.ClockPowerSave = hsd->Init.ClockPowerSave;
|
||||
if (io_cfg->bus_width == MMCSD_BUS_WIDTH_4)
|
||||
{
|
||||
Init.BusWide = SDMMC_BUS_WIDE_4B;
|
||||
}
|
||||
else if (io_cfg->bus_width == MMCSD_BUS_WIDTH_8)
|
||||
{
|
||||
Init.BusWide = SDMMC_BUS_WIDE_8B;
|
||||
}
|
||||
else
|
||||
{
|
||||
Init.BusWide = SDMMC_BUS_WIDE_1B;
|
||||
}
|
||||
Init.HardwareFlowControl = hsd->Init.HardwareFlowControl;
|
||||
/* Check if user Clock div < Normal speed 25Mhz, no change in Clockdiv */
|
||||
if (hsd->Init.ClockDiv >= (sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ)))
|
||||
{
|
||||
Init.ClockDiv = hsd->Init.ClockDiv;
|
||||
}
|
||||
//CARD_ULTRA_HIGH_SPEED :UHS-I SD Card <50Mo/s for SDR50, DDR5 Cards and <104Mo/s for SDR104, Spec version 3.01
|
||||
else if (MMCSD_TIMING_UHS_SDR50 <= io_cfg->timing && io_cfg->timing <= MMCSD_TIMING_UHS_DDR50)
|
||||
{
|
||||
/* UltraHigh speed SD card,user Clock div */
|
||||
Init.ClockDiv = hsd->Init.ClockDiv;
|
||||
}
|
||||
//CARD_HIGH_SPEED: High Speed Card <25Mo/s , Spec version 2.00
|
||||
else if (io_cfg->timing == MMCSD_TIMING_SD_HS)
|
||||
{
|
||||
/* High speed SD card, Max Frequency = 50Mhz */
|
||||
if (hsd->Init.ClockDiv == 0U)
|
||||
{
|
||||
if (sdmmc_clk > SD_HIGH_SPEED_FREQ)
|
||||
{
|
||||
Init.ClockDiv = sdmmc_clk / (2U * SD_HIGH_SPEED_FREQ);
|
||||
}
|
||||
else
|
||||
{
|
||||
Init.ClockDiv = hsd->Init.ClockDiv;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((sdmmc_clk/(2U * hsd->Init.ClockDiv)) > SD_HIGH_SPEED_FREQ)
|
||||
{
|
||||
Init.ClockDiv = sdmmc_clk / (2U * SD_HIGH_SPEED_FREQ);
|
||||
}
|
||||
else
|
||||
{
|
||||
Init.ClockDiv = hsd->Init.ClockDiv;
|
||||
}
|
||||
}
|
||||
}
|
||||
//CARD_NORMAL_SPEED: Normal Speed Card <12.5Mo/s , Spec Version 1.01
|
||||
else if (io_cfg->timing == MMCSD_TIMING_LEGACY)
|
||||
{
|
||||
/* No High speed SD card, Max Frequency = 25Mhz */
|
||||
if (hsd->Init.ClockDiv == 0U)
|
||||
{
|
||||
if (sdmmc_clk > SD_NORMAL_SPEED_FREQ)
|
||||
{
|
||||
Init.ClockDiv = sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ);
|
||||
}
|
||||
else
|
||||
{
|
||||
Init.ClockDiv = hsd->Init.ClockDiv;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((sdmmc_clk/(2U * hsd->Init.ClockDiv)) > SD_NORMAL_SPEED_FREQ)
|
||||
{
|
||||
Init.ClockDiv = sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ);
|
||||
}
|
||||
else
|
||||
{
|
||||
Init.ClockDiv = hsd->Init.ClockDiv;
|
||||
}
|
||||
}
|
||||
}
|
||||
(void)SDMMC_Init(hsd->Instance, Init);
|
||||
}
|
||||
switch ((io_cfg->power_mode)&0X03)
|
||||
{
|
||||
case MMCSD_POWER_OFF:
|
||||
/* Set Power State to OFF */
|
||||
(void)SDMMC_PowerState_OFF(hsd->Instance);
|
||||
break;
|
||||
case MMCSD_POWER_UP:
|
||||
/* In F4 series chips, 0X01 is reserved bit and has no practical effect.
|
||||
For F7 series chips, 0X01 is power-on after power-off,The SDMMC disables the function and the card clock stops.
|
||||
For H7 series chips, 0X03 is the power-on function.
|
||||
*/
|
||||
case MMCSD_POWER_ON:
|
||||
/* Set Power State to ON */
|
||||
(void)SDMMC_PowerState_ON(hsd->Instance);
|
||||
break;
|
||||
default:
|
||||
LOG_W("unknown power mode %d", io_cfg->power_mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
if (enable)
|
||||
{
|
||||
LOG_D("enable sdio irq");
|
||||
__HAL_SD_ENABLE_IT(&sdio->sdio_des.hw_sdio, SDMMC_IT_SDIOIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D("disable sdio irq");
|
||||
__HAL_SD_ENABLE_IT(&sdio->sdio_des.hw_sdio, SDMMC_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)
|
||||
{
|
||||
struct rthw_sdio *sdio = host->private_data;
|
||||
rt_uint32_t intstatus = sdio->sdio_des.hw_sdio.Instance->STA;
|
||||
|
||||
/* clear irq flag*/
|
||||
__HAL_SD_CLEAR_FLAG(&sdio->sdio_des.hw_sdio, intstatus);
|
||||
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)
|
||||
{
|
||||
LOG_E("L:%d F:%s",(sdio_des == RT_NULL ? "sdio_des 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));
|
||||
#ifdef BSP_USING_SDIO1
|
||||
if(sdio_des->hw_sdio.Instance == SDMMC1)
|
||||
{
|
||||
rt_event_init(&sdio->event, "sdio1", RT_IPC_FLAG_FIFO);
|
||||
rt_mutex_init(&sdio->mutex, "sdio1", RT_IPC_FLAG_PRIO);
|
||||
}
|
||||
#endif /* BSP_USING_SDIO1 */
|
||||
#ifdef BSP_USING_SDIO2
|
||||
if(sdio_des->hw_sdio.Instance == SDMMC2)
|
||||
{
|
||||
rt_event_init(&sdio->event, "sdio2", RT_IPC_FLAG_FIFO);
|
||||
rt_mutex_init(&sdio->mutex, "sdio2", RT_IPC_FLAG_PRIO);
|
||||
}
|
||||
#endif /* BSP_USING_SDIO2 */
|
||||
|
||||
/* set host default 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_HIGHSPEED;
|
||||
#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 get stm32 sdio clock.
|
||||
* @param hw_sdio: stm32_sdio
|
||||
* @retval PCLK2Freq
|
||||
*/
|
||||
static rt_uint32_t stm32_sdio_clock_get(void)
|
||||
{
|
||||
#ifndef SOC_SERIES_STM32H7RS
|
||||
return HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC);
|
||||
#else
|
||||
return HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC12);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SDMMC1_IRQHandler(void)
|
||||
{
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
/* Process All SDIO Interrupt Sources */
|
||||
rthw_sdio_irq_process(host1);
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
|
||||
void SDMMC2_IRQHandler(void)
|
||||
{
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
/* Process All SDIO Interrupt Sources */
|
||||
rthw_sdio_irq_process(host2);
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
|
||||
int rt_hw_sdio_init(void)
|
||||
{
|
||||
#ifdef BSP_USING_SDIO1
|
||||
struct stm32_sdio_des sdio_des1 = {0};
|
||||
sdio_des1.hw_sdio.Instance = SDMMC1;
|
||||
|
||||
HAL_SD_MspInit(&sdio_des1.hw_sdio);
|
||||
HAL_NVIC_SetPriority(SDMMC1_IRQn, 2, 0);
|
||||
HAL_NVIC_EnableIRQ(SDMMC1_IRQn);
|
||||
|
||||
sdio_des1.clk_get = stm32_sdio_clock_get;
|
||||
|
||||
host1 = sdio_host_create(&sdio_des1);
|
||||
|
||||
if (host1 == RT_NULL)
|
||||
{
|
||||
LOG_E("host1 create fail");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
#endif /* BSP_USING_SDIO1 */
|
||||
|
||||
#ifdef BSP_USING_SDIO2
|
||||
struct stm32_sdio_des sdio_des2 = {0};
|
||||
sdio_des2.hw_sdio.Instance = SDMMC2;
|
||||
|
||||
HAL_SD_MspInit(&sdio_des2.hw_sdio);
|
||||
HAL_NVIC_SetPriority(SDMMC2_IRQn, 2, 0);
|
||||
HAL_NVIC_EnableIRQ(SDMMC2_IRQn);
|
||||
|
||||
sdio_des2.clk_get = stm32_sdio_clock_get;
|
||||
|
||||
host2 = sdio_host_create(&sdio_des2);
|
||||
|
||||
if (host2 == RT_NULL)
|
||||
{
|
||||
LOG_E("host2 create fail");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
#endif /* BSP_USING_SDIO2 */
|
||||
return RT_EOK;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(rt_hw_sdio_init);
|
||||
|
||||
void stm32_mmcsd_change(void)
|
||||
{
|
||||
#ifdef BSP_USING_SDIO1
|
||||
mmcsd_change(host1);
|
||||
#endif /* BSP_USING_SDIO2 */
|
||||
#ifdef BSP_USING_SDIO2
|
||||
mmcsd_change(host2);
|
||||
#endif /* BSP_USING_SDIO2 */
|
||||
}
|
||||
|
||||
#endif /* RT_USING_SDIO */
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-05-23 liuduanfei first version
|
||||
* 2020-08-25 wanghaijing add sdmmmc2
|
||||
* 2023-03-26 wdfk-prog Distinguish between SDMMC and SDIO drivers
|
||||
*/
|
||||
|
||||
#ifndef __DRV_SDMMC_H__
|
||||
#define __DRV_SDMMC_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
#include "rtdevice.h"
|
||||
#include <rthw.h>
|
||||
#include <drv_common.h>
|
||||
#include <string.h>
|
||||
#include <drivers/dev_mmcsd_core.h>
|
||||
#include <drivers/dev_sdio.h>
|
||||
|
||||
#define SDIO_BUFF_SIZE 4096
|
||||
#define SDIO_ALIGN_LEN 32
|
||||
|
||||
#define SDIO1_BASE_ADDRESS (SDMMC1_BASE)
|
||||
#define SDIO2_BASE_ADDRESS (SDMMC2_BASE)
|
||||
|
||||
#ifndef SDIO_CLOCK_FREQ
|
||||
#define SDIO_CLOCK_FREQ (200U * 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 (25 * 1000 * 1000)
|
||||
#endif
|
||||
|
||||
/* Frequencies used in the driver for clock divider calculation */
|
||||
#define SD_INIT_FREQ 400000U /* Initalization phase : 400 kHz max */
|
||||
#define SD_NORMAL_SPEED_FREQ 25000000U /* Normal speed phase : 25 MHz max */
|
||||
#define SD_HIGH_SPEED_FREQ 50000000U /* High speed phase : 50 MHz max */
|
||||
|
||||
#define SDIO_ERRORS \
|
||||
(SDMMC_STA_IDMATE | SDMMC_STA_ACKTIMEOUT | \
|
||||
SDMMC_STA_RXOVERR | SDMMC_STA_TXUNDERR | \
|
||||
SDMMC_STA_DTIMEOUT | SDMMC_STA_CTIMEOUT | \
|
||||
SDMMC_STA_DCRCFAIL | SDMMC_STA_CCRCFAIL)
|
||||
|
||||
#define SDIO_MASKR_ALL \
|
||||
(SDMMC_MASK_CCRCFAILIE | SDMMC_MASK_DCRCFAILIE | SDMMC_MASK_CTIMEOUTIE | \
|
||||
SDMMC_MASK_TXUNDERRIE | SDMMC_MASK_RXOVERRIE | SDMMC_MASK_CMDRENDIE | \
|
||||
SDMMC_MASK_CMDSENTIE | SDMMC_MASK_DATAENDIE | SDMMC_MASK_ACKTIMEOUTIE)
|
||||
|
||||
#define HW_SDIO_DATATIMEOUT (0xFFFFFFFFU)
|
||||
|
||||
typedef rt_uint32_t (*sdio_clk_get)(void);
|
||||
|
||||
struct stm32_sdio_des
|
||||
{
|
||||
SD_HandleTypeDef hw_sdio;
|
||||
sdio_clk_get clk_get;
|
||||
};
|
||||
|
||||
/* stm32 sdio dirver class */
|
||||
struct stm32_sdio_class
|
||||
{
|
||||
struct stm32_sdio_des *des;
|
||||
const struct stm32_sdio_config *cfg;
|
||||
struct rt_mmcsd_host host;
|
||||
};
|
||||
|
||||
extern void stm32_mmcsd_change(void);
|
||||
|
||||
#endif /* __DRV_SDMMC_H__ */
|
||||
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-12-04 zylx first version
|
||||
*/
|
||||
|
||||
#include <board.h>
|
||||
#include <rtthread.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 */
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-11-08 balanceTWK first version
|
||||
* 2023-06-27 Meco Man replace stm32_udelay as rt_hw_us_delay
|
||||
*/
|
||||
|
||||
#include "drv_soft_i2c.h"
|
||||
#include "drv_config.h"
|
||||
|
||||
#if defined(BSP_USING_I2C1) || defined(BSP_USING_I2C2) || defined(BSP_USING_I2C3) || defined(BSP_USING_I2C4) || defined(BSP_USING_I2C5)
|
||||
|
||||
|
||||
//#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.i2c.sw"
|
||||
#include <drv_log.h>
|
||||
|
||||
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
|
||||
#ifdef BSP_USING_I2C5
|
||||
I2C5_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);
|
||||
}
|
||||
|
||||
static void stm32_i2c_pin_init(void)
|
||||
{
|
||||
rt_size_t obj_num = sizeof(i2c_obj) / sizeof(struct stm32_i2c);
|
||||
|
||||
for(rt_size_t i = 0; i < obj_num; i++)
|
||||
{
|
||||
stm32_i2c_gpio_init(&i2c_obj[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
static const struct rt_i2c_bit_ops stm32_bit_ops_default =
|
||||
{
|
||||
.data = RT_NULL,
|
||||
.pin_init = stm32_i2c_pin_init,
|
||||
.set_sda = stm32_set_sda,
|
||||
.set_scl = stm32_set_scl,
|
||||
.get_sda = stm32_get_sda,
|
||||
.get_scl = stm32_get_scl,
|
||||
.udelay = rt_hw_us_delay,
|
||||
.delay_us = 1,
|
||||
.timeout = 100,
|
||||
.i2c_pin_init_flag = RT_FALSE
|
||||
};
|
||||
|
||||
/**
|
||||
* 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);
|
||||
rt_hw_us_delay(100);
|
||||
rt_pin_write(cfg->scl, PIN_LOW);
|
||||
rt_hw_us_delay(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_err_t result;
|
||||
|
||||
for (rt_size_t i = 0; i < sizeof(i2c_obj) / sizeof(struct stm32_i2c); i++)
|
||||
{
|
||||
i2c_obj[i].ops = stm32_bit_ops_default;
|
||||
i2c_obj[i].ops.data = (void*)&soft_i2c_config[i];
|
||||
i2c_obj[i].i2c_bus.priv = &i2c_obj[i].ops;
|
||||
result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c_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 /* defined(BSP_USING_I2C1) || defined(BSP_USING_I2C2) || defined(BSP_USING_I2C3) || defined(BSP_USING_I2C4) */
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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 i2c_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
|
||||
|
||||
#ifdef BSP_USING_I2C5
|
||||
#define I2C5_BUS_CONFIG \
|
||||
{ \
|
||||
.scl = BSP_I2C5_SCL_PIN, \
|
||||
.sda = BSP_I2C5_SDA_PIN, \
|
||||
.bus_name = "i2c5", \
|
||||
}
|
||||
#endif
|
||||
int rt_hw_i2c_init(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-6-14 solar first version
|
||||
*/
|
||||
#include <board.h>
|
||||
#include <string.h>
|
||||
#include "drv_soft_spi.h"
|
||||
#include "drv_config.h"
|
||||
|
||||
#if defined(RT_USING_SPI) && defined(RT_USING_SOFT_SPI) && defined(RT_USING_PIN)
|
||||
|
||||
//#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.soft_spi"
|
||||
#include <drv_log.h>
|
||||
|
||||
static struct stm32_soft_spi_config soft_spi_config[] =
|
||||
{
|
||||
#ifdef BSP_USING_SOFT_SPI1
|
||||
SOFT_SPI1_BUS_CONFIG,
|
||||
#endif
|
||||
#ifdef BSP_USING_SOFT_SPI2
|
||||
SOFT_SPI2_BUS_CONFIG,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct stm32_soft_spi spi_obj[sizeof(soft_spi_config) / sizeof(soft_spi_config[0])];
|
||||
|
||||
/**
|
||||
* Attach the spi device to soft SPI bus, this function must be used after initialization.
|
||||
*/
|
||||
rt_err_t rt_hw_softspi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin)
|
||||
{
|
||||
|
||||
rt_err_t result;
|
||||
struct rt_spi_device *spi_device;
|
||||
|
||||
/* attach the device to soft spi bus*/
|
||||
spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
|
||||
RT_ASSERT(spi_device != RT_NULL);
|
||||
|
||||
result = rt_spi_bus_attach_device_cspin(spi_device, device_name, bus_name, cs_pin, RT_NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void stm32_spi_gpio_init(struct stm32_soft_spi *spi)
|
||||
{
|
||||
struct stm32_soft_spi_config *cfg = (struct stm32_soft_spi_config *)spi->cfg;
|
||||
rt_pin_mode(cfg->sck, PIN_MODE_OUTPUT);
|
||||
rt_pin_mode(cfg->miso, PIN_MODE_INPUT);
|
||||
rt_pin_mode(cfg->mosi, PIN_MODE_OUTPUT);
|
||||
|
||||
rt_pin_write(cfg->miso, PIN_HIGH);
|
||||
rt_pin_write(cfg->sck, PIN_HIGH);
|
||||
rt_pin_write(cfg->mosi, PIN_HIGH);
|
||||
}
|
||||
|
||||
void stm32_tog_sclk(void *data)
|
||||
{
|
||||
struct stm32_soft_spi_config* cfg = (struct stm32_soft_spi_config*)data;
|
||||
if(rt_pin_read(cfg->sck) == PIN_HIGH)
|
||||
{
|
||||
rt_pin_write(cfg->sck, PIN_LOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_pin_write(cfg->sck, PIN_HIGH);
|
||||
}
|
||||
}
|
||||
|
||||
void stm32_set_sclk(void *data, rt_int32_t state)
|
||||
{
|
||||
|
||||
struct stm32_soft_spi_config* cfg = (struct stm32_soft_spi_config*)data;
|
||||
if (state)
|
||||
{
|
||||
rt_pin_write(cfg->sck, PIN_HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_pin_write(cfg->sck, PIN_LOW);
|
||||
}
|
||||
}
|
||||
|
||||
void stm32_set_mosi(void *data, rt_int32_t state)
|
||||
{
|
||||
struct stm32_soft_spi_config* cfg = (struct stm32_soft_spi_config*)data;
|
||||
if (state)
|
||||
{
|
||||
rt_pin_write(cfg->mosi, PIN_HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_pin_write(cfg->mosi, PIN_LOW);
|
||||
}
|
||||
}
|
||||
|
||||
void stm32_set_miso(void *data, rt_int32_t state)
|
||||
{
|
||||
struct stm32_soft_spi_config* cfg = (struct stm32_soft_spi_config*)data;
|
||||
if (state)
|
||||
{
|
||||
rt_pin_write(cfg->miso, PIN_HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_pin_write(cfg->miso, PIN_LOW);
|
||||
}
|
||||
}
|
||||
|
||||
rt_int32_t stm32_get_sclk(void *data)
|
||||
{
|
||||
struct stm32_soft_spi_config* cfg = (struct stm32_soft_spi_config*)data;
|
||||
return rt_pin_read(cfg->sck);
|
||||
}
|
||||
|
||||
rt_int32_t stm32_get_mosi(void *data)
|
||||
{
|
||||
struct stm32_soft_spi_config* cfg = (struct stm32_soft_spi_config*)data;
|
||||
return rt_pin_read(cfg->mosi);
|
||||
}
|
||||
|
||||
rt_int32_t stm32_get_miso(void *data)
|
||||
{
|
||||
struct stm32_soft_spi_config* cfg = (struct stm32_soft_spi_config*)data;
|
||||
return rt_pin_read(cfg->miso);
|
||||
}
|
||||
|
||||
void stm32_dir_mosi(void *data, rt_int32_t state)
|
||||
{
|
||||
struct stm32_soft_spi_config* cfg = (struct stm32_soft_spi_config*)data;
|
||||
if (state)
|
||||
{
|
||||
rt_pin_mode(cfg->mosi, PIN_MODE_INPUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_pin_mode(cfg->mosi, PIN_MODE_OUTPUT);
|
||||
}
|
||||
}
|
||||
|
||||
void stm32_dir_miso(void *data, rt_int32_t state)
|
||||
{
|
||||
struct stm32_soft_spi_config* cfg = (struct stm32_soft_spi_config*)data;
|
||||
if (state)
|
||||
{
|
||||
rt_pin_mode(cfg->miso, PIN_MODE_INPUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_pin_mode(cfg->miso, PIN_MODE_OUTPUT);
|
||||
}
|
||||
}
|
||||
|
||||
static void stm32_pin_init(void)
|
||||
{
|
||||
rt_size_t obj_num = sizeof(spi_obj) / sizeof(struct stm32_soft_spi);
|
||||
|
||||
for(rt_size_t i = 0; i < obj_num; i++)
|
||||
{
|
||||
stm32_spi_gpio_init(&spi_obj[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static struct rt_spi_bit_ops stm32_soft_spi_ops =
|
||||
{
|
||||
.data = RT_NULL,
|
||||
.pin_init = stm32_pin_init,
|
||||
.tog_sclk = stm32_tog_sclk,
|
||||
.set_sclk = stm32_set_sclk,
|
||||
.set_mosi = stm32_set_mosi,
|
||||
.set_miso = stm32_set_miso,
|
||||
.get_sclk = stm32_get_sclk,
|
||||
.get_mosi = stm32_get_mosi,
|
||||
.get_miso = stm32_get_miso,
|
||||
.dir_mosi = stm32_dir_mosi,
|
||||
.dir_miso = stm32_dir_miso,
|
||||
.udelay = rt_hw_us_delay,
|
||||
.delay_us = 1,
|
||||
};
|
||||
|
||||
/* Soft SPI initialization function */
|
||||
int rt_hw_softspi_init(void)
|
||||
{
|
||||
rt_size_t obj_num = sizeof(spi_obj) / sizeof(struct stm32_soft_spi);
|
||||
rt_err_t result;
|
||||
|
||||
for (rt_size_t i = 0; i < obj_num; i++)
|
||||
{
|
||||
memcpy(&spi_obj[i].ops, &stm32_soft_spi_ops, sizeof(struct rt_spi_bit_ops));
|
||||
spi_obj[i].ops.data = (void *)&soft_spi_config[i];
|
||||
spi_obj[i].spi.ops = &stm32_soft_spi_ops;
|
||||
spi_obj[i].cfg = (void *)&soft_spi_config[i];
|
||||
result = rt_spi_bit_add_bus(&spi_obj[i].spi, soft_spi_config[i].bus_name, &spi_obj[i].ops);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
INIT_BOARD_EXPORT(rt_hw_softspi_init);
|
||||
|
||||
#endif /* defined(RT_USING_SPI) && defined(RT_USING_SOFT_SPI) && defined(RT_USING_PIN) */
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-6-14 solar first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_SOFT_SPI__
|
||||
#define __DRV_SOFT_SPI__
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtdevice.h>
|
||||
#include <dev_spi_bit_ops.h>
|
||||
|
||||
/* stm32 soft spi config */
|
||||
struct stm32_soft_spi_config
|
||||
{
|
||||
rt_uint8_t sck;
|
||||
rt_uint8_t mosi;
|
||||
rt_uint8_t miso;
|
||||
const char *bus_name;
|
||||
};
|
||||
|
||||
/* stm32 soft spi dirver */
|
||||
struct stm32_soft_spi
|
||||
{
|
||||
struct rt_spi_bit_obj spi;
|
||||
struct rt_spi_bit_ops ops;
|
||||
struct stm32_soft_spi_config *cfg;
|
||||
};
|
||||
|
||||
#ifdef BSP_USING_SOFT_SPI1
|
||||
#define SOFT_SPI1_BUS_CONFIG \
|
||||
{ \
|
||||
.sck = BSP_S_SPI1_SCK_PIN, \
|
||||
.mosi = BSP_S_SPI1_MOSI_PIN, \
|
||||
.miso = BSP_S_SPI1_MISO_PIN, \
|
||||
.bus_name = "sspi1", \
|
||||
}
|
||||
#endif /* BSP_USING_SOFT_SPI1 */
|
||||
#ifdef BSP_USING_SOFT_SPI2
|
||||
#define SOFT_SPI2_BUS_CONFIG \
|
||||
{ \
|
||||
.sck = BSP_S_SPI2_SCK_PIN, \
|
||||
.mosi = BSP_S_SPI2_MOSI_PIN, \
|
||||
.miso = BSP_S_SPI2_MISO_PIN, \
|
||||
.bus_name = "sspi2", \
|
||||
}
|
||||
#endif /* BSP_USING_SOFT_SPI2 */
|
||||
|
||||
rt_err_t rt_hw_softspi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin);
|
||||
int rt_soft_spi_init(void);
|
||||
|
||||
#endif /* __DRV_SOFT_SPI__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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"
|
||||
#include <ipc/completion.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
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;
|
||||
|
||||
struct rt_completion cpt;
|
||||
};
|
||||
|
||||
#endif /*__DRV_SPI_H__ */
|
||||
@@ -0,0 +1,884 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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
|
||||
* 2020-11-18 leizhixiong add STM32H7 series support
|
||||
* 2023-08-21 Donocean fix the MCU crash when using timer6
|
||||
* 2023-12-24 Meco Man add TIMx existing check
|
||||
*/
|
||||
|
||||
#include <rtdevice.h>
|
||||
#include "drv_config.h"
|
||||
|
||||
//#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.tim"
|
||||
#include <drv_log.h>
|
||||
|
||||
#if defined(BSP_USING_TIM1) && !defined(TIM1)
|
||||
#error "timer1 doesn't exist in this STM32 series, but you enabled the BSP_USING_TIM1"
|
||||
#endif
|
||||
#if defined(BSP_USING_TIM2) && !defined(TIM2)
|
||||
#error "timer2 doesn't exist in this STM32 series, but you enabled the BSP_USING_TIM2"
|
||||
#endif
|
||||
#if defined(BSP_USING_TIM3) && !defined(TIM3)
|
||||
#error "timer3 doesn't exist in this STM32 series, but you enabled the BSP_USING_TIM3"
|
||||
#endif
|
||||
#if defined(BSP_USING_TIM4) && !defined(TIM4)
|
||||
#error "timer4 doesn't exist in this STM32 series, but you enabled the BSP_USING_TIM4"
|
||||
#endif
|
||||
#if defined(BSP_USING_TIM5) && !defined(TIM5)
|
||||
#error "timer5 doesn't exist in this STM32 series, but you enabled the BSP_USING_TIM5"
|
||||
#endif
|
||||
#if defined(BSP_USING_TIM6) && !defined(TIM6)
|
||||
#error "timer6 doesn't exist in this STM32 series, but you enabled the BSP_USING_TIM6"
|
||||
#endif
|
||||
#if defined(BSP_USING_TIM7) && !defined(TIM7)
|
||||
#error "timer7 doesn't exist in this STM32 series, but you enabled the BSP_USING_TIM7"
|
||||
#endif
|
||||
#if defined(BSP_USING_TIM8) && !defined(TIM8)
|
||||
#error "timer8 doesn't exist in this STM32 series, but you enabled the BSP_USING_TIM8"
|
||||
#endif
|
||||
#if defined(BSP_USING_TIM9) && !defined(TIM9)
|
||||
#error "timer9 doesn't exist in this STM32 series, but you enabled the BSP_USING_TIM9"
|
||||
#endif
|
||||
#if defined(BSP_USING_TIM10) && !defined(TIM10)
|
||||
#error "timer10 doesn't exist in this STM32 series, but you enabled the BSP_USING_TIM10"
|
||||
#endif
|
||||
#if defined(BSP_USING_TIM11) && !defined(TIM11)
|
||||
#error "timer11 doesn't exist in this STM32 series, but you enabled the BSP_USING_TIM11"
|
||||
#endif
|
||||
#if defined(BSP_USING_TIM12) && !defined(TIM12)
|
||||
#error "timer12 doesn't exist in this STM32 series, but you enabled the BSP_USING_TIM12"
|
||||
#endif
|
||||
#if defined(BSP_USING_TIM13) && !defined(TIM13)
|
||||
#error "timer13 doesn't exist in this STM32 series, but you enabled the BSP_USING_TIM13"
|
||||
#endif
|
||||
#if defined(BSP_USING_TIM14) && !defined(TIM14)
|
||||
#error "timer14 doesn't exist in this STM32 series, but you enabled the BSP_USING_TIM14"
|
||||
#endif
|
||||
#if defined(BSP_USING_TIM15) && !defined(TIM15)
|
||||
#error "timer15 doesn't exist in this STM32 series, but you enabled the BSP_USING_TIM15"
|
||||
#endif
|
||||
#if defined(BSP_USING_TIM16) && !defined(TIM16)
|
||||
#error "timer16 doesn't exist in this STM32 series, but you enabled the BSP_USING_TIM16"
|
||||
#endif
|
||||
#if defined(BSP_USING_TIM17) && !defined(TIM17)
|
||||
#error "timer17 doesn't exist in this STM32 series, but you enabled the BSP_USING_TIM17"
|
||||
#endif
|
||||
#if defined(BSP_USING_TIM18) && !defined(TIM18)
|
||||
#error "timer18 doesn't exist in this STM32 series, but you enabled the BSP_USING_TIM18"
|
||||
#endif
|
||||
#if defined(BSP_USING_TIM19) && !defined(TIM19)
|
||||
#error "timer19 doesn't exist in this STM32 series, but you enabled the BSP_USING_TIM19"
|
||||
#endif
|
||||
|
||||
/* APBx timer clocks frequency doubler state related to APB1CLKDivider value */
|
||||
void stm32_tim_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 /* !(defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)) */
|
||||
#endif /* defined(SOC_SERIES_STM32MP1) */
|
||||
}
|
||||
|
||||
void stm32_tim_enable_clock(TIM_HandleTypeDef* htim_base)
|
||||
{
|
||||
RT_ASSERT(htim_base != RT_NULL);
|
||||
|
||||
if(RT_FALSE);
|
||||
#ifdef TIM1
|
||||
else if(htim_base->Instance==TIM1)
|
||||
{
|
||||
__HAL_RCC_TIM1_CLK_ENABLE();
|
||||
}
|
||||
#endif /* TIM1 */
|
||||
#ifdef TIM2
|
||||
else if(htim_base->Instance==TIM2)
|
||||
{
|
||||
__HAL_RCC_TIM2_CLK_ENABLE();
|
||||
}
|
||||
#endif /* TIM2 */
|
||||
#ifdef TIM3
|
||||
else if(htim_base->Instance==TIM3)
|
||||
{
|
||||
__HAL_RCC_TIM3_CLK_ENABLE();
|
||||
}
|
||||
#endif /* TIM3 */
|
||||
#ifdef TIM4
|
||||
else if(htim_base->Instance==TIM4)
|
||||
{
|
||||
__HAL_RCC_TIM4_CLK_ENABLE();
|
||||
}
|
||||
#endif /* TIM4 */
|
||||
#ifdef TIM5
|
||||
else if(htim_base->Instance==TIM5)
|
||||
{
|
||||
__HAL_RCC_TIM5_CLK_ENABLE();
|
||||
}
|
||||
#endif /* TIM5 */
|
||||
#ifdef TIM6
|
||||
else if(htim_base->Instance==TIM6)
|
||||
{
|
||||
__HAL_RCC_TIM6_CLK_ENABLE();
|
||||
}
|
||||
#endif /* TIM6 */
|
||||
#ifdef TIM7
|
||||
else if(htim_base->Instance==TIM7)
|
||||
{
|
||||
__HAL_RCC_TIM7_CLK_ENABLE();
|
||||
}
|
||||
#endif /* TIM7 */
|
||||
#ifdef TIM8
|
||||
else if(htim_base->Instance==TIM8)
|
||||
{
|
||||
__HAL_RCC_TIM8_CLK_ENABLE();
|
||||
}
|
||||
#endif /* TIM8 */
|
||||
#ifdef TIM9
|
||||
else if(htim_base->Instance==TIM9)
|
||||
{
|
||||
__HAL_RCC_TIM9_CLK_ENABLE();
|
||||
}
|
||||
#endif /* TIM9 */
|
||||
#ifdef TIM10
|
||||
else if(htim_base->Instance==TIM10)
|
||||
{
|
||||
__HAL_RCC_TIM10_CLK_ENABLE();
|
||||
}
|
||||
#endif /* TIM10 */
|
||||
#ifdef TIM11
|
||||
else if(htim_base->Instance==TIM11)
|
||||
{
|
||||
__HAL_RCC_TIM11_CLK_ENABLE();
|
||||
}
|
||||
#endif /* TIM11 */
|
||||
#ifdef TIM12
|
||||
else if(htim_base->Instance==TIM12)
|
||||
{
|
||||
__HAL_RCC_TIM12_CLK_ENABLE();
|
||||
}
|
||||
#endif /* TIM12 */
|
||||
#ifdef TIM13
|
||||
else if(htim_base->Instance==TIM13)
|
||||
{
|
||||
__HAL_RCC_TIM13_CLK_ENABLE();
|
||||
}
|
||||
#endif /* TIM13 */
|
||||
#ifdef TIM14
|
||||
else if(htim_base->Instance==TIM14)
|
||||
{
|
||||
__HAL_RCC_TIM14_CLK_ENABLE();
|
||||
}
|
||||
#endif /* TIM14 */
|
||||
#ifdef TIM15
|
||||
else if(htim_base->Instance==TIM15)
|
||||
{
|
||||
__HAL_RCC_TIM15_CLK_ENABLE();
|
||||
}
|
||||
#endif /* TIM15 */
|
||||
#ifdef TIM16
|
||||
else if(htim_base->Instance==TIM16)
|
||||
{
|
||||
__HAL_RCC_TIM16_CLK_ENABLE();
|
||||
}
|
||||
#endif /* TIM16 */
|
||||
#ifdef TIM17
|
||||
else if(htim_base->Instance==TIM17)
|
||||
{
|
||||
__HAL_RCC_TIM17_CLK_ENABLE();
|
||||
}
|
||||
#endif /* TIM17 */
|
||||
#ifdef TIM18
|
||||
else if(htim_base->Instance==TIM18)
|
||||
{
|
||||
__HAL_RCC_TIM18_CLK_ENABLE();
|
||||
}
|
||||
#endif /* TIM18 */
|
||||
#ifdef TIM19
|
||||
else if(htim_base->Instance==TIM19)
|
||||
{
|
||||
__HAL_RCC_TIM19_CLK_ENABLE();
|
||||
}
|
||||
#endif /* TIM19 */
|
||||
else
|
||||
{
|
||||
RT_ASSERT(RT_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BSP_USING_TIM
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
stm32_tim_pclkx_doubler_get(&pclk1_doubler, &pclk2_doubler);
|
||||
|
||||
/* time init */
|
||||
/* Some series may only have APBPERIPH_BASE, don't have HAL_RCC_GetPCLK2Freq */
|
||||
#if defined(APBPERIPH_BASE)
|
||||
prescaler_value = (uint32_t)(HAL_RCC_GetPCLK1Freq() * pclk1_doubler / 10000) - 1;
|
||||
#elif defined(APB1PERIPH_BASE) || defined(APB2PERIPH_BASE)
|
||||
if ((rt_uint32_t)tim->Instance >= APB2PERIPH_BASE)
|
||||
{
|
||||
prescaler_value = (uint32_t)(HAL_RCC_GetPCLK2Freq() * pclk2_doubler / 10000) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
prescaler_value = (uint32_t)(HAL_RCC_GetPCLK1Freq() * pclk1_doubler / 10000) - 1;
|
||||
}
|
||||
#endif
|
||||
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_STM32G4) || 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;
|
||||
}
|
||||
|
||||
stm32_tim_enable_clock(tim);
|
||||
HAL_NVIC_SetPriority(tim_device->tim_irqn, 3, 0); /* set the TIMx priority */
|
||||
HAL_NVIC_EnableIRQ(tim_device->tim_irqn); /* enable the TIMx global Interrupt */
|
||||
__HAL_TIM_CLEAR_FLAG(tim, TIM_FLAG_UPDATE); /* clear update flag */
|
||||
__HAL_TIM_URS_ENABLE(tim); /* enable update request source */
|
||||
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_ERROR;
|
||||
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=0;
|
||||
|
||||
/* set timer frequence */
|
||||
freq = *((rt_uint32_t *)arg);
|
||||
|
||||
stm32_tim_pclkx_doubler_get(&pclk1_doubler, &pclk2_doubler);
|
||||
|
||||
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
|
||||
if (0
|
||||
#ifdef TIM1
|
||||
|| tim->Instance == TIM1
|
||||
#endif /* TIM1 */
|
||||
#ifdef TIM8
|
||||
|| tim->Instance == TIM8
|
||||
#endif /* TIM8 */
|
||||
#ifdef TIM9
|
||||
|| tim->Instance == TIM9
|
||||
#endif /* TIM9 */
|
||||
#ifdef TIM10
|
||||
|| tim->Instance == TIM10
|
||||
#endif /* TIM10 */
|
||||
#ifdef TIM11
|
||||
|| tim->Instance == TIM11
|
||||
#endif /* TIM11 */
|
||||
)
|
||||
#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G4)
|
||||
if (0
|
||||
#ifdef TIM15
|
||||
|| tim->Instance == TIM15
|
||||
#endif /* TIM15 */
|
||||
#ifdef TIM16
|
||||
|| tim->Instance == TIM16
|
||||
#endif /* TIM16 */
|
||||
#ifdef TIM17
|
||||
|| tim->Instance == TIM17
|
||||
#endif /* TIM17 */
|
||||
)
|
||||
#elif defined(SOC_SERIES_STM32WB)
|
||||
if (0
|
||||
#ifdef TIM16
|
||||
|| tim->Instance == TIM16
|
||||
#endif /* TIM16 */
|
||||
#ifdef TIM17
|
||||
|| tim->Instance == TIM17
|
||||
#endif /* TIM17 */
|
||||
)
|
||||
#elif defined(SOC_SERIES_STM32MP1)
|
||||
if(0
|
||||
#ifdef TIM14
|
||||
|| tim->Instance == TIM14
|
||||
#endif /* TIM14 */
|
||||
#ifdef TIM16
|
||||
|| tim->Instance == TIM16
|
||||
#endif /* TIM16 */
|
||||
#ifdef TIM17
|
||||
|| tim->Instance == TIM17
|
||||
#endif /* TIM17 */
|
||||
)
|
||||
#elif defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32H7)
|
||||
if (0)
|
||||
#else
|
||||
#error "This driver has not supported this series yet!"
|
||||
#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) */
|
||||
{
|
||||
#if !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32G0)
|
||||
val = HAL_RCC_GetPCLK2Freq() * pclk2_doubler / freq;
|
||||
#endif /* !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32G0) */
|
||||
}
|
||||
else
|
||||
{
|
||||
val = HAL_RCC_GetPCLK1Freq() * pclk1_doubler / freq;
|
||||
}
|
||||
__HAL_TIM_SET_PRESCALER(tim, val - 1);
|
||||
|
||||
/* Update frequency value */
|
||||
tim->Instance->EGR |= TIM_EVENTSOURCE_UPDATE;
|
||||
|
||||
result = RT_EOK;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
result = -RT_EINVAL;
|
||||
}
|
||||
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
|
||||
#if defined(STM32G0B0xx) || defined(STM32G0B1xx) || defined(STM32G0C1xx)
|
||||
#if defined(BSP_USING_TIM3) || defined(BSP_USING_TIM4)
|
||||
void TIM3_TIM4_IRQHandler(void)
|
||||
{
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
#ifdef BSP_USING_TIM3
|
||||
HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM3_INDEX].tim_handle);
|
||||
#endif
|
||||
#ifdef BSP_USING_TIM4
|
||||
HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM4_INDEX].tim_handle);
|
||||
#endif
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#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
|
||||
#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_TIM6
|
||||
void TIM6_DAC_IRQHandler(void)
|
||||
{
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM6_INDEX].tim_handle);
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif
|
||||
#ifdef BSP_USING_TIM7
|
||||
void TIM7_IRQHandler(void)
|
||||
{
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM7_INDEX].tim_handle);
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif
|
||||
#ifdef BSP_USING_TIM8
|
||||
void TIM8_UP_IRQHandler(void)
|
||||
{
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM8_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)|| defined(SOC_SERIES_STM32G4)
|
||||
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) || defined(SOC_SERIES_STM32G4)
|
||||
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_TIM6
|
||||
if (htim->Instance == TIM6)
|
||||
{
|
||||
rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM6_INDEX].time_device);
|
||||
}
|
||||
#endif
|
||||
#ifdef BSP_USING_TIM7
|
||||
if (htim->Instance == TIM7)
|
||||
{
|
||||
rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM7_INDEX].time_device);
|
||||
}
|
||||
#endif
|
||||
#ifdef BSP_USING_TIM8
|
||||
if (htim->Instance == TIM8)
|
||||
{
|
||||
rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM8_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)
|
||||
{
|
||||
rt_uint32_t 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 /* BSP_USING_TIM */
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-11-01 Meco Man First version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_TIM_H__
|
||||
#define __DRV_TIM_H__
|
||||
|
||||
#include <rtdef.h>
|
||||
#include <board.h>
|
||||
|
||||
void stm32_tim_pclkx_doubler_get(rt_uint32_t *pclk1_doubler, rt_uint32_t *pclk2_doubler);
|
||||
void stm32_tim_enable_clock(TIM_HandleTypeDef* htim_base);
|
||||
|
||||
#endif /* __DRV_TIM_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2024, 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) \
|
||||
|| defined(SOC_SERIES_STM32H5) || defined(SOC_SERIES_STM32H7RS)
|
||||
#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
|
||||
|
||||
#define UART_CTRL_SET_BLOCK_TIMEOUT 0x20
|
||||
|
||||
/* 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;
|
||||
};
|
||||
|
||||
/* stm32 uart dirver class */
|
||||
struct stm32_uart
|
||||
{
|
||||
UART_HandleTypeDef handle;
|
||||
struct stm32_uart_config *config;
|
||||
rt_uint32_t DR_mask;
|
||||
rt_uint32_t tx_block_timeout;
|
||||
|
||||
#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__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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_STM32WL) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32F0) \
|
||||
|| defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32L5) \
|
||||
|| defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32F3) \
|
||||
|| defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5) || defined(SOC_SERIES_STM32H7RS)
|
||||
#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_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) \
|
||||
|| defined(SOC_SERIES_STM32H5) || defined(SOC_SERIES_STM32H7RS)
|
||||
#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__ */
|
||||
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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 <rtthread.h>
|
||||
|
||||
#ifdef BSP_USING_USBD
|
||||
#include <rtdevice.h>
|
||||
#include "board.h"
|
||||
#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},
|
||||
{0x2, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
|
||||
{0x2, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
|
||||
{0x3, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
|
||||
{0x3, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
|
||||
#endif
|
||||
{0x4, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED},
|
||||
{0x4, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED},
|
||||
{0x5, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED},
|
||||
{0x5, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED},
|
||||
{0x6, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED},
|
||||
{0x6, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED},
|
||||
{0x7, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
|
||||
{0x8, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
|
||||
{0x9, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
|
||||
#if !defined(SOC_SERIES_STM32F1)
|
||||
{0x9, 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_ssize_t _ep_read(rt_uint8_t address, void *buffer)
|
||||
{
|
||||
rt_size_t size = 0;
|
||||
RT_ASSERT(buffer != RT_NULL);
|
||||
return size;
|
||||
}
|
||||
|
||||
static rt_ssize_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_ssize_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
|
||||
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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 "drv_usbh.h"
|
||||
#include "board.h"
|
||||
|
||||
#define LOG_TAG "drv.usb.host"
|
||||
#define DBG_LVL DBG_INFO
|
||||
#include <drv_log.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;
|
||||
LOG_D("usb connected");
|
||||
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;
|
||||
LOG_D("usb disconnnect");
|
||||
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)
|
||||
{
|
||||
LOG_D("reset port");
|
||||
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)
|
||||
{
|
||||
LOG_D("nak");
|
||||
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)
|
||||
{
|
||||
LOG_D("stall");
|
||||
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)
|
||||
{
|
||||
LOG_D("error");
|
||||
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))
|
||||
{
|
||||
LOG_D("ok");
|
||||
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);
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, 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 ************/
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-12-07 balanceTWK first version
|
||||
*/
|
||||
|
||||
#include <board.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef RT_USING_WDT
|
||||
#include "drv_config.h"
|
||||
|
||||
//#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_STM32G4)|| 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 */
|
||||
Reference in New Issue
Block a user