diff --git a/APP_Framework/Applications/app_test/test_adc.c b/APP_Framework/Applications/app_test/test_adc.c index ceceec161..c1b8f66d3 100644 --- a/APP_Framework/Applications/app_test/test_adc.c +++ b/APP_Framework/Applications/app_test/test_adc.c @@ -26,9 +26,8 @@ void TestAdc(void) { int adc_fd; - uint8 adc_channel = 0x0; - uint16 adc_sample, adc_value_decimal = 0; - float adc_value; + uint8 adc_channel = 0x1; + uint16 adc_sample = 0; adc_fd = PrivOpen(ADC_DEV_DRIVER, O_RDWR); if (adc_fd < 0) { @@ -45,13 +44,11 @@ void TestAdc(void) return; } - PrivRead(adc_fd, &adc_sample, 2); - - adc_value = (float)adc_sample * (3.3 / 4096); - - adc_value_decimal = (adc_value - (uint16)adc_value) * 1000; - - printf("adc sample %u value integer %u decimal %u\n", adc_sample, (uint16)adc_value, adc_value_decimal); + for (int i = 0; i < 10; i ++) { + PrivRead(adc_fd, &adc_sample, 2); + printf("adc sample %u mv\n", adc_sample); + PrivTaskDelay(500); + } PrivClose(adc_fd); diff --git a/APP_Framework/Applications/app_test/test_dac.c b/APP_Framework/Applications/app_test/test_dac.c index 37ac2bf1c..8628d1a00 100644 --- a/APP_Framework/Applications/app_test/test_dac.c +++ b/APP_Framework/Applications/app_test/test_dac.c @@ -22,17 +22,16 @@ #include #ifdef ADD_XIZI_FEATURES -void TestDac(void) +static pthread_t test_dac_task; + +static void *TestDacTask(void *parameter) { int dac_fd; - uint16 dac_set_value = 800; - uint16 dac_sample, dac_value_decimal = 0; - float dac_value; + uint16 dac_set_value = 4096 * 10;//sin length dac_fd = PrivOpen(DAC_DEV_DRIVER, O_RDWR); if (dac_fd < 0) { KPrintf("open dac fd error %d\n", dac_fd); - return; } struct PrivIoctlCfg ioctl_cfg; @@ -41,20 +40,24 @@ void TestDac(void) if (0 != PrivIoctl(dac_fd, OPE_CFG, &ioctl_cfg)) { KPrintf("ioctl dac fd error %d\n", dac_fd); PrivClose(dac_fd); - return; } - PrivRead(dac_fd, &dac_sample, 2); - - dac_value = (float)dac_sample * (3.3 / 4096);//Vref+ need to be 3.3V - - dac_value_decimal = (dac_value - (uint16)dac_value) * 1000; - - printf("dac sample %u value integer %u decimal %u\n", dac_sample, (uint16)dac_value, dac_value_decimal); + while (1) { + //start dac output sin + PrivWrite(dac_fd, NULL, 0); + } PrivClose(dac_fd); +} - return; +void TestDac(void) +{ + pthread_attr_t tid; + tid.schedparam.sched_priority = 20; + tid.stacksize = 4096; + + PrivTaskCreate(&test_dac_task, &tid, &TestDacTask, NULL); + PrivTaskStartup(&test_dac_task); } PRIV_SHELL_CMD_FUNCTION(TestDac, a dac test sample, PRIV_SHELL_CMD_MAIN_ATTR); #endif \ No newline at end of file diff --git a/APP_Framework/Applications/app_test/test_hwtimer.c b/APP_Framework/Applications/app_test/test_hwtimer.c index 9e6f7f981..9438683f8 100644 --- a/APP_Framework/Applications/app_test/test_hwtimer.c +++ b/APP_Framework/Applications/app_test/test_hwtimer.c @@ -28,11 +28,11 @@ static uint16_t pin_fd=0; static struct PinStat pin_led; -void ledflip(void *parameter) +void LedFlip(void *parameter) { pin_led.pin = BSP_LED_PIN; pin_led.val = !pin_led.val; - PrivWrite(pin_fd,&pin_led,NULL_PARAMETER); + PrivWrite(pin_fd, &pin_led, NULL_PARAMETER); } void TestHwTimer(void) @@ -40,22 +40,22 @@ void TestHwTimer(void) x_ticks_t period = 100000; pin_fd = PrivOpen(HWTIMER_PIN_DEV_DRIVER, O_RDWR); - if(pin_fd<0){ + if(pin_fd<0) { printf("open pin fd error:%d\n",pin_fd); return; } int timer_fd = PrivOpen(HWTIMER_TIMER_DEV_DRIVER, O_RDWR); - if(timer_fd<0){ + if(timer_fd<0) { printf("open timer fd error:%d\n",timer_fd); return; } //config led pin in board - struct PinParam parameter; - parameter.cmd = GPIO_CONFIG_MODE; - parameter.pin = BSP_LED_PIN; - parameter.mode = GPIO_CFG_OUTPUT; + struct PinParam parameter; + parameter.cmd = GPIO_CONFIG_MODE; + parameter.pin = BSP_LED_PIN; + parameter.mode = GPIO_CFG_OUTPUT; struct PrivIoctlCfg ioctl_cfg; ioctl_cfg.ioctl_driver_type = PIN_TYPE; @@ -68,7 +68,7 @@ void TestHwTimer(void) } ioctl_cfg.ioctl_driver_type = TIME_TYPE; - ioctl_cfg.args = (void *)&ledflip; + ioctl_cfg.args = (void *)&LedFlip; if (0 != PrivIoctl(timer_fd, OPE_INT, &ioctl_cfg)) { printf("timer pin fd error %d\n", pin_fd); PrivClose(pin_fd); @@ -82,13 +82,10 @@ void TestHwTimer(void) return; } - while(1){ + while(1) { } - // int32 timer_handle = KCreateTimer("LED on and off by 1s",&ledflip,&pin_fd,period,TIMER_TRIGGER_PERIODIC); - - // KTimerStartRun(timer_handle); PrivClose(pin_fd); PrivClose(timer_fd); } diff --git a/Ubiquitous/XiZi_IIoT/board/cortex-m4-emulator/README.md b/Ubiquitous/XiZi_IIoT/board/cortex-m4-emulator/README.md index f8d004f9a..b5b89263b 100644 --- a/Ubiquitous/XiZi_IIoT/board/cortex-m4-emulator/README.md +++ b/Ubiquitous/XiZi_IIoT/board/cortex-m4-emulator/README.md @@ -91,8 +91,8 @@ git clone https://gitlink.org.cn/xuos/xiuos.git 使用VScode打开代码,具体操作步骤为:在源码文件夹下打开系统终端,输入`code .`即可打开VScode开发环境,如下图所示: -
- +
+
@@ -145,14 +145,14 @@ make BOARD=cortex-m4-emulator menuconfig 2.在menuconfig界面配置需要关闭和开启的功能,按回车键进入下级菜单,按Y键选中需要开启的功能,按N键选中需要关闭的功能,配置结束后保存并退出(本例旨在演示简单的输出例程,所以没有需要配置的选项,双击快捷键ESC退出配置) -
- +
+
退出时选择`yes`保存上面所配置的内容,如下图所示: -
- +
+
3.继续执行以下命令,进行编译 @@ -183,8 +183,8 @@ qemu-system-arm -machine netduinoplus2 -nographic -kernel build/XiZi-cortex-m4- QEMU运行起来后将会在终端上看到信息打印输出 -
- +
+
### 4.3 调试 @@ -204,5 +204,5 @@ qemu-system-arm -machine netduinoplus2 -nographic -kernel build/XiZi-cortex-m4- 然后要重新开启另一个linux系统终端一个终端,执行`riscv-none-embed-gdb`命令 ``` -gdb-multiarch build/XiZi-cortex-m4-emulator.elf -ex "target remote localhost:1234" +gdb-multiarch build/XiZi-cortex-m4-emulator.elf -ex "target remote localhost:1234" ``` \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/adc/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/adc/Kconfig index f721032c6..fdc0b1c91 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/adc/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/adc/Kconfig @@ -1,74 +1,13 @@ -menuconfig BSP_USING_ADC1 - bool "Enable ADC1" - default y - if BSP_USING_ADC1 - config ADC1_BUS_NAME - string "adc 1 bus name" - default "adc1" +if BSP_USING_ADC + config ADC1_BUS_NAME + string "adc 1 bus name" + default "adc1" - config ADC1_DRIVER_NAME - string "adc 1 driver name" - default "adc1_drv" + config ADC1_DRIVER_NAME + string "adc 1 driver name" + default "adc1_drv" - config ADC1_DEVICE_NAME - string "adc 1 bus device name" - default "adc1_dev" - - config ADC1_GPIO_NUM - int "adc 1 gpio pin num" - default "0" - - config ADC1_GPIO_DEF - string "adc 1 gpio define type" - default "A" - endif - -menuconfig BSP_USING_ADC2 - bool "Enable ADC2" - default y - if BSP_USING_ADC2 - config ADC2_BUS_NAME - string "adc 2 bus name" - default "adc2" - - config ADC2_DRIVER_NAME - string "adc 2 driver name" - default "adc2_drv" - - config ADC2_DEVICE_NAME - string "adc 2 bus device name" - default "adc2_dev" - - config ADC2_GPIO_NUM - int "adc 2 gpio pin num" - default "6" - - config ADC2_GPIO_DEF - string "adc 2 gpio define type" - default "A" - endif - -menuconfig BSP_USING_ADC3 - bool "Enable ADC3" - default y - if BSP_USING_ADC3 - config ADC3_BUS_NAME - string "adc 3 bus name" - default "adc3" - - config ADC3_DRIVER_NAME - string "adc 3 driver name" - default "adc3_drv" - - config ADC3_DEVICE_NAME - string "adc 3 bus device name" - default "adc3_dev" - - config ADC3_GPIO_NUM - int "adc 3 gpio pin num" - default "0" - - config ADC3_GPIO_DEF - string "adc 3 gpio define type" - default "A" - endif + config ADC1_DEVICE_NAME + string "adc 1 bus device name" + default "adc1_dev" +endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/adc/connect_adc.c b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/adc/connect_adc.c index 620b21d8f..4e8b09475 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/adc/connect_adc.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/adc/connect_adc.c @@ -20,79 +20,251 @@ #include -#define _ADC_CONS(string1, string2) string1##string2 -#define ADC_CONS(string1, string2) _ADC_CONS(string1, string2) +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ -#ifdef BSP_USING_ADC1 -#define ADC1_GPIO ADC_CONS(GPIO_Pin_, ADC1_GPIO_NUM) +/* The clock source of ADC. */ +#define ADC_CLK_SYS_CLK (1U) +#define ADC_CLK_PLLH (2U) +#define ADC_CLK_PLLA (3U) + +/* + * Selects a clock source according to the application requirements. + * PCLK4 is the clock for digital interface. + * PCLK2 is the clock for analog circuit. + * PCLK4 and PCLK2 are synchronous when the clock source is PLL. + * PCLK4 : PCLK2 = 1:1, 2:1, 4:1, 8:1, 1:2, 1:4. + * PCLK2 is in range [1MHz, 60MHz]. + * If the system clock is selected as the ADC clock, macro 'ADC_ADC_CLK' can only be defined as 'CLK_PERIPHCLK_PCLK'. + * If PLLH is selected as the ADC clock, macro 'ADC_ADC_CLK' can be defined as 'CLK_PERIPHCLK_PLLx'(x=Q, R). + * If PLLA is selected as the ADC clock, macro 'ADC_ADC_CLK' can be defined as 'CLK_PERIPHCLK_PLLXx'(x=P, Q, R). + */ +#define ADC_CLK_SEL (ADC_CLK_SYS_CLK) + +#if (ADC_CLK_SEL == ADC_CLK_SYS_CLK) +#define ADC_CLK (CLK_PERIPHCLK_PCLK) + +#elif (ADC_CLK_SEL == ADC_CLK_PLLH) +#define ADC_CLK (CLK_PERIPHCLK_PLLQ) + +#elif (ADC_CLK_SEL == ADC_CLK_PLLA) +#define ADC_CLK (CLK_PERIPHCLK_PLLXP) + +#else +#error "The clock source your selected does not exist!!!" #endif -#ifdef BSP_USING_ADC2 -#define ADC2_GPIO ADC_CONS(GPIO_Pin_, ADC2_GPIO_NUM) -#endif +/* ADC unit instance for this example. */ +#define ADC_UNIT (CM_ADC1) +#define ADC_PERIPH_CLK (FCG3_PERIPH_ADC1) -#ifdef BSP_USING_ADC3 -#define ADC3_GPIO ADC_CONS(GPIO_Pin_, ADC3_GPIO_NUM) -#endif +/* Selects ADC channels that needed. */ +#define ADC_CH_POTENTIOMETER (ADC_CH3) +#define ADC_CH (ADC_CH_POTENTIOMETER) +#define ADC_CH_PORT (GPIO_PORT_A) +#define ADC_CH_PIN (GPIO_PIN_03) -static int AdcUdelay(uint32 us) +/* ADC sequence to be used. */ +#define ADC_SEQ (ADC_SEQ_A) +/* Flag of conversion end. */ +#define ADC_EOC_FLAG (ADC_FLAG_EOCA) + +/* ADC reference voltage. The voltage of pin VREFH. */ +#define ADC_VREF (3.3F) + +/* ADC accuracy(according to the resolution of ADC). */ +#define ADC_ACCURACY (1UL << 12U) + +/* Calculate the voltage(mV). */ +#define ADC_CAL_VOL(adcVal) (uint16_t)((((float32_t)(adcVal) * ADC_VREF) / ((float32_t)ADC_ACCURACY)) * 1000.F) + +/* Timeout value. */ +#define ADC_TIMEOUT_VAL (1000U) + +/** + * @brief Set specified ADC pin to analog mode. + * @param None + * @retval None + */ +static void AdcSetPinAnalogMode(void) { - uint32 ticks; - uint32 told, tnow, tcnt = 0; - uint32 reload = SysTick->LOAD; + stc_gpio_init_t stcGpioInit; - ticks = us * reload / (1000000 / 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) { - return 0; - break; - } - } - } + (void)GPIO_StructInit(&stcGpioInit); + stcGpioInit.u16PinAttr = PIN_ATTR_ANALOG; + (void)GPIO_Init(ADC_CH_PORT, ADC_CH_PIN, &stcGpioInit); } -static uint16 GetAdcAverageValue(CM_ADC_TypeDef *ADCx, uint8 channel, uint8 times) +/** + * @brief Configures ADC clock. + * @param None + * @retval None + */ +static void AdcClockConfig(void) { - uint32 temp_val = 0; - int i; +#if (ADC_CLK_SEL == ADC_CLK_SYS_CLK) + /* + * 1. Configures the clock divider of PCLK2 and PCLK4 here or in the function of configuring the system clock. + * In this example, the system clock is MRC@8MHz. + * PCLK4 is the digital interface clock, and PCLK2 is the analog circuit clock. + * Make sure that PCLK2 and PCLK4 meet the following conditions: + * PCLK4 : PCLK2 = 1:1, 2:1, 4:1, 8:1, 1:2, 1:4. + * PCLK2 is in range [1MHz, 60MHz]. + */ + CLK_SetClockDiv((CLK_BUS_PCLK2 | CLK_BUS_PCLK4), (CLK_PCLK2_DIV8 | CLK_PCLK4_DIV2)); - for(i = 0;i < times;i ++) { - temp_val += ADC_GetValue(ADCx, channel) & 0x0FFF; - KPrintf("GetAdcAverageValue val %u\n", ADC_GetValue(ADCx, channel)); - AdcUdelay(5000); - } - return temp_val / times; -} +#elif (ADC_CLK_SEL == ADC_CLK_PLLH) + /* + * 1. Configures PLLH and the divider of PLLHx(x=Q, R). + * PLLHx(x=Q, R) is used as both the digital interface clock and the analog circuit clock. + * PLLHx(x=Q, R) must be in range [1MHz, 60MHz] for ADC use. + * The input source of PLLH is XTAL(8MHz). + */ + stc_clock_pll_init_t stcPLLHInit; + stc_clock_xtal_init_t stcXtalInit; + /* Configures XTAL. PLLH input source is XTAL. */ + (void)CLK_XtalStructInit(&stcXtalInit); + stcXtalInit.u8State = CLK_XTAL_ON; + stcXtalInit.u8Drv = CLK_XTAL_DRV_ULOW; + stcXtalInit.u8Mode = CLK_XTAL_MD_OSC; + stcXtalInit.u8StableTime = CLK_XTAL_STB_499US; + (void)CLK_XtalInit(&stcXtalInit); + + (void)CLK_PLLStructInit(&stcPLLHInit); + /* + * PLLHx(x=Q, R) = ((PLL_source / PLLM) * PLLN) / PLLx + * PLLHQ = (8 / 1) * 80 /16 = 40MHz + * PLLHR = (8 / 1) * 80 /16 = 40MHz + */ + stcPLLHInit.u8PLLState = CLK_PLL_ON; + stcPLLHInit.PLLCFGR = 0UL; + stcPLLHInit.PLLCFGR_f.PLLM = (1UL - 1UL); + stcPLLHInit.PLLCFGR_f.PLLN = (80UL - 1UL); + stcPLLHInit.PLLCFGR_f.PLLP = (4UL - 1UL); + stcPLLHInit.PLLCFGR_f.PLLQ = (16UL - 1UL); + stcPLLHInit.PLLCFGR_f.PLLR = (16UL - 1UL); + /* stcPLLHInit.PLLCFGR_f.PLLSRC = CLK_PLL_SRC_XTAL; */ + (void)CLK_PLLInit(&stcPLLHInit); + +#elif (ADC_CLK_SEL == ADC_CLK_PLLA) + /* + * 1. Configures PLLA and the divider of PLLAx(x=P, Q, R). + * PLLAx(x=P, Q, R) is used as both the digital interface clock and the analog circuit clock. + * PLLAx(x=P, Q, R) must be in range [1MHz, 60MHz] for ADC use. + * The input source of PLLA is HRC(16MHz). + */ + stc_clock_pllx_init_t stcPLLAInit; + + /* Enable HRC(16MHz) for PLLA. */ + CLK_HrcCmd(ENABLE); + + /* Specify the input source of PLLA. NOTE!!! PLLA and PLLH use the same input source. */ + CLK_SetPLLSrc(CLK_PLL_SRC_HRC); + /* PLLA configuration */ + (void)CLK_PLLxStructInit(&stcPLLAInit); + /* + * PLLAx(x=P, Q, R) = ((PLL_source / PLLM) * PLLN) / PLLx + * PLLAP = (16 / 2) * 40 / 8 = 40MHz + * PLLAQ = (16 / 2) * 40 / 10 = 32MHz + * PLLAR = (16 / 2) * 40 / 16 = 20MHz + */ + stcPLLAInit.u8PLLState = CLK_PLLX_ON; + stcPLLAInit.PLLCFGR = 0UL; + stcPLLAInit.PLLCFGR_f.PLLM = (2UL - 1UL); + stcPLLAInit.PLLCFGR_f.PLLN = (40UL - 1UL); + stcPLLAInit.PLLCFGR_f.PLLR = (8UL - 1UL); + stcPLLAInit.PLLCFGR_f.PLLQ = (10UL - 1UL); + stcPLLAInit.PLLCFGR_f.PLLP = (16UL - 1UL); + (void)CLK_PLLxInit(&stcPLLAInit); +#endif + /* 2. Specifies the clock source of ADC. */ + CLK_SetPeriClockSrc(ADC_CLK); +} + +/** + * @brief Initializes ADC. + * @param None + * @retval None + */ +static void AdcInitConfig(void) +{ + stc_adc_init_t stcAdcInit; + + /* 1. Enable ADC peripheral clock. */ + FCG_Fcg3PeriphClockCmd(ADC_PERIPH_CLK, ENABLE); + + /* 2. Modify the default value depends on the application. Not needed here. */ + (void)ADC_StructInit(&stcAdcInit); + + /* 3. Initializes ADC. */ + (void)ADC_Init(ADC_UNIT, &stcAdcInit); + + /* 4. ADC channel configuration. */ + /* 4.1 Set the ADC pin to analog input mode. */ + AdcSetPinAnalogMode(); + /* 4.2 Enable ADC channels. Call ADC_ChCmd() again to enable more channels if needed. */ + ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CH, ENABLE); + + /* 5. Conversion data average calculation function, if needed. + Call ADC_ConvDataAverageChCmd() again to enable more average channels if needed. */ + ADC_ConvDataAverageConfig(ADC_UNIT, ADC_AVG_CNT8); + ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CH, ENABLE); +} + +/** + * @brief Use ADC in polling mode. + * @param None + * @retval uint16_t u16AdcValue + */ +static uint16_t AdcPolling(void) +{ + uint16_t u16AdcValue = 0; + int32_t iRet = LL_ERR; + __IO uint32_t u32TimeCount = 0UL; + + /* Can ONLY start sequence A conversion. + Sequence B needs hardware trigger to start conversion. */ + ADC_Start(ADC_UNIT); + do { + if (ADC_GetStatus(ADC_UNIT, ADC_EOC_FLAG) == SET) { + ADC_ClearStatus(ADC_UNIT, ADC_EOC_FLAG); + iRet = LL_OK; + break; + } + } while (u32TimeCount++ < ADC_TIMEOUT_VAL); + + if (iRet == LL_OK) { + /* Get any ADC value of sequence A channel that needed. */ + u16AdcValue = ADC_GetValue(ADC_UNIT, ADC_CH); + KPrintf("The ADC value of potentiometer is %u, voltage is %u mV\r\n", + u16AdcValue, ADC_CAL_VOL(u16AdcValue)); + } else { + ADC_Stop(ADC_UNIT); + KPrintf("ADC exception.\r\n"); + } + + return ADC_CAL_VOL(u16AdcValue); +} static uint32 AdcOpen(void *dev) { x_err_t ret = EOK; - stc_adc_init_t stcAdcInit; - ADC_StructInit(&stcAdcInit); struct AdcHardwareDevice* adc_dev = (struct AdcHardwareDevice*)dev; - CM_ADC_TypeDef *ADCx= (CM_ADC_TypeDef *)adc_dev->private_data; - ADC_Init((ADCx),&stcAdcInit); + + AdcClockConfig(); + AdcInitConfig(); + return ret; } - static uint32 AdcClose(void *dev) { - // CM_ADC_TypeDef *adc_dev = (CM_ADC_TypeDef*)dev; struct AdcHardwareDevice* adc_dev = (struct AdcHardwareDevice*)dev; - CM_ADC_TypeDef *ADCx= (CM_ADC_TypeDef *)adc_dev->private_data; - + + ADC_Stop(ADC_UNIT); ADC_DeInit(ADCx); return EOK; @@ -100,19 +272,10 @@ static uint32 AdcClose(void *dev) static uint32 AdcRead(void *dev, struct BusBlockReadParam *read_param) { - struct AdcHardwareDevice *adc_dev = (struct AdcHardwareDevice *)dev; + *(uint16 *)read_param->buffer = AdcPolling(); + read_param->read_length = 2; - struct HwAdc *adc_cfg = (struct HwAdc *)adc_dev->haldev.private_data; - - uint16 adc_average_value = 0; - uint8 times = 20; - - adc_average_value = GetAdcAverageValue(adc_cfg->ADCx, adc_cfg->adc_channel, times); - - *(uint16 *)read_param->buffer = adc_average_value; - read_param->read_length = 2; - - return read_param->read_length; + return EOK; } static uint32 AdcDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) @@ -131,9 +294,9 @@ static uint32 AdcDrvConfigure(void *drv, struct BusConfigureInfo *configure_info { case OPE_CFG: adc_cfg->adc_channel = *(uint8 *)configure_info->private_data; - if (adc_cfg->adc_channel > 18) { - KPrintf("AdcDrvConfigure set adc channel(0-18) %u error!", adc_cfg->adc_channel); - adc_cfg->adc_channel = 0; + if (adc_cfg->adc_channel != 1) { + KPrintf("AdcDrvConfigure set adc channel(1) %u error!", adc_cfg->adc_channel); + adc_cfg->adc_channel = 1; ret = ERROR; } break; @@ -156,7 +319,7 @@ int HwAdcInit(void) { x_err_t ret = EOK; -#ifdef BSP_USING_ADC1 +#ifdef BSP_USING_ADC static struct AdcBus adc1_bus; static struct AdcDriver adc1_drv; static struct AdcHardwareDevice adc1_dev; @@ -183,7 +346,7 @@ int HwAdcInit(void) adc1_dev.adc_dev_done = &dev_done; adc1_cfg.ADCx = CM_ADC1; - adc1_cfg.adc_channel = 0; + adc1_cfg.adc_channel = 1; ret = AdcDeviceRegister(&adc1_dev, (void *)&adc1_cfg, ADC1_DEVICE_NAME); if (ret != EOK) { @@ -197,88 +360,6 @@ int HwAdcInit(void) } #endif -#ifdef BSP_USING_ADC2 - static struct AdcBus adc2_bus; - static struct AdcDriver adc2_drv; - static struct AdcHardwareDevice adc2_dev; - static struct HwAdc adc2_cfg; - - adc2_drv.configure = AdcDrvConfigure; - - ret = AdcBusInit(&adc2_bus, ADC2_BUS_NAME); - if (ret != EOK) { - KPrintf("ADC2 bus init error %d\n", ret); - return ERROR; - } - - ret = AdcDriverInit(&adc2_drv, ADC2_DRIVER_NAME); - if (ret != EOK) { - KPrintf("ADC2 driver init error %d\n", ret); - return ERROR; - } - ret = AdcDriverAttachToBus(ADC2_DRIVER_NAME, ADC2_BUS_NAME); - if (ret != EOK) { - KPrintf("ADC2 driver attach error %d\n", ret); - return ERROR; - } - - adc2_dev.adc_dev_done = &dev_done; - adc2_cfg.ADCx = CM_ADC2; - adc2_cfg.adc_channel = 0; - - ret = AdcDeviceRegister(&adc2_dev, (void *)&adc2_cfg, ADC2_DEVICE_NAME); - if (ret != EOK) { - KPrintf("ADC2 device register error %d\n", ret); - return ERROR; - } - ret = AdcDeviceAttachToBus(ADC2_DEVICE_NAME, ADC2_BUS_NAME); - if (ret != EOK) { - KPrintf("ADC2 device register error %d\n", ret); - return ERROR; - } -#endif - -#ifdef BSP_USING_ADC3 - static struct AdcBus adc3_bus; - static struct AdcDriver adc3_drv; - static struct AdcHardwareDevice adc3_dev; - static struct HwAdc adc3_cfg; - - adc3_drv.configure = AdcDrvConfigure; - - ret = AdcBusInit(&adc3_bus, ADC3_BUS_NAME); - if (ret != EOK) { - KPrintf("ADC3 bus init error %d\n", ret); - return ERROR; - } - - ret = AdcDriverInit(&adc3_drv, ADC3_DRIVER_NAME); - if (ret != EOK) { - KPrintf("ADC3 driver init error %d\n", ret); - return ERROR; - } - ret = AdcDriverAttachToBus(ADC3_DRIVER_NAME, ADC3_BUS_NAME); - if (ret != EOK) { - KPrintf("ADC3 driver attach error %d\n", ret); - return ERROR; - } - - adc3_dev.adc_dev_done = &dev_done; - adc3_cfg.ADCx = CM_ADC3; - adc3_cfg.adc_channel = 0; - - ret = AdcDeviceRegister(&adc3_dev, (void *)&adc3_cfg, ADC3_DEVICE_NAME); - if (ret != EOK) { - KPrintf("ADC3 device register error %d\n", ret); - return ERROR; - } - ret = AdcDeviceAttachToBus(ADC3_DEVICE_NAME, ADC3_BUS_NAME); - if (ret != EOK) { - KPrintf("ADC3 device register error %d\n", ret); - return ERROR; - } -#endif - return ret; } diff --git a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/common/hc32_ll_driver/src/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/common/hc32_ll_driver/src/Makefile index 501d182d5..7254a2cb6 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/common/hc32_ll_driver/src/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/common/hc32_ll_driver/src/Makefile @@ -9,7 +9,7 @@ ifeq ($(CONFIG_BSP_USING_ADC),y) endif ifeq ($(CONFIG_BSP_USING_DAC),y) - SRC_FILES += hc32_ll_dac.c + SRC_FILES += hc32_ll_dac.c hc32_ll_mau.c endif ifeq ($(CONFIG_BSP_USING_SDIO),y) diff --git a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/dac/connect_dac.c b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/dac/connect_dac.c index 3cbd220c3..efcc80743 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/dac/connect_dac.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/dac/connect_dac.c @@ -20,56 +20,301 @@ #include -#define _DAC_CONS(string1, string2) string1##string2 -#define DAC_CONS(string1, string2) _DAC_CONS(string1, string2) +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ +#define DAC_UNIT1_PORT (GPIO_PORT_A) +#define DAC_UNIT1_CHN1_PIN (GPIO_PIN_04) -#ifdef BSP_USING_DAC -#define DAC_GPIO DAC_CONS(GPIO_Pin_, DAC_GPIO_NUM) +#define VREFH (3.3F) +#define DAC_CHN1 (0U) +#define DAC_CHN2 (1U) +#define DAC_DATA_ALIGN_12b_R (0U) +#define DAC_DATA_ALIGN_12b_L (1U) + +#define SUPPORT_AMP +#define SUPPORT_ADP +#define SINGLE_WAVE_DAC_CHN (DAC_CHN1) +#define DAC_DATA_ALIGN (DAC_DATA_ALIGN_12b_L) + +#define SINE_DOT_NUMBER (4096U) +#define SINE_NEGATIVE_TO_POSITVE (1.0F) + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ +typedef enum { + DAC_Unit1, + DAC_Unit2, + DAC_Unit_Max, +}en_dac_unit_t; + +typedef enum { + E_Dac_Single, + E_Dac_Dual, +}en_dac_cvt_t; + +typedef struct { + CM_DAC_TypeDef *pUnit; + en_dac_cvt_t enCvtType; + uint16_t u16Ch; +} stc_dac_handle_t; + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ +static stc_dac_handle_t m_stcDACHandle[DAC_Unit_Max] = {0}; +static uint32_t gu32SinTable[SINE_DOT_NUMBER]; +static stc_dac_handle_t *pSingleDac; + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ +/** + * @brief MAU Initialization + * @param None + * @retval None + */ +static void MauInit(void) +{ + /* Enable MAU peripheral clock. */ + FCG_Fcg0PeriphClockCmd(PWC_FCG0_MAU, ENABLE); +} + +/** + * @brief MAU De-Initialization + * @param None + * @retval None + */ +static void MauDeinit(void) +{ + /* Enable MAU peripheral clock. */ + FCG_Fcg0PeriphClockCmd(PWC_FCG0_MAU, DISABLE); +} + +/** + * @brief Sin table Initialization + * @param [in] pSinTable sin table + * @param [in] u32count number of pSinTable items + * @retval None + */ +static void SinTableInit(uint32_t pSinTable[], uint32_t u32count) +{ + uint32_t i; + uint32_t u32AngAvg = (uint32_t)(float32_t)((float32_t)((float32_t)MAU_SIN_ANGIDX_TOTAL / (float32_t)u32count) + 0.5); + float32_t fSin; + for (i = 0U; i < u32count; i++) { + fSin = (((float32_t)MAU_Sin(CM_MAU, (uint16_t)(u32AngAvg * i)) + / (float32_t)MAU_SIN_Q15_SCALAR + SINE_NEGATIVE_TO_POSITVE) / VREFH) * + (float32_t)DAC_DATAREG_VALUE_MAX + 0.5F; + +#if (DAC_DATA_ALIGN == DAC_DATA_ALIGN_12b_L) + { + pSinTable[i] = (uint32_t)fSin << 4; + } +#else + { + pSinTable[i] = (uint32_t)fSin; + } #endif - + } +} + +/** + * @brief Enable DAC peripheral clock + * @param [in] enUnit The selected DAC unit + * @retval None + */ +static void DacPClkEnable(en_dac_unit_t enUnit) +{ + uint32_t u32PClk; + switch (enUnit) { + case DAC_Unit1: + u32PClk = PWC_FCG3_DAC1; + break; + case DAC_Unit2: + u32PClk = PWC_FCG3_DAC2; + break; + default: + u32PClk = PWC_FCG3_DAC1 | PWC_FCG3_DAC2; + break; + } + /* Enable DAC peripheral clock. */ + FCG_Fcg3PeriphClockCmd(u32PClk, ENABLE); +} + +/** + * @brief Init DAC single channel + * @param [in] enUnit The selected DAC unit + * @retval A pointer of DAC handler + */ +static stc_dac_handle_t *DacSingleConversionInit(en_dac_unit_t enUnit) +{ + uint8_t u8Port; + uint16_t u16Pin; + stc_dac_handle_t *pDac; + + if (enUnit == DAC_Unit1) { + pDac = &m_stcDACHandle[DAC_Unit1]; + pDac->pUnit = CM_DAC1; + } else { + pDac = &m_stcDACHandle[DAC_Unit2]; + pDac->pUnit = CM_DAC2; + } + DacPClkEnable(enUnit); + + pDac->enCvtType = E_Dac_Single; +#if (SINGLE_WAVE_DAC_CHN == DAC_CHN1) + pDac->u16Ch = DAC_CH1; +#else + pDac->u16Ch = DAC_CH2; +#endif + + /* Init DAC by default value: source from data register and output enabled*/ + DAC_DeInit(pDac->pUnit); + stc_dac_init_t stInit; + (void)DAC_StructInit(&stInit); + (void)DAC_Init(pDac->pUnit, pDac->u16Ch, &stInit); +#if (DAC_DATA_ALIGN == DAC_DATA_ALIGN_12b_L) + DAC_DataRegAlignConfig(pDac->pUnit, DAC_DATA_ALIGN_L); +#else + DAC_DataRegAlignConfig(pDac->pUnit, DAC_DATA_ALIGN_R); +#endif + + /* Set DAC pin attribute to analog */ + if (enUnit == DAC_Unit1) { + u8Port = DAC_UNIT1_PORT; +#if (SINGLE_WAVE_DAC_CHN == DAC_CHN1) + u16Pin = DAC_UNIT1_CHN1_PIN; +#endif + } + stc_gpio_init_t stcGpioInit; + (void)GPIO_StructInit(&stcGpioInit); + stcGpioInit.u16PinAttr = PIN_ATTR_ANALOG; + (void)GPIO_Init(u8Port, u16Pin, &stcGpioInit); + +#ifdef SUPPORT_ADP + /* Set ADC first */ + /* Enable ADC peripheral clock. */ + FCG_Fcg3PeriphClockCmd(PWC_FCG3_ADC1 | PWC_FCG3_ADC2 | PWC_FCG3_ADC3, ENABLE); + if (CM_ADC1->STR == 0U) { + if (CM_ADC2->STR == 0U) { + if (CM_ADC3->STR == 0U) { + DAC_ADCPrioConfig(pDac->pUnit, DAC_ADP_SELECT_ALL, ENABLE); + DAC_ADCPrioCmd(pDac->pUnit, ENABLE); + } + } + } +#endif + return pDac; +} + +/** + * @brief Start single DAC conversions + * @param [in] pDac A pointer of DAC handler + * @retval None + */ +static void DacStartSingleConversion(const stc_dac_handle_t *pDac) +{ + /* Enalbe AMP */ +#ifdef SUPPORT_AMP + (void)DAC_AMPCmd(pDac->pUnit, pDac->u16Ch, ENABLE); +#endif + + (void)DAC_Start(pDac->pUnit, pDac->u16Ch); + +#ifdef SUPPORT_AMP + /* delay 3us before setting data*/ + DDL_DelayMS(1U); +#endif +} + +/** + * @brief Convert data by single DAC channel + * @param [in] pDac A pointer of DAC handler + * @param [in] pDataTable The data table to be converted + * @param [in] u32count Number of data table items + * @retval None + */ +__STATIC_INLINE void DacSetSingleConversionData(const stc_dac_handle_t *pDac, uint32_t const pDataTable[], uint32_t u32count) +{ + uint32_t i = 0U; + + for (i = 0U; i < u32count; i++) { +#ifdef SUPPORT_ADP + uint32_t u32TryCount = 100U; + while (u32TryCount != 0U) { + u32TryCount--; + if (SET != DAC_GetChConvertState(pDac->pUnit, pDac->u16Ch)) { + break; + } + } +#endif + DAC_SetChData(pDac->pUnit, pDac->u16Ch, (uint16_t)pDataTable[i]); + } +} + +/** + * @brief stop DAC conversion + * @param [in] pDac A pointer of DAC handler + * @retval None + */ +static void DAC_StopConversion(const stc_dac_handle_t *pDac) +{ + if (NULL == pDac) { + DAC_DeInit(CM_DAC1); + DAC_DeInit(CM_DAC2); + } else if (pDac->enCvtType != E_Dac_Dual) { + (void)DAC_Stop(pDac->pUnit, pDac->u16Ch); + } else { + DAC_StopDualCh(pDac->pUnit); + } +} static uint32 DacOpen(void *dev) { struct DacHardwareDevice *dac_dev = (struct DacHardwareDevice *)dev; - CM_DAC_TypeDef *DACx = (CM_DAC_TypeDef *)dac_dev->private_data; + /* Init MAU for generating sine data*/ + MauInit(); + /* Init sine data table */ + SinTableInit(gu32SinTable, SINE_DOT_NUMBER); - stc_dac_init_t pstcDacInit; - - DAC_StructInit(&pstcDacInit); - - DAC_Init(DACx,DAC_CH1,&pstcDacInit); + /* Init single DAC */ + pSingleDac = DacSingleConversionInit(DAC_Unit1); return EOK; } static uint32 DacClose(void *dev) { - struct DacHardwareDevice *dac_dev = (struct DacHardwareDevice *)dev; - CM_DAC_TypeDef *DACx = (CM_DAC_TypeDef *)dac_dev->private_data; - + + DAC_StopConversion(pSingleDac); + DAC_DeInit(DACx); + MauDeinit(); + + memset(gu32SinTable, 0 , sizeof(gu32SinTable)); + return EOK; } - -static uint32 DacRead(void *dev, struct BusBlockReadParam *read_param) +static uint32 DacWrite(void *dev, struct BusBlockWriteParam *write_param) { struct DacHardwareDevice *dac_dev = (struct DacHardwareDevice *)dev; + struct HwDac *dac_cfg = (struct HwDac *)dac_dev->haldev.private_data; - CM_DAC_TypeDef *DACx = (CM_DAC_TypeDef *)dac_dev->private_data; + for (int i = 0; i < dac_cfg->digital_data; i ++) { + DacStartSingleConversion(pSingleDac); + DacSetSingleConversionData(pSingleDac, &gu32SinTable[i], 1U); + if (i > SINE_DOT_NUMBER) { + i = 0; + } + } - uint16 dac_set_value = 0; - - dac_set_value = DAC_GetChConvertState(DACx,DAC_CH1); - - *(uint16 *)read_param->buffer = dac_set_value; - read_param->read_length = 2; - - return read_param->read_length; return EOK; } @@ -88,8 +333,6 @@ static uint32 DacDrvConfigure(void *drv, struct BusConfigureInfo *configure_info { case OPE_CFG: dac_cfg->digital_data = *(uint16 *)configure_info->private_data; - // DAC_SetChannel1Data(DAC_Align_12b_R, dac_cfg->digital_data);//12 bits、R-Align data format, digital data - DAC_SetChData(dac_cfg->DACx,DAC_CH1,dac_cfg->digital_data); break; default: break; @@ -102,8 +345,8 @@ static const struct DacDevDone dev_done = { DacOpen, DacClose, + DacWrite, NONE, - DacRead, }; int HwDacInit(void) diff --git a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/include/connect_dac.h b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/include/connect_dac.h index 1108fcfdb..c99f28010 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/include/connect_dac.h +++ b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/include/connect_dac.h @@ -34,13 +34,6 @@ struct HwDac uint16 digital_data; }; -typedef struct { - CM_DAC_TypeDef *pUnit; - // en_dac_cvt_t enCvtType; - uint16_t u16Ch; -} stc_dac_handle_t; - - int HwDacInit(void); #ifdef __cplusplus