未验证 提交 286d4f65 编写于 作者: B Bernard Xiong 提交者: GitHub

Merge pull request #4116 from thread-liu/step4-ev1

[add] drivers for stm32mp157a-ev1
/*
* Copyright (c) 2006-2022, 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__ */
......@@ -23,7 +23,6 @@ extern "C" {
{ \
.Instance = SPI1, \
.bus_name = "spi1", \
.irq_type = SPI1_IRQn, \
}
#endif /* SPI1_BUS_CONFIG */
#endif /* BSP_USING_SPI1 */
......@@ -58,7 +57,6 @@ extern "C" {
{ \
.Instance = SPI2, \
.bus_name = "spi2", \
.irq_type = SPI2_IRQn, \
}
#endif /* SPI2_BUS_CONFIG */
#endif /* BSP_USING_SPI2 */
......@@ -93,7 +91,6 @@ extern "C" {
{ \
.Instance = SPI3, \
.bus_name = "spi3", \
.irq_type = SPI3_IRQn, \
}
#endif /* SPI3_BUS_CONFIG */
#endif /* BSP_USING_SPI3 */
......@@ -128,7 +125,6 @@ extern "C" {
{ \
.Instance = SPI4, \
.bus_name = "spi4", \
.irq_type = SPI4_IRQn, \
}
#endif /* SPI4_BUS_CONFIG */
#endif /* BSP_USING_SPI4 */
......
......@@ -110,6 +110,7 @@ extern "C" {
#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"
......
......@@ -147,7 +147,7 @@ static rt_uint32_t _rng_rand(struct hwcrypto_rng *ctx)
{
return gen_random ;
}
return 0;
}
......
......@@ -52,8 +52,12 @@ static int stm32_qspi_init(struct rt_qspi_device *device, struct rt_qspi_configu
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)
{
......
......@@ -66,7 +66,9 @@ if GetDepend(['RT_USING_SDIO']):
if GetDepend(['RT_USING_AUDIO']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sai.c']
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sai_ex.c']
if GetDepend(['BSP_USING_DCMI']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_dcmi.c']
if GetDepend(['BSP_USING_FMC']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_ll_fmc.c']
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_ll_fsmc.c']
......@@ -89,6 +91,19 @@ if GetDepend(['BSP_USING_LTDC']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_ll_dma2d.c']
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_dsi.c']
if GetDepend(['BSP_USING_FDCAN']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_fdcan.c']
if GetDepend(['BSP_USING_QSPI']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_qspi.c']
if GetDepend(['BSP_USING_SPDIFRX']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_spdifrx.c']
if GetDepend(['BSP_USING_DFSDM']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_dfsdm.c']
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_dfsdm_ex.c']
if GetDepend(['BSP_USING_SDMMC']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_ll_sdmmc.c']
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sd.c']
......
......@@ -34,16 +34,16 @@
#define HAL_MODULE_ENABLED
#define HAL_ADC_MODULE_ENABLED
/*#define HAL_CEC_MODULE_ENABLED */
/*#define HAL_CRC_MODULE_ENABLED */
/*#define HAL_CRYP_MODULE_ENABLED */
#define HAL_CRC_MODULE_ENABLED
#define HAL_CRYP_MODULE_ENABLED
#define HAL_DAC_MODULE_ENABLED
/*#define HAL_DCMI_MODULE_ENABLED */
#define HAL_DCMI_MODULE_ENABLED
/*#define HAL_DSI_MODULE_ENABLED */
/*#define HAL_DFSDM_MODULE_ENABLED */
#define HAL_DFSDM_MODULE_ENABLED
/*#define HAL_DTS_MODULE_ENABLED */
/*#define HAL_ETH_MODULE_ENABLED */
/*#define HAL_FDCAN_MODULE_ENABLED */
/*#define HAL_HASH_MODULE_ENABLED */
#define HAL_FDCAN_MODULE_ENABLED
#define HAL_HASH_MODULE_ENABLED
/*#define HAL_HCD_MODULE_ENABLED */
#define HAL_HSEM_MODULE_ENABLED
#define HAL_I2C_MODULE_ENABLED
......@@ -55,14 +55,14 @@
/*#define HAL_NAND_MODULE_ENABLED */
/*#define HAL_NOR_MODULE_ENABLED */
/*#define HAL_PCD_MODULE_ENABLED */
/*#define HAL_QSPI_MODULE_ENABLED */
/*#define HAL_RNG_MODULE_ENABLED */
#define HAL_QSPI_MODULE_ENABLED
#define HAL_RNG_MODULE_ENABLED
#define HAL_SAI_MODULE_ENABLED
#define HAL_SD_MODULE_ENABLED
/*#define HAL_MMC_MODULE_ENABLED */
/*#define HAL_RTC_MODULE_ENABLED */
/*#define HAL_SMBUS_MODULE_ENABLED */
/*#define HAL_SPDIFRX_MODULE_ENABLED */
#define HAL_SPDIFRX_MODULE_ENABLED
#define HAL_SPI_MODULE_ENABLED
/*#define HAL_SRAM_MODULE_ENABLED */
/*#define HAL_TAMP_MODULE_ENABLED */
......
......@@ -14,6 +14,10 @@ menu "Onboard Peripheral Drivers"
select BSP_USING_UART
select BSP_USING_UART4
default y
config BSP_USING_EXTI
bool "Enable exti sample"
default n
config BSP_USING_PMIC
bool "Enable PMIC"
......@@ -21,6 +25,12 @@ menu "Onboard Peripheral Drivers"
select BSP_USING_I2C3
default y
config BSP_USING_PWR
bool "Enable PM (power control)"
select BSP_USING_LPTIM
select BSP_USING_LPTIM1
default n
config BSP_USING_NAND
bool "Enable FMC (MT29F8G08ABACAH4)"
select RT_USING_FMC
......@@ -28,6 +38,13 @@ menu "Onboard Peripheral Drivers"
select RT_MTD_NAND_DEBUG
default n
config BSP_USING_QSPI_FLASH
bool "Enable QSPI FLASH (MX25L51245G)"
select BSP_USING_QSPI
select RT_USING_SFUD
select RT_SFUD_USING_QSPI
default n
config BSP_USING_OPENAMP
bool "Enable OpenAMP"
select RT_USING_OPENAMP
......@@ -51,7 +68,7 @@ menu "Onboard Peripheral Drivers"
if BSP_USING_SD_CARD
config SD_USING_DFS
bool "sd card fatfs"
default n
default y
endif
menuconfig BSP_USING_EMMC
......@@ -65,12 +82,43 @@ menu "Onboard Peripheral Drivers"
endif
config BSP_USING_AUDIO
bool "Enable Audio Device (WM8994)"
select RT_USING_AUDIO
select BSP_USING_PMIC
select BSP_USING_I2C
select BSP_USING_I2C2
default n
bool "Enable Audio Device (WM8994)"
select RT_USING_AUDIO
select BSP_USING_PMIC
select BSP_USING_SDMMC
select BSP_USING_SD_CARD
select SD_USING_DFS
select BSP_USING_I2C
select BSP_USING_I2C2
default n
config BSP_USING_DCMI
bool "Enable CAMERA (ov5640)"
select BSP_USING_MFX
select BSP_USING_PMIC
select BSP_USING_I2C
select BSP_USING_I2C2
default n
config BSP_USING_MFX
bool "Enable Multi Function eXpander"
default n
menuconfig BSP_USING_RS485
bool "Enable RS485 "
default n
if BSP_USING_RS485
comment "set rts pin number "
config BSP_RS485_RTS_PIN
int "RS485 rts pin number"
range 1 176
default 5
config RS485_UART_DEVICE_NAME
string "the uart name for rs485"
default "uart3"
endif
endmenu
......@@ -80,6 +128,28 @@ menu "On-chip Peripheral Drivers"
select RT_USING_PIN
default y
config BSP_USING_WWDG
bool "Enable WWDG"
select RT_USING_WWDG
select RT_USING_WDT
default n
config BSP_USING_QSPI
bool "Enable QSPI BUS"
select RT_USING_QSPI
select RT_USING_SPI
default n
config BSP_USING_SPDIFRX
bool "Enable spdifrx"
select BSP_USING_AUDIO
default n
config BSP_USING_DFSDM
bool "Enable dfsdm"
select BSP_USING_AUDIO
default n
menuconfig BSP_USING_UART
bool "Enable UART"
select RT_USING_SERIAL
......@@ -133,6 +203,16 @@ menu "On-chip Peripheral Drivers"
default n
endif
menuconfig BSP_USING_LPTIM
bool "Enable lptimer"
default n
select RT_USING_LPTIMER
if BSP_USING_LPTIM
config BSP_USING_LPTIM1
bool "Enable LPTIM1"
default n
endif
menuconfig BSP_USING_PWM
bool "Enable pwm"
default n
......@@ -224,22 +304,21 @@ menu "On-chip Peripheral Drivers"
select RT_USING_SPI
default n
if BSP_USING_SPI
config BSP_USING_SPI5
bool "Enable SPI5 BUS"
default n
config BSP_SPI5_TX_USING_DMA
bool "Enable SPI5 TX DMA"
depends on BSP_USING_SPI5
config BSP_USING_SPI1
bool "Enable SPI1 BUS"
default n
config BSP_SPI5_RX_USING_DMA
bool "Enable SPI5 RX DMA"
depends on BSP_USING_SPI5
select BSP_SPI5_TX_USING_DMA
default n
endif
menuconfig BSP_USING_FDCAN
bool "Enable FDCAN"
default n
if BSP_USING_FDCAN
config BSP_USING_FDCAN1
bool "Enable FDCAN1"
default n
endif
source "../libraries/HAL_Drivers/Kconfig"
endmenu
......
......@@ -13,6 +13,9 @@ CubeMX_Config/Common/System/system_stm32mp1xx.c
CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
''')
if GetDepend(['BSP_USING_SPI1']):
src += Glob('ports/spi_sample.c')
if GetDepend(['BSP_USING_PMIC']):
src += Glob('ports/drv_pmic.c')
......@@ -32,6 +35,47 @@ if GetDepend(['BSP_USING_AUDIO']):
src += Glob('ports/drv_wm8994.c')
src += Glob('ports/drv_sound.c')
if GetDepend(['BSP_USING_DCMI']):
src += Glob('ports/drv_dcmi.c')
src += Glob('ports/drv_ov5640.c')
if GetDepend(['BSP_USING_MFX']):
src += Glob('ports/drv_mfx.c')
src += Glob('ports/mfxstm32l152.c')
if GetDepend(['BSP_USING_FDCAN']):
src += Glob('ports/drv_fdcan.c')
if GetDepend(['BSP_USING_QSPI']):
src += Glob('ports/drv_qspi_flash.c')
if GetDepend(['BSP_USING_SPDIFRX']):
src += Glob('ports/drv_spdifrx.c')
if GetDepend(['BSP_USING_DFSDM']):
src += Glob('ports/drv_dfsdm.c')
if GetDepend(['BSP_USING_WWDG']):
src += Glob('ports/drv_wwdg.c')
if GetDepend(['BSP_USING_EXTI']):
src += Glob('ports/drv_exti.c')
if GetDepend(['BSP_USING_RNG']) or GetDepend(['BSP_USING_HASH']) or GetDepend(['BSP_USING_CRC']) or GetDepend(['BSP_USING_CRYP']):
src += Glob('ports/crypto_sample.c')
if GetDepend(['BSP_USING_PWR']):
src += Glob('ports/drv_pwr.c')
if GetDepend(['BSP_USING_LPTIM1']):
src += Glob('ports/drv_lptim.c')
if GetDepend(['BSP_USING_RS485']):
src += Glob('ports/drv_rs485.c')
if GetDepend(['BSP_USING_TIM14']):
src += Glob('ports/timer_sample.c')
if GetDepend(['BSP_USING_OPENAMP']):
src += Glob('CubeMX_Config/CM4/Src/ipcc.c')
src += Glob('CubeMX_Config/CM4/Src/openamp.c')
......
......@@ -23,14 +23,9 @@ extern "C" {
#endif
#define STM32_FLASH_START_ADRESS ((uint32_t)0x10000000)
#if defined(BSP_USING_OPENAMP)
#define STM32_FLASH_SIZE (64 * 1024)
#else
#define STM32_FLASH_SIZE (256 * 1024)
#endif
#define STM32_FLASH_SIZE (191 * 1024)
#define STM32_FLASH_END_ADDRESS ((uint32_t)(STM32_FLASH_START_ADRESS + STM32_FLASH_SIZE))
#if defined(BSP_USING_OPENAMP)
#define STM32_SRAM_BEGIN (uint32_t)0x10030000
#else
......
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-06-27 thread-liu first version
*/
#include <board.h>
#include "drv_crypto.h"
#include <hwcrypto.h>
#include <string.h>
#include <stdlib.h>
#if defined(BSP_USING_RNG)
static rt_err_t hw_rng_sample(int random_num)
{
rt_err_t result = RT_EOK;
int i = 0, num0 = 0, num1 = 0;
if (random_num == 0)
{
return RT_ERROR;
}
for (i = 0; i< random_num; i++)
{
result = rt_hwcrypto_rng_update();
rt_kprintf("%d ", result);
result%2 ? num1++ : num0++;
}
rt_kprintf("\neven numbers : %d, odd numbers: %d\n",num1, num0);
return RT_EOK;
}
#endif
#if defined(BSP_USING_CRC)
static void hw_crc_sample(uint8_t *temp, int size)
{
struct rt_hwcrypto_ctx *ctx;
rt_uint32_t result = 0;
struct hwcrypto_crc_cfg cfg =
{
.last_val = 0xFFFFFFFF,
.poly = 0x04C11DB7,
.width = 32,
.xorout = 0x00000000,
.flags = 0,
};
ctx = rt_hwcrypto_crc_create(rt_hwcrypto_dev_default(), HWCRYPTO_CRC_CRC32);
rt_hwcrypto_crc_cfg(ctx, &cfg);
result = rt_hwcrypto_crc_update(ctx, temp, size);
rt_kprintf("crc result: %x \n", result);
rt_hwcrypto_crc_destroy(ctx);
}
#endif
#if defined(BSP_USING_HASH)
static void hw_hash_sample()
{
int i = 0;
struct rt_hwcrypto_ctx *ctx = RT_NULL;
const uint8_t hash_input[] = "RT-Thread was born in 2006, it is an open source, neutral, and community-based real-time operating system (RTOS).";
static uint8_t sha1_output[20];
static uint8_t sha1_except[20] = {0xff, 0x3c, 0x95, 0x54, 0x95, 0xf0, 0xad,
0x02, 0x1b, 0xa8, 0xbc, 0xa2, 0x2e, 0xa5,
0xb0, 0x62, 0x1b, 0xdf, 0x7f, 0xec};
static uint8_t md5_output[16];
static uint8_t md5_except[16] = {0x40, 0x86, 0x03, 0x80, 0x0d, 0x8c, 0xb9,
0x4c, 0xd6, 0x7d, 0x28, 0xfc, 0xf6, 0xc3,
0xac, 0x8b};
static uint8_t sha224_output[28];
static uint8_t sha224_except[28] = {0x6f, 0x62, 0x52, 0x7d, 0x80, 0xe6,
0x9f, 0x82, 0x78, 0x7a, 0x46, 0x91,
0xb0, 0xe9, 0x64, 0x89, 0xe6, 0xc3,
0x6b, 0x7e, 0xcf, 0xca, 0x11, 0x42,
0xc8, 0x77, 0x13, 0x79};
static uint8_t sha256_output[32];
static uint8_t sha256_except[32] = {0x74, 0x19, 0xb9, 0x0e, 0xd1, 0x46,
0x37, 0x0a, 0x55, 0x18, 0x26, 0x6c,
0x50, 0xd8, 0x71, 0x34, 0xfa, 0x1f,
0x5f, 0x5f, 0xe4, 0x9a, 0xe9, 0x40,
0x0a, 0x7d, 0xa0, 0x26, 0x1b, 0x86,
0x67, 0x45};
rt_kprintf("Hash Test start: \n");
rt_kprintf("Hash Test string: \n");
for (i = 0; i < sizeof(hash_input); i++)
{
rt_kprintf("%c", hash_input[i]);
}
rt_kprintf("\n");
/* sh1 test*/
ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_SHA1);
if (ctx == RT_NULL)
{
rt_kprintf("create hash[%08x] context err!\n", HWCRYPTO_TYPE_SHA1);
return ;
}
rt_kprintf("Create sha1 type success!\n");
rt_kprintf("Except sha1 result: \n");
for (i = 0; i < sizeof(sha1_except); i++)
{
rt_kprintf("%x ", sha1_except[i]);
}
rt_kprintf("\n");
/* start sha1 */
rt_hwcrypto_hash_update(ctx, hash_input, rt_strlen((char const *)hash_input));
/* get sha1 result */
rt_hwcrypto_hash_finish(ctx, sha1_output, rt_strlen((char const *)sha1_output));
rt_kprintf("Actual sha1 result: \n");
for (i = 0; i < sizeof(sha1_output); i++)
{
rt_kprintf("%x ", sha1_output[i]);
}
rt_kprintf("\n");
if(rt_memcmp(sha1_output, sha1_except, sizeof(sha1_except)/sizeof(sha1_except[0])) != 0)
{
rt_kprintf("Hash type sha1 Test error, The actual result is not equal to the except result\n");
}
else
{
rt_kprintf("Hash type sha1 Test success, The actual result is equal to the except result\n");
}
/* deinit hash*/
rt_hwcrypto_hash_destroy(ctx);
/* md5 test*/
ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_MD5);
if (ctx == RT_NULL)
{
rt_kprintf("create hash[%08x] context err!\n", HWCRYPTO_TYPE_MD5);
return ;
}
rt_kprintf("Create md5 type success!\n");
rt_kprintf("Except md5 result: \n");
for (i = 0; i < sizeof(md5_except); i++)
{
rt_kprintf("%x ", md5_except[i]);
}
rt_kprintf("\n");
/* start md5 */
rt_hwcrypto_hash_update(ctx, hash_input, rt_strlen((char const *)hash_input));
/* get md5 result */
rt_hwcrypto_hash_finish(ctx, md5_output, rt_strlen((char const *)md5_output));
rt_kprintf("Actual md5 result: \n");
for (i = 0; i < sizeof(md5_output); i++)
{
rt_kprintf("%x ", md5_output[i]);
}
rt_kprintf("\n");
if(rt_memcmp(md5_output, md5_except, sizeof(md5_except)/sizeof(md5_except[0])) != 0)
{
rt_kprintf("Hash type md5 Test error, The actual result is not equal to the except result\n");
}
else
{
rt_kprintf("Hash type md5 Test success, The actual result is equal to the except result\n");
}
/* deinit hash*/
rt_hwcrypto_hash_destroy(ctx);
/* sha224 test */
ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_SHA224);
if (ctx == RT_NULL)
{
rt_kprintf("create hash[%08x] context err!\n", HWCRYPTO_TYPE_SHA224);
return ;
}
rt_kprintf("Create sha224 type success!\n");
rt_kprintf("Except sha224 result: \n");
for (i = 0; i < sizeof(sha224_except); i++)
{
rt_kprintf("%x ", sha224_except[i]);
}
rt_kprintf("\n");
/* start sha224 */
rt_hwcrypto_hash_update(ctx, hash_input, rt_strlen((char const *)hash_input));
/* get sha224 result */
rt_hwcrypto_hash_finish(ctx, sha224_output, rt_strlen((char const *)sha224_output));
rt_kprintf("Actual sha224 result: \n");
for (i = 0; i < sizeof(sha224_output); i++)
{
rt_kprintf("%x ", sha224_output[i]);
}
rt_kprintf("\n");
if(rt_memcmp(sha224_output, sha224_except, sizeof(sha224_except)/sizeof(sha224_except[0])) != 0)
{
rt_kprintf("Hash type sha224 Test error, The actual result is not equal to the except result\n");
}
else
{
rt_kprintf("Hash type sha224 Test success, The actual result is equal to the except result\n");
}
rt_hwcrypto_hash_destroy(ctx);
/* sha256 test*/
ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_SHA256);
if (ctx == RT_NULL)
{
rt_kprintf("create hash[%08x] context err!\n", HWCRYPTO_TYPE_SHA256);
return ;
}
rt_kprintf("Create sha256 type success!\n");
rt_kprintf("Except sha256 result: \n");
for (i = 0; i < sizeof(sha256_except); i++)
{
rt_kprintf("%x ", sha256_except[i]);
}
rt_kprintf("\n");
/* start sha256 */
rt_hwcrypto_hash_update(ctx, hash_input, rt_strlen((char const *)hash_input));
/* get sha256 result */
rt_hwcrypto_hash_finish(ctx, sha256_output, rt_strlen((char const *)sha256_output));
rt_kprintf("Actual sha256 result: \n");
for (i = 0; i < sizeof(sha256_output); i++)
{
rt_kprintf("%x ", sha256_output[i]);
}
rt_kprintf("\n");
if(rt_memcmp(sha256_output, sha256_except, sizeof(sha256_except)/sizeof(sha256_except[0])) != 0)
{
rt_kprintf("Hash type sha256 Test error, The actual result is not equal to the except result\n");
}
else
{
rt_kprintf("Hash type sha256 Test success, The actual result is equal to the except result\n");
}
rt_hwcrypto_hash_destroy(ctx);
rt_kprintf("Hash Test over!\n");
}
#endif
static int crypto(int argc, char **argv)
{
int result = RT_EOK;
static rt_device_t device = RT_NULL;
char *result_str;
if (argc > 1)
{
if (!strcmp(argv[1], "probe"))
{
if (argc == 3)
{
char *dev_name = argv[2];
device = rt_device_find(dev_name);
result_str = (device == RT_NULL) ? "failure" : "success";
rt_kprintf("probe %s %s \n", argv[2], result_str);
}
else
{
rt_kprintf("crypto probe <crypto_name> - probe crypto by name\n");
}
}
else
{
if (device == RT_NULL)
{
rt_kprintf("Please using 'crypto probe <crypto_name>' first\n");
return -RT_ERROR;
}
if (!strcmp(argv[1], "rng"))
{
#if defined (BSP_USING_RNG)
if (argc == 3)
{
result = hw_rng_sample(atoi(argv[2]));
if(result != RT_EOK)
{
rt_kprintf("please input a legal number, not <%d>\n", atoi(argv[2]));
}
}
else
{
rt_kprintf("rng <number> - generate <number> digital\n");
}
#else
rt_kprintf("please enable RNG first!\n");
#endif
}
else if (!strcmp(argv[1], "crc"))
{
#if defined (BSP_USING_CRC)
int size = 0, i = 0;
if (argc > 3)
{
size = argc - 2;
uint8_t *data = rt_malloc(size);
if (data)
{
for (i = 0; i < size; i++)
{
data[i] = strtol(argv[2 + i], NULL, 0);
}
hw_crc_sample(data, size);
rt_free(data);
}
else
{
rt_kprintf("Low memory!\n");
}
}
else
{
rt_kprintf("crypto crc data1 ... dataN - calculate data1 ... dataN crc\n");
}
#else
rt_kprintf("please enable CRC first!\n");
#endif
}
else if (!strcmp(argv[1], "hash"))
{
#if defined (BSP_USING_HASH)
if (argc == 3)
{
hw_hash_sample();
}
else
{
rt_kprintf("crypto hash sample - hash use sample\n");
}
#else
rt_kprintf("please enable CRC first!\n");
#endif
}
else
{
rt_kprintf("Unknown command. Please enter 'crypto' for help\n");
}
}
}
else
{
rt_kprintf("Usage: \n");
rt_kprintf("crypto probe <crypto_name> - probe crypto by name\n");
rt_kprintf("crypto rng number - generate numbers digital\n");
rt_kprintf("crypto crc data1 ... dataN - calculate data1 ... dataN crc\n");
rt_kprintf("crypto hash sample - hash use sample\n");
result = -RT_ERROR;
}
return result;
}
MSH_CMD_EXPORT(crypto, crypto function);
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-07-27 thread-liu the first version
*/
#include "board.h"
#if defined(BSP_USING_DCMI)
#include "drv_dcmi.h"
#define DRV_DEBUG
#define LOG_TAG "drv.dcmi"
#include <drv_log.h>
struct stm32_dcmi
{
struct rt_device dev;
};
static struct stm32_dcmi rt_dcmi = {0};
DCMI_HandleTypeDef dcmi = {0};
DMA_HandleTypeDef hdma_dcmi = {0};
extern void jpeg_data_process(void);
static void rt_hw_dmci_dma_init(void)
{
__HAL_RCC_DMAMUX_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
hdma_dcmi.Instance = DMA1_Stream3;
hdma_dcmi.Init.Request = DMA_REQUEST_DCMI;
hdma_dcmi.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_dcmi.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_dcmi.Init.MemInc = DMA_MINC_ENABLE;
hdma_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_dcmi.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_dcmi.Init.Mode = DMA_CIRCULAR;
hdma_dcmi.Init.Priority = DMA_PRIORITY_HIGH;
hdma_dcmi.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_dcmi.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_dcmi.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_dcmi.Init.PeriphBurst = DMA_PBURST_SINGLE;
HAL_DMA_Init(&hdma_dcmi);
__HAL_LINKDMA(&dcmi, DMA_Handle, hdma_dcmi);
HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 0x02, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);
}
void rt_hw_dcmi_dma_config(rt_uint32_t dst_addr1, rt_uint32_t dst_addr2, rt_uint16_t len)
{
HAL_DMAEx_MultiBufferStart(&hdma_dcmi, (rt_uint32_t)&DCMI->DR, dst_addr1, dst_addr2, len);
__HAL_DMA_ENABLE_IT(&hdma_dcmi, DMA_IT_TC);
}
static rt_err_t rt_hw_dcmi_init(DCMI_HandleTypeDef *device)
{
RT_ASSERT(device != RT_NULL);
device->Instance = DCMI;
device->Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
device->Init.PCKPolarity = DCMI_PCKPOLARITY_RISING;
device->Init.VSPolarity = DCMI_VSPOLARITY_LOW;
device->Init.HSPolarity = DCMI_HSPOLARITY_LOW;
device->Init.CaptureRate = DCMI_CR_ALL_FRAME;
device->Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;
device->Init.JPEGMode = DCMI_JPEG_DISABLE;
device->Init.ByteSelectMode = DCMI_BSM_ALL;
device->Init.ByteSelectStart = DCMI_OEBS_ODD;
device->Init.LineSelectMode = DCMI_LSM_ALL;
device->Init.LineSelectStart = DCMI_OELS_ODD;
if (HAL_DCMI_Init(device) != HAL_OK)
{
LOG_E("dcmi init error!");
return RT_ERROR;
}
DCMI->IER = 0x0;
__HAL_DCMI_ENABLE_IT(device, DCMI_IT_FRAME);
__HAL_DCMI_ENABLE(device);
rt_hw_dmci_dma_init();
return RT_EOK;
}
void DCMI_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_DCMI_IRQHandler(&dcmi);
/* leave interrupt */
rt_interrupt_leave();
}
/* Capture a frame of the image */
void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
{
/* enter interrupt */
rt_interrupt_enter();
jpeg_data_process();
__HAL_DCMI_ENABLE_IT(&dcmi,DCMI_IT_FRAME);
/* leave interrupt */
rt_interrupt_leave();
}
void DMA1_Stream3_IRQHandler(void)
{
extern void rt_hw_camera_rx_callback(void);
/* enter interrupt */
rt_interrupt_enter();
if(__HAL_DMA_GET_FLAG(&hdma_dcmi, DMA_FLAG_TCIF3_7)!=RESET)
{
__HAL_DMA_CLEAR_FLAG(&hdma_dcmi, DMA_FLAG_TCIF3_7);
rt_hw_camera_rx_callback();
}
/* leave interrupt */
rt_interrupt_leave();
}
static rt_err_t rt_dcmi_init(rt_device_t dev)
{
RT_ASSERT(dev != RT_NULL);
rt_err_t result = RT_EOK;
result = rt_hw_dcmi_init(&dcmi);
if (result != RT_EOK)
{
return result;
}
return result;
}
static rt_err_t rt_dcmi_open(rt_device_t dev, rt_uint16_t oflag)
{
RT_ASSERT(dev != RT_NULL);
return RT_EOK;
}
static rt_err_t rt_dcmi_close(rt_device_t dev)
{
RT_ASSERT(dev != RT_NULL);
return RT_EOK;
}
static rt_err_t rt_dcmi_control(rt_device_t dev, int cmd, void *args)
{
RT_ASSERT(dev != RT_NULL);
return RT_EOK;
}
static rt_size_t rt_dcmi_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
RT_ASSERT(dev != RT_NULL);
return RT_EOK;
}
static rt_size_t rt_dcmi_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
RT_ASSERT(dev != RT_NULL);
return RT_EOK;
}
int dcmi_init(void)
{
rt_dcmi.dev.type = RT_Device_Class_Miscellaneous;
rt_dcmi.dev.init = rt_dcmi_init;
rt_dcmi.dev.open = rt_dcmi_open;
rt_dcmi.dev.close = rt_dcmi_close;
rt_dcmi.dev.read = rt_dcmi_read;
rt_dcmi.dev.write = rt_dcmi_write;
rt_dcmi.dev.control = rt_dcmi_control;
rt_dcmi.dev.user_data = RT_NULL;
rt_device_register(&rt_dcmi.dev, "dcmi", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
LOG_I("dcmi init success!");
return RT_EOK;
}
INIT_BOARD_EXPORT(dcmi_init);
#endif
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-07-27 thread-liu first version
*/
#ifndef __DRV_DCMI_H__
#define __DRV_DCMI_H__
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-07-07 thread-liu first version
*/
#include "board.h"
#if defined(BSP_USING_DFSDM)
#include "drv_wm8994.h"
#include "drv_dfsdm.h"
#define DRV_DEBUG
#define LOG_TAG "drv.dfsdm"
#include <drv_log.h>
#define FILTER_FIFO_SIZE (1024)
#if defined(__CC_ARM) || defined(__CLANG_ARM)
__attribute__((at(0x2FFC8000)))
#elif defined ( __GNUC__ )
__attribute__((at(0x2FFC8000)))
#elif defined(__ICCARM__)
#pragma location = 0x2FFC8000
#endif
rt_int32_t FILTER0_FIFO[FILTER_FIFO_SIZE];
#define PALY_SIZE 2048
#if defined(__CC_ARM) || defined(__CLANG_ARM)
__attribute__((at(0x2FFCA000)))
#elif defined ( __GNUC__ )
__attribute__((at(0x2FFCA000)))
#elif defined(__ICCARM__)
#pragma location = 0x2FFCA000
#endif
static rt_int16_t PLAY_BUF[PALY_SIZE];
#if defined(__CC_ARM) || defined(__CLANG_ARM)
__attribute__((at(0x2FFC9000)))
#elif defined ( __GNUC__ )
__attribute__((at(0x2FFC9000)))
#elif defined(__ICCARM__)
#pragma location = 0x2FFC9000
#endif
rt_int32_t FILTER1_FIFO[FILTER_FIFO_SIZE];
static volatile rt_uint8_t DmaLeftRecBuffCplt = 0;
static volatile rt_uint8_t DmaRightRecBuffCplt = 0;
static volatile rt_uint8_t DmaLeftRecHalfBuffCplt = 0;
static volatile rt_uint8_t DmaRightRecHalfBuffCplt = 0;
static DFSDM_Channel_HandleTypeDef hdfsdm1_channel0 = {0}; /* data_in1_right */
static DFSDM_Channel_HandleTypeDef hdfsdm1_channel1 = {0}; /* data_in1_left */
static DFSDM_Filter_HandleTypeDef hdfsdm1_filter0 = {0}; /* data_in1_right */
static DFSDM_Filter_HandleTypeDef hdfsdm1_filter1 = {0}; /* data_in1_left */
extern DMA_HandleTypeDef hdma_dfsdm1_flt0;
extern DMA_HandleTypeDef hdma_dfsdm1_flt1;
static struct rt_device dfsdm_dev = {0};
void DMA2_Stream2_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_DMA_IRQHandler(&hdma_dfsdm1_flt1);
/* leave interrupt */
rt_interrupt_leave();
}
void DMA2_Stream1_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_DMA_IRQHandler(&hdma_dfsdm1_flt0);
/* leave interrupt */
rt_interrupt_leave();
}
void HAL_DFSDM_FilterRegConvHalfCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
{
if(hdfsdm_filter == &hdfsdm1_filter1)
{
DmaLeftRecHalfBuffCplt = 1;
}
else
{
DmaRightRecHalfBuffCplt = 1;
}
}
void HAL_DFSDM_FilterRegConvCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
{
if (hdfsdm_filter == &hdfsdm1_filter1)
{
DmaLeftRecBuffCplt = 1;
}
else
{
DmaRightRecBuffCplt = 1;
}
}
static int rt_hw_dfsdm_init(void)
{
/* DATAIN1_LEFT */
__HAL_DFSDM_CHANNEL_RESET_HANDLE_STATE(&hdfsdm1_channel1);
hdfsdm1_channel1.Instance = DFSDM1_Channel1;
hdfsdm1_channel1.Init.OutputClock.Activation = ENABLE;
hdfsdm1_channel1.Init.OutputClock.Selection = DFSDM_CHANNEL_OUTPUT_CLOCK_SYSTEM; /* 209MHZ */
hdfsdm1_channel1.Init.OutputClock.Divider = 74; /* 209/74 = 2.82MHZ*/
hdfsdm1_channel1.Init.Input.Multiplexer = DFSDM_CHANNEL_EXTERNAL_INPUTS;
hdfsdm1_channel1.Init.Input.DataPacking = DFSDM_CHANNEL_STANDARD_MODE;
hdfsdm1_channel1.Init.Input.Pins = DFSDM_CHANNEL_SAME_CHANNEL_PINS;
hdfsdm1_channel1.Init.SerialInterface.Type = DFSDM_CHANNEL_SPI_RISING ; /* left */
hdfsdm1_channel1.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
hdfsdm1_channel1.Init.Awd.FilterOrder = DFSDM_CHANNEL_FASTSINC_ORDER;
hdfsdm1_channel1.Init.Awd.Oversampling = 10;
hdfsdm1_channel1.Init.Offset = 0;
hdfsdm1_channel1.Init.RightBitShift = 2;
if(HAL_OK != HAL_DFSDM_ChannelInit(&hdfsdm1_channel1))
{
return RT_ERROR;
}
/* DATAIN1_RIGHT */
__HAL_DFSDM_CHANNEL_RESET_HANDLE_STATE(&hdfsdm1_channel0);
hdfsdm1_channel0.Instance = DFSDM1_Channel0;
hdfsdm1_channel0.Init.OutputClock.Activation = ENABLE;
hdfsdm1_channel0.Init.OutputClock.Selection = DFSDM_CHANNEL_OUTPUT_CLOCK_SYSTEM;
hdfsdm1_channel0.Init.OutputClock.Divider = 74; /* 209/74 = 2.82MHZ*/
hdfsdm1_channel0.Init.Input.Multiplexer = DFSDM_CHANNEL_EXTERNAL_INPUTS;
hdfsdm1_channel0.Init.Input.DataPacking = DFSDM_CHANNEL_STANDARD_MODE;
hdfsdm1_channel0.Init.Input.Pins = DFSDM_CHANNEL_FOLLOWING_CHANNEL_PINS;
hdfsdm1_channel0.Init.SerialInterface.Type = DFSDM_CHANNEL_SPI_FALLING; /* right */
hdfsdm1_channel0.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
hdfsdm1_channel0.Init.Awd.FilterOrder = DFSDM_CHANNEL_FASTSINC_ORDER;
hdfsdm1_channel0.Init.Awd.Oversampling = 10;
hdfsdm1_channel0.Init.Offset = 0;
hdfsdm1_channel0.Init.RightBitShift = 2;
if(HAL_OK != HAL_DFSDM_ChannelInit(&hdfsdm1_channel0))
{
return RT_ERROR;
}
/* Initialize filter 0 (data_in1 right channel) */
__HAL_DFSDM_FILTER_RESET_HANDLE_STATE(&hdfsdm1_filter0);
hdfsdm1_filter0.Instance = DFSDM1_Filter0;
hdfsdm1_filter0.Init.RegularParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
hdfsdm1_filter0.Init.RegularParam.FastMode = ENABLE;
hdfsdm1_filter0.Init.RegularParam.DmaMode = ENABLE;
hdfsdm1_filter0.Init.InjectedParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
hdfsdm1_filter0.Init.InjectedParam.ScanMode = DISABLE;
hdfsdm1_filter0.Init.InjectedParam.DmaMode = DISABLE;
hdfsdm1_filter0.Init.FilterParam.SincOrder = DFSDM_FILTER_SINC3_ORDER;
hdfsdm1_filter0.Init.FilterParam.Oversampling = 64; /* 209 / ( 74 * 64) = 44.1KHZ*/
hdfsdm1_filter0.Init.FilterParam.IntOversampling = 1;
if (HAL_OK != HAL_DFSDM_FilterInit(&hdfsdm1_filter0))
{
return RT_ERROR;
}
/* Initialize filter 1 (data_in1 left channel) */
__HAL_DFSDM_FILTER_RESET_HANDLE_STATE(&hdfsdm1_filter1);
hdfsdm1_filter1.Instance = DFSDM1_Filter1;
hdfsdm1_filter1.Init.RegularParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
hdfsdm1_filter1.Init.RegularParam.FastMode = ENABLE;
hdfsdm1_filter1.Init.RegularParam.DmaMode = ENABLE;
hdfsdm1_filter1.Init.InjectedParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
hdfsdm1_filter1.Init.InjectedParam.ScanMode = DISABLE;
hdfsdm1_filter1.Init.InjectedParam.DmaMode = DISABLE;
hdfsdm1_filter1.Init.FilterParam.SincOrder = DFSDM_FILTER_SINC3_ORDER;
hdfsdm1_filter1.Init.FilterParam.Oversampling = 64; /* 209 / ( 74 * 64) = 44.1KHZ*/
hdfsdm1_filter1.Init.FilterParam.IntOversampling = 1;
if (HAL_OK != HAL_DFSDM_FilterInit(&hdfsdm1_filter1))
{
return RT_ERROR;
}
/* Configure regular channel and continuous mode for filter 0 (data_in1 left channel) */
if (HAL_OK != HAL_DFSDM_FilterConfigRegChannel(&hdfsdm1_filter1, DFSDM_CHANNEL_1, DFSDM_CONTINUOUS_CONV_ON))
{
return RT_ERROR;
}
/* Configure regular channel and continuous mode for filter 1 (data_in1 right channel) */
if (HAL_OK != HAL_DFSDM_FilterConfigRegChannel(&hdfsdm1_filter0, DFSDM_CHANNEL_0, DFSDM_CONTINUOUS_CONV_ON))
{
return RT_ERROR;
}
return RT_EOK;
}
/* dfsdm start coversions */
static rt_err_t rt_hw_dfsdm_open(void)
{
if (HAL_OK != HAL_DFSDM_FilterRegularStart_DMA(&hdfsdm1_filter0, FILTER0_FIFO, FILTER_FIFO_SIZE))
{
LOG_E("DFSDM DATA_IN1 rifht channel start conversions failed!");
return RT_ERROR;
}
if (HAL_OK != HAL_DFSDM_FilterRegularStart_DMA(&hdfsdm1_filter1, FILTER1_FIFO, FILTER_FIFO_SIZE))
{
LOG_E("DFSDM DATA_IN1 left channel start conversions failed!");
return RT_ERROR;
}
return RT_EOK;
}
static rt_err_t _init(rt_device_t dev)
{
RT_ASSERT(dev != RT_NULL);
rt_hw_dfsdm_init();
return RT_EOK;
}
static rt_err_t _open(rt_device_t dev, rt_uint16_t oflag)
{
RT_ASSERT(dev != RT_NULL);
rt_hw_dfsdm_open();
return RT_EOK;
}
static rt_err_t _close(rt_device_t dev)
{
RT_ASSERT(dev != RT_NULL);
HAL_DFSDM_FilterRegularStop_DMA(&hdfsdm1_filter0);
HAL_DFSDM_FilterRegularStop_DMA(&hdfsdm1_filter1);
return RT_EOK;
}
static rt_size_t _read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
RT_ASSERT(dev != RT_NULL);
rt_uint32_t i = 0;
rt_int16_t *p = RT_NULL;
p = (rt_int16_t *)buffer;
if (!pos)
{
for (i = 0; i < 512; i++)
{
p[2*i] = (int16_t)SaturaLH((FILTER0_FIFO[i] >> 8), -32768, 32767);
p[(2*i)+1] = (int16_t)SaturaLH((FILTER1_FIFO[i] >> 8), -32768, 32767);
}
}
else
{
for (i = 512; i < 1024; i++)
{
p[2*i] = (int16_t)SaturaLH((FILTER0_FIFO[i] >> 8), -32768, 32767);
p[(2*i)+1] = (int16_t)SaturaLH((FILTER1_FIFO[i] >> 8), -32768, 32767);
}
}
return size;
}
static rt_size_t _write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
RT_ASSERT(dev != RT_NULL);
return RT_EOK;
}
static rt_err_t _control(rt_device_t dev, int cmd, void *args)
{
RT_ASSERT(dev != RT_NULL);
return RT_EOK;
}
int dfsdm_init(void)
{
dfsdm_dev.type = RT_Device_Class_Miscellaneous;
dfsdm_dev.init = _init;
dfsdm_dev.open = _open;
dfsdm_dev.close = _close;
dfsdm_dev.read = _read;
dfsdm_dev.write = _write;
dfsdm_dev.control = _control;
dfsdm_dev.user_data = RT_NULL;
rt_device_register(&dfsdm_dev, "dfsdm1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
LOG_I("dfsdm1 init success!");
return RT_EOK;
}
INIT_DEVICE_EXPORT(dfsdm_init);
static int dfsdm_sample(int argc, char **argv)
{
if (argc != 1)
{
rt_kprintf("Usage:\n");
rt_kprintf("dfsdm_sample\n");
return -1;
}
static struct rt_device *dfsdm_dev = RT_NULL;
static struct rt_device *sound_dev = RT_NULL;
rt_uint16_t play_type = OUTPUT_DEVICE_HEADPHONE;
rt_uint16_t tickstart = 0;
extern SAI_HandleTypeDef hsai_BlockA2;
dfsdm_dev = rt_device_find("dfsdm1");
if (dfsdm_dev == RT_NULL)
{
rt_kprintf("no dfsdm device!");
return RT_ERROR;
}
sound_dev = rt_device_find("decoder");
if (sound_dev == RT_NULL)
{
rt_kprintf("no decoder device!");
return RT_ERROR;
}
/* open dfsdm device */
rt_device_open(dfsdm_dev, RT_DEVICE_OFLAG_RDWR);
/* open sound device */
rt_device_open(sound_dev, RT_DEVICE_OFLAG_WRONLY);
rt_device_control(sound_dev, SET_PLAY_TYPE, &play_type);
rt_device_control(sound_dev, START_PLAY, RT_NULL);
rt_memset(PLAY_BUF, 0, PALY_SIZE);
tickstart = rt_tick_get();
if (HAL_SAI_Transmit_DMA(&hsai_BlockA2, (uint8_t *)PLAY_BUF, PALY_SIZE) != HAL_OK)
{
rt_kprintf("sai transmit dma failed!\n");
return RT_ERROR;
}
rt_kprintf("dfsdm audio record test begin!\n");
while (1)
{
if ((rt_tick_get() - tickstart) > 0x1000)
{
HAL_SAI_DMAStop(&hsai_BlockA2);
rt_device_close(dfsdm_dev);
break;
}
if (DmaLeftRecHalfBuffCplt && DmaRightRecHalfBuffCplt)
{
rt_device_read(dfsdm_dev, 0, PLAY_BUF, 512);
DmaLeftRecHalfBuffCplt = 0;
DmaRightRecHalfBuffCplt = 0;
}
else if (DmaLeftRecBuffCplt && DmaRightRecBuffCplt)
{
rt_device_read(dfsdm_dev, 1, PLAY_BUF, 512);
DmaLeftRecBuffCplt = 0;
DmaRightRecBuffCplt = 0;
}
}
rt_kprintf("dfsdm audio record test end!\n");
return RT_EOK;
}
MSH_CMD_EXPORT(dfsdm_sample, dfsdm audiorecord test);
#endif
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-07-07 thread-liu first version
*/
#ifndef __DRV_DFSDM_H__
#define __DRV_DFSDM_H__
#include "board.h"
#ifdef __cplusplus
extern "C" {
#endif
#define SaturaLH(N, L, H) (((N)<(L))?(L):(((N)>(H))?(H):(N)))
#ifdef __cplusplus
}
#endif
#endif
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-07-27 thread-liu first version
*/
#include "board.h"
#ifdef BSP_USING_EXTI
//#define DRV_DEBUG
#define LOG_TAG "drv.exti"
#include <drv_log.h>
/* defined the KEY2 pin: */
#define KEY2_PIN GET_PIN(A, 13)
void key2_on(void *args)
{
rt_kprintf("press key2!\n");
}
static int exti_sample(void)
{
rt_pin_mode(KEY2_PIN, PIN_MODE_INPUT_PULLUP);
rt_pin_attach_irq(KEY2_PIN, PIN_IRQ_MODE_FALLING, key2_on, RT_NULL);
rt_pin_irq_enable(KEY2_PIN, PIN_IRQ_ENABLE);
return RT_EOK;
}
INIT_DEVICE_EXPORT(exti_sample);
#endif
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-07-06 thread-liu first version
*/
#include "board.h"
#if defined(BSP_USING_FDCAN1) || defined(BSP_USING_FDCAN2)
#include "drv_fdcan.h"
//#define DRV_DEBUG
#define LOG_TAG "drv.fdcan"
#include <drv_log.h>
struct stm32_fdcan
{
struct rt_device dev;
FDCAN_HandleTypeDef fdcan;
FDCAN_FilterTypeDef filter;
FDCAN_TxHeaderTypeDef tx_config;
FDCAN_RxHeaderTypeDef rx_config;
volatile rt_uint8_t fifo0;
volatile rt_uint8_t fifo1;
};
static struct stm32_fdcan rt_fdcan = {0};
static rt_err_t rt_fdcan_init(rt_device_t dev)
{
RT_ASSERT(dev != RT_NULL);
struct stm32_fdcan *device = (struct stm32_fdcan *)dev;
device->fdcan.Instance = FDCAN1;
device->fdcan.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
device->fdcan.Init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK;
device->fdcan.Init.AutoRetransmission = ENABLE;
device->fdcan.Init.TransmitPause = DISABLE;
device->fdcan.Init.ProtocolException = ENABLE;
device->fdcan.Init.NominalPrescaler = 0x01; /* tq = NominalPrescaler x (1/fdcan_ker_ck) */
device->fdcan.Init.NominalSyncJumpWidth = 0x08;
device->fdcan.Init.DataPrescaler = 0x01;
device->fdcan.Init.DataSyncJumpWidth = 0x04;
device->fdcan.Init.DataTimeSeg1 = 0x05; /* DataTimeSeg1 = Propagation_segment + Phase_segment_1 */
device->fdcan.Init.DataTimeSeg2 = 0x04;
device->fdcan.Init.NominalTimeSeg1 = 0x1F; /* NominalTimeSeg1 = Propagation_segment + Phase_segment_1 */
device->fdcan.Init.NominalTimeSeg2 = 0x08;
device->fdcan.Init.MessageRAMOffset = 0x00;
device->fdcan.Init.StdFiltersNbr = 0x01;
device->fdcan.Init.ExtFiltersNbr = 0x01;
device->fdcan.Init.RxFifo0ElmtsNbr = 0x01;
device->fdcan.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
device->fdcan.Init.RxFifo1ElmtsNbr = 0x02;
device->fdcan.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
device->fdcan.Init.RxBuffersNbr = 0x00;
device->fdcan.Init.TxEventsNbr = 0x00;
device->fdcan.Init.TxBuffersNbr = 0x00;
device->fdcan.Init.TxFifoQueueElmtsNbr = 0x01;
device->fdcan.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
device->fdcan.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
if (HAL_FDCAN_Init(&device->fdcan) != HAL_OK)
{
return RT_ERROR;
}
device->filter.IdType = FDCAN_EXTENDED_ID;
device->filter.FilterIndex = 0;
device->filter.FilterType = FDCAN_FILTER_MASK;
device->filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
device->filter.FilterID1 = 0x1111111;
device->filter.FilterID2 = 0x2222222;
if (HAL_FDCAN_ConfigFilter(&device->fdcan, &device->filter)!=HAL_OK)
{
return RT_ERROR;
}
HAL_FDCAN_Start(&device->fdcan);
HAL_FDCAN_ActivateNotification(&device->fdcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); /* open rx fifo0 new message it */
device->fifo0 = RESET;
device->fifo1 = RESET;
return RT_EOK;
}
static rt_err_t rt_fdcan_open(rt_device_t dev, rt_uint16_t oflag)
{
RT_ASSERT(dev != RT_NULL);
return RT_EOK;
}
static rt_err_t rt_fdcan_close(rt_device_t dev)
{
RT_ASSERT(dev != RT_NULL);
return RT_EOK;
}
static rt_err_t rt_fdcan_control(rt_device_t dev, int cmd, void *args)
{
RT_ASSERT(dev != RT_NULL);
struct stm32_fdcan *device = (struct stm32_fdcan *)dev;
switch (cmd)
{
case FDCAN_MODE_NORMAL:
device->fdcan.Init.Mode = FDCAN_MODE_NORMAL;
break;
case FDCAN_MODE_INTERNAL_LOOPBACK:
device->fdcan.Init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK;
break;
default:
break;
}
HAL_FDCAN_Init(&device->fdcan);
return RT_EOK;
}
static rt_size_t rt_fdcan_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
RT_ASSERT(dev != RT_NULL);
struct stm32_fdcan *device = (struct stm32_fdcan *)dev;
if (rt_fdcan.fifo0 == SET)
{
rt_fdcan.fifo0 = RESET;
if (HAL_FDCAN_GetRxMessage(&device->fdcan, FDCAN_RX_FIFO0, &device->rx_config, (uint8_t *)buffer) != HAL_OK)
{
LOG_E("get msg error from fdcan fifo0!");
return 0;
}
return device->rx_config.DataLength >> 16;
}
if (rt_fdcan.fifo1 == SET)
{
rt_fdcan.fifo0 = RESET;
if (HAL_FDCAN_GetRxMessage(&device->fdcan, FDCAN_RX_FIFO1, &device->rx_config, (uint8_t *)buffer) != HAL_OK)
{
LOG_E("get msg error from fdcan fifo1!");
return 0;
}
return device->rx_config.DataLength >> 16;
}
return 0;
}
static rt_size_t rt_fdcan_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
RT_ASSERT(dev != RT_NULL);
struct stm32_fdcan *device = (struct stm32_fdcan *)dev;
device->tx_config.Identifier = 0x1111112;
device->tx_config.IdType = FDCAN_EXTENDED_ID;
device->tx_config.TxFrameType = FDCAN_DATA_FRAME;
device->tx_config.DataLength = FDCAN_DLC_BYTES_8;
device->tx_config.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
device->tx_config.BitRateSwitch = FDCAN_BRS_OFF;
device->tx_config.FDFormat = FDCAN_CLASSIC_CAN;
device->tx_config.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
device->tx_config.MessageMarker = 0xCC;
if (HAL_FDCAN_AddMessageToTxFifoQ(&device->fdcan, &device->tx_config, (uint8_t *)buffer) != HAL_OK)
{
return RT_ERROR;
}
return RT_EOK;
}
void FDCAN1_IT0_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_FDCAN_IRQHandler(&rt_fdcan.fdcan);
/* leave interrupt */
rt_interrupt_leave();
}
void FDCAN1_IT1_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_FDCAN_IRQHandler(&rt_fdcan.fdcan);
/* leave interrupt */
rt_interrupt_leave();
}
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
if (hfdcan->Instance == FDCAN1)
{
if ((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET)
{
rt_fdcan.fifo0 = SET;
HAL_FDCAN_ActivateNotification(hfdcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0);
}
}
}
void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs)
{
if ((RxFifo1ITs & FDCAN_IT_RX_FIFO1_NEW_MESSAGE) != RESET)
{
rt_fdcan.fifo1 = SET;
HAL_FDCAN_ActivateNotification(hfdcan, FDCAN_IT_RX_FIFO1_NEW_MESSAGE, 0);
}
}
int fdcan_init(void)
{
rt_fdcan.dev.type = RT_Device_Class_CAN;
rt_fdcan.dev.init = rt_fdcan_init;
rt_fdcan.dev.open = rt_fdcan_open;
rt_fdcan.dev.close = rt_fdcan_close;
rt_fdcan.dev.read = rt_fdcan_read;
rt_fdcan.dev.write = rt_fdcan_write;
rt_fdcan.dev.control = rt_fdcan_control;
rt_fdcan.dev.user_data = RT_NULL;
rt_device_register(&rt_fdcan.dev, "fdcan1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
LOG_I("fdcan1 init success!");
return RT_EOK;
}
INIT_DEVICE_EXPORT(fdcan_init);
#ifdef FINSH_USING_MSH
#include <finsh.h>
int fdcan_sample(int argc, char **argv)
{
rt_err_t result = RT_EOK;
rt_uint8_t i, rx_buf[8], tx_buf[8];
struct rt_device *dev = RT_NULL;
if (argc != 9)
{
rt_kprintf("Usage:\n");
rt_kprintf("fdcan_sample 1 2 3 4 5 6 7 8\n");
return -1;
}
for (i = 0; i < 8; i++)
{
tx_buf[i] = atoi(argv[i+1]);
}
dev = rt_device_find("fdcan1");
if (dev == RT_NULL)
{
rt_kprintf("can't find fdcan1 device!\n");
return RT_ERROR;
}
rt_device_open(dev, RT_DEVICE_OFLAG_RDWR);
rt_device_write(dev, 0, tx_buf, 8);
rt_thread_delay(1);
rt_device_read(dev, 0, rx_buf, 8);
rt_kprintf("fdcan1 loopback test over, rbuf = ");
for (i = 0; i < 8; i++)
{
rt_kprintf(" %x ", rx_buf[i]);
}
rt_kprintf("\n");
return result;
}
MSH_CMD_EXPORT(fdcan_sample, fdcan loopback mode test);
#endif
#endif
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-07-06 thread-liu first version
*/
#ifndef __DRV_FDCAN_H__
#define __DRV_FDCAN_H__
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-06-19 thread-liu first version
*/
#include <board.h>
#ifdef BSP_USING_LPTIM
#include "drv_config.h"
#include <string.h>
#include <stdlib.h>
//#define DRV_DEBUG
#define LOG_TAG "drv.lptimer"
#include <drv_log.h>
#define LED5_PIN GET_PIN(D, 9)
LPTIM_HandleTypeDef hlptim1;
extern int lptim_stop(void);
void LPTIM1_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_LPTIM_IRQHandler(&hlptim1);
/* leave interrupt */
rt_interrupt_leave();
}
void HAL_LPTIM_AutoReloadMatchCallback(LPTIM_HandleTypeDef *hlptim)
{
if(hlptim->Instance == LPTIM1)
{
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_9);
}
#if defined(BSP_USING_PWR)
/* All level of ITs can interrupt */
__set_BASEPRI(0U);
lptim_stop();
rt_kprintf("system returns to normal!\n");
#endif
}
static int lptim_control(uint8_t pre_value)
{
if(pre_value > 7)
{
pre_value = 7;
}
hlptim1.Instance->CFGR &= ~(7 << 9); /* clear PRESC[2:0] */
hlptim1.Instance->CFGR |= pre_value << 9; /* set PRESC[2:0] */
rt_kprintf("set lptim pre value [0x%x] success!\n", pre_value);
return RT_EOK;
}
int lptim_start(void)
{
/* ### Start counting in interrupt mode ############################# */
if (HAL_LPTIM_Counter_Start_IT(&hlptim1, 32767) != HAL_OK)
{
LOG_D("lptim1 start counting failed!\n");
return -RT_ERROR;
}
LOG_D("lptim1 start counting success!\n");
return RT_EOK;
}
int lptim_stop(void)
{
if (HAL_LPTIM_Counter_Stop_IT(&hlptim1) != HAL_OK)
{
LOG_D("lptim1 stop failed!\n");
return -RT_ERROR;
}
LOG_D("lptim1 stop counting success!\n");
return RT_EOK;
}
int lptim_init(void)
{
rt_pin_mode(LED5_PIN, PIN_MODE_OUTPUT);
hlptim1.Instance = LPTIM1;
hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV8;
hlptim1.Init.UltraLowPowerClock.Polarity = LPTIM_CLOCKPOLARITY_RISING;
hlptim1.Init.UltraLowPowerClock.SampleTime = LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION;
hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
hlptim1.Init.OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH;
hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;
hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)
{
LOG_D("lptim init failed!\n");
return -RT_ERROR;
}
LOG_D("lptim init success!\n");
return RT_EOK;
}
INIT_DEVICE_EXPORT(lptim_init);
static int lptim_sample(int argc, char *argv[])
{
if (argc > 1)
{
if (!strcmp(argv[1], "start"))
{
lptim_start();
return RT_EOK;
}
else if (!strcmp(argv[1], "stop"))
{
lptim_stop();
return RT_EOK;
}
else if (!strcmp(argv[1], "set"))
{
if (argc > 2)
{
lptim_control(atoi(argv[2]));
return RT_EOK;
}
else
{
goto _exit;
}
}
else
{
goto _exit;
}
}
_exit:
{
rt_kprintf("Usage:\n");
rt_kprintf("lptim_sample start - start lptim, the LED5 will start blink\n");
rt_kprintf("lptim_sample stop - stop lptim, the LED5 will stop blink\n");
rt_kprintf("lptim_sample set - set the lptim prescaler to change LED5 blink frquency, lptim_sample set [0 - 7]\n");
}
return -RT_ERROR;
}
MSH_CMD_EXPORT(lptim_sample, low power timer sample);
#endif
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-08 thread-liu first version
*/
#include "board.h"
#include "mfxstm32l152.h"
#define DRV_DEBUG
#define LOG_TAG "drv.mfx"
#include <drv_log.h>
#define CHIP_ADDRESS 0x42 /* mfx address */
#define I2C_NAME "i2c2"
struct st_mfx
{
struct rt_device dev;
struct rt_i2c_bus_device *i2c_bus;
rt_uint8_t id;
rt_uint16_t type;
};
static struct st_mfx rt_mfx = {0};
static IO_DrvTypeDef *IoDrv = NULL;
static rt_err_t read_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint16_t len, rt_uint8_t *buf)
{
struct rt_i2c_msg msg[2] = {0, 0};
RT_ASSERT(bus != RT_NULL);
msg[0].addr = CHIP_ADDRESS;
msg[0].flags = RT_I2C_WR;
msg[0].buf = &reg;
msg[0].len = 1;
msg[1].addr = CHIP_ADDRESS;
msg[1].flags = RT_I2C_RD;
msg[1].len = len;
msg[1].buf = buf;
if (rt_i2c_transfer(bus, msg, 2) == 2)
{
return RT_EOK;
}
return RT_ERROR;
}
/* i2c write reg */
static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t data)
{
rt_uint8_t buf[2];
struct rt_i2c_msg msgs;
RT_ASSERT(bus != RT_NULL);
buf[0] = reg;
buf[1] = data;
msgs.addr = CHIP_ADDRESS;
msgs.flags = RT_I2C_WR;
msgs.buf = buf;
msgs.len = sizeof(buf);
if (rt_i2c_transfer(bus, &msgs, 1) == 1)
{
return RT_EOK;
}
return RT_ERROR;
}
void MFX_IO_Init(void)
{
rt_mfx.i2c_bus = rt_i2c_bus_device_find(I2C_NAME);
if (rt_mfx.i2c_bus == RT_NULL)
{
LOG_E("can't find %c deivce", I2C_NAME);
}
}
void MFX_IO_DeInit(void)
{
}
void MFX_IO_ITConfig(void)
{
static rt_uint8_t mfx_io_it_enabled = 0;
GPIO_InitTypeDef gpio_init_structure;
if(mfx_io_it_enabled == 0)
{
mfx_io_it_enabled = 1;
/* Enable the GPIO EXTI clock */
__HAL_RCC_GPIOI_CLK_ENABLE();
gpio_init_structure.Pin = GPIO_PIN_8;
gpio_init_structure.Pull = GPIO_NOPULL;
gpio_init_structure.Speed = GPIO_SPEED_FREQ_LOW;
gpio_init_structure.Mode = GPIO_MODE_IT_RISING;
HAL_GPIO_Init(GPIOI, &gpio_init_structure);
/* Enable and set GPIO EXTI Interrupt to the lowest priority */
HAL_NVIC_SetPriority((IRQn_Type)(EXTI8_IRQn), 0x04, 0x00);
HAL_NVIC_EnableIRQ((IRQn_Type)(EXTI8_IRQn));
}
}
void MFX_IO_Write(rt_uint16_t Addr, rt_uint8_t Reg, rt_uint8_t Value)
{
write_reg(rt_mfx.i2c_bus, Reg, Value);
}
rt_uint8_t MFX_IO_Read(rt_uint16_t Addr, rt_uint8_t Reg)
{
rt_uint8_t value = 0;
read_reg(rt_mfx.i2c_bus, Reg, 1, &value);
return value;
}
rt_uint16_t MFX_IO_ReadMultiple(rt_uint16_t Addr, rt_uint8_t Reg, rt_uint8_t *Buffer, rt_uint16_t Length)
{
return read_reg(rt_mfx.i2c_bus, Reg, Length, Buffer);
}
RT_WEAK void MFX_IO_Delay(rt_uint32_t Delay)
{
rt_thread_delay(Delay);
}
RT_WEAK void MFX_IO_Wakeup(void)
{
}
RT_WEAK void MFX_IO_EnableWakeupPin(void)
{
}
rt_uint8_t BSP_IO_DeInit(void)
{
IoDrv = NULL;
return RT_EOK;
}
rt_uint32_t BSP_IO_ITGetStatus(rt_uint32_t IoPin)
{
/* Return the IO Pin IT status */
return (IoDrv->ITStatus(0, IoPin));
}
/**
* @brief Clears all the IO IT pending bits.
* @retval None
*/
void BSP_IO_ITClear(void)
{
/* Clear all IO IT pending bits */
IoDrv->ClearIT(0, MFXSTM32L152_GPIO_PINS_ALL);
}
void BSP_IO_ITClearPin(rt_uint32_t IO_Pins_To_Clear)
{
/* Clear only the selected list of IO IT pending bits */
IoDrv->ClearIT(0, IO_Pins_To_Clear);
}
/**
* @brief Configures the IO pin(s) according to IO mode structure value.
* @param IoPin: IO pin(s) to be configured.
* This parameter can be one of the following values:
* @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23.
* @param IoMode: IO pin mode to configure
* This parameter can be one of the following values:
* @arg IO_MODE_INPUT
* @arg IO_MODE_OUTPUT
* @arg IO_MODE_IT_RISING_EDGE
* @arg IO_MODE_IT_FALLING_EDGE
* @arg IO_MODE_IT_LOW_LEVEL
* @arg IO_MODE_IT_HIGH_LEVEL
* @arg IO_MODE_ANALOG
* @arg IO_MODE_OFF
* @arg IO_MODE_INPUT_PU,
* @arg IO_MODE_INPUT_PD,
* @arg IO_MODE_OUTPUT_OD,
* @arg IO_MODE_OUTPUT_OD_PU,
* @arg IO_MODE_OUTPUT_OD_PD,
* @arg IO_MODE_OUTPUT_PP,
* @arg IO_MODE_OUTPUT_PP_PU,
* @arg IO_MODE_OUTPUT_PP_PD,
* @arg IO_MODE_IT_RISING_EDGE_PU
* @arg IO_MODE_IT_FALLING_EDGE_PU
* @arg IO_MODE_IT_LOW_LEVEL_PU
* @arg IO_MODE_IT_HIGH_LEVEL_PU
* @arg IO_MODE_IT_RISING_EDGE_PD
* @arg IO_MODE_IT_FALLING_EDGE_PD
* @arg IO_MODE_IT_LOW_LEVEL_PD
* @arg IO_MODE_IT_HIGH_LEVEL_PD
* @retval RT_EOK if all initializations are OK. Other value if error.
*/
rt_uint8_t rt_mfx_pin_mode(rt_uint32_t IoPin, IO_ModeTypedef IoMode)
{
/* Configure the selected IO pin(s) mode */
IoDrv->Config(0, IoPin, IoMode);
return RT_EOK;
}
/**
* @brief Sets the IRQ_OUT pin polarity and type
* @param IoIrqOutPinPolarity: High/Low
* @param IoIrqOutPinType: OpenDrain/PushPull
* @retval OK
*/
rt_uint8_t rt_mfx_config_irq(rt_uint8_t IoIrqOutPinPolarity, rt_uint8_t IoIrqOutPinType)
{
if((rt_mfx.id == MFXSTM32L152_ID_1) || (rt_mfx.id == MFXSTM32L152_ID_2))
{
/* Initialize the IO driver structure */
mfxstm32l152_SetIrqOutPinPolarity(0, IoIrqOutPinPolarity);
mfxstm32l152_SetIrqOutPinType(0, IoIrqOutPinType);
}
return RT_EOK;
}
/**
* @brief Sets the selected pins state.
* @param IoPin: Selected pins to write.
* This parameter can be any combination of the IO pins.
* @param PinState: New pins state to write
* @retval None
*/
void rt_mfx_pin_write(rt_uint32_t IoPin, rt_base_t PinState)
{
/* Set the Pin state */
IoDrv->WritePin(0, IoPin, PinState);
}
/**
* @brief Gets the selected pins current state.
* @param IoPin: Selected pins to read.
* This parameter can be any combination of the IO pins.
* @retval The current pins state
*/
rt_uint32_t rt_mfx_pin_read(rt_uint32_t IoPin)
{
return(IoDrv->ReadPin(0, IoPin));
}
/**
* @brief Toggles the selected pins state.
* @param IoPin: Selected pins to toggle.
* This parameter can be any combination of the IO pins.
* @note This function is only used to toggle one pin in the same time
* @retval None
*/
void rt_mfx_pin_toggle(rt_uint32_t IoPin)
{
/* Toggle the current pin state */
if(IoDrv->ReadPin(0, IoPin) != 0)
{
IoDrv->WritePin(0, IoPin, 0); /* Reset */
}
else
{
IoDrv->WritePin(0, IoPin, 1); /* Set */
}
}
int rt_mfx_init(void)
{
/* Read ID and verify the MFX is ready */
rt_mfx.id = mfxstm32l152_io_drv.ReadID(0);
if((rt_mfx.id == MFXSTM32L152_ID_1) || (rt_mfx.id == MFXSTM32L152_ID_2))
{
/* Initialize the IO driver structure */
IoDrv = &mfxstm32l152_io_drv;
/* Initialize MFX */
IoDrv->Init(0);
IoDrv->Start(0, IO_PIN_ALL);
LOG_I("mfx init success, id: 0x%x", rt_mfx.id);
return RT_EOK;
}
LOG_I("mfx init error, id: 0x%x", rt_mfx.id);
return RT_ERROR;
}
INIT_DEVICE_EXPORT(rt_mfx_init);
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-08 thread-liu first version
*/
#ifndef __DRV_MFX_H__
#define __DRV_MFX_H__
#include "board.h"
#include "mfxstm32l152.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum
{
BSP_IO_PIN_RESET = 0,
BSP_IO_PIN_SET = 1
}BSP_IO_PinStateTypeDef;
#define CAMERA_RST1 MFXSTM32L152_AGPIO_PIN_3
#define CAMERA_XSDN MFXSTM32L152_AGPIO_PIN_2
#define CARMERA_PLUG MFXSTM32L152_GPIO_PIN_12
void rt_mfx_init(void);
rt_uint32_t BSP_IO_ITGetStatus(rt_uint32_t IoPin);
void BSP_IO_ITClear(void);
void BSP_IO_ITClearPin(rt_uint32_t IO_Pins_To_Clear);
rt_uint8_t rt_mfx_pin_mode(rt_uint32_t IoPin, IO_ModeTypedef IoMode);
rt_uint8_t rt_mfx_config_irq(rt_uint8_t IoIrqOutPinPolarity, rt_uint8_t IoIrqOutPinType);
void rt_mfx_pin_write(rt_uint32_t IoPin, rt_base_t PinState);
rt_uint32_t rt_mfx_pin_read(rt_uint32_t IoPin);
void rt_mfx_pin_toggle(rt_uint32_t IoPin);
#ifdef __cplusplus
}
#endif
#endif
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-03 thread-liu the first version
*/
#include "board.h"
#if defined(BSP_USING_DCMI)
#include "drv_mfx.h"
#include <dfs_posix.h>
#include "drv_ov5640.h"
//#define DRV_DEBUG
//#define CAMERA_DUMP
#define LOG_TAG "drv.ov5640"
#include <drv_log.h>
#define CHIP_ADDRESS 0x3C /* OV5640 address */
#define I2C_NAME "i2c2"
#define JPEG_BUF_SIZE 8 * 1024
#define JPEG_LINE_SIZE 1 * 1024
#if defined(__CC_ARM) || defined(__CLANG_ARM)
__attribute__((at(0x2FFCC000)))
#elif defined(__GNUC__)
__attribute__((at(0x2FFCC000)))
#elif defined(__ICCARM__)
#pragma location = 0x2FFCC000
#endif
static rt_int32_t JPEG_DATA_BUF[JPEG_BUF_SIZE];
#if defined(__CC_ARM) || defined(__CLANG_ARM)
__attribute__((at(0x2FFDC000)))
#elif defined(__GNUC__)
__attribute__((at(0x2FFDC000)))
#elif defined(__ICCARM__)
#pragma location = 0x2FFDC000
#endif
static rt_int32_t JPEG_LINE_BUF[2][JPEG_LINE_SIZE];
volatile rt_uint32_t jpeg_data_len = 0;
volatile rt_uint8_t jpeg_data_ok = 0;
struct rt_i2c_bus_device *i2c_bus = RT_NULL;
extern DCMI_HandleTypeDef dcmi;
extern DMA_HandleTypeDef hdma_dcmi;
#if defined(CAMERA_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
static rt_err_t read_reg(struct rt_i2c_bus_device *bus, rt_uint16_t reg, rt_uint8_t len, rt_uint8_t *buf)
{
struct rt_i2c_msg msg[2] = {0, 0};
static rt_uint8_t i2c_reg[2] = {0, 0};
RT_ASSERT(bus != RT_NULL);
i2c_reg[0] = ((uint16_t)(reg >> 8) & 0xFF);
i2c_reg[1] = ((uint16_t)(reg & 0xFF));
msg[0].addr = CHIP_ADDRESS;
msg[0].flags = RT_I2C_WR;
msg[0].buf = i2c_reg;
msg[0].len = 2;
msg[1].addr = CHIP_ADDRESS;
msg[1].flags = RT_I2C_RD;
msg[1].len = len;
msg[1].buf = buf;
if (rt_i2c_transfer(bus, msg, 2) == 2)
{
return RT_EOK;
}
return RT_ERROR;
}
/* i2c write reg */
static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint16_t reg, rt_uint8_t data)
{
rt_uint8_t buf[3];
struct rt_i2c_msg msgs;
RT_ASSERT(bus != RT_NULL);
buf[0] = ((uint16_t)(reg >> 8) & 0xFF);
buf[1] = ((uint16_t)(reg)&0xFF);
buf[2] = data;
msgs.addr = CHIP_ADDRESS;
msgs.flags = RT_I2C_WR;
msgs.buf = buf;
msgs.len = 3;
if (rt_i2c_transfer(bus, &msgs, 1) == 1)
{
return RT_EOK;
}
return RT_ERROR;
}
static rt_err_t ov5640_read_id(struct rt_i2c_bus_device *bus, rt_uint16_t *id)
{
rt_uint8_t read_value[2];
read_reg(bus, 0x300A, 1, &read_value[0]);
read_reg(bus, 0x300B, 1, &read_value[1]);
*id = ((uint16_t)(read_value[0] << 8) & 0xFF00);
*id |= ((uint16_t)(read_value[1]) & 0x00FF);
if (*id != OV5640_ID)
{
LOG_E("ov5640 init error, id: 0x%04x", *id);
return RT_ERROR;
}
LOG_I("ov5640 init success, id: 0x%04x", *id);
return RT_EOK;
}
static rt_err_t ov5640_hard_reset(struct rt_i2c_bus_device *bus)
{
/* Camera sensor RESET sequence */
rt_mfx_pin_mode(CAMERA_RST1, IO_MODE_OUTPUT);
rt_mfx_pin_mode(CAMERA_XSDN, IO_MODE_OUTPUT);
/* Assert the camera STANDBY pin (active high) */
rt_mfx_pin_write(CAMERA_XSDN, BSP_IO_PIN_SET);
/* Assert the camera RSTI pin (active low) */
rt_mfx_pin_write(CAMERA_RST1, BSP_IO_PIN_RESET);
rt_thread_delay(100); /* RST and XSDN signals asserted during 100ms */
/* De-assert the camera STANDBY pin (active high) */
rt_mfx_pin_write(CAMERA_XSDN, BSP_IO_PIN_RESET);
rt_thread_delay(3); /* RST de-asserted and XSDN asserted during 3ms */
/* De-assert the camera RSTI pin (active low) */
rt_mfx_pin_write(CAMERA_RST1, BSP_IO_PIN_SET);
rt_thread_delay(6); /* RST de-asserted during 3ms */
return RT_EOK;
}
void OV5640_Flash_Ctrl(struct rt_i2c_bus_device *bus, rt_uint8_t sw)
{
write_reg(bus, 0x3016, 0X02);
write_reg(bus, 0x301C, 0X02);
if (sw)
{
write_reg(bus, 0X3019, 0X02);
}
else
{
write_reg(bus, 0X3019, 0X00);
}
}
static rt_err_t ov5640_config(struct rt_i2c_bus_device *bus)
{
rt_uint32_t i = 0;
rt_uint8_t value = 0;
write_reg(bus, 0x3103, 0X11); /* system clock from pad, bit[1] */
write_reg(bus, 0X3008, 0X82); /* soft reset */
rt_thread_delay(10);
for (i = 0; i < (sizeof(RGB565_Init) / 4); i++)
{
write_reg(bus, RGB565_Init[i][0], RGB565_Init[i][1]);
rt_thread_delay(10);
read_reg(bus, RGB565_Init[i][0], 1, &value);
if (RGB565_Init[i][1] != value)
{
LOG_D("error reg value[0x%x]:0x%02x - 0x%02x", RGB565_Init[i][0], RGB565_Init[i][1], value);
}
}
OV5640_Flash_Ctrl(bus, 1); /* open camera flash*/
rt_thread_delay(3);
OV5640_Flash_Ctrl(bus, 0); /* close camera flash*/
return RT_EOK;
}
/* JPEG */
void ov5640_jpeg_mode(struct rt_i2c_bus_device *bus)
{
rt_uint16_t i = 0;
for (i = 0; i < (sizeof(OV5640_jpeg_reg_tbl) / 4); i++)
{
write_reg(bus, OV5640_jpeg_reg_tbl[i][0], OV5640_jpeg_reg_tbl[i][1]);
}
}
/* RGB565 */
void ov5640_rgb565_mode(struct rt_i2c_bus_device *bus)
{
rt_uint16_t i = 0;
for (i = 0; i < (sizeof(ov5640_rgb565_reg_tbl) / 4); i++)
{
write_reg(bus, ov5640_rgb565_reg_tbl[i][0], ov5640_rgb565_reg_tbl[i][1]);
}
write_reg(bus, 0x3821, 0x06);
}
rt_uint8_t ov5640_focus_init(struct rt_i2c_bus_device *bus)
{
rt_uint16_t tickstart = 0 ,i = 0;
rt_uint16_t addr = 0x8000;
rt_uint8_t state = 0x8F;
write_reg(bus, 0x3000, 0x20); //reset MCU
for (i = 0; i < sizeof(OV5640_AF_Config); i++)
{
write_reg(bus, addr, OV5640_AF_Config[i]);
addr++;
}
write_reg(bus, 0x3022, 0x00);
write_reg(bus, 0x3023, 0x00);
write_reg(bus, 0x3024, 0x00);
write_reg(bus, 0x3025, 0x00);
write_reg(bus, 0x3026, 0x00);
write_reg(bus, 0x3027, 0x00);
write_reg(bus, 0x3028, 0x00);
write_reg(bus, 0x3029, 0x7f);
write_reg(bus, 0x3000, 0x00);
i = 0;
tickstart = rt_tick_get();
do
{
read_reg(bus, 0x3029, 1, &state);
if (rt_tick_get() - tickstart > 1000)
{
return RT_ERROR;
}
} while (state != 0x70);
return RT_EOK;
}
void ov5640_set_light(struct rt_i2c_bus_device *bus, rt_uint8_t mode)
{
rt_uint8_t i = 0;
write_reg(bus, 0x3212, 0x03); //start group 3
for (i = 0; i < 7; i++)
{
write_reg(bus, 0x3400 + i, OV5640_LIGHTMODE_TBL[mode][i]);
}
write_reg(bus, 0x3212, 0x13); //end group 3
write_reg(bus, 0x3212, 0xa3); //launch group 3
}
/* sat:0~6 */
void ov5640_color_saturation(struct rt_i2c_bus_device *bus, rt_uint8_t sat)
{
rt_uint8_t i = 0;
write_reg(bus, 0x3212, 0x03); //start group 3
write_reg(bus, 0x5381, 0x1c);
write_reg(bus, 0x5382, 0x5a);
write_reg(bus, 0x5383, 0x06);
for (i = 0; i < 6; i++)
{
write_reg(bus, 0x5384 + i, OV5640_SATURATION_TBL[sat][i]);
}
write_reg(bus, 0x538b, 0x98);
write_reg(bus, 0x538a, 0x01);
write_reg(bus, 0x3212, 0x13); //end group 3
write_reg(bus, 0x3212, 0xa3); //launch group 3
}
/* bright:0~8 */
void ov5640_set_brightness(struct rt_i2c_bus_device *bus, rt_uint8_t bright)
{
rt_uint8_t brtval;
if (bright < 4)
{
brtval = 4 - bright;
}
else
{
brtval = bright - 4;
}
write_reg(bus, 0x3212, 0x03); //start group 3
write_reg(bus, 0x5587, brtval << 4);
if (bright < 4)
{
write_reg(bus, 0x5588, 0x09);
}
else
{
write_reg(bus, 0x5588, 0x01);
}
write_reg(bus, 0x3212, 0x13); //end group 3
write_reg(bus, 0x3212, 0xa3); //launch group 3
}
/* contrast:0~6 */
void ov5640_contrast(struct rt_i2c_bus_device *bus, rt_uint8_t contrast)
{
rt_uint8_t reg0val = 0x00;
rt_uint8_t reg1val = 0x20;
switch (contrast)
{
case 0:
reg1val = reg0val = 0X14;
break;
case 1:
reg1val = reg0val = 0X18;
break;
case 2:
reg1val = reg0val = 0X1C;
break;
case 4:
reg0val = 0X10;
reg1val = 0X24;
break;
case 5:
reg0val = 0X18;
reg1val = 0X28;
break;
case 6:
reg0val = 0X1C;
reg1val = 0X2C;
break;
}
write_reg(bus, 0x3212, 0x03); //start group 3
write_reg(bus, 0x5585, reg0val);
write_reg(bus, 0x5586, reg1val);
write_reg(bus, 0x3212, 0x13); //end group 3
write_reg(bus, 0x3212, 0xa3); //launch group 3
}
/* sharp:0~33 */
void ov5640_set_sharpness(struct rt_i2c_bus_device *bus, rt_uint8_t sharp)
{
if (sharp < 33)
{
write_reg(bus, 0x5308, 0x65);
write_reg(bus, 0x5302, sharp);
}
else
{
write_reg(bus, 0x5308, 0x25);
write_reg(bus, 0x5300, 0x08);
write_reg(bus, 0x5301, 0x30);
write_reg(bus, 0x5302, 0x10);
write_reg(bus, 0x5303, 0x00);
write_reg(bus, 0x5309, 0x08);
write_reg(bus, 0x530a, 0x30);
write_reg(bus, 0x530b, 0x04);
write_reg(bus, 0x530c, 0x06);
}
}
rt_uint8_t ov5640_focus_constant(struct rt_i2c_bus_device *bus)
{
rt_uint8_t temp = 0;
rt_uint16_t tickstrat = 0;
write_reg(bus, 0x3023, 0x01);
write_reg(bus, 0x3022, 0x08);
do
{
tickstrat = rt_tick_get();
read_reg(bus, 0x3023, 1, &temp);
if (rt_tick_get() - tickstrat > 1000)
{
return RT_ERROR;
}
} while (temp != 0x00);
write_reg(bus, 0x3023, 0x01);
write_reg(bus, 0x3022, 0x04);
do
{
tickstrat = rt_tick_get();
read_reg(bus, 0x3023, 1, &temp);
if (rt_tick_get() - tickstrat > 1000)
{
return RT_ERROR;
}
} while (temp != 0x00);
return 0;
}
rt_uint8_t ov5640_set_outsize(struct rt_i2c_bus_device *bus, rt_uint16_t offx, rt_uint16_t offy, rt_uint16_t width, rt_uint16_t height)
{
write_reg(bus, 0X3212, 0X03);
write_reg(bus, 0x3808, width >> 8);
write_reg(bus, 0x3809, width & 0xff);
write_reg(bus, 0x380a, height >> 8);
write_reg(bus, 0x380b, height & 0xff);
write_reg(bus, 0x3810, offx >> 8);
write_reg(bus, 0x3811, offx & 0xff);
write_reg(bus, 0x3812, offy >> 8);
write_reg(bus, 0x3813, offy & 0xff);
write_reg(bus, 0X3212, 0X13);
write_reg(bus, 0X3212, 0Xa3);
return RT_EOK;
}
void rt_hw_camera_rx_callback(void)
{
rt_uint16_t i;
rt_int32_t *pbuf = RT_NULL;
pbuf = JPEG_DATA_BUF + jpeg_data_len;
if (hdma_dcmi.Instance->CR & (1 << 19))
{
for (i = 0; i < JPEG_LINE_SIZE; i++)
{
pbuf[i] = JPEG_LINE_BUF[0][i];
}
jpeg_data_len += JPEG_LINE_SIZE;
}
else
{
for (i = 0; i < JPEG_LINE_SIZE; i++)
{
pbuf[i] = JPEG_LINE_BUF[1][i];
}
jpeg_data_len += JPEG_LINE_SIZE;
}
}
/* After a frame of JPEG data has been collected. */
void jpeg_data_process(void)
{
rt_uint16_t i, rlen;
int *pbuf = RT_NULL;
if (!jpeg_data_ok)
{
__HAL_DMA_DISABLE(&hdma_dcmi);
rlen = JPEG_LINE_SIZE - __HAL_DMA_GET_COUNTER(&hdma_dcmi);
pbuf = JPEG_DATA_BUF + jpeg_data_len;
if (hdma_dcmi.Instance->CR & (1 << 19))
{
for (i = 0; i < rlen; i++)
{
pbuf[i] = JPEG_LINE_BUF[1][i];
}
}
else
{
for (i = 0; i < rlen; i++)
{
pbuf[i] = JPEG_LINE_BUF[0][i];
}
}
jpeg_data_len += rlen;
jpeg_data_ok = 1;
}
if (jpeg_data_ok == 2)
{
__HAL_DMA_SET_COUNTER(&hdma_dcmi, JPEG_LINE_SIZE);
__HAL_DMA_ENABLE(&hdma_dcmi);
jpeg_data_ok = 0;
jpeg_data_len = 0;
}
}
int rt_hw_ov5640_init(void)
{
extern void rt_hw_dcmi_dma_config(rt_uint32_t dst_addr1, rt_uint32_t dst_addr2, rt_uint16_t len);
static rt_uint16_t id = 0;
rt_device_t dcmi_dev = RT_NULL;
i2c_bus = rt_i2c_bus_device_find(I2C_NAME);
if (i2c_bus == RT_NULL)
{
LOG_E("can't find %c deivce", I2C_NAME);
return RT_ERROR;
}
ov5640_hard_reset(i2c_bus);
ov5640_read_id(i2c_bus, &id);
ov5640_config(i2c_bus);
ov5640_rgb565_mode(i2c_bus); /* rgb565 mode */
ov5640_focus_init(i2c_bus);
ov5640_jpeg_mode(i2c_bus); /* jpeg mode */
ov5640_set_light(i2c_bus, 0); /* auto mode */
ov5640_color_saturation(i2c_bus, 3);
ov5640_set_brightness(i2c_bus, 4); /* brigetness 0 */
ov5640_contrast(i2c_bus, 3);
ov5640_set_sharpness(i2c_bus, 33);
ov5640_focus_constant(i2c_bus);
/* dcmi init */
dcmi_dev = rt_device_find("dcmi");
if (dcmi_dev == RT_NULL)
{
LOG_E("can't find dcmi device!");
return RT_ERROR;
}
rt_device_open(dcmi_dev, RT_DEVICE_FLAG_RDWR);
rt_hw_dcmi_dma_config((rt_uint32_t)&JPEG_LINE_BUF[0], (rt_uint32_t)&JPEG_LINE_BUF[1], JPEG_LINE_SIZE);
ov5640_set_outsize(i2c_bus, 4, 0, jpeg_picture_size[1][0], jpeg_picture_size[1][1]);
return RT_EOK;
}
INIT_APP_EXPORT(rt_hw_ov5640_init);
int camera_sample(int argc, char **argv)
{
int fd = -1;
rt_uint32_t i, jpg_start, jpg_len;
rt_uint16_t tickstart = 0;
rt_uint8_t jpg_head = 0;
rt_uint8_t *p = RT_NULL;
if (argc != 2)
{
rt_kprintf("Usage:\n");
rt_kprintf("camera_sample file.jpg\n");
return -1;
}
/* start dcmi capture */
__HAL_DMA_ENABLE(&hdma_dcmi);
dcmi.Instance->CR |= DCMI_CR_CAPTURE;
tickstart = rt_tick_get();
while (1)
{
if (rt_tick_get() - tickstart > 1000)
{
LOG_E("picture capture overtime!");
break;
}
if (jpeg_data_ok == 1)
{
dcmi.Instance->CR &= ~(DCMI_CR_CAPTURE);
tickstart = rt_tick_get();
while(dcmi.Instance->CR & 0x01)
{
if (rt_tick_get() - tickstart > 0x1000)
{
rt_kprintf("dcmi close failed!\n");
jpeg_data_ok = 2;
break;
}
}
__HAL_DMA_DISABLE(&hdma_dcmi);
p = (rt_uint8_t *)JPEG_DATA_BUF;
jpg_len = 0;
jpg_head = 0;
for (i = 0; i < jpeg_data_len * 4; i++)
{
/* jpg head */
if ((p[i] == 0xFF) && (p[i + 1] == 0xD8))
{
jpg_start = i;
jpg_head = 1;
}
/* jpg end */
if ((p[i] == 0xFF) && (p[i + 1] == 0xD9) && jpg_head)
{
jpg_len = i - jpg_start + 2; /* a picture len */
break;
}
}
if (jpg_len)
{
p += jpg_start;
fd = open(argv[1], O_WRONLY | O_CREAT);
if (fd < 0)
{
rt_kprintf("open file for recording failed!\n");
return -RT_ERROR;
}
else
{
write(fd, p, jpg_len);
close(fd);
rt_kprintf("picture capture complate!\n");
break;
}
}
jpeg_data_ok = 2;
}
}
return RT_EOK;
}
MSH_CMD_EXPORT(camera_sample, record picture to a jpg file);
#endif
此差异已折叠。
......@@ -798,47 +798,47 @@ static rt_err_t rt_hw_pmic_init_register(void)
stpmu1_write_reg(BUCK_ICC_TURNOFF_REG, 0x30);
stpmu1_write_reg(LDO_ICC_TURNOFF_REG, 0x3b);
/* vddcore */
STPMU1_Regulator_Voltage_Set(STPMU1_BUCK1, 1200);
STPMU1_Regulator_Enable(STPMU1_BUCK1);
/* vddcore */
STPMU1_Regulator_Voltage_Set(STPMU1_BUCK1, 1200);
STPMU1_Regulator_Enable(STPMU1_BUCK1);
/* vddddr */
STPMU1_Regulator_Voltage_Set(STPMU1_BUCK2, 1350);
STPMU1_Regulator_Enable(STPMU1_BUCK2);
/* vddddr */
STPMU1_Regulator_Voltage_Set(STPMU1_BUCK2, 1350);
STPMU1_Regulator_Enable(STPMU1_BUCK2);
/* vdd */
STPMU1_Regulator_Voltage_Set(STPMU1_BUCK3, 3300);
STPMU1_Regulator_Enable(STPMU1_BUCK3);
/* vdd */
STPMU1_Regulator_Voltage_Set(STPMU1_BUCK3, 3300);
STPMU1_Regulator_Enable(STPMU1_BUCK3);
/* 3v3 */
STPMU1_Regulator_Voltage_Set(STPMU1_BUCK4, 3300);
STPMU1_Regulator_Enable(STPMU1_BUCK4);
/* 3v3 */
STPMU1_Regulator_Voltage_Set(STPMU1_BUCK4, 3300);
STPMU1_Regulator_Enable(STPMU1_BUCK4);
/* vdda */
STPMU1_Regulator_Voltage_Set(STPMU1_LDO1, 2900);
STPMU1_Regulator_Enable(STPMU1_LDO1);
/* vdda */
STPMU1_Regulator_Voltage_Set(STPMU1_LDO1, 2900);
STPMU1_Regulator_Enable(STPMU1_LDO1);
/* 2v8 */
STPMU1_Regulator_Voltage_Set(STPMU1_LDO2, 2800);
STPMU1_Regulator_Enable(STPMU1_LDO2);
/* 2v8 */
STPMU1_Regulator_Voltage_Set(STPMU1_LDO2, 2800);
STPMU1_Regulator_Enable(STPMU1_LDO2);
/* vtt_ddr lod3 mode buck2/2 */
STPMU1_Regulator_Voltage_Set(STPMU1_LDO3, 0xFFFF);
STPMU1_Regulator_Enable(STPMU1_LDO3);
/* vtt_ddr lod3 mode buck2/2 */
STPMU1_Regulator_Voltage_Set(STPMU1_LDO3, 0xFFFF);
STPMU1_Regulator_Enable(STPMU1_LDO3);
/* vdd_usb */
STPMU1_Regulator_Voltage_Set(STPMU1_LDO4, 3300);
STPMU1_Regulator_Enable(STPMU1_LDO4);
/* vdd_usb */
STPMU1_Regulator_Voltage_Set(STPMU1_LDO4, 3300);
STPMU1_Regulator_Enable(STPMU1_LDO4);
/* vdd_sd */
STPMU1_Regulator_Voltage_Set(STPMU1_LDO5, 2900);
STPMU1_Regulator_Enable(STPMU1_LDO5);
/* vdd_sd */
STPMU1_Regulator_Voltage_Set(STPMU1_LDO5, 2900);
STPMU1_Regulator_Enable(STPMU1_LDO5);
/* 1v8 */
STPMU1_Regulator_Voltage_Set(STPMU1_LDO6, 1800);
STPMU1_Regulator_Enable(STPMU1_LDO6);
/* 1v8 */
STPMU1_Regulator_Voltage_Set(STPMU1_LDO6, 1800);
STPMU1_Regulator_Enable(STPMU1_LDO6);
STPMU1_Regulator_Enable(STPMU1_VREFDDR);
STPMU1_Regulator_Enable(STPMU1_VREFDDR);
return RT_EOK;
}
......
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-07-27 thread-liu first version
*/
#include "board.h"
//#define DRV_DEBUG
#define LOG_TAG "drv.pwr"
#include <drv_log.h>
extern int lptim_start(void);
extern int lptim_stop(void);
static RCC_ClkInitTypeDef RCC_ClkInit = {0};
#define __WAIT_EVENT_TIMEOUT(__CONDITION__, __TIMEOUT_VAL__) \
do { \
__IO uint32_t count = __TIMEOUT_VAL__ * (SystemCoreClock / 20U / 1000U); \
do \
{ \
if (count-- == 0U) \
{ \
return HAL_TIMEOUT; \
} \
} \
while (__CONDITION__ == 0U); \
} while(0)
/* Back up clock tree */
static void backup_cm4_clocks(void)
{
rt_uint32_t *pFLatency = NULL;
/* Back up MCU clock configuration */
HAL_RCC_GetClockConfig(&RCC_ClkInit, pFLatency);
}
/* Restore the CM4 clock source muxer and the CM4 prescaler. */
rt_err_t restore_cm4_clock(void)
{
/* Update SystemCoreClock variable */
SystemCoreClock = HAL_RCC_GetSystemCoreClockFreq();
/* Enable PLL3 if needed */
if (RCC_ClkInit.MCUInit.MCU_Clock == RCC_MCUSSOURCE_PLL3)
{
/* Enable PLL3 */
__HAL_RCC_PLL3_ENABLE();
/* Wait till PLL3 is ready */
__WAIT_EVENT_TIMEOUT(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL3RDY), CLOCKSWITCH_TIMEOUT_VALUE);
/* Enable PLL3 outputs */
__HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL3_DIVP | RCC_PLL3_DIVQ | RCC_PLL3_DIVR);
}
/* Configure MCU clock only */
__HAL_RCC_MCU_SOURCE(RCC_ClkInit.MCUInit.MCU_Clock);
/* Wait till MCU is ready */
__WAIT_EVENT_TIMEOUT(__HAL_RCC_GET_FLAG(RCC_FLAG_MCUSSRCRDY),
CLOCKSWITCH_TIMEOUT_VALUE);
/* Update SystemCoreClock variable */
SystemCoreClock = HAL_RCC_GetSystemCoreClockFreq();
/* Reconfigure Systick */
if (HAL_InitTick(uwTickPrio) != HAL_OK)
{
return RT_ERROR;
}
/* Set MCU division factor */
__HAL_RCC_MCU_DIV(RCC_ClkInit.MCUInit.MCU_Div);
/* Wait till MCUDIV is ready */
__WAIT_EVENT_TIMEOUT(__HAL_RCC_GET_FLAG(RCC_FLAG_MCUDIVRDY),
CLOCKSWITCH_TIMEOUT_VALUE);
/* Update SystemCoreClock variable */
SystemCoreClock = HAL_RCC_GetSystemCoreClockFreq();
/* Reconfigure Systick */
if (HAL_InitTick(uwTickPrio) != HAL_OK)
{
return RT_ERROR;
}
return RT_EOK;
}
void RCC_WAKEUP_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_RCC_WAKEUP_IRQHandler();
/* leave interrupt */
rt_interrupt_leave();
}
void HAL_RCC_WAKEUP_Callback()
{
if (__HAL_PWR_GET_FLAG(PWR_FLAG_STOP) == 1U)
{
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_STOP);
}
restore_cm4_clock();
/* All level of ITs can interrupt */
__set_BASEPRI(0U);
rt_kprintf("system exit stop mode success!\n");
}
static void enter_sleep_mode(void)
{
__set_BASEPRI((1) << (8 - __NVIC_PRIO_BITS));
lptim_start();
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
}
static void enter_stop_mode(void)
{
/*
* Only the IT with the highest priority (0 value) can interrupt.
* RCC_WAKEUP_IRQn IT is intended to have the highest priority and to be the
* only one IT having this value
* RCC_WAKEUP_IRQn is generated only when RCC is completely resumed from
* CSTOP (protection mechanism)
*/
__set_BASEPRI((1) << (8 - __NVIC_PRIO_BITS));
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_STOP);
backup_cm4_clocks();
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}
static void pm_wackup_key_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_NVIC_SetPriority(EXTI13_IRQn, 0x01, 0);
HAL_NVIC_EnableIRQ(EXTI13_IRQn);
}
int drv_pm_hw_init(void)
{
pm_wackup_key_init();
return RT_EOK;
}
INIT_BOARD_EXPORT(drv_pm_hw_init);
static int pwr_sample(int argc, char *argv[])
{
if (argc > 1)
{
if (!rt_strcmp(argv[1], "stop"))
{
rt_kprintf("system will enter stop mode! you can press USER2 button to exit this mode\n");
enter_stop_mode();
return RT_EOK;
}
else if (!rt_strcmp(argv[1], "sleep"))
{
rt_kprintf("system will enter sleep mode! lptim1 will wake up the system\n");
enter_sleep_mode();
return RT_EOK;
}
else
{
goto _exit;
}
}
_exit:
{
rt_kprintf("Usage:\n");
rt_kprintf("pwr_sample stop - system enter stop mode\n");
rt_kprintf("pwr_sample sleep - system enter sleep mode\n");
}
return -RT_ERROR;
}
MSH_CMD_EXPORT(pwr_sample, enter low power mode sample);
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-07-07 thread-liu first version
*/
#include <board.h>
#include <drv_qspi.h>
#include <rtdevice.h>
#include <rthw.h>
#include <finsh.h>
#ifdef BSP_USING_QSPI_FLASH
#include "spi_flash.h"
#include "spi_flash_sfud.h"
/**
* @brief QSPI MSP Initialization
* This function configures the hardware resources used in this example
* @param hqspi: QSPI handle pointer
* @retval None
*/
void HAL_QSPI_MspInit(QSPI_HandleTypeDef* hqspi)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
if(hqspi->Instance==QUADSPI)
{
/* USER CODE BEGIN QUADSPI_MspInit 0 */
if (IS_ENGINEERING_BOOT_MODE())
{
PeriphClkInit.Sdmmc12ClockSelection = RCC_QSPICLKSOURCE_ACLK;
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_QSPI;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE END QUADSPI_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_QSPI_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**QUADSPI GPIO Configuration
PF6 ------> QUADSPI_BK1_IO3
PF7 ------> QUADSPI_BK1_IO2
PF8 ------> QUADSPI_BK1_IO0
PF9 ------> QUADSPI_BK1_IO1
PF10 ------> QUADSPI_CLK
PB6 ------> QUADSPI_BK1_NCS
*/
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7 | GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
/**QUADSPI GPIO Configuration
PC0 ------> QUADSPI_BK2_NCS
PH3 ------> QUADSPI_BK2_IO1
PG7 ------> QUADSPI_BK2_IO3
PG10 ------> QUADSPI_BK2_IO2
PH2 ------> QUADSPI_BK2_IO0
*/
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Alternate = GPIO_AF11_QUADSPI;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
/* USER CODE BEGIN QUADSPI_MspInit 1 */
/* USER CODE END QUADSPI_MspInit 1 */
}
}
/**
* @brief QSPI MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hqspi: QSPI handle pointer
* @retval None
*/
void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef* hqspi)
{
if(hqspi->Instance==QUADSPI)
{
/* USER CODE BEGIN QUADSPI_MspDeInit 0 */
/* USER CODE END QUADSPI_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_QSPI_CLK_DISABLE();
/**QUADSPI GPIO Configuration
PC0 ------> QUADSPI_BK2_NCS
PF10 ------> QUADSPI_CLK
PB6 ------> QUADSPI_BK1_NCS
PH3 ------> QUADSPI_BK2_IO1
PG7 ------> QUADSPI_BK2_IO3
PG10 ------> QUADSPI_BK2_IO2
PF7 ------> QUADSPI_BK1_IO2
PF6 ------> QUADSPI_BK1_IO3
PH2 ------> QUADSPI_BK2_IO0
PF8 ------> QUADSPI_BK1_IO0
PF9 ------> QUADSPI_BK1_IO1
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0);
HAL_GPIO_DeInit(GPIOF, GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6);
HAL_GPIO_DeInit(GPIOH, GPIO_PIN_3|GPIO_PIN_2);
HAL_GPIO_DeInit(GPIOG, GPIO_PIN_7|GPIO_PIN_10);
/* USER CODE BEGIN QUADSPI_MspDeInit 1 */
/* USER CODE END QUADSPI_MspDeInit 1 */
}
}
static int rt_hw_qspi_flash_with_sfud_init(void)
{
stm32_qspi_bus_attach_device("qspi1", "qspi10", RT_NULL, 4, RT_NULL, RT_NULL);
/* init MX25L51245G */
if (RT_NULL == rt_sfud_flash_probe("MX25L51245G", "qspi10"))
{
return -RT_ERROR;
}
return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_qspi_flash_with_sfud_init);
#endif /* BSP_USING_QSPI_FLASH */
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-10-24 thread-liu first version
*/
#include <board.h>
#include "drv_rs485.h"
#ifdef BSP_USING_RS485
#define RS485_OUT rt_pin_write(BSP_RS485_RTS_PIN, PIN_HIGH)
#define RS485_IN rt_pin_write(BSP_RS485_RTS_PIN, PIN_LOW)
static rt_device_t serial = {0};
static struct rt_semaphore rx_sem = {0};
/* uart send data callback function */
static rt_err_t rs485_output(rt_device_t dev, void * buffer)
{
return RT_EOK;
}
/* uart receive data callback function */
static rt_err_t rs485_input(rt_device_t dev, rt_size_t size)
{
rt_sem_release(&rx_sem);
return RT_EOK;
}
/* send string */
int rs485_send_data(char *tbuf, rt_uint16_t t_len)
{
/* change rs485 mode */
RS485_OUT;
/* send data */
rt_device_write(serial, 0, tbuf, t_len);
/* change rs485 mode */
RS485_IN;
return RT_EOK;
}
static void rs485_thread_entry(void *parameter)
{
char ch;
while (1)
{
/* A byte of data is read from a serial port, and if it is not read, it waits for the received semaphore */
while (rt_device_read(serial, -1, &ch, 1) != 1)
{
rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
}
/* The data read through the serial port output dislocation */
ch = ch + 1;
/* send char */
rs485_send_data(&ch, 1);
}
}
/* rs485 rts pin init */
static int rs485_init(void)
{
/* find uart device */
serial = rt_device_find(RS485_UART_DEVICE_NAME);
if (!serial)
{
rt_kprintf("find %s failed!\n", RS485_UART_DEVICE_NAME);
return RT_ERROR;
}
rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);
/* set receive data callback function */
rt_device_set_rx_indicate(serial, rs485_input);
/* set the send completion callback function */
rt_device_set_tx_complete(serial, rs485_output);
rt_pin_mode(BSP_RS485_RTS_PIN, PIN_MODE_OUTPUT);
RS485_IN;
rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
/* create rs485 thread */
rt_thread_t thread = rt_thread_create("rs485", rs485_thread_entry, RT_NULL, 1024, 25, 10);
if (thread != RT_NULL)
{
rt_thread_startup(thread);
}
else
{
return RT_ERROR;
}
return RT_EOK;
}
INIT_DEVICE_EXPORT(rs485_init);
#endif /* bsp_using_RS485 */
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-10-24 thread-liu first version
*/
#ifndef __DRV_RS485_H__
#define __DRV_RS485_H__
#ifdef __cplusplus
extern "C" {
#endif
#define RS485_SEND_MODE 0
#define RS485_RECV_MODE 1
#ifdef __cplusplus
}
#endif
#endif /* drv_rs485.h */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -23,7 +23,7 @@ elif CROSS_TOOL == 'keil':
EXEC_PATH = r'C:/Keil_v5'
elif CROSS_TOOL == 'iar':
PLATFORM = 'iar'
EXEC_PATH = r'C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.0'
EXEC_PATH = r'D:\software\Embedded Workbench 8.3'
if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH')
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册