mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-09-21 18:57:16 +08:00
Synwit MCU 采用新的 BSP 框架,将 BSP 与 libraries 分离 (#8432)
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = []
|
||||
|
||||
if GetDepend(['RT_USING_SERIAL']):
|
||||
src += ['drv_uart.c']
|
||||
|
||||
if GetDepend(['RT_USING_PIN']):
|
||||
src += ['drv_gpio.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_HWTIMER']):
|
||||
src += ['drv_hwtimer.c']
|
||||
|
||||
if GetDepend(['RT_USING_I2C']):
|
||||
src += ['drv_soft_i2c.c']
|
||||
|
||||
if GetDepend(['RT_USING_PWM']):
|
||||
src += ['drv_pwm.c']
|
||||
|
||||
if GetDepend(['RT_USING_RTC']):
|
||||
src += ['drv_rtc.c']
|
||||
|
||||
if GetDepend(['RT_USING_SPI']):
|
||||
src += ['drv_spi.c']
|
||||
|
||||
if GetDepend(['RT_USING_WDT']):
|
||||
src += ['drv_wdt.c']
|
||||
|
||||
if GetDepend(['RT_USING_HWCRYPTO']):
|
||||
src += ['drv_crypto.c']
|
||||
|
||||
if GetDepend(['RT_USING_SDIO']):
|
||||
src += ['drv_sdio.c']
|
||||
|
||||
if GetDepend(['BSP_USING_SDRAM']):
|
||||
src += ['drv_sdram.c']
|
||||
|
||||
if GetDepend(['BSP_USING_RGB_LCD']):
|
||||
src += ['drv_rgb_lcd.c']
|
||||
|
||||
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = [cwd])
|
||||
|
||||
Return('group')
|
||||
@@ -0,0 +1,326 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#include "drv_adc.h"
|
||||
|
||||
#ifdef RT_USING_ADC
|
||||
#ifdef BSP_USING_ADC
|
||||
|
||||
//#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.adc"
|
||||
#include <drv_log.h>
|
||||
|
||||
#if !defined(BSP_USING_ADC0) && !defined(BSP_USING_ADC1)
|
||||
#error "Please define at least one BSP_USING_ADCx"
|
||||
/* this driver can be disabled at menuconfig ? RT-Thread Components ? Device Drivers */
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_ADC0
|
||||
#ifndef ADC0_CFG
|
||||
#define ADC0_CFG \
|
||||
{ \
|
||||
.name = "adc0", \
|
||||
.ADCx = ADC0, \
|
||||
.ADC_initstruct.clk_src = ADC_CLKSRC_HRC_DIV8, \
|
||||
.ADC_initstruct.samplAvg = ADC_AVG_SAMPLE1, \
|
||||
.ADC_initstruct.EOC_IEn = 0, \
|
||||
.ADC_initstruct.HalfIEn = 0, \
|
||||
.ADC_SEQ_initstruct.trig_src = ADC_TRIGGER_SW, \
|
||||
.ADC_SEQ_initstruct.conv_cnt = 1, \
|
||||
.ADC_SEQ_initstruct.samp_tim = ADC_SAMPLE_1CLOCK, \
|
||||
}
|
||||
#endif /* ADC0_CFG */
|
||||
#endif /* BSP_USING_ADC0 */
|
||||
|
||||
#ifdef BSP_USING_ADC1
|
||||
#ifndef ADC1_CFG
|
||||
#define ADC1_CFG \
|
||||
{ \
|
||||
.name = "adc1", \
|
||||
.ADCx = ADC1, \
|
||||
.ADC_initstruct.clk_src = ADC_CLKSRC_HRC_DIV8, \
|
||||
.ADC_initstruct.samplAvg = ADC_AVG_SAMPLE1, \
|
||||
.ADC_initstruct.EOC_IEn = 0, \
|
||||
.ADC_initstruct.HalfIEn = 0, \
|
||||
.ADC_SEQ_initstruct.trig_src = ADC_TRIGGER_SW, \
|
||||
.ADC_SEQ_initstruct.conv_cnt = 1, \
|
||||
.ADC_SEQ_initstruct.samp_tim = ADC_SAMPLE_1CLOCK, \
|
||||
}
|
||||
#endif /* ADC1_CFG */
|
||||
#endif /* BSP_USING_ADC1 */
|
||||
|
||||
struct swm_adc_cfg
|
||||
{
|
||||
const char *name;
|
||||
ADC_TypeDef *ADCx;
|
||||
ADC_InitStructure ADC_initstruct;
|
||||
ADC_SEQ_InitStructure ADC_SEQ_initstruct;
|
||||
};
|
||||
|
||||
struct swm_adc_device
|
||||
{
|
||||
struct swm_adc_cfg *adc_cfg;
|
||||
struct rt_adc_device adc_device;
|
||||
};
|
||||
|
||||
static struct swm_adc_cfg swm_adc_cfg[] =
|
||||
{
|
||||
#ifdef BSP_USING_ADC0
|
||||
ADC0_CFG,
|
||||
#endif
|
||||
#ifdef BSP_USING_ADC1
|
||||
ADC1_CFG,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct swm_adc_device adc_obj[sizeof(swm_adc_cfg) / sizeof(swm_adc_cfg[0])];
|
||||
|
||||
static rt_uint32_t swm_adc_get_channel(rt_uint32_t channel)
|
||||
{
|
||||
rt_uint32_t swm_channel = 0;
|
||||
|
||||
switch (channel)
|
||||
{
|
||||
case 0:
|
||||
swm_channel = ADC_CH0;
|
||||
break;
|
||||
case 1:
|
||||
swm_channel = ADC_CH1;
|
||||
break;
|
||||
case 2:
|
||||
swm_channel = ADC_CH2;
|
||||
break;
|
||||
case 3:
|
||||
swm_channel = ADC_CH3;
|
||||
break;
|
||||
case 4:
|
||||
swm_channel = ADC_CH4;
|
||||
break;
|
||||
case 5:
|
||||
swm_channel = ADC_CH5;
|
||||
break;
|
||||
case 6:
|
||||
swm_channel = ADC_CH6;
|
||||
break;
|
||||
case 7:
|
||||
swm_channel = ADC_CH7;
|
||||
break;
|
||||
case 8:
|
||||
swm_channel = ADC_CH8;
|
||||
break;
|
||||
case 9:
|
||||
swm_channel = ADC_CH9;
|
||||
break;
|
||||
case 10:
|
||||
swm_channel = ADC_CH10;
|
||||
break;
|
||||
case 11:
|
||||
swm_channel = ADC_CH11;
|
||||
break;
|
||||
}
|
||||
|
||||
return swm_channel;
|
||||
}
|
||||
|
||||
static rt_err_t swm_adc_enabled(struct rt_adc_device *adc_device, rt_uint32_t channel, rt_bool_t enabled)
|
||||
{
|
||||
uint32_t adc_chn;
|
||||
struct swm_adc_cfg *adc_cfg;
|
||||
RT_ASSERT(adc_device != RT_NULL);
|
||||
adc_cfg = adc_device->parent.user_data;
|
||||
|
||||
if (channel < 12)
|
||||
{
|
||||
/* set swm ADC channel */
|
||||
adc_chn = swm_adc_get_channel(channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("ADC channel must be between 0 and 11.");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
adc_cfg->ADCx->SEQCHN0 |= adc_chn;
|
||||
}
|
||||
else
|
||||
{
|
||||
adc_cfg->ADCx->SEQCHN0 &= ~adc_chn;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t swm_adc_convert(struct rt_adc_device *adc_device, rt_uint32_t channel, rt_uint32_t *value)
|
||||
{
|
||||
uint32_t chn, val, adc_chn;
|
||||
struct swm_adc_cfg *adc_cfg;
|
||||
RT_ASSERT(adc_device != RT_NULL);
|
||||
RT_ASSERT(value != RT_NULL);
|
||||
adc_cfg = adc_device->parent.user_data;
|
||||
|
||||
if (channel < 12)
|
||||
{
|
||||
/* set swm ADC channel */
|
||||
adc_chn = swm_adc_get_channel(channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("ADC channel must be between 0 and 11.");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
*value = 0xFFFFFFFF;
|
||||
|
||||
/* start ADC */
|
||||
ADC_Start(adc_cfg->ADCx, ADC_SEQ0);
|
||||
|
||||
/* Wait for the ADC to convert */
|
||||
while (adc_cfg->ADCx->GO & ADC_GO_BUSY_Msk)
|
||||
__NOP();
|
||||
while ((adc_cfg->ADCx->SEQ[0].SR & ADC_SR_EMPTY_Msk) == 0)
|
||||
{
|
||||
val = ADC_Read(adc_cfg->ADCx, ADC_SEQ0, &chn);
|
||||
if (chn == adc_chn)
|
||||
{
|
||||
*value = val;
|
||||
}
|
||||
}
|
||||
|
||||
if (*value == 0xFFFFFFFF)
|
||||
{
|
||||
LOG_E("ADC channel can not find.");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static const struct rt_adc_ops swm_adc_ops =
|
||||
{
|
||||
.enabled = swm_adc_enabled,
|
||||
.convert = swm_adc_convert,
|
||||
};
|
||||
|
||||
int swm_adc_init(void)
|
||||
{
|
||||
int i = 0;
|
||||
int result = RT_EOK;
|
||||
|
||||
for (i = 0; i < sizeof(swm_adc_cfg) / sizeof(swm_adc_cfg[0]); i++)
|
||||
{
|
||||
/* ADC init */
|
||||
adc_obj[i].adc_cfg = &swm_adc_cfg[i];
|
||||
|
||||
if (adc_obj[i].adc_cfg->ADCx == ADC0)
|
||||
{
|
||||
#ifdef BSP_USING_ADC0_CHN0
|
||||
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH0;
|
||||
PORT_Init(PORTC, PIN6, PORTC_PIN6_ADC0_CH0, 0); //PC.6 => ADC.CH0
|
||||
#endif
|
||||
#ifdef BSP_USING_ADC0_CHN1
|
||||
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH1;
|
||||
PORT_Init(PORTC, PIN5, PORTC_PIN5_ADC0_CH1, 0); //PC.5 => ADC.CH1
|
||||
#endif
|
||||
#ifdef BSP_USING_ADC0_CHN2
|
||||
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH2;
|
||||
PORT_Init(PORTC, PIN4, PORTC_PIN4_ADC0_CH2, 0); //PC.4 => ADC.CH2
|
||||
#endif
|
||||
#ifdef BSP_USING_ADC0_CHN3
|
||||
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH3;
|
||||
PORT_Init(PORTC, PIN3, PORTC_PIN3_ADC0_CH3, 0); //PC.3 => ADC.CH3
|
||||
#endif
|
||||
#ifdef BSP_USING_ADC0_CHN4
|
||||
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH4;
|
||||
PORT_Init(PORTC, PIN2, PORTC_PIN2_ADC0_CH4, 0); //PC.2 => ADC.CH4
|
||||
#endif
|
||||
#ifdef BSP_USING_ADC0_CHN5
|
||||
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH5;
|
||||
PORT_Init(PORTC, PIN1, PORTC_PIN1_ADC0_CH5, 0); //PC.1 => ADC.CH5
|
||||
#endif
|
||||
#ifdef BSP_USING_ADC0_CHN6
|
||||
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH6;
|
||||
PORT_Init(PORTC, PIN0, PORTC_PIN0_ADC0_CH6, 0); //PC.0 => ADC.CH6
|
||||
#endif
|
||||
#ifdef BSP_USING_ADC0_CHN7
|
||||
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH7;
|
||||
PORT_Init(PORTA, PIN15, PORTA_PIN15_ADC0_CH7, 0); //PA.15 => ADC.CH7
|
||||
#endif
|
||||
#ifdef BSP_USING_ADC0_CHN8
|
||||
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH8;
|
||||
PORT_Init(PORTA, PIN14, PORTA_PIN14_ADC0_CH8, 0); //PA.14 => ADC.CH8
|
||||
#endif
|
||||
#ifdef BSP_USING_ADC0_CHN9
|
||||
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH9;
|
||||
PORT_Init(PORTA, PIN13, PORTA_PIN13_ADC0_CH9, 0); //PA.13 => ADC.CH9
|
||||
#endif
|
||||
#ifdef BSP_USING_ADC0_CHN10
|
||||
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH10;
|
||||
PORT_Init(PORTA, PIN12, PORTA_PIN12_ADC0_CH10, 0); //PA.12 => ADC.CH10
|
||||
#endif
|
||||
#ifdef BSP_USING_ADC0_CHN11
|
||||
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH11;
|
||||
PORT_Init(PORTA, PIN10, PORTA_PIN10_ADC0_CH11, 0); //PA.10 => ADC.CH11
|
||||
#endif
|
||||
}
|
||||
else if (adc_obj[i].adc_cfg->ADCx == ADC1)
|
||||
{
|
||||
#ifdef BSP_USING_ADC1_CHN0
|
||||
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH0;
|
||||
PORT_Init(PORTD, PIN1, PORTD_PIN1_ADC1_CH0, 0); //PD.1 => ADC1.CH0
|
||||
#endif
|
||||
#ifdef BSP_USING_ADC1_CHN1
|
||||
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH1;
|
||||
PORT_Init(PORTD, PIN0, PORTD_PIN0_ADC1_CH1, 0); //PD.0 => ADC1.CH1
|
||||
#endif
|
||||
#ifdef BSP_USING_ADC1_CHN2
|
||||
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH2;
|
||||
PORT_Init(PORTC, PIN13, PORTC_PIN13_ADC1_CH2, 0); //PC.13 => ADC1.CH2
|
||||
#endif
|
||||
#ifdef BSP_USING_ADC1_CHN3
|
||||
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH3;
|
||||
PORT_Init(PORTC, PIN12, PORTC_PIN12_ADC1_CH3, 0); //PC.12 => ADC1.CH3
|
||||
#endif
|
||||
#ifdef BSP_USING_ADC1_CHN4
|
||||
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH4;
|
||||
PORT_Init(PORTC, PIN11, PORTC_PIN11_ADC1_CH4, 0); //PC.11 => ADC1.CH4
|
||||
#endif
|
||||
#ifdef BSP_USING_ADC1_CHN5
|
||||
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH5;
|
||||
PORT_Init(PORTC, PIN10, PORTC_PIN10_ADC1_CH5, 0); //PC.10 => ADC1.CH5
|
||||
#endif
|
||||
#ifdef BSP_USING_ADC1_CHN6
|
||||
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH6;
|
||||
PORT_Init(PORTC, PIN9, PORTC_PIN9_ADC1_CH6, 0); //PC.9 => ADC1.CH6
|
||||
#endif
|
||||
}
|
||||
|
||||
ADC_Init(adc_obj[i].adc_cfg->ADCx, &(adc_obj[i].adc_cfg->ADC_initstruct));
|
||||
ADC_SEQ_Init(adc_obj[i].adc_cfg->ADCx, ADC_SEQ0, &(adc_obj[i].adc_cfg->ADC_SEQ_initstruct));
|
||||
ADC_Open(adc_obj[i].adc_cfg->ADCx);
|
||||
ADC_Calibrate(adc_obj[i].adc_cfg->ADCx);
|
||||
|
||||
result = rt_hw_adc_register(&adc_obj[i].adc_device, adc_obj[i].adc_cfg->name, &swm_adc_ops, adc_obj[i].adc_cfg);
|
||||
if(result != RT_EOK)
|
||||
{
|
||||
LOG_E("%s register fail.", adc_obj[i].adc_cfg->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D("%s register success.", adc_obj[i].adc_cfg->name);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
INIT_BOARD_EXPORT(swm_adc_init);
|
||||
#endif /* BSP_USING_ADC */
|
||||
#endif /* RT_USING_ADC */
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_ADC_H__
|
||||
#define __DRV_ADC_H__
|
||||
|
||||
#include "board.h"
|
||||
|
||||
int swm_adc_init(void);
|
||||
|
||||
#endif /* __DRV_ADC_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-02-16 lik first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_CAN_H__
|
||||
#define __DRV_CAN_H__
|
||||
|
||||
#include "board.h"
|
||||
|
||||
int swm_can_init(void);
|
||||
|
||||
#endif /* __DRV_CAN_H__ */
|
||||
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#include "drv_crypto.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef RT_USING_HWCRYPTO
|
||||
|
||||
//#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.crypto"
|
||||
#include <drv_log.h>
|
||||
|
||||
struct swm_hwcrypto_device
|
||||
{
|
||||
struct rt_hwcrypto_device dev;
|
||||
struct rt_mutex mutex;
|
||||
};
|
||||
|
||||
static struct swm_hwcrypto_device hwcrypto_obj;
|
||||
|
||||
#ifdef BSP_USING_CRC
|
||||
|
||||
struct swm_crc_cfg
|
||||
{
|
||||
CRC_TypeDef *CRCx;
|
||||
CRC_InitStructure CRC_initstruct;
|
||||
};
|
||||
|
||||
static struct hwcrypto_crc_cfg swm_crc_cfg;
|
||||
|
||||
static rt_uint32_t swm_crc_update(struct hwcrypto_crc *ctx, const rt_uint8_t *in, rt_size_t length)
|
||||
{
|
||||
rt_uint32_t result = 0;
|
||||
struct swm_hwcrypto_device *hwcrypto_dev = (struct swm_hwcrypto_device *)ctx->parent.device->user_data;
|
||||
|
||||
struct swm_crc_cfg *crc_cfg = (struct swm_crc_cfg *)(ctx->parent.contex);
|
||||
|
||||
rt_mutex_take(&hwcrypto_dev->mutex, RT_WAITING_FOREVER);
|
||||
|
||||
if (memcmp(&swm_crc_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg)) != 0)
|
||||
{
|
||||
crc_cfg->CRCx = CRC;
|
||||
|
||||
crc_cfg->CRC_initstruct.init_crc = ctx->crc_cfg.last_val;
|
||||
|
||||
switch (ctx->crc_cfg.poly)
|
||||
{
|
||||
case 0x07:
|
||||
crc_cfg->CRC_initstruct.Poly = CRC_POLY_107;
|
||||
break;
|
||||
case 0x1021:
|
||||
crc_cfg->CRC_initstruct.Poly = CRC_POLY_11021;
|
||||
break;
|
||||
case 0x8005:
|
||||
crc_cfg->CRC_initstruct.Poly = CRC_POLY_18005;
|
||||
break;
|
||||
case 0x04C11DB7:
|
||||
crc_cfg->CRC_initstruct.Poly = CRC_POLY_104C11DB7;
|
||||
break;
|
||||
default:
|
||||
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
switch (ctx->crc_cfg.width)
|
||||
{
|
||||
case 8:
|
||||
crc_cfg->CRC_initstruct.in_width = CRC_WIDTH_8;
|
||||
break;
|
||||
case 16:
|
||||
crc_cfg->CRC_initstruct.in_width = CRC_WIDTH_16;
|
||||
break;
|
||||
case 32:
|
||||
crc_cfg->CRC_initstruct.in_width = CRC_WIDTH_32;
|
||||
break;
|
||||
default:
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
switch (ctx->crc_cfg.flags)
|
||||
{
|
||||
case 0:
|
||||
crc_cfg->CRC_initstruct.in_not = false;
|
||||
crc_cfg->CRC_initstruct.out_not = false;
|
||||
break;
|
||||
case CRC_FLAG_REFIN:
|
||||
crc_cfg->CRC_initstruct.in_not = true;
|
||||
crc_cfg->CRC_initstruct.out_not = false;
|
||||
break;
|
||||
case CRC_FLAG_REFOUT:
|
||||
crc_cfg->CRC_initstruct.in_not = false;
|
||||
crc_cfg->CRC_initstruct.out_not = true;
|
||||
break;
|
||||
case CRC_FLAG_REFIN | CRC_FLAG_REFOUT:
|
||||
crc_cfg->CRC_initstruct.in_not = true;
|
||||
crc_cfg->CRC_initstruct.out_not = true;
|
||||
break;
|
||||
default:
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
crc_cfg->CRC_initstruct.in_rev = CRC_REV_NOT;
|
||||
crc_cfg->CRC_initstruct.out_rev = CRC_REV_NOT;
|
||||
CRC_Init(crc_cfg->CRCx, &(crc_cfg->CRC_initstruct));
|
||||
memcpy(&swm_crc_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg));
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < length; i++)
|
||||
CRC_Write((uint32_t)in[i]);
|
||||
result = CRC_Result();
|
||||
|
||||
ctx->crc_cfg.last_val = result;
|
||||
|
||||
swm_crc_cfg.last_val = ctx->crc_cfg.last_val;
|
||||
result = (result ? result ^ (ctx->crc_cfg.xorout) : result);
|
||||
|
||||
_exit:
|
||||
rt_mutex_release(&hwcrypto_dev->mutex);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static const struct hwcrypto_crc_ops swm_crc_ops =
|
||||
{
|
||||
.update = swm_crc_update,
|
||||
};
|
||||
#endif /* BSP_USING_CRC */
|
||||
|
||||
#if defined(BSP_USING_RNG)
|
||||
|
||||
struct swm_rng_cfg
|
||||
{
|
||||
SYS_TypeDef *SYSx;
|
||||
};
|
||||
|
||||
static rt_uint32_t swm_rng_update(struct hwcrypto_rng *ctx)
|
||||
{
|
||||
rt_uint32_t gen_randoml = 0, gen_randomh = 0;
|
||||
|
||||
struct swm_rng_cfg *rng_cfg = (struct swm_rng_cfg *)(ctx->parent.contex);
|
||||
|
||||
while ((rng_cfg->SYSx->PRNGCR & SYS_PRNGCR_RDY_Msk) == 0)
|
||||
__NOP();
|
||||
gen_randoml = rng_cfg->SYSx->PRNGDL;
|
||||
gen_randomh = rng_cfg->SYSx->PRNGDH;
|
||||
return gen_randoml;
|
||||
}
|
||||
|
||||
static const struct hwcrypto_rng_ops swm_rng_ops =
|
||||
{
|
||||
.update = swm_rng_update,
|
||||
};
|
||||
#endif /* BSP_USING_RNG */
|
||||
|
||||
static rt_err_t swm_crypto_create(struct rt_hwcrypto_ctx *ctx)
|
||||
{
|
||||
rt_err_t res = RT_EOK;
|
||||
|
||||
switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
|
||||
{
|
||||
#if defined(BSP_USING_CRC)
|
||||
case HWCRYPTO_TYPE_CRC:
|
||||
{
|
||||
struct swm_crc_cfg *crc_cfg = rt_calloc(1, sizeof(struct swm_crc_cfg));
|
||||
if (RT_NULL == crc_cfg)
|
||||
{
|
||||
res = -RT_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
ctx->contex = crc_cfg;
|
||||
((struct hwcrypto_crc *)ctx)->ops = &swm_crc_ops;
|
||||
break;
|
||||
}
|
||||
#endif /* BSP_USING_CRC */
|
||||
|
||||
#if defined(BSP_USING_RNG)
|
||||
case HWCRYPTO_TYPE_RNG:
|
||||
{
|
||||
struct swm_rng_cfg *rng_cfg = rt_calloc(1, sizeof(struct swm_rng_cfg));
|
||||
if (RT_NULL == rng_cfg)
|
||||
{
|
||||
res = -RT_ERROR;
|
||||
break;
|
||||
}
|
||||
rng_cfg->SYSx = SYS;
|
||||
rng_cfg->SYSx->HRCCR |= (1 << SYS_HRCCR_ON_Pos);
|
||||
rng_cfg->SYSx->LRCCR |= (1 << SYS_LRCCR_ON_Pos);
|
||||
rng_cfg->SYSx->PRNGCR = (0 << SYS_PRNGCR_CLR_Pos) |
|
||||
(3 << SYS_PRNGCR_MODE_Pos);
|
||||
ctx->contex = rng_cfg;
|
||||
((struct hwcrypto_rng *)ctx)->ops = &swm_rng_ops;
|
||||
|
||||
break;
|
||||
}
|
||||
#endif /* BSP_USING_RNG */
|
||||
|
||||
default:
|
||||
res = -RT_ERROR;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static void swm_crypto_destroy(struct rt_hwcrypto_ctx *ctx)
|
||||
{
|
||||
struct swm_crc_cfg *crc_cfg = (struct swm_crc_cfg *)(ctx->contex);
|
||||
switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
|
||||
{
|
||||
#if defined(BSP_USING_CRC)
|
||||
case HWCRYPTO_TYPE_CRC:
|
||||
crc_cfg->CRCx->CR &= ~CRC_CR_EN_Msk;
|
||||
break;
|
||||
#endif /* BSP_USING_CRC */
|
||||
|
||||
#if defined(BSP_USING_RNG)
|
||||
case HWCRYPTO_TYPE_RNG:
|
||||
break;
|
||||
#endif /* BSP_USING_RNG */
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
rt_free(ctx->contex);
|
||||
}
|
||||
|
||||
static rt_err_t swm_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_CRC)
|
||||
case HWCRYPTO_TYPE_CRC:
|
||||
if (des->contex && src->contex)
|
||||
{
|
||||
rt_memcpy(des->contex, src->contex, sizeof(struct swm_crc_cfg));
|
||||
}
|
||||
break;
|
||||
#endif /* BSP_USING_CRC */
|
||||
|
||||
#if defined(BSP_USING_RNG)
|
||||
case HWCRYPTO_TYPE_RNG:
|
||||
if (des->contex && src->contex)
|
||||
{
|
||||
rt_memcpy(des->contex, src->contex, sizeof(struct swm_rng_cfg));
|
||||
}
|
||||
break;
|
||||
#endif /* BSP_USING_RNG */
|
||||
|
||||
default:
|
||||
res = -RT_ERROR;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static void swm_crypto_reset(struct rt_hwcrypto_ctx *ctx)
|
||||
{
|
||||
struct swm_crc_cfg *crc_cfg = (struct swm_crc_cfg *)(ctx->contex);
|
||||
switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
|
||||
{
|
||||
#if defined(BSP_USING_CRC)
|
||||
case HWCRYPTO_TYPE_CRC:
|
||||
crc_cfg->CRCx->CR &= ~CRC_CR_EN_Msk;
|
||||
break;
|
||||
#endif /* BSP_USING_CRC */
|
||||
|
||||
#if defined(BSP_USING_RNG)
|
||||
case HWCRYPTO_TYPE_RNG:
|
||||
break;
|
||||
#endif /* BSP_USING_RNG */
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct rt_hwcrypto_ops swm_hwcrypto_ops =
|
||||
{
|
||||
.create = swm_crypto_create,
|
||||
.destroy = swm_crypto_destroy,
|
||||
.copy = swm_crypto_clone,
|
||||
.reset = swm_crypto_reset,
|
||||
};
|
||||
|
||||
int swm_crypto_init(void)
|
||||
{
|
||||
rt_uint32_t cpuid[2] = {0};
|
||||
|
||||
hwcrypto_obj.dev.ops = &swm_hwcrypto_ops;
|
||||
|
||||
cpuid[0] = SCB->CPUID;
|
||||
hwcrypto_obj.dev.id = 0;
|
||||
rt_memcpy(&hwcrypto_obj.dev.id, cpuid, 8);
|
||||
|
||||
hwcrypto_obj.dev.user_data = &hwcrypto_obj;
|
||||
|
||||
if (rt_hwcrypto_register(&hwcrypto_obj.dev, RT_HWCRYPTO_DEFAULT_NAME) != RT_EOK)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
rt_mutex_init(&hwcrypto_obj.mutex, RT_HWCRYPTO_DEFAULT_NAME, RT_IPC_FLAG_FIFO);
|
||||
return 0;
|
||||
}
|
||||
INIT_BOARD_EXPORT(swm_crypto_init);
|
||||
|
||||
#endif /* RT_USING_HWCRYPTO */
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_CRYPTO_H__
|
||||
#define __DRV_CRYPTO_H__
|
||||
|
||||
#include "board.h"
|
||||
|
||||
int swm_crypto_init(void);
|
||||
|
||||
#endif /* __DRV_CRYPTO_H__ */
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-02-10 lik first version
|
||||
*/
|
||||
|
||||
#include "drv_dac.h"
|
||||
|
||||
#ifdef BSP_USING_DAC
|
||||
|
||||
//#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.dac"
|
||||
#include <drv_log.h>
|
||||
|
||||
static struct rt_dac_device swm_dac_device;
|
||||
|
||||
static rt_err_t swm_dac_enabled(struct rt_dac_device *device, rt_uint32_t channel)
|
||||
{
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
|
||||
if (channel != 0)
|
||||
{
|
||||
LOG_E("dac channel must be 0.");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
DAC_Open(DAC);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t swm_dac_disabled(struct rt_dac_device *device, rt_uint32_t channel)
|
||||
{
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
|
||||
if (channel != 0)
|
||||
{
|
||||
LOG_E("dac channel must be 0.");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
DAC_Close(DAC);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t swm_dac_convert(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value)
|
||||
{
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
RT_ASSERT(value != RT_NULL);
|
||||
|
||||
if (channel != 0)
|
||||
{
|
||||
LOG_E("dac channel must be 0.");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
DAC->DHR = *value;
|
||||
while(DAC->SR & DAC_SR_DHRFULL_Msk) __NOP();
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static const struct rt_dac_ops swm_dac_ops =
|
||||
{
|
||||
.disabled = swm_dac_disabled,
|
||||
.enabled = swm_dac_enabled,
|
||||
.convert = swm_dac_convert,
|
||||
};
|
||||
|
||||
int swm_dac_init(void)
|
||||
{
|
||||
int result = RT_EOK;
|
||||
|
||||
PORT_Init(PORTD, PIN2, PORTD_PIN2_DAC_OUT, 0);
|
||||
|
||||
DAC_Init(DAC, DAC_FORMAT_LSB12B);
|
||||
|
||||
SYS->DACCR &= ~SYS_DACCR_VRADJ_Msk;
|
||||
SYS->DACCR |= (17 << SYS_DACCR_VRADJ_Pos);
|
||||
|
||||
/* register dac device */
|
||||
result = rt_hw_dac_register(&swm_dac_device, "dac", &swm_dac_ops, RT_NULL);
|
||||
if(result != RT_EOK)
|
||||
{
|
||||
LOG_E("dac register fail.");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D("dac register success.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(swm_dac_init);
|
||||
|
||||
#endif /* BSP_USING_DAC */
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-02-10 lik first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_DAC_H__
|
||||
#define __DRV_DAC_H__
|
||||
|
||||
#include "board.h"
|
||||
|
||||
int swm_dac_init(void);
|
||||
|
||||
#endif /* __DRV_DAC_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_GPIO_H__
|
||||
#define __DRV_GPIO_H__
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#define GET_PIN(GPIOx,PIN) (rt_uint8_t)__SWM_GET_PIN_##GPIOx(PIN)
|
||||
|
||||
#define __SWM_GET_PIN_A(PIN) (PIN)
|
||||
#define __SWM_GET_PIN_B(PIN) (16 + PIN)
|
||||
#define __SWM_GET_PIN_C(PIN) (32 + PIN)
|
||||
#define __SWM_GET_PIN_D(PIN) (48 + PIN)
|
||||
#define __SWM_GET_PIN_E(PIN) (64 + PIN)
|
||||
#define __SWM_GET_PIN_M(PIN) (80 + PIN)
|
||||
#define __SWM_GET_PIN_N(PIN) (96 + PIN)
|
||||
|
||||
int swm_pin_init(void);
|
||||
|
||||
#endif /* __DRV_GPIO_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_HWTIMER_H__
|
||||
#define __DRV_HWTIMER_H__
|
||||
|
||||
#include "board.h"
|
||||
|
||||
int swm_timer_init(void);
|
||||
|
||||
#endif /* __DRV_HWTIMER_H__ */
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, 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,408 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#include "drv_pwm.h"
|
||||
|
||||
#ifdef RT_USING_PWM
|
||||
#ifdef BSP_USING_PWM
|
||||
|
||||
//#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.pwm"
|
||||
#include <drv_log.h>
|
||||
|
||||
#if !defined(BSP_USING_PWM0) && !defined(BSP_USING_PWM1) && !defined(BSP_USING_PWM2) && !defined(BSP_USING_PWM3) && !defined(BSP_USING_PWM4)
|
||||
#error "Please define at least one BSP_USING_PWMx"
|
||||
/* this driver can be disabled at menuconfig ? RT-Thread Components ? Device Drivers */
|
||||
#endif
|
||||
|
||||
#define MIN_PERIOD 2
|
||||
#define MIN_PULSE 1
|
||||
|
||||
#ifdef BSP_USING_PWM0
|
||||
#ifndef PWM0_CFG
|
||||
#define PWM0_CFG \
|
||||
{ \
|
||||
.name = "pwm0", \
|
||||
.PWMx = PWM0, \
|
||||
.pwm_initstruct.Mode = PWM_CENTER_ALIGNED, \
|
||||
.pwm_initstruct.Clkdiv = 15, \
|
||||
.pwm_initstruct.Period = 10000, \
|
||||
.pwm_initstruct.HdutyA = 5000, \
|
||||
.pwm_initstruct.DeadzoneA = 0, \
|
||||
.pwm_initstruct.IdleLevelA = 0, \
|
||||
.pwm_initstruct.IdleLevelAN = 0, \
|
||||
.pwm_initstruct.OutputInvA = 0, \
|
||||
.pwm_initstruct.OutputInvAN = 1, \
|
||||
.pwm_initstruct.HdutyB = 5000, \
|
||||
.pwm_initstruct.DeadzoneB = 0, \
|
||||
.pwm_initstruct.IdleLevelB = 0, \
|
||||
.pwm_initstruct.IdleLevelBN = 0, \
|
||||
.pwm_initstruct.OutputInvB = 0, \
|
||||
.pwm_initstruct.OutputInvBN = 1, \
|
||||
.pwm_initstruct.UpOvfIE = 0, \
|
||||
.pwm_initstruct.DownOvfIE = 0, \
|
||||
.pwm_initstruct.UpCmpAIE = 0, \
|
||||
.pwm_initstruct.DownCmpAIE = 0, \
|
||||
.pwm_initstruct.UpCmpBIE = 0, \
|
||||
.pwm_initstruct.DownCmpBIE = 0, \
|
||||
.pwm_mask = PWM0_MSK, \
|
||||
}
|
||||
#endif /* PWM0_CFG */
|
||||
#endif /* BSP_USING_PWM0 */
|
||||
|
||||
#ifdef BSP_USING_PWM1
|
||||
#ifndef PWM1_CFG
|
||||
#define PWM1_CFG \
|
||||
{ \
|
||||
.name = "pwm1", \
|
||||
.PWMx = PWM1, \
|
||||
.pwm_initstruct.Mode = PWM_CENTER_ALIGNED, \
|
||||
.pwm_initstruct.Clkdiv = 15, \
|
||||
.pwm_initstruct.Period = 10000, \
|
||||
.pwm_initstruct.HdutyA = 5000, \
|
||||
.pwm_initstruct.DeadzoneA = 0, \
|
||||
.pwm_initstruct.IdleLevelA = 0, \
|
||||
.pwm_initstruct.IdleLevelAN = 0, \
|
||||
.pwm_initstruct.OutputInvA = 0, \
|
||||
.pwm_initstruct.OutputInvAN = 1, \
|
||||
.pwm_initstruct.HdutyB = 5000, \
|
||||
.pwm_initstruct.DeadzoneB = 0, \
|
||||
.pwm_initstruct.IdleLevelB = 0, \
|
||||
.pwm_initstruct.IdleLevelBN = 0, \
|
||||
.pwm_initstruct.OutputInvB = 0, \
|
||||
.pwm_initstruct.OutputInvBN = 1, \
|
||||
.pwm_initstruct.UpOvfIE = 0, \
|
||||
.pwm_initstruct.DownOvfIE = 0, \
|
||||
.pwm_initstruct.UpCmpAIE = 0, \
|
||||
.pwm_initstruct.DownCmpAIE = 0, \
|
||||
.pwm_initstruct.UpCmpBIE = 0, \
|
||||
.pwm_initstruct.DownCmpBIE = 0, \
|
||||
.pwm_mask = PWM1_MSK, \
|
||||
}
|
||||
#endif /* PWM1_CFG */
|
||||
#endif /* BSP_USING_PWM1 */
|
||||
|
||||
#ifdef BSP_USING_PWM2
|
||||
#ifndef PWM2_CFG
|
||||
#define PWM2_CFG \
|
||||
{ \
|
||||
.name = "pwm2", \
|
||||
.PWMx = PWM2, \
|
||||
.pwm_initstruct.Mode = PWM_CENTER_ALIGNED, \
|
||||
.pwm_initstruct.Clkdiv = 15, \
|
||||
.pwm_initstruct.Period = 10000, \
|
||||
.pwm_initstruct.HdutyA = 5000, \
|
||||
.pwm_initstruct.DeadzoneA = 0, \
|
||||
.pwm_initstruct.IdleLevelA = 0, \
|
||||
.pwm_initstruct.IdleLevelAN = 0, \
|
||||
.pwm_initstruct.OutputInvA = 0, \
|
||||
.pwm_initstruct.OutputInvAN = 1, \
|
||||
.pwm_initstruct.HdutyB = 5000, \
|
||||
.pwm_initstruct.DeadzoneB = 0, \
|
||||
.pwm_initstruct.IdleLevelB = 0, \
|
||||
.pwm_initstruct.IdleLevelBN = 0, \
|
||||
.pwm_initstruct.OutputInvB = 0, \
|
||||
.pwm_initstruct.OutputInvBN = 1, \
|
||||
.pwm_initstruct.UpOvfIE = 0, \
|
||||
.pwm_initstruct.DownOvfIE = 0, \
|
||||
.pwm_initstruct.UpCmpAIE = 0, \
|
||||
.pwm_initstruct.DownCmpAIE = 0, \
|
||||
.pwm_initstruct.UpCmpBIE = 0, \
|
||||
.pwm_initstruct.DownCmpBIE = 0, \
|
||||
.pwm_mask = PWM2_MSK, \
|
||||
}
|
||||
#endif /* PWM2_CFG */
|
||||
#endif /* BSP_USING_PWM2 */
|
||||
|
||||
#ifdef BSP_USING_PWM3
|
||||
#ifndef PWM3_CFG
|
||||
#define PWM3_CFG \
|
||||
{ \
|
||||
.name = "pwm3", \
|
||||
.PWMx = PWM3, \
|
||||
.pwm_initstruct.Mode = PWM_CENTER_ALIGNED, \
|
||||
.pwm_initstruct.Clkdiv = 15, \
|
||||
.pwm_initstruct.Period = 10000, \
|
||||
.pwm_initstruct.HdutyA = 5000, \
|
||||
.pwm_initstruct.DeadzoneA = 0, \
|
||||
.pwm_initstruct.IdleLevelA = 0, \
|
||||
.pwm_initstruct.IdleLevelAN = 0, \
|
||||
.pwm_initstruct.OutputInvA = 0, \
|
||||
.pwm_initstruct.OutputInvAN = 1, \
|
||||
.pwm_initstruct.HdutyB = 5000, \
|
||||
.pwm_initstruct.DeadzoneB = 0, \
|
||||
.pwm_initstruct.IdleLevelB = 0, \
|
||||
.pwm_initstruct.IdleLevelBN = 0, \
|
||||
.pwm_initstruct.OutputInvB = 0, \
|
||||
.pwm_initstruct.OutputInvBN = 1, \
|
||||
.pwm_initstruct.UpOvfIE = 0, \
|
||||
.pwm_initstruct.DownOvfIE = 0, \
|
||||
.pwm_initstruct.UpCmpAIE = 0, \
|
||||
.pwm_initstruct.DownCmpAIE = 0, \
|
||||
.pwm_initstruct.UpCmpBIE = 0, \
|
||||
.pwm_initstruct.DownCmpBIE = 0, \
|
||||
.pwm_mask = PWM3_MSK, \
|
||||
}
|
||||
#endif /* PWM3_CFG */
|
||||
#endif /* BSP_USING_PWM3 */
|
||||
|
||||
#ifdef BSP_USING_PWM4
|
||||
#ifndef PWM4_CFG
|
||||
#define PWM4_CFG \
|
||||
{ \
|
||||
.name = "pwm4", \
|
||||
.PWMx = PWM4, \
|
||||
.pwm_initstruct.Mode = PWM_CENTER_ALIGNED, \
|
||||
.pwm_initstruct.Clkdiv = 15, \
|
||||
.pwm_initstruct.Period = 10000, \
|
||||
.pwm_initstruct.HdutyA = 5000, \
|
||||
.pwm_initstruct.DeadzoneA = 0, \
|
||||
.pwm_initstruct.IdleLevelA = 0, \
|
||||
.pwm_initstruct.IdleLevelAN = 0, \
|
||||
.pwm_initstruct.OutputInvA = 0, \
|
||||
.pwm_initstruct.OutputInvAN = 1, \
|
||||
.pwm_initstruct.HdutyB = 5000, \
|
||||
.pwm_initstruct.DeadzoneB = 0, \
|
||||
.pwm_initstruct.IdleLevelB = 0, \
|
||||
.pwm_initstruct.IdleLevelBN = 0, \
|
||||
.pwm_initstruct.OutputInvB = 0, \
|
||||
.pwm_initstruct.OutputInvBN = 1, \
|
||||
.pwm_initstruct.UpOvfIE = 0, \
|
||||
.pwm_initstruct.DownOvfIE = 0, \
|
||||
.pwm_initstruct.UpCmpAIE = 0, \
|
||||
.pwm_initstruct.DownCmpAIE = 0, \
|
||||
.pwm_initstruct.UpCmpBIE = 0, \
|
||||
.pwm_initstruct.DownCmpBIE = 0, \
|
||||
.pwm_mask = PWM4_MSK, \
|
||||
}
|
||||
#endif /* PWM4_CFG */
|
||||
#endif /* BSP_USING_PWM4 */
|
||||
|
||||
struct swm_pwm_cfg
|
||||
{
|
||||
const char *name;
|
||||
PWM_TypeDef *PWMx;
|
||||
PWM_InitStructure pwm_initstruct;
|
||||
uint32_t pwm_mask;
|
||||
};
|
||||
|
||||
struct swm_pwm_device
|
||||
{
|
||||
struct swm_pwm_cfg *pwm_cfg;
|
||||
struct rt_device_pwm pwm_device;
|
||||
};
|
||||
|
||||
static struct swm_pwm_cfg swm_pwm_cfg[] =
|
||||
{
|
||||
#ifdef BSP_USING_PWM0
|
||||
PWM0_CFG,
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM1
|
||||
PWM1_CFG,
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM2
|
||||
PWM2_CFG,
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM3
|
||||
PWM3_CFG,
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM4
|
||||
PWM4_CFG,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct swm_pwm_device pwm_obj[sizeof(swm_pwm_cfg) / sizeof(swm_pwm_cfg[0])] = {0};
|
||||
|
||||
static rt_err_t swm_pwm_enable(struct rt_device_pwm *pwm_device, struct rt_pwm_configuration *configuration, rt_bool_t enable)
|
||||
{
|
||||
struct swm_pwm_cfg *pwm_cfg = RT_NULL;
|
||||
RT_ASSERT(pwm_device != RT_NULL);
|
||||
pwm_cfg = pwm_device->parent.user_data;
|
||||
|
||||
if (!enable)
|
||||
{
|
||||
PWM_Stop(pwm_cfg->pwm_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
PWM_Start(pwm_cfg->pwm_mask);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t swm_pwm_get(struct rt_device_pwm *pwm_device, struct rt_pwm_configuration *configuration)
|
||||
{
|
||||
rt_uint64_t tim_clock;
|
||||
|
||||
struct swm_pwm_cfg *pwm_cfg = RT_NULL;
|
||||
RT_ASSERT(pwm_device != RT_NULL);
|
||||
pwm_cfg = pwm_device->parent.user_data;
|
||||
|
||||
configuration->period = PWM_GetPeriod(pwm_cfg->PWMx) * 1000UL; //中心对称模式下频率降低一半
|
||||
configuration->pulse = PWM_GetHDuty(pwm_cfg->PWMx, configuration->channel) * 1000UL;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t swm_pwm_set(struct rt_device_pwm *pwm_device, struct rt_pwm_configuration *configuration)
|
||||
{
|
||||
rt_uint32_t period, pulse;
|
||||
rt_uint64_t tim_clock;
|
||||
|
||||
struct swm_pwm_cfg *pwm_cfg = RT_NULL;
|
||||
RT_ASSERT(pwm_device != RT_NULL);
|
||||
pwm_cfg = pwm_device->parent.user_data;
|
||||
|
||||
period = (unsigned long long)configuration->period / 1000UL; //中心对称模式下频率降低一半
|
||||
pulse = (unsigned long long)configuration->pulse / 1000UL;
|
||||
if (period < MIN_PERIOD)
|
||||
{
|
||||
period = MIN_PERIOD;
|
||||
}
|
||||
if (pulse < MIN_PULSE)
|
||||
{
|
||||
pulse = MIN_PULSE;
|
||||
}
|
||||
PWM_SetPeriod(pwm_cfg->PWMx, period);
|
||||
PWM_SetHDuty(pwm_cfg->PWMx, PWM_CH_A, pulse);
|
||||
PWM_SetHDuty(pwm_cfg->PWMx, PWM_CH_B, pulse);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t swm_pwm_control(struct rt_device_pwm *pwm_device, int cmd, void *arg)
|
||||
{
|
||||
RT_ASSERT(pwm_device != RT_NULL);
|
||||
|
||||
struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case PWM_CMD_ENABLE:
|
||||
return swm_pwm_enable(pwm_device, configuration, RT_TRUE);
|
||||
case PWM_CMD_DISABLE:
|
||||
return swm_pwm_enable(pwm_device, configuration, RT_FALSE);
|
||||
case PWM_CMD_SET:
|
||||
return swm_pwm_set(pwm_device, configuration);
|
||||
case PWM_CMD_GET:
|
||||
return swm_pwm_get(pwm_device, configuration);
|
||||
default:
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct rt_pwm_ops pwm_ops =
|
||||
{
|
||||
.control = swm_pwm_control};
|
||||
|
||||
int swm_pwm_init(void)
|
||||
{
|
||||
int i = 0;
|
||||
int result = RT_EOK;
|
||||
|
||||
for (i = 0; i < sizeof(swm_pwm_cfg) / sizeof(swm_pwm_cfg[0]); i++)
|
||||
{
|
||||
pwm_obj[i].pwm_cfg = &swm_pwm_cfg[i];
|
||||
|
||||
if (pwm_obj[i].pwm_cfg->PWMx == PWM0)
|
||||
{
|
||||
#ifdef BSP_USING_PWM0A
|
||||
PORT_Init(PORTM, PIN1, PORTM_PIN1_PWM0A, 0);
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM0AN
|
||||
PORT_Init(PORTM, PIN4, PORTM_PIN4_PWM0AN, 0);
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM0B
|
||||
PORT_Init(PORTM, PIN2, PORTM_PIN2_PWM0B, 0);
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM0BN
|
||||
PORT_Init(PORTM, PIN5, PORTM_PIN5_PWM0BN, 0);
|
||||
#endif
|
||||
}
|
||||
else if (pwm_obj[i].pwm_cfg->PWMx == PWM1)
|
||||
{
|
||||
#ifdef BSP_USING_PWM1A
|
||||
PORT_Init(PORTM, PIN3, PORTM_PIN3_PWM1A, 0);
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM1AN
|
||||
PORT_Init(PORTM, PIN6, PORTM_PIN6_PWM1AN, 0);
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM1B
|
||||
PORT_Init(PORTD, PIN9, PORTD_PIN9_PWM1B, 0);
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM1BN
|
||||
PORT_Init(PORTD, PIN8, PORTD_PIN8_PWM1BN, 0);
|
||||
#endif
|
||||
}
|
||||
else if (pwm_obj[i].pwm_cfg->PWMx == PWM2)
|
||||
{
|
||||
#ifdef BSP_USING_PWM2A
|
||||
PORT_Init(PORTM, PIN12, PORTM_PIN12_PWM2A, 0);
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM2AN
|
||||
PORT_Init(PORTM, PIN9, PORTM_PIN9_PWM2AN, 0);
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM2B
|
||||
PORT_Init(PORTM, PIN11, PORTM_PIN11_PWM2B, 0);
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM2BN
|
||||
PORT_Init(PORTM, PIN8, PORTM_PIN8_PWM2BN, 0);
|
||||
#endif
|
||||
}
|
||||
else if (pwm_obj[i].pwm_cfg->PWMx == PWM3)
|
||||
{
|
||||
#ifdef BSP_USING_PWM3A
|
||||
PORT_Init(PORTC, PIN2, PORTC_PIN2_PWM3A, 0);
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM3AN
|
||||
PORT_Init(PORTC, PIN3, PORTC_PIN3_PWM3AN, 0);
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM3B
|
||||
PORT_Init(PORTB, PIN1, PORTB_PIN1_PWM3B, 0);
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM3BN
|
||||
PORT_Init(PORTB, PIN0, PORTB_PIN0_PWM3BN, 0);
|
||||
#endif
|
||||
}
|
||||
else if (pwm_obj[i].pwm_cfg->PWMx == PWM4)
|
||||
{
|
||||
#ifdef BSP_USING_PWM4A
|
||||
PORT_Init(PORTB, PIN15, PORTB_PIN15_PWM4A, 0);
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM4AN
|
||||
// PORT_Init(PORTB, PIN14, PORTB_PIN14_PWM4AN, 0); //SWDIO
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM4B
|
||||
PORT_Init(PORTB, PIN13, PORTB_PIN13_PWM4B, 0);
|
||||
#endif
|
||||
#ifdef BSP_USING_PWM4BN
|
||||
// PORT_Init(PORTB, PIN12, PORTB_PIN12_PWM4BN, 0); //SWDCK
|
||||
#endif
|
||||
}
|
||||
|
||||
pwm_obj[i].pwm_cfg->pwm_initstruct.Clkdiv = SystemCoreClock / 1000000UL / 2; //中心对称模式下频率降低一半
|
||||
PWM_Init(pwm_obj[i].pwm_cfg->PWMx, &(pwm_obj[i].pwm_cfg->pwm_initstruct));
|
||||
result = rt_device_pwm_register(&pwm_obj[i].pwm_device, pwm_obj[i].pwm_cfg->name, &pwm_ops, pwm_obj[i].pwm_cfg);
|
||||
if(result != RT_EOK)
|
||||
{
|
||||
LOG_E("%s register fail.", pwm_obj[i].pwm_cfg->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D("%s register success.", pwm_obj[i].pwm_cfg->name);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(swm_pwm_init);
|
||||
|
||||
#endif /* BSP_USING_PWM */
|
||||
#endif /* RT_USING_PWM */
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_PWM_H__
|
||||
#define __DRV_PWM_H__
|
||||
|
||||
#include "board.h"
|
||||
|
||||
int swm_pwm_init(void);
|
||||
|
||||
#endif /* __DRV_PWM_H__ */
|
||||
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-02-25 lik first version
|
||||
*/
|
||||
|
||||
#include "drv_rgb_lcd.h"
|
||||
|
||||
#ifdef BSP_USING_RGB_LCD
|
||||
#include "rgb_lcd_port.h"
|
||||
|
||||
#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.rgb_lcd"
|
||||
#include <drv_log.h>
|
||||
|
||||
#define LCD_DEVICE(dev) (struct swm_rgb_lcd_device *)(dev)
|
||||
|
||||
struct swm_rgb_lcd_device rgb_lcd_obj;
|
||||
|
||||
static rt_err_t swm_rgb_lcd_configure(struct rt_device *device)
|
||||
{
|
||||
struct swm_rgb_lcd_device *rgb_lcd = LCD_DEVICE(device);
|
||||
/* nothing, right now */
|
||||
rgb_lcd = rgb_lcd;
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t swm_rgb_lcd_control(struct rt_device *device, int cmd, void *args)
|
||||
{
|
||||
struct swm_rgb_lcd_device *rgb_lcd = LCD_DEVICE(device);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
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 = rgb_lcd->lcd_info.pixel_format;
|
||||
info->bits_per_pixel = rgb_lcd->lcd_info.bits_per_pixel;
|
||||
info->width = rgb_lcd->lcd_info.width;
|
||||
info->height = rgb_lcd->lcd_info.height;
|
||||
info->framebuffer = rgb_lcd->lcd_info.framebuffer;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
#if defined(LCD_BACKLIGHT_USING_PWM)
|
||||
static 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)
|
||||
static void turn_on_lcd_backlight(void)
|
||||
{
|
||||
rt_pin_mode(LCD_DISP_GPIO, PIN_MODE_OUTPUT);
|
||||
rt_pin_write(LCD_DISP_GPIO, PIN_HIGH);
|
||||
|
||||
rt_pin_mode(LCD_BL_GPIO, PIN_MODE_OUTPUT);
|
||||
rt_pin_write(LCD_BL_GPIO, PIN_HIGH);
|
||||
}
|
||||
#else
|
||||
static void turn_on_lcd_backlight(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
static const struct rt_device_ops swm_lcd_ops =
|
||||
{
|
||||
.init = swm_rgb_lcd_configure,
|
||||
.open = RT_NULL,
|
||||
.close = RT_NULL,
|
||||
.read = RT_NULL,
|
||||
.write = RT_NULL,
|
||||
.control = swm_rgb_lcd_control};
|
||||
#endif
|
||||
|
||||
int swm_rgb_lcd_init(void)
|
||||
{
|
||||
rt_err_t result = RT_EOK;
|
||||
struct rt_device *device = &rgb_lcd_obj.parent;
|
||||
|
||||
/* memset rgb_lcd_obj to zero */
|
||||
memset(&rgb_lcd_obj, 0x00, sizeof(rgb_lcd_obj));
|
||||
|
||||
/* config LCD dev info */
|
||||
rgb_lcd_obj.lcd_info.height = LCD_HEIGHT;
|
||||
rgb_lcd_obj.lcd_info.width = LCD_WIDTH;
|
||||
rgb_lcd_obj.lcd_info.bits_per_pixel = LCD_BITS_PER_PIXEL;
|
||||
rgb_lcd_obj.lcd_info.pixel_format = LCD_PIXEL_FORMAT;
|
||||
|
||||
/* malloc memory for Triple Buffering */
|
||||
rgb_lcd_obj.lcd_info.framebuffer = rt_malloc_align(LCD_BUF_SIZE,4);
|
||||
if (rgb_lcd_obj.lcd_info.framebuffer == RT_NULL)
|
||||
{
|
||||
LOG_E("init frame buffer failed!\n");
|
||||
result = -RT_ENOMEM;
|
||||
goto __exit;
|
||||
}
|
||||
/* memset buff to 0xFF */
|
||||
memset(rgb_lcd_obj.lcd_info.framebuffer, 0xFF, LCD_BUF_SIZE);
|
||||
|
||||
device->type = RT_Device_Class_Graphic;
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
device->ops = &swm_lcd_ops;
|
||||
#else
|
||||
device->init = swm_rgb_lcd_configure;
|
||||
device->control = swm_rgb_lcd_control;
|
||||
#endif
|
||||
/* register lcd device */
|
||||
rt_device_register(device, "rgb_lcd", RT_DEVICE_FLAG_RDWR);
|
||||
|
||||
LCD_InitStructure LCD_initStruct;
|
||||
|
||||
// PORT_Init(PORTB, PIN1, PORTB_PIN1_LCD_B0, 0);
|
||||
// PORT_Init(PORTB, PIN11, PORTB_PIN11_LCD_B1, 0);
|
||||
// PORT_Init(PORTB, PIN13, PORTB_PIN13_LCD_B2, 0);
|
||||
PORT_Init(PORTB, PIN15, PORTB_PIN15_LCD_B3, 0);
|
||||
PORT_Init(PORTA, PIN2, PORTA_PIN2_LCD_B4, 0);
|
||||
PORT_Init(PORTA, PIN9, PORTA_PIN9_LCD_B5, 0);
|
||||
PORT_Init(PORTA, PIN10, PORTA_PIN10_LCD_B6, 0);
|
||||
PORT_Init(PORTA, PIN11, PORTA_PIN11_LCD_B7, 0);
|
||||
|
||||
// PORT_Init(PORTA, PIN12, PORTA_PIN12_LCD_G0, 0);
|
||||
// PORT_Init(PORTA, PIN13, PORTA_PIN13_LCD_G1, 0);
|
||||
PORT_Init(PORTA, PIN14, PORTA_PIN14_LCD_G2, 0);
|
||||
PORT_Init(PORTA, PIN15, PORTA_PIN15_LCD_G3, 0);
|
||||
PORT_Init(PORTC, PIN0, PORTC_PIN0_LCD_G4, 0);
|
||||
PORT_Init(PORTC, PIN1, PORTC_PIN1_LCD_G5, 0);
|
||||
PORT_Init(PORTC, PIN2, PORTC_PIN2_LCD_G6, 0);
|
||||
PORT_Init(PORTC, PIN3, PORTC_PIN3_LCD_G7, 0);
|
||||
|
||||
// PORT_Init(PORTC, PIN4, PORTC_PIN4_LCD_R0, 0);
|
||||
// PORT_Init(PORTC, PIN5, PORTC_PIN5_LCD_R1, 0);
|
||||
// PORT_Init(PORTC, PIN8, PORTC_PIN8_LCD_R2, 0);
|
||||
PORT_Init(PORTC, PIN9, PORTC_PIN9_LCD_R3, 0);
|
||||
PORT_Init(PORTC, PIN10, PORTC_PIN10_LCD_R4, 0);
|
||||
PORT_Init(PORTC, PIN11, PORTC_PIN11_LCD_R5, 0);
|
||||
PORT_Init(PORTC, PIN12, PORTC_PIN12_LCD_R6, 0);
|
||||
PORT_Init(PORTC, PIN13, PORTC_PIN13_LCD_R7, 0);
|
||||
|
||||
PORT_Init(PORTB, PIN2, PORTB_PIN2_LCD_VSYNC, 0);
|
||||
PORT_Init(PORTB, PIN3, PORTB_PIN3_LCD_HSYNC, 0);
|
||||
PORT_Init(PORTB, PIN4, PORTB_PIN4_LCD_DEN, 0);
|
||||
PORT_Init(PORTB, PIN5, PORTB_PIN5_LCD_DCLK, 0);
|
||||
|
||||
LCD_initStruct.ClkDiv = LCD_CLK_DIV;
|
||||
LCD_initStruct.Format = ((LCD_BITS_PER_PIXEL == 16) ? LCD_FMT_RGB565 : LCD_FMT_RGB888);
|
||||
LCD_initStruct.HnPixel = LCD_WIDTH;
|
||||
LCD_initStruct.VnPixel = LCD_HEIGHT;
|
||||
LCD_initStruct.Hfp = LCD_HFP;
|
||||
LCD_initStruct.Hbp = LCD_HBP;
|
||||
LCD_initStruct.Vfp = LCD_VFP;
|
||||
LCD_initStruct.Vbp = LCD_VBP;
|
||||
LCD_initStruct.HsyncWidth = LCD_HSYNC_WIDTH;
|
||||
LCD_initStruct.VsyncWidth = LCD_VSYNC_WIDTH;
|
||||
|
||||
LCD_initStruct.DataSource = (uint32_t)rgb_lcd_obj.lcd_info.framebuffer;
|
||||
LCD_initStruct.Background = 0xFFFFFF;
|
||||
LCD_initStruct.SampleEdge = LCD_SAMPLE_FALL;
|
||||
LCD_initStruct.IntEOTEn = 0;
|
||||
LCD_Init(LCD, &LCD_initStruct);
|
||||
LCD_Start(LCD);
|
||||
turn_on_lcd_backlight();
|
||||
__exit:
|
||||
if (result != RT_EOK)
|
||||
{
|
||||
if (rgb_lcd_obj.lcd_info.framebuffer)
|
||||
{
|
||||
rt_free(rgb_lcd_obj.lcd_info.framebuffer);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
INIT_BOARD_EXPORT(swm_rgb_lcd_init);
|
||||
|
||||
int lcd_test(void)
|
||||
{
|
||||
struct swm_rgb_lcd_device *rgb_lcd;
|
||||
rgb_lcd = (struct swm_rgb_lcd_device *)rt_device_find("rgb_lcd");
|
||||
|
||||
// while (1)
|
||||
{
|
||||
/* red */
|
||||
for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
|
||||
{
|
||||
rgb_lcd->lcd_info.framebuffer[2 * i] = 0x00;
|
||||
rgb_lcd->lcd_info.framebuffer[2 * i + 1] = 0xF8;
|
||||
}
|
||||
rgb_lcd->parent.control(&rgb_lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
|
||||
rt_thread_mdelay(1000);
|
||||
/* green */
|
||||
for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
|
||||
{
|
||||
rgb_lcd->lcd_info.framebuffer[2 * i] = 0xE0;
|
||||
rgb_lcd->lcd_info.framebuffer[2 * i + 1] = 0x07;
|
||||
}
|
||||
rgb_lcd->parent.control(&rgb_lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
|
||||
rt_thread_mdelay(1000);
|
||||
/* blue */
|
||||
for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
|
||||
{
|
||||
rgb_lcd->lcd_info.framebuffer[2 * i] = 0x1F;
|
||||
rgb_lcd->lcd_info.framebuffer[2 * i + 1] = 0x00;
|
||||
}
|
||||
rgb_lcd->parent.control(&rgb_lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
|
||||
rt_thread_mdelay(1000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
MSH_CMD_EXPORT(lcd_test, lcd_test);
|
||||
|
||||
#endif /* BSP_USING_RGB_LCD */
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_RGB_LCD_H__
|
||||
#define __DRV_RGB_LCD_H__
|
||||
|
||||
#include "board.h"
|
||||
|
||||
struct swm_rgb_lcd_device
|
||||
{
|
||||
struct rt_device parent;
|
||||
struct rt_device_graphic_info lcd_info;
|
||||
};
|
||||
|
||||
int swm_rgb_lcd_init(void);
|
||||
|
||||
#endif /* __DRV_RGB_LCD_H__ */
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#include "drv_rtc.h"
|
||||
|
||||
#ifdef RT_USING_RTC
|
||||
#ifdef BSP_USING_RTC
|
||||
|
||||
//#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.rtc"
|
||||
#include <drv_log.h>
|
||||
|
||||
static rt_rtc_dev_t swm_rtc_device;
|
||||
|
||||
static uint32_t calcWeekDay(uint32_t year, uint32_t month, uint32_t date)
|
||||
{
|
||||
uint32_t i, cnt = 0;
|
||||
const uint32_t daysOfMonth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
|
||||
for (i = 1; i < month; i++)
|
||||
cnt += daysOfMonth[i];
|
||||
|
||||
cnt += date;
|
||||
|
||||
if ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)) && (month >= 3))
|
||||
cnt += 1;
|
||||
|
||||
cnt += (year - 1901) * 365;
|
||||
|
||||
for (i = 1901; i < year; i++)
|
||||
{
|
||||
if ((i % 4 == 0) && ((i % 100 != 0) || (i % 400 == 0)))
|
||||
cnt += 1;
|
||||
}
|
||||
|
||||
return (cnt + 1) % 7;
|
||||
}
|
||||
|
||||
static time_t swm_get_rtc_time_stamp(void)
|
||||
{
|
||||
RTC_DateTime get_datetime = {0};
|
||||
struct tm tm_new;
|
||||
|
||||
RTC_GetDateTime(RTC, &get_datetime);
|
||||
|
||||
tm_new.tm_sec = get_datetime.Second;
|
||||
tm_new.tm_min = get_datetime.Minute;
|
||||
tm_new.tm_hour = get_datetime.Hour;
|
||||
tm_new.tm_mday = get_datetime.Date;
|
||||
tm_new.tm_mon = get_datetime.Month - 1;
|
||||
tm_new.tm_year = get_datetime.Year - 1900;
|
||||
|
||||
LOG_D("get rtc time.");
|
||||
return mktime(&tm_new);
|
||||
}
|
||||
static rt_err_t swm_set_rtc_time_stamp(time_t time_stamp)
|
||||
{
|
||||
RTC_DateTime set_datetime = {0};
|
||||
struct tm now;
|
||||
|
||||
gmtime_r(&time_stamp, &now);
|
||||
set_datetime.Second = now.tm_sec;
|
||||
set_datetime.Minute = now.tm_min;
|
||||
set_datetime.Hour = now.tm_hour;
|
||||
set_datetime.Date = now.tm_mday;
|
||||
set_datetime.Month = now.tm_mon + 1;
|
||||
set_datetime.Year = now.tm_year + 1900;
|
||||
// set_datetime.Day = now.tm_wday;
|
||||
|
||||
RTC_Stop(RTC);
|
||||
while (RTC->CFGABLE == 0)
|
||||
;
|
||||
RTC->MINSEC = (set_datetime.Second << RTC_MINSEC_SEC_Pos) |
|
||||
(set_datetime.Minute << RTC_MINSEC_MIN_Pos);
|
||||
RTC->DATHUR = (set_datetime.Hour << RTC_DATHUR_HOUR_Pos) |
|
||||
((set_datetime.Date) << RTC_DATHUR_DATE_Pos);
|
||||
RTC->MONDAY = (calcWeekDay(set_datetime.Year, set_datetime.Month, set_datetime.Date)
|
||||
<< RTC_MONDAY_DAY_Pos) |
|
||||
((set_datetime.Month) << RTC_MONDAY_MON_Pos);
|
||||
RTC->YEAR = set_datetime.Year;
|
||||
RTC->LOAD = 1 << RTC_LOAD_TIME_Pos;
|
||||
RTC_Start(RTC);
|
||||
|
||||
LOG_D("set rtc time.");
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t swm_rtc_configure(void)
|
||||
{
|
||||
RTC_InitStructure rtc_initstruct;
|
||||
|
||||
rtc_initstruct.clksrc = RTC_CLKSRC_XTAL32K;
|
||||
rtc_initstruct.Year = 2020;
|
||||
rtc_initstruct.Month = 2;
|
||||
rtc_initstruct.Date = 28;
|
||||
rtc_initstruct.Hour = 23;
|
||||
rtc_initstruct.Minute = 59;
|
||||
rtc_initstruct.Second = 55;
|
||||
rtc_initstruct.SecondIEn = 0;
|
||||
rtc_initstruct.MinuteIEn = 0;
|
||||
RTC_Init(RTC, &rtc_initstruct);
|
||||
RTC_Start(RTC);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t swm_rtc_get_secs(time_t *args)
|
||||
{
|
||||
*args = swm_get_rtc_time_stamp();
|
||||
LOG_D("RTC: get rtc_time %x\n", *args);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t swm_rtc_set_secs(time_t *args)
|
||||
{
|
||||
rt_err_t result = RT_EOK;
|
||||
|
||||
if (swm_set_rtc_time_stamp(*args))
|
||||
{
|
||||
result = -RT_ERROR;
|
||||
}
|
||||
LOG_D("RTC: set rtc_time %x\n", *args);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static const struct rt_rtc_ops swm_rtc_ops =
|
||||
{
|
||||
.init = swm_rtc_configure,
|
||||
.get_secs = swm_rtc_get_secs,
|
||||
.set_secs = swm_rtc_set_secs,
|
||||
RT_NULL,
|
||||
RT_NULL,
|
||||
RT_NULL,
|
||||
RT_NULL,
|
||||
};
|
||||
|
||||
int swm_rtc_init(void)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
swm_rtc_configure();
|
||||
|
||||
swm_rtc_device.ops = &swm_rtc_ops;
|
||||
result = rt_hw_rtc_register(&swm_rtc_device, "rtc", RT_DEVICE_FLAG_RDWR,RT_NULL);
|
||||
if (result != RT_EOK)
|
||||
{
|
||||
LOG_E("rtc register err code: %d", result);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D("rtc register success.");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(swm_rtc_init);
|
||||
|
||||
#endif /* BSP_USING_RTC */
|
||||
#endif /* RT_USING_RTC */
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_RTC_H__
|
||||
#define __DRV_RTC_H__
|
||||
|
||||
#include "board.h"
|
||||
|
||||
int swm_rtc_init(void);
|
||||
|
||||
#endif /* __DRV_RTC_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_SDIO_H__
|
||||
#define __DRV_SDIO_H__
|
||||
|
||||
#include "board.h"
|
||||
|
||||
int swm_sdio_init(void);
|
||||
|
||||
#endif /* __DRV_SDIO_H__ */
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#include "drv_sdram.h"
|
||||
|
||||
#ifdef BSP_USING_SDRAM
|
||||
|
||||
#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.sdram"
|
||||
#include <drv_log.h>
|
||||
|
||||
int swm_sdram_init(void)
|
||||
{
|
||||
SDRAM_InitStructure SDRAM_InitStruct;
|
||||
|
||||
PORT_Init(PORTM, PIN13, PORTM_PIN13_SDR_CLK, 0);
|
||||
PORT_Init(PORTM, PIN14, PORTM_PIN14_SDR_CKE, 0);
|
||||
PORT_Init(PORTB, PIN7, PORTB_PIN7_SDR_WE, 0);
|
||||
PORT_Init(PORTB, PIN8, PORTB_PIN8_SDR_CAS, 0);
|
||||
PORT_Init(PORTB, PIN9, PORTB_PIN9_SDR_RAS, 0);
|
||||
PORT_Init(PORTB, PIN10, PORTB_PIN10_SDR_CS, 0);
|
||||
PORT_Init(PORTE, PIN15, PORTE_PIN15_SDR_BA0, 0);
|
||||
PORT_Init(PORTE, PIN14, PORTE_PIN14_SDR_BA1, 0);
|
||||
PORT_Init(PORTN, PIN14, PORTN_PIN14_SDR_A0, 0);
|
||||
PORT_Init(PORTN, PIN13, PORTN_PIN13_SDR_A1, 0);
|
||||
PORT_Init(PORTN, PIN12, PORTN_PIN12_SDR_A2, 0);
|
||||
PORT_Init(PORTN, PIN11, PORTN_PIN11_SDR_A3, 0);
|
||||
PORT_Init(PORTN, PIN10, PORTN_PIN10_SDR_A4, 0);
|
||||
PORT_Init(PORTN, PIN9, PORTN_PIN9_SDR_A5, 0);
|
||||
PORT_Init(PORTN, PIN8, PORTN_PIN8_SDR_A6, 0);
|
||||
PORT_Init(PORTN, PIN7, PORTN_PIN7_SDR_A7, 0);
|
||||
PORT_Init(PORTN, PIN6, PORTN_PIN6_SDR_A8, 0);
|
||||
PORT_Init(PORTN, PIN3, PORTN_PIN3_SDR_A9, 0);
|
||||
PORT_Init(PORTN, PIN15, PORTN_PIN15_SDR_A10, 0);
|
||||
PORT_Init(PORTN, PIN2, PORTN_PIN2_SDR_A11, 0);
|
||||
PORT_Init(PORTM, PIN15, PORTM_PIN15_SDR_A12, 0);
|
||||
PORT_Init(PORTE, PIN7, PORTE_PIN7_SDR_D0, 1);
|
||||
PORT_Init(PORTE, PIN6, PORTE_PIN6_SDR_D1, 1);
|
||||
PORT_Init(PORTE, PIN5, PORTE_PIN5_SDR_D2, 1);
|
||||
PORT_Init(PORTE, PIN4, PORTE_PIN4_SDR_D3, 1);
|
||||
PORT_Init(PORTE, PIN3, PORTE_PIN3_SDR_D4, 1);
|
||||
PORT_Init(PORTE, PIN2, PORTE_PIN2_SDR_D5, 1);
|
||||
PORT_Init(PORTE, PIN1, PORTE_PIN1_SDR_D6, 1);
|
||||
PORT_Init(PORTE, PIN0, PORTE_PIN0_SDR_D7, 1);
|
||||
PORT_Init(PORTE, PIN8, PORTE_PIN8_SDR_D8, 1);
|
||||
PORT_Init(PORTE, PIN9, PORTE_PIN9_SDR_D9, 1);
|
||||
PORT_Init(PORTE, PIN10, PORTE_PIN10_SDR_D10, 1);
|
||||
PORT_Init(PORTE, PIN11, PORTE_PIN11_SDR_D11, 1);
|
||||
PORT_Init(PORTE, PIN12, PORTE_PIN12_SDR_D12, 1);
|
||||
PORT_Init(PORTE, PIN13, PORTE_PIN13_SDR_D13, 1);
|
||||
PORT_Init(PORTC, PIN14, PORTC_PIN14_SDR_D14, 1);
|
||||
PORT_Init(PORTC, PIN15, PORTC_PIN15_SDR_D15, 1);
|
||||
PORT_Init(PORTB, PIN6, PORTB_PIN6_SDR_LDQM, 0);
|
||||
PORT_Init(PORTM, PIN12, PORTM_PIN12_SDR_UDQM, 0);
|
||||
|
||||
SDRAM_InitStruct.Size = SDRAM_SIZE_8MB;
|
||||
SDRAM_InitStruct.ClkDiv = SDRAM_CLKDIV_1;
|
||||
SDRAM_InitStruct.CASLatency = SDRAM_CASLATENCY_3;
|
||||
SDRAM_InitStruct.RefreshTime = 64;
|
||||
SDRAM_InitStruct.TimeTRP = SDRAM_TRP_2;
|
||||
SDRAM_InitStruct.TimeTRCD = SDRAM_TRCD_2;
|
||||
SDRAM_InitStruct.TimeTRC = SDRAM_TRC_7;
|
||||
SDRAM_Init(&SDRAM_InitStruct);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* BSP_USING_SDRAM */
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_SDRAM_H__
|
||||
#define __DRV_SDRAM_H__
|
||||
|
||||
#include "board.h"
|
||||
|
||||
int swm_sdram_init(void);
|
||||
|
||||
#endif /* __DRV_SDRAM_H__ */
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#include "drv_soft_i2c.h"
|
||||
|
||||
#ifdef RT_USING_I2C
|
||||
#ifdef BSP_USING_I2C
|
||||
|
||||
//#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.i2c"
|
||||
#include <drv_log.h>
|
||||
|
||||
#if !defined(BSP_USING_I2C0) && !defined(BSP_USING_I2C1)
|
||||
#error "Please define at least one BSP_USING_I2Cx"
|
||||
/* this driver can be disabled at menuconfig ? RT-Thread Components ? Device Drivers */
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_I2C0
|
||||
#define I2C0_BUS_CFG \
|
||||
{ \
|
||||
.scl = BSP_I2C0_SCL_PIN, \
|
||||
.sda = BSP_I2C0_SDA_PIN, \
|
||||
.name = "i2c0", \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_I2C1
|
||||
#define I2C1_BUS_CFG \
|
||||
{ \
|
||||
.scl = BSP_I2C1_SCL_PIN, \
|
||||
.sda = BSP_I2C1_SDA_PIN, \
|
||||
.name = "i2c1", \
|
||||
}
|
||||
#endif
|
||||
|
||||
/* swm config class */
|
||||
struct swm_soft_i2c_cfg
|
||||
{
|
||||
rt_uint8_t scl;
|
||||
rt_uint8_t sda;
|
||||
const char *name;
|
||||
};
|
||||
/* swm i2c dirver class */
|
||||
struct swm_soft_i2c_device
|
||||
{
|
||||
struct rt_i2c_bit_ops ops;
|
||||
struct rt_i2c_bus_device i2c2_bus;
|
||||
};
|
||||
|
||||
static const struct swm_soft_i2c_cfg swm_soft_i2c_cfg[] =
|
||||
{
|
||||
#ifdef BSP_USING_I2C0
|
||||
I2C0_BUS_CFG,
|
||||
#endif
|
||||
#ifdef BSP_USING_I2C1
|
||||
I2C1_BUS_CFG,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct swm_soft_i2c_device i2c_obj[sizeof(swm_soft_i2c_cfg) / sizeof(swm_soft_i2c_cfg[0])];
|
||||
|
||||
/**
|
||||
* This function initializes the i2c pin.
|
||||
*
|
||||
* @param swm i2c dirver class.
|
||||
*/
|
||||
static void swm_i2c_gpio_init(struct swm_soft_i2c_device *i2c)
|
||||
{
|
||||
struct swm_soft_i2c_cfg *soft_i2c_cfg = (struct swm_soft_i2c_cfg *)i2c->ops.data;
|
||||
|
||||
rt_pin_mode(soft_i2c_cfg->scl, PIN_MODE_OUTPUT_OD);
|
||||
rt_pin_mode(soft_i2c_cfg->sda, PIN_MODE_OUTPUT_OD);
|
||||
|
||||
rt_pin_write(soft_i2c_cfg->scl, PIN_HIGH);
|
||||
rt_pin_write(soft_i2c_cfg->sda, PIN_HIGH);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function sets the sda pin.
|
||||
*
|
||||
* @param swm config class.
|
||||
* @param The sda pin state.
|
||||
*/
|
||||
static void swm_i2c_set_sda(void *data, rt_int32_t state)
|
||||
{
|
||||
struct swm_soft_i2c_cfg *soft_i2c_cfg = (struct swm_soft_i2c_cfg *)data;
|
||||
rt_pin_mode(soft_i2c_cfg->sda, PIN_MODE_OUTPUT_OD);
|
||||
if (state)
|
||||
{
|
||||
rt_pin_write(soft_i2c_cfg->sda, PIN_HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_pin_write(soft_i2c_cfg->sda, PIN_LOW);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function sets the scl pin.
|
||||
*
|
||||
* @param swm config class.
|
||||
* @param The scl pin state.
|
||||
*/
|
||||
static void swm_i2c_set_scl(void *data, rt_int32_t state)
|
||||
{
|
||||
struct swm_soft_i2c_cfg *soft_i2c_cfg = (struct swm_soft_i2c_cfg *)data;
|
||||
rt_pin_mode(soft_i2c_cfg->scl, PIN_MODE_OUTPUT_OD);
|
||||
if (state)
|
||||
{
|
||||
rt_pin_write(soft_i2c_cfg->scl, PIN_HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_pin_write(soft_i2c_cfg->scl, PIN_LOW);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function gets the sda pin state.
|
||||
*
|
||||
* @param The sda pin state.
|
||||
*/
|
||||
static rt_int32_t swm_i2c_get_sda(void *data)
|
||||
{
|
||||
struct swm_soft_i2c_cfg *soft_i2c_cfg = (struct swm_soft_i2c_cfg *)data;
|
||||
rt_pin_mode(soft_i2c_cfg->sda, PIN_MODE_INPUT_PULLDOWN);
|
||||
return rt_pin_read(soft_i2c_cfg->sda);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function gets the scl pin state.
|
||||
*
|
||||
* @param The scl pin state.
|
||||
*/
|
||||
static rt_int32_t swm_i2c_get_scl(void *data)
|
||||
{
|
||||
struct swm_soft_i2c_cfg *soft_i2c_cfg = (struct swm_soft_i2c_cfg *)data;
|
||||
rt_pin_mode(soft_i2c_cfg->scl, PIN_MODE_INPUT_PULLDOWN);
|
||||
return rt_pin_read(soft_i2c_cfg->scl);
|
||||
}
|
||||
|
||||
/**
|
||||
* The time delay function.
|
||||
*
|
||||
* @param microseconds.
|
||||
*/
|
||||
static void swm_i2c_udelay(rt_uint32_t us)
|
||||
{
|
||||
rt_uint32_t ticks;
|
||||
rt_uint32_t told, tnow, tcnt = 0;
|
||||
rt_uint32_t reload = SysTick->LOAD;
|
||||
|
||||
ticks = us * reload / (1000000 / RT_TICK_PER_SECOND);
|
||||
told = SysTick->VAL;
|
||||
while (1)
|
||||
{
|
||||
tnow = SysTick->VAL;
|
||||
if (tnow != told)
|
||||
{
|
||||
if (tnow < told)
|
||||
{
|
||||
tcnt += told - tnow;
|
||||
}
|
||||
else
|
||||
{
|
||||
tcnt += reload - tnow + told;
|
||||
}
|
||||
told = tnow;
|
||||
if (tcnt >= ticks)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct rt_i2c_bit_ops swm_i2c_bit_ops =
|
||||
{
|
||||
.data = RT_NULL,
|
||||
.set_sda = swm_i2c_set_sda,
|
||||
.set_scl = swm_i2c_set_scl,
|
||||
.get_sda = swm_i2c_get_sda,
|
||||
.get_scl = swm_i2c_get_scl,
|
||||
.udelay = swm_i2c_udelay,
|
||||
.delay_us = 1,
|
||||
.timeout = 100};
|
||||
|
||||
/* I2C initialization function */
|
||||
int swm_i2c_init(void)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
for (int i = 0; i < sizeof(i2c_obj) / sizeof(struct swm_soft_i2c_device); i++)
|
||||
{
|
||||
i2c_obj[i].ops = swm_i2c_bit_ops;
|
||||
i2c_obj[i].ops.data = (void *)&swm_soft_i2c_cfg[i];
|
||||
i2c_obj[i].i2c2_bus.priv = &i2c_obj[i].ops;
|
||||
swm_i2c_gpio_init(&i2c_obj[i]);
|
||||
result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c2_bus, swm_soft_i2c_cfg[i].name);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
LOG_D("software simulation %s init done, pin scl: %d, pin sda %d",
|
||||
swm_soft_i2c_cfg[i].name,
|
||||
swm_soft_i2c_cfg[i].scl,
|
||||
swm_soft_i2c_cfg[i].sda);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(swm_i2c_init);
|
||||
#endif /* BSP_USING_I2C */
|
||||
#endif /* RT_USING_I2C */
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_SOFT_I2C_H__
|
||||
#define __DRV_SOFT_I2C_H__
|
||||
|
||||
#include "board.h"
|
||||
|
||||
int swm_i2c_init(void);
|
||||
|
||||
#endif /* __DRV_SOFT_I2C_H__ */
|
||||
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#include "drv_spi.h"
|
||||
|
||||
#ifdef RT_USING_SPI
|
||||
#ifdef BSP_USING_SPI
|
||||
|
||||
//#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.spi"
|
||||
#include <drv_log.h>
|
||||
|
||||
#if !defined(BSP_USING_SPI0) && !defined(BSP_USING_SPI1)
|
||||
#error "Please define at least one BSP_USING_SPIx"
|
||||
/* this driver can be disabled at menuconfig ? RT-Thread Components ? Device Drivers */
|
||||
#endif
|
||||
|
||||
struct swm_spi_cs
|
||||
{
|
||||
GPIO_TypeDef *GPIOx;
|
||||
uint32_t gpio_pin;
|
||||
};
|
||||
|
||||
struct swm_spi_cfg
|
||||
{
|
||||
const char *name;
|
||||
SPI_TypeDef *SPIx;
|
||||
SPI_InitStructure spi_initstruct;
|
||||
};
|
||||
|
||||
/* swm spi dirver class */
|
||||
struct swm_spi_device
|
||||
{
|
||||
struct swm_spi_cfg *spi_cfg;
|
||||
struct rt_spi_configuration *configure;
|
||||
struct rt_spi_bus spi_bus;
|
||||
};
|
||||
|
||||
#ifdef BSP_USING_SPI0
|
||||
#ifndef SPI0_BUS_CONFIG
|
||||
#define SPI0_BUS_CONFIG \
|
||||
{ \
|
||||
.name = "spi0", \
|
||||
.SPIx = SPI0, \
|
||||
.spi_initstruct.clkDiv = SPI_CLKDIV_16, \
|
||||
.spi_initstruct.FrameFormat = SPI_FORMAT_SPI, \
|
||||
.spi_initstruct.SampleEdge = SPI_SECOND_EDGE, \
|
||||
.spi_initstruct.IdleLevel = SPI_HIGH_LEVEL, \
|
||||
.spi_initstruct.WordSize = 8, \
|
||||
.spi_initstruct.Master = 1, \
|
||||
.spi_initstruct.RXThreshold = 0, \
|
||||
.spi_initstruct.RXThresholdIEn = 0, \
|
||||
.spi_initstruct.TXThreshold = 0, \
|
||||
.spi_initstruct.TXThresholdIEn = 0, \
|
||||
.spi_initstruct.TXCompleteIEn = 0, \
|
||||
}
|
||||
#endif /* SPI0_BUS_CONFIG */
|
||||
#endif /* BSP_USING_SPI0 */
|
||||
|
||||
#ifdef BSP_USING_SPI1
|
||||
#ifndef SPI1_BUS_CONFIG
|
||||
#define SPI1_BUS_CONFIG \
|
||||
{ \
|
||||
.name = "spi1", \
|
||||
.SPIx = SPI1, \
|
||||
.spi_initstruct.clkDiv = SPI_CLKDIV_16, \
|
||||
.spi_initstruct.FrameFormat = SPI_FORMAT_SPI, \
|
||||
.spi_initstruct.SampleEdge = SPI_SECOND_EDGE, \
|
||||
.spi_initstruct.IdleLevel = SPI_HIGH_LEVEL, \
|
||||
.spi_initstruct.WordSize = 8, \
|
||||
.spi_initstruct.Master = 1, \
|
||||
.spi_initstruct.RXThreshold = 0, \
|
||||
.spi_initstruct.RXThresholdIEn = 0, \
|
||||
.spi_initstruct.TXThreshold = 0, \
|
||||
.spi_initstruct.TXThresholdIEn = 0, \
|
||||
.spi_initstruct.TXCompleteIEn = 0, \
|
||||
}
|
||||
#endif /* SPI1_BUS_CONFIG */
|
||||
#endif /* BSP_USING_SPI1 */
|
||||
|
||||
static struct swm_spi_cfg swm_spi_cfg[] =
|
||||
{
|
||||
#ifdef BSP_USING_SPI0
|
||||
SPI0_BUS_CONFIG,
|
||||
#endif
|
||||
#ifdef BSP_USING_SPI1
|
||||
SPI1_BUS_CONFIG,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct swm_spi_device spi_bus_obj[sizeof(swm_spi_cfg) / sizeof(swm_spi_cfg[0])] = {0};
|
||||
|
||||
static rt_err_t swm_spi_configure(struct rt_spi_device *device,
|
||||
struct rt_spi_configuration *configure)
|
||||
{
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
RT_ASSERT(configure != RT_NULL);
|
||||
|
||||
struct swm_spi_device *spi_drv = rt_container_of(device->bus, struct swm_spi_device, spi_bus);
|
||||
spi_drv->configure = configure;
|
||||
struct swm_spi_cfg *spi_cfg = spi_drv->spi_cfg;
|
||||
|
||||
if (configure->mode & RT_SPI_SLAVE)
|
||||
{
|
||||
spi_cfg->spi_initstruct.Master = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_cfg->spi_initstruct.Master = 1;
|
||||
}
|
||||
|
||||
if (configure->mode & RT_SPI_3WIRE)
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
if (configure->data_width == 8)
|
||||
{
|
||||
spi_cfg->spi_initstruct.WordSize = 8;
|
||||
}
|
||||
else if (configure->data_width == 16)
|
||||
{
|
||||
spi_cfg->spi_initstruct.WordSize = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -RT_EIO;
|
||||
}
|
||||
|
||||
if (configure->mode & RT_SPI_CPHA)
|
||||
{
|
||||
spi_cfg->spi_initstruct.SampleEdge = SPI_SECOND_EDGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_cfg->spi_initstruct.SampleEdge = SPI_FIRST_EDGE;
|
||||
}
|
||||
|
||||
if (configure->mode & RT_SPI_CPOL)
|
||||
{
|
||||
spi_cfg->spi_initstruct.IdleLevel = SPI_HIGH_LEVEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_cfg->spi_initstruct.IdleLevel = SPI_LOW_LEVEL;
|
||||
}
|
||||
|
||||
if (configure->max_hz >= SystemCoreClock / 2)
|
||||
{
|
||||
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_2;
|
||||
}
|
||||
else if (configure->max_hz >= SystemCoreClock / 4)
|
||||
{
|
||||
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_4;
|
||||
}
|
||||
else if (configure->max_hz >= SystemCoreClock / 8)
|
||||
{
|
||||
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_8;
|
||||
}
|
||||
else if (configure->max_hz >= SystemCoreClock / 16)
|
||||
{
|
||||
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_16;
|
||||
}
|
||||
else if (configure->max_hz >= SystemCoreClock / 32)
|
||||
{
|
||||
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_32;
|
||||
}
|
||||
else if (configure->max_hz >= SystemCoreClock / 64)
|
||||
{
|
||||
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_64;
|
||||
}
|
||||
else if (configure->max_hz >= SystemCoreClock / 128)
|
||||
{
|
||||
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_128;
|
||||
}
|
||||
else if (configure->max_hz >= SystemCoreClock / 256)
|
||||
{
|
||||
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_256;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* min prescaler 512 */
|
||||
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_512;
|
||||
}
|
||||
|
||||
SPI_Init(spi_cfg->SPIx, &(spi_cfg->spi_initstruct));
|
||||
SPI_Open(spi_cfg->SPIx);
|
||||
LOG_D("%s init done", spi_cfg->name);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
#define SPISTEP(datalen) (((datalen) == 8) ? 1 : 2)
|
||||
#define SPISEND_1(reg, ptr, datalen) \
|
||||
do \
|
||||
{ \
|
||||
if (datalen == 8) \
|
||||
{ \
|
||||
(reg) = *(rt_uint8_t *)(ptr); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
(reg) = *(rt_uint16_t *)(ptr); \
|
||||
} \
|
||||
} while (0)
|
||||
#define SPIRECV_1(reg, ptr, datalen) \
|
||||
do \
|
||||
{ \
|
||||
if (datalen == 8) \
|
||||
{ \
|
||||
*(rt_uint8_t *)(ptr) = (reg); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
*(rt_uint16_t *)(ptr) = reg; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static rt_err_t swm_spi_txrx1b(struct swm_spi_device *spi_drv, void *rcvb, const void *sndb)
|
||||
{
|
||||
rt_uint32_t padrcv = 0;
|
||||
rt_uint32_t padsnd = 0xFF;
|
||||
if (!rcvb && !sndb)
|
||||
{
|
||||
return -RT_ERROR;
|
||||
}
|
||||
if (!rcvb)
|
||||
{
|
||||
rcvb = &padrcv;
|
||||
}
|
||||
if (!sndb)
|
||||
{
|
||||
sndb = &padsnd;
|
||||
}
|
||||
while (SPI_IsTXFull(spi_drv->spi_cfg->SPIx))
|
||||
;
|
||||
SPISEND_1(spi_drv->spi_cfg->SPIx->DATA, sndb, spi_drv->spi_cfg->spi_initstruct.WordSize);
|
||||
while (SPI_IsRXEmpty(spi_drv->spi_cfg->SPIx))
|
||||
;
|
||||
SPIRECV_1(spi_drv->spi_cfg->SPIx->DATA, rcvb, spi_drv->spi_cfg->spi_initstruct.WordSize);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_uint32_t swm_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
|
||||
{
|
||||
rt_err_t res;
|
||||
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
RT_ASSERT(device->bus != RT_NULL);
|
||||
RT_ASSERT(device->bus->parent.user_data != RT_NULL);
|
||||
RT_ASSERT(message != RT_NULL);
|
||||
|
||||
struct swm_spi_device *spi_drv = rt_container_of(device->bus, struct swm_spi_device, spi_bus);
|
||||
struct swm_spi_cfg *spi_cfg = spi_drv->spi_cfg;
|
||||
struct swm_spi_cs *cs = device->parent.user_data;
|
||||
|
||||
if (message->cs_take)
|
||||
{
|
||||
GPIO_ClrBit(cs->GPIOx, cs->gpio_pin);
|
||||
}
|
||||
|
||||
LOG_D("%s transfer prepare and start", spi_cfg->name);
|
||||
LOG_D("%s sendbuf: %X, recvbuf: %X, length: %d",
|
||||
spi_cfg->name, (uint32_t)message->send_buf, (uint32_t)message->recv_buf, message->length);
|
||||
|
||||
const rt_uint8_t *sndb = message->send_buf;
|
||||
rt_uint8_t *rcvb = message->recv_buf;
|
||||
rt_int32_t length = message->length;
|
||||
|
||||
while (length)
|
||||
{
|
||||
res = swm_spi_txrx1b(spi_drv, rcvb, sndb);
|
||||
if (rcvb)
|
||||
{
|
||||
rcvb += SPISTEP(spi_cfg->spi_initstruct.WordSize);
|
||||
}
|
||||
if (sndb)
|
||||
{
|
||||
sndb += SPISTEP(spi_cfg->spi_initstruct.WordSize);
|
||||
}
|
||||
if (res != RT_EOK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
length--;
|
||||
}
|
||||
/* Wait until Busy flag is reset before disabling SPI */
|
||||
while (!SPI_IsTXEmpty(spi_cfg->SPIx) && !SPI_IsRXEmpty(spi_cfg->SPIx))
|
||||
;
|
||||
if (message->cs_release)
|
||||
{
|
||||
GPIO_SetBit(cs->GPIOx, cs->gpio_pin);
|
||||
}
|
||||
return message->length - length;
|
||||
}
|
||||
|
||||
static const struct rt_spi_ops swm_spi_ops =
|
||||
{
|
||||
.configure = swm_spi_configure,
|
||||
.xfer = swm_spi_xfer,
|
||||
};
|
||||
|
||||
//cannot be used before completion init
|
||||
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, GPIO_TypeDef *cs_gpiox, uint32_t cs_gpio_pin)
|
||||
{
|
||||
RT_ASSERT(bus_name != RT_NULL);
|
||||
RT_ASSERT(device_name != RT_NULL);
|
||||
|
||||
rt_err_t result;
|
||||
struct rt_spi_device *spi_device;
|
||||
struct swm_spi_cs *cs_pin;
|
||||
|
||||
GPIO_Init(cs_gpiox, cs_gpio_pin, 1, 1, 0, 0);
|
||||
GPIO_SetBit(cs_gpiox, cs_gpio_pin);
|
||||
|
||||
spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
|
||||
RT_ASSERT(spi_device != RT_NULL);
|
||||
cs_pin = (struct swm_spi_cs *)rt_malloc(sizeof(struct swm_spi_cs));
|
||||
RT_ASSERT(cs_pin != RT_NULL);
|
||||
cs_pin->GPIOx = cs_gpiox;
|
||||
cs_pin->gpio_pin = cs_gpio_pin;
|
||||
|
||||
result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
|
||||
if (result != RT_EOK)
|
||||
{
|
||||
LOG_E("%s attach to %s faild, %d\n", device_name, bus_name, result);
|
||||
}
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
LOG_D("%s attach to %s done", device_name, bus_name);
|
||||
return result;
|
||||
}
|
||||
|
||||
int swm_spi_init(void)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
#ifdef BSP_USING_SPI0
|
||||
PORT_Init(PORTM, PIN2, PORTM_PIN2_SPI0_SCLK, 0);
|
||||
PORT_Init(PORTM, PIN4, PORTM_PIN4_SPI0_MISO, 1);
|
||||
PORT_Init(PORTM, PIN5, PORTM_PIN5_SPI0_MOSI, 0);
|
||||
#endif //BSP_USING_SPI0
|
||||
|
||||
#ifdef BSP_USING_SPI1
|
||||
PORT_Init(PORTB, PIN2, PORTB_PIN2_SPI1_SCLK, 0);
|
||||
PORT_Init(PORTB, PIN3, PORTB_PIN3_SPI1_MISO, 1);
|
||||
PORT_Init(PORTB, PIN4, PORTB_PIN4_SPI1_MOSI, 0);
|
||||
#endif //BSP_USING_SPI1
|
||||
|
||||
for (int i = 0; i < sizeof(swm_spi_cfg) / sizeof(swm_spi_cfg[0]); i++)
|
||||
{
|
||||
spi_bus_obj[i].spi_cfg = &swm_spi_cfg[i];
|
||||
spi_bus_obj[i].spi_bus.parent.user_data = &swm_spi_cfg[i];
|
||||
result = rt_spi_bus_register(&spi_bus_obj[i].spi_bus, swm_spi_cfg[i].name, &swm_spi_ops);
|
||||
if (result != RT_EOK)
|
||||
{
|
||||
LOG_E("%s bus register fail.", swm_spi_cfg[i].name);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D("%s bus register success.", swm_spi_cfg[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
INIT_BOARD_EXPORT(swm_spi_init);
|
||||
|
||||
#endif /* BSP_USING_SPI */
|
||||
#endif /* RT_USING_SPI */
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_SPI_H__
|
||||
#define __DRV_SPI_H__
|
||||
|
||||
#include "board.h"
|
||||
|
||||
//cannot be used before completion init
|
||||
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, GPIO_TypeDef *GPIOx, uint32_t n);
|
||||
int swm_spi_init(void);
|
||||
|
||||
#endif /* __DRV_SPI_H__ */
|
||||
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#include "drv_uart.h"
|
||||
|
||||
#ifdef RT_USING_SERIAL
|
||||
#ifdef BSP_USING_UART
|
||||
|
||||
//#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.uart"
|
||||
#include <drv_log.h>
|
||||
|
||||
#if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2) && \
|
||||
!defined(BSP_USING_UART3)
|
||||
#error "Please define at least one BSP_USING_UARTx"
|
||||
/* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_UART0
|
||||
#ifndef UART0_CFG
|
||||
#define UART0_CFG \
|
||||
{ \
|
||||
.name = "uart0", \
|
||||
.UARTx = UART0, \
|
||||
.irq = UART0_IRQn, \
|
||||
.uart_initstruct.Baudrate = 115200, \
|
||||
.uart_initstruct.DataBits = UART_DATA_8BIT, \
|
||||
.uart_initstruct.Parity = UART_PARITY_NONE, \
|
||||
.uart_initstruct.StopBits = UART_STOP_1BIT, \
|
||||
.uart_initstruct.RXThreshold = 0, \
|
||||
.uart_initstruct.RXThresholdIEn = 1, \
|
||||
.uart_initstruct.TXThresholdIEn = 0, \
|
||||
.uart_initstruct.TimeoutTime = 10, \
|
||||
.uart_initstruct.TimeoutIEn = 1, \
|
||||
}
|
||||
#endif /* UART0_CFG */
|
||||
#endif /* BSP_USING_UART0 */
|
||||
|
||||
#ifdef BSP_USING_UART1
|
||||
#ifndef UART1_CFG
|
||||
#define UART1_CFG \
|
||||
{ \
|
||||
.name = "uart1", \
|
||||
.UARTx = UART1, \
|
||||
.irq = UART1_IRQn, \
|
||||
.uart_initstruct.Baudrate = 115200, \
|
||||
.uart_initstruct.DataBits = UART_DATA_8BIT, \
|
||||
.uart_initstruct.Parity = UART_PARITY_NONE, \
|
||||
.uart_initstruct.StopBits = UART_STOP_1BIT, \
|
||||
.uart_initstruct.RXThreshold = 0, \
|
||||
.uart_initstruct.RXThresholdIEn = 1, \
|
||||
.uart_initstruct.TXThresholdIEn = 0, \
|
||||
.uart_initstruct.TimeoutTime = 10, \
|
||||
.uart_initstruct.TimeoutIEn = 1, \
|
||||
}
|
||||
#endif /* UART1_CFG */
|
||||
#endif /* BSP_USING_UART1 */
|
||||
|
||||
#ifdef BSP_USING_UART2
|
||||
#ifndef UART2_CFG
|
||||
#define UART2_CFG \
|
||||
{ \
|
||||
.name = "uart2", \
|
||||
.UARTx = UART2, \
|
||||
.irq = UART2_IRQn, \
|
||||
.uart_initstruct.Baudrate = 115200, \
|
||||
.uart_initstruct.DataBits = UART_DATA_8BIT, \
|
||||
.uart_initstruct.Parity = UART_PARITY_NONE, \
|
||||
.uart_initstruct.StopBits = UART_STOP_1BIT, \
|
||||
.uart_initstruct.RXThreshold = 0, \
|
||||
.uart_initstruct.RXThresholdIEn = 1, \
|
||||
.uart_initstruct.TXThresholdIEn = 0, \
|
||||
.uart_initstruct.TimeoutTime = 10, \
|
||||
.uart_initstruct.TimeoutIEn = 1, \
|
||||
}
|
||||
#endif /* UART2_CFG */
|
||||
#endif /* BSP_USING_UART2 */
|
||||
|
||||
#ifdef BSP_USING_UART3
|
||||
#ifndef UART3_CFG
|
||||
#define UART3_CFG \
|
||||
{ \
|
||||
.name = "uart3", \
|
||||
.UARTx = UART3, \
|
||||
.irq = UART3_IRQn, \
|
||||
.uart_initstruct.Baudrate = 115200, \
|
||||
.uart_initstruct.DataBits = UART_DATA_8BIT, \
|
||||
.uart_initstruct.Parity = UART_PARITY_NONE, \
|
||||
.uart_initstruct.StopBits = UART_STOP_1BIT, \
|
||||
.uart_initstruct.RXThreshold = 0, \
|
||||
.uart_initstruct.RXThresholdIEn = 1, \
|
||||
.uart_initstruct.TXThresholdIEn = 0, \
|
||||
.uart_initstruct.TimeoutTime = 10, \
|
||||
.uart_initstruct.TimeoutIEn = 1, \
|
||||
}
|
||||
#endif /* UART3_CFG */
|
||||
#endif /* BSP_USING_UART3 */
|
||||
|
||||
/* swm config class */
|
||||
struct swm_uart_cfg
|
||||
{
|
||||
const char *name;
|
||||
UART_TypeDef *UARTx;
|
||||
IRQn_Type irq;
|
||||
UART_InitStructure uart_initstruct;
|
||||
};
|
||||
|
||||
/* swm uart dirver class */
|
||||
struct swm_uart_device
|
||||
{
|
||||
struct swm_uart_cfg *uart_cfg;
|
||||
struct rt_serial_device serial_device;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
#ifdef BSP_USING_UART0
|
||||
UART0_INDEX,
|
||||
#endif
|
||||
#ifdef BSP_USING_UART1
|
||||
UART1_INDEX,
|
||||
#endif
|
||||
#ifdef BSP_USING_UART2
|
||||
UART2_INDEX,
|
||||
#endif
|
||||
#ifdef BSP_USING_UART3
|
||||
UART3_INDEX,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct swm_uart_cfg swm_uart_cfg[] =
|
||||
{
|
||||
#ifdef BSP_USING_UART0
|
||||
UART0_CFG,
|
||||
#endif
|
||||
#ifdef BSP_USING_UART1
|
||||
UART1_CFG,
|
||||
#endif
|
||||
#ifdef BSP_USING_UART2
|
||||
UART2_CFG,
|
||||
#endif
|
||||
#ifdef BSP_USING_UART3
|
||||
UART3_CFG,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct swm_uart_device uart_obj[sizeof(swm_uart_cfg) / sizeof(swm_uart_cfg[0])] = {0};
|
||||
|
||||
static rt_err_t swm_uart_configure(struct rt_serial_device *serial_device, struct serial_configure *configure)
|
||||
{
|
||||
struct swm_uart_cfg *uart_cfg;
|
||||
RT_ASSERT(serial_device != RT_NULL);
|
||||
RT_ASSERT(configure != RT_NULL);
|
||||
uart_cfg = serial_device->parent.user_data;
|
||||
|
||||
uart_cfg->uart_initstruct.Baudrate = configure->baud_rate;
|
||||
switch (configure->data_bits)
|
||||
{
|
||||
case DATA_BITS_8:
|
||||
uart_cfg->uart_initstruct.DataBits = UART_DATA_8BIT;
|
||||
break;
|
||||
case DATA_BITS_9:
|
||||
uart_cfg->uart_initstruct.DataBits = UART_DATA_9BIT;
|
||||
break;
|
||||
default:
|
||||
uart_cfg->uart_initstruct.DataBits = UART_DATA_8BIT;
|
||||
break;
|
||||
}
|
||||
switch (configure->stop_bits)
|
||||
{
|
||||
case STOP_BITS_1:
|
||||
uart_cfg->uart_initstruct.StopBits = UART_STOP_1BIT;
|
||||
break;
|
||||
case STOP_BITS_2:
|
||||
uart_cfg->uart_initstruct.StopBits = UART_STOP_2BIT;
|
||||
break;
|
||||
default:
|
||||
uart_cfg->uart_initstruct.StopBits = UART_STOP_1BIT;
|
||||
break;
|
||||
}
|
||||
switch (configure->parity)
|
||||
{
|
||||
case PARITY_NONE:
|
||||
uart_cfg->uart_initstruct.Parity = UART_PARITY_NONE;
|
||||
break;
|
||||
case PARITY_ODD:
|
||||
uart_cfg->uart_initstruct.Parity = UART_PARITY_ODD;
|
||||
break;
|
||||
case PARITY_EVEN:
|
||||
uart_cfg->uart_initstruct.Parity = UART_PARITY_EVEN;
|
||||
break;
|
||||
default:
|
||||
uart_cfg->uart_initstruct.Parity = UART_PARITY_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
UART_Init(uart_cfg->UARTx, &(uart_cfg->uart_initstruct));
|
||||
UART_Open(uart_cfg->UARTx);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t swm_uart_control(struct rt_serial_device *serial_device, int cmd, void *arg)
|
||||
{
|
||||
struct swm_uart_cfg *uart_cfg;
|
||||
RT_ASSERT(serial_device != RT_NULL);
|
||||
uart_cfg = serial_device->parent.user_data;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case RT_DEVICE_CTRL_CLR_INT:
|
||||
/* disable rx irq */
|
||||
NVIC_DisableIRQ(uart_cfg->irq);
|
||||
break;
|
||||
case RT_DEVICE_CTRL_SET_INT:
|
||||
/* enable rx irq */
|
||||
NVIC_EnableIRQ(uart_cfg->irq);
|
||||
break;
|
||||
}
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static int swm_uart_putc(struct rt_serial_device *serial_device, char c)
|
||||
{
|
||||
struct swm_uart_cfg *uart_cfg;
|
||||
RT_ASSERT(serial_device != RT_NULL);
|
||||
uart_cfg = serial_device->parent.user_data;
|
||||
|
||||
UART_WriteByte(uart_cfg->UARTx, c);
|
||||
while (UART_IsTXBusy(uart_cfg->UARTx))
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int swm_uart_getc(struct rt_serial_device *serial_device)
|
||||
{
|
||||
int ch;
|
||||
struct swm_uart_cfg *uart_cfg;
|
||||
RT_ASSERT(serial_device != RT_NULL);
|
||||
uart_cfg = serial_device->parent.user_data;
|
||||
|
||||
ch = -1;
|
||||
if (UART_IsRXFIFOEmpty(uart_cfg->UARTx) == 0)
|
||||
{
|
||||
UART_ReadByte(uart_cfg->UARTx, (uint32_t *)&ch);
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
static const struct rt_uart_ops swm_uart_ops =
|
||||
{
|
||||
.configure = swm_uart_configure,
|
||||
.control = swm_uart_control,
|
||||
.putc = swm_uart_putc,
|
||||
.getc = swm_uart_getc,
|
||||
.dma_transmit = RT_NULL};
|
||||
|
||||
/**
|
||||
* Uart common interrupt process. This need add to uart ISR.
|
||||
*
|
||||
* @param serial serial device
|
||||
*/
|
||||
static void swm_uart_isr(struct rt_serial_device *serial_device)
|
||||
{
|
||||
struct swm_uart_cfg *uart_cfg;
|
||||
RT_ASSERT(serial_device != RT_NULL);
|
||||
uart_cfg = serial_device->parent.user_data;
|
||||
|
||||
/* UART in mode Receiver -------------------------------------------------*/
|
||||
if (UART_INTStat(uart_cfg->UARTx, UART_IT_RX_THR) || UART_INTStat(uart_cfg->UARTx, UART_IT_RX_TOUT))
|
||||
{
|
||||
if(!UART_IsRXFIFOEmpty(uart_cfg->UARTx))
|
||||
{
|
||||
rt_hw_serial_isr(serial_device, RT_SERIAL_EVENT_RX_IND);
|
||||
}
|
||||
|
||||
if(UART_INTStat(uart_cfg->UARTx, UART_IT_RX_TOUT))
|
||||
{
|
||||
UART_INTClr(uart_cfg->UARTx, UART_IT_RX_TOUT);
|
||||
|
||||
rt_hw_serial_isr(serial_device, RT_SERIAL_EVENT_RX_TIMEOUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BSP_USING_UART0)
|
||||
void UART0_Handler(void)
|
||||
{
|
||||
rt_interrupt_enter();
|
||||
swm_uart_isr(&(uart_obj[UART0_INDEX].serial_device));
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif /* BSP_USING_UART0 */
|
||||
|
||||
#if defined(BSP_USING_UART1)
|
||||
void UART1_Handler(void)
|
||||
{
|
||||
rt_interrupt_enter();
|
||||
swm_uart_isr(&(uart_obj[UART1_INDEX].serial_device));
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif /* BSP_USING_UART1 */
|
||||
|
||||
#if defined(BSP_USING_UART2)
|
||||
void UART2_Handler(void)
|
||||
{
|
||||
rt_interrupt_enter();
|
||||
swm_uart_isr(&(uart_obj[UART2_INDEX].serial_device));
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif /* BSP_USING_UART2 */
|
||||
|
||||
#if defined(BSP_USING_UART3)
|
||||
void UART3_Handler(void)
|
||||
{
|
||||
rt_interrupt_enter();
|
||||
swm_uart_isr(&(uart_obj[UART3_INDEX].serial_device));
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif /* BSP_USING_UART3 */
|
||||
|
||||
int swm_uart_init(void)
|
||||
{
|
||||
struct serial_configure serial_cfg = RT_SERIAL_CONFIG_DEFAULT;
|
||||
int i = 0;
|
||||
rt_err_t result = RT_EOK;
|
||||
|
||||
#ifdef BSP_USING_UART0
|
||||
PORT_Init(PORTM, PIN0, PORTM_PIN0_UART0_RX, 1);
|
||||
PORT_Init(PORTM, PIN1, PORTM_PIN1_UART0_TX, 0);
|
||||
#endif
|
||||
#ifdef BSP_USING_UART1
|
||||
PORT_Init(PORTD, PIN4, PORTD_PIN4_UART1_RX, 1);
|
||||
PORT_Init(PORTD, PIN3, PORTD_PIN3_UART1_TX, 0);
|
||||
#endif
|
||||
#ifdef BSP_USING_UART2
|
||||
PORT_Init(PORTC, PIN1, PORTC_PIN1_UART2_RX, 1);
|
||||
PORT_Init(PORTC, PIN0, PORTC_PIN0_UART2_TX, 0);
|
||||
#endif
|
||||
#ifdef BSP_USING_UART3
|
||||
PORT_Init(PORTC, PIN2, PORTC_PIN2_UART3_RX, 1);
|
||||
PORT_Init(PORTC, PIN3, PORTC_PIN3_UART3_TX, 0);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < sizeof(swm_uart_cfg) / sizeof(swm_uart_cfg[0]); i++)
|
||||
{
|
||||
uart_obj[i].uart_cfg = &swm_uart_cfg[i];
|
||||
uart_obj[i].serial_device.ops = &swm_uart_ops;
|
||||
uart_obj[i].serial_device.config = serial_cfg;
|
||||
|
||||
result = rt_hw_serial_register(&uart_obj[i].serial_device, uart_obj[i].uart_cfg->name,
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart_obj[i].uart_cfg);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* BSP_USING_UART */
|
||||
#endif /* RT_USING_SERIAL */
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_UART_H__
|
||||
#define __DRV_UART_H__
|
||||
|
||||
#include "board.h"
|
||||
|
||||
int swm_uart_init(void);
|
||||
|
||||
#endif /* __DRV_UART_H__ */
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#include "drv_wdt.h"
|
||||
|
||||
#ifdef RT_USING_WDT
|
||||
#ifdef BSP_USING_WDT
|
||||
//#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.wdt"
|
||||
#include <drv_log.h>
|
||||
|
||||
struct swm_wdt_cfg
|
||||
{
|
||||
const char *name;
|
||||
WDT_TypeDef *WDTx;
|
||||
};
|
||||
|
||||
struct swm_wdt_device
|
||||
{
|
||||
struct swm_wdt_cfg *wdt_cfg;
|
||||
struct rt_watchdog_device wdt_device;
|
||||
};
|
||||
|
||||
static struct swm_wdt_cfg swm_wdt_cfg =
|
||||
{
|
||||
.name = "wdt",
|
||||
.WDTx = WDT,
|
||||
};
|
||||
|
||||
static struct swm_wdt_device wdt_obj;
|
||||
|
||||
static rt_err_t swm_wdt_configure(rt_watchdog_t *wdt_device)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t swm_wdt_control(rt_watchdog_t *wdt_device, int cmd, void *arg)
|
||||
{
|
||||
struct swm_wdt_cfg *wdt_cfg;
|
||||
RT_ASSERT(wdt_device != RT_NULL);
|
||||
wdt_cfg = wdt_device->parent.user_data;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case RT_DEVICE_CTRL_WDT_KEEPALIVE:
|
||||
WDT_Feed(wdt_cfg->WDTx);
|
||||
break;
|
||||
case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
|
||||
WDT_Init(wdt_cfg->WDTx, 0, (1024 * (*(rt_uint32_t *)arg)));
|
||||
break;
|
||||
case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:
|
||||
*(rt_uint32_t *)arg = (wdt_cfg->WDTx->RSTVAL) / 1024;
|
||||
break;
|
||||
case RT_DEVICE_CTRL_WDT_GET_TIMELEFT:
|
||||
// not support
|
||||
break;
|
||||
case RT_DEVICE_CTRL_WDT_START:
|
||||
WDT_Start(wdt_cfg->WDTx);
|
||||
break;
|
||||
case RT_DEVICE_CTRL_WDT_STOP:
|
||||
WDT_Stop(wdt_cfg->WDTx);
|
||||
break;
|
||||
default:
|
||||
LOG_W("This command is not supported.");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static const struct rt_watchdog_ops swm_wdt_ops =
|
||||
{
|
||||
.init = swm_wdt_configure,
|
||||
.control = swm_wdt_control};
|
||||
|
||||
int swm_wdt_init(void)
|
||||
{
|
||||
int result = RT_EOK;
|
||||
|
||||
wdt_obj.wdt_cfg = &swm_wdt_cfg;
|
||||
wdt_obj.wdt_device.ops = &swm_wdt_ops;
|
||||
|
||||
result = rt_hw_watchdog_register(&wdt_obj.wdt_device, wdt_obj.wdt_cfg->name, RT_DEVICE_FLAG_RDWR, wdt_obj.wdt_cfg);
|
||||
if(result != RT_EOK)
|
||||
{
|
||||
LOG_E("wdt device register fail.");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D("wdt device register success.");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
INIT_BOARD_EXPORT(swm_wdt_init);
|
||||
|
||||
#endif /* BSP_USING_WDT */
|
||||
#endif /* RT_USING_WDT */
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-07-01 lik first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_WDT_H__
|
||||
#define __DRV_WDT_H__
|
||||
|
||||
#include "board.h"
|
||||
|
||||
int swm_wdt_init(void);
|
||||
|
||||
#endif /* __DRV_WDT_H__ */
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-02-26 lik first version
|
||||
*/
|
||||
|
||||
#ifndef __LCD_PORT_H__
|
||||
#define __LCD_PORT_H__
|
||||
|
||||
#include "board.h"
|
||||
|
||||
/* atk 4.3 inch screen, 480 * 272 */
|
||||
#define LCD_WIDTH 480
|
||||
#define LCD_HEIGHT 272
|
||||
#define LCD_BITS_PER_PIXEL 16
|
||||
#define LCD_BUF_SIZE (LCD_WIDTH * LCD_HEIGHT * LCD_BITS_PER_PIXEL / 8)
|
||||
#define LCD_PIXEL_FORMAT RTGRAPHIC_PIXEL_FORMAT_RGB565
|
||||
|
||||
#define LCD_CLK_DIV 15
|
||||
#define LCD_HSYNC_WIDTH 5
|
||||
#define LCD_VSYNC_WIDTH 5
|
||||
#define LCD_HBP 40
|
||||
#define LCD_VBP 8
|
||||
#define LCD_HFP 5
|
||||
#define LCD_VFP 8
|
||||
|
||||
#define LCD_BACKLIGHT_USING_GPIO
|
||||
#define LCD_BL_GPIO GET_PIN(D, 9)
|
||||
#define LCD_DISP_GPIO GET_PIN(D, 1)
|
||||
|
||||
#endif /* __LCD_PORT_H__ */
|
||||
Reference in New Issue
Block a user