Synwit MCU 采用新的 BSP 框架,将 BSP 与 libraries 分离 (#8432)

This commit is contained in:
Xian Wu
2023-12-27 18:41:52 +08:00
committed by GitHub
parent 7b4592c2d1
commit 6360253c12
301 changed files with 2671 additions and 4213 deletions
@@ -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__ */