diff --git a/device/st/bearpi_hm_micro/liteos_a/hdf_config/adc/adc_config.hcs b/device/st/bearpi_hm_micro/liteos_a/hdf_config/adc/adc_config.hcs new file mode 100755 index 0000000000000000000000000000000000000000..023d6902bf3e04ed8f34d6d86993c1e7095fc5b7 --- /dev/null +++ b/device/st/bearpi_hm_micro/liteos_a/hdf_config/adc/adc_config.hcs @@ -0,0 +1,48 @@ +root { + platform { + adc_config { + match_attr = "st_stm32mp157_adc"; + + template stm32mp1_adc_device { + dev_num = 1; + adc_enable = false; + reg_pbase = 0x48003000; + reg_size = 0x100; + sample_time = 0x0; // 1.5 ADC clock cycles + /* + From left to right, indicate channels from low to high; 0:disable 1:enable + */ + channel_enable = [0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; + data_width = 16; + /* [port,pin] + 0:GPIOA 1:GPIOB 2:GPIOC ...... 253:internal channel 254:ADC dedicated pin 255:unavailable + 0:PIN0 1:PIN1 2:PIN2 ...... 253:internal channel 254:ADC dedicated pin 255:unavailable + */ + pins = [254,254 ,254,254 ,5,11 ,0,6 + ,2,4 ,1,1 ,5,12 ,0,7 + ,2,5 ,1,0 ,2,0 ,2,1 + ,2,2 ,2,3 ,0,2 ,0,3 + ,0,0 ,0,1 ,0,4 ,0,5]; + } + + adc_1_0x48003000 :: stm32mp1_adc_device { + dev_num = 1; + adc_enable = true; + data_width = 8; + } + + adc_2_0x48003100 :: stm32mp1_adc_device { + dev_num = 2; + reg_pbase = 0x48003100; + reg_size = 0x200; + channel_enable = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; + pins = [254,254 ,254,254 ,5,13 ,0,6 + ,2,4 ,1,1 ,5,14 ,0,7 + ,2,5 ,1,0 ,2,0 ,2,1 + ,255,255 ,255,255 ,0,4 ,0,5 + ,253,253 ,253,253 ,253,253 ,253,253]; + /** Vbat Tsen Vref VddCore */ + } + } + } +} diff --git a/device/st/bearpi_hm_micro/liteos_a/hdf_config/device_info/device_info.hcs b/device/st/bearpi_hm_micro/liteos_a/hdf_config/device_info/device_info.hcs index c6ed24e5cd7f2e09a1372284f19c2eb3b00bc716..fe5f1bd3a66c49878831fe85d091fd02e2f76147 100755 --- a/device/st/bearpi_hm_micro/liteos_a/hdf_config/device_info/device_info.hcs +++ b/device/st/bearpi_hm_micro/liteos_a/hdf_config/device_info/device_info.hcs @@ -28,6 +28,14 @@ serviceName = "HDF_PLATFORM_PWM_2"; deviceMatchAttr = "st_stm32mp157_pwm_2"; } + device1 :: deviceNode { + policy = 1; + priority = 12; + permission = 0644; + moduleName = "HDF_PLATFORM_PWM"; + serviceName = "HDF_PLATFORM_PWM_3"; + deviceMatchAttr = "st_stm32mp157_pwm_3"; + } } device_gpio :: device { device0 :: deviceNode { @@ -123,6 +131,22 @@ deviceMatchAttr = "st_stm32mp157_i2c"; } } + device_adc :: device { + device0 :: deviceNode { + policy = 0; + priority = 50; + permission = 0644; + moduleName = "HDF_PLATFORM_ADC_MANAGER"; + serviceName = "HDF_PLATFORM_ADC_MANAGER"; + } + device1 :: deviceNode { + policy = 0; + priority = 55; + permission = 0644; + moduleName = "stm32mp157_adc_driver"; + deviceMatchAttr = "st_stm32mp157_adc"; + } + } device_e53 :: device { device0 :: deviceNode { policy = 2; diff --git a/device/st/bearpi_hm_micro/liteos_a/hdf_config/hdf.hcs b/device/st/bearpi_hm_micro/liteos_a/hdf_config/hdf.hcs index 28b47010dfe4eb2128181269d5df70d5ee6fdb75..10aa3c9ae5a55a5129bf2962cae5365cb294ec7a 100755 --- a/device/st/bearpi_hm_micro/liteos_a/hdf_config/hdf.hcs +++ b/device/st/bearpi_hm_micro/liteos_a/hdf_config/hdf.hcs @@ -1,4 +1,5 @@ #include "device_info/device_info.hcs" +#include "adc/adc_config.hcs" #include "uart/uart_config.hcs" #include "watchdog/watchdog_config.hcs" #include "mmc/mmc_config.hcs" diff --git a/device/st/bearpi_hm_micro/liteos_a/hdf_config/pwm/pwm_config.hcs b/device/st/bearpi_hm_micro/liteos_a/hdf_config/pwm/pwm_config.hcs old mode 100644 new mode 100755 index 456851036854869ff2df919d72e7af5c7fe93934..5917f7c5c0788173cb63f460a564a26fa69802da --- a/device/st/bearpi_hm_micro/liteos_a/hdf_config/pwm/pwm_config.hcs +++ b/device/st/bearpi_hm_micro/liteos_a/hdf_config/pwm/pwm_config.hcs @@ -11,15 +11,24 @@ root { match_attr = ""; } - device_0X40000000 :: pwm_device { + device_pwm2 :: pwm_device { tim_addr = 0x40000000; tim_clk_hz = 10000000; //10KHZ - channel = 0; //channel_1 + channel = 1; //channel_1 num = 2; - gpio_port_addr = 0x50002000; + gpio_port_addr = 0x50002000; //GPIOA pin_number = 5; //PA5 match_attr = "st_stm32mp157_pwm_2"; } + device_pwm3 :: pwm_device { + tim_addr = 0x40001000; + tim_clk_hz = 10000000; //10KHZ + channel = 1; //channel_1 + num = 3; + gpio_port_addr = 0x50002000; //GPIOA + pin_number = 6; //PA6 + match_attr = "st_stm32mp157_pwm_3"; + } } } } diff --git a/device/st/drivers/BUILD.gn b/device/st/drivers/BUILD.gn index 1dbe5e9bedebebf68f3398be742e3ad0e6599ba1..e0ea7e2408a309fe138bd0000c010c49e64e3620 100755 --- a/device/st/drivers/BUILD.gn +++ b/device/st/drivers/BUILD.gn @@ -15,6 +15,7 @@ import("//drivers/adapter/khdf/liteos/hdf.gni") group("drivers") { deps = [ + "adc", "pwm", "uart", "iwdg", diff --git a/device/st/drivers/adc/BUILD.gn b/device/st/drivers/adc/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..905912b4e131df413dfff0403926ff73e9106e72 --- /dev/null +++ b/device/st/drivers/adc/BUILD.gn @@ -0,0 +1,24 @@ +# Copyright (c) 2022 Nanjing Xiaoxiongpai Intelligent Technology CO., LIMITED. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//drivers/adapter/khdf/liteos/hdf.gni") + +module_switch = defined(LOSCFG_DRIVERS_HDF_PLATFORM_ADC) +module_name = "hdf_adc" +hdf_driver(module_name) { + sources = [ "stm32mp1_adc.c"] + include_dirs = [ + ".", + "//device/st/drivers/stm32mp1xx_hal/STM32MP1xx_HAL_Driver/Inc", + ] +} diff --git a/device/st/drivers/adc/stm32mp1_adc.c b/device/st/drivers/adc/stm32mp1_adc.c new file mode 100755 index 0000000000000000000000000000000000000000..643f3976b94038ff5d83ec5b89cbc0a0605920d3 --- /dev/null +++ b/device/st/drivers/adc/stm32mp1_adc.c @@ -0,0 +1,433 @@ +/* + * Copyright (c) 2022 Nanjing Xiaoxiongpai Intelligent Technology CO., LIMITED. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "stm32mp1_adc.h" +#include "device_resource_if.h" +#include "hdf_device_desc.h" +#include "hdf_log.h" +#include "osal_io.h" +#include "osal_mem.h" +#include "osal_time.h" +#include "stm32mp1xx.h" +#include "stm32mp1xx_hal_conf.h" + +#define HDF_LOG_TAG stm32mp1_adc + +static void Mp1xxAdcPinInit(struct Mp1xxAdcDevice *stm32mp1) +{ + uint32_t i; + uint32_t value; + volatile unsigned char *gpioBase; + volatile unsigned char *comBase; + + gpioBase = OsalIoRemap(MP1XX_GPIO_BASE + MP1XX_GPIO_MODE_REG_OFFSET, + MP1XX_GPIO_GROUP_NUMBER * MP1XX_GPIO_GROUP_SIZE); + for (i = 0; i < MP1XX_ADC_CHANNEL_COUNT_MAX; i++) { + if (stm32mp1->validChannel[i] == 0 || stm32mp1->pins[i * MP1_ADC_PIN_DATA_WIDTH] >= MP1XX_GPIO_GROUP_NUMBER) { + continue; + } + + value = OSAL_READL(gpioBase); + value |= (MP1XX_GPIO_ANALOG_MODE_MASK << MP1XX_GPIO_REG_PIN_SHIFT); + OSAL_WRITEL(value, MP1XX_GPIO_BASE + MP1XX_GPIO_MODE_REG_OFFSET); + + RCC->MC_AHB4ENSETR |= 0x1U << stm32mp1->pins[i * MP1_ADC_PIN_DATA_WIDTH]; + } + RCC->PLL4CR |= 0x1U; + comBase = OsalIoRemap(MP1XX_ADC_COMMON_REG_BASE, MP1XX_ADC_COMMON_REG_SIZE); + OSAL_WRITEL(MP1XX_ADC_CKMODE_SEL, comBase + MP1XX_ADC_CCR_OFFSET); + if (stm32mp1->devNum == MP1XX_ADC_DEVICE_2) { + value = stm32mp1->validChannel[MP1XX_ADC_VDDCORE_CHANNEL] & 0x1U; // VddCore + OSAL_WRITEL(value, stm32mp1->regBase + MP1XX_ADC_OR_OFFSET); + value = stm32mp1->validChannel[MP1XX_ADC_VREF_CHANNEL] & 0x1U; // Vref + value |= (stm32mp1->validChannel[MP1XX_ADC_TSEN_CHANNEL] & 0x1U) << MP1XX_ADC_VREF_SHIFT; // Tsen + value |= (stm32mp1->validChannel[MP1XX_ADC_VBAT_CHANNEL] & 0x1U) << MP1XX_ADC_VBAT_SHIFT; // Vbat + OSAL_WRITEL(value, comBase + MP1XX_ADC_CCR_OFFSET); + } +} + +static inline void Mp1xxAdcReset(struct Mp1xxAdcDevice *stm32mp1) +{ + (void)stm32mp1; +} + +static inline void Mp1xxAdcSetConfig(struct Mp1xxAdcDevice *stm32mp1) +{ + uint32_t value; + + value = 0x1U << MP1XX_ADC_JQDIS_SHIFT; + OSAL_WRITEL(value, stm32mp1->regBase + MP1XX_ADC_CFGR_OFFSET); +} + +static inline void Mp1xxAdcSetSampleTime(struct Mp1xxAdcDevice *stm32mp1) +{ + uint32_t sampleTime; + uint32_t i; + + sampleTime = 0; + for (i = 0; i sampleTime & MP1XX_SAMPLE_TIME_MASK) << (i * MP1XX_SAMPLE_TIME_BITS); + } + OSAL_WRITEL(sampleTime, stm32mp1->regBase + MP1XX_ADC_SMPR1_OFFSET); + OSAL_WRITEL(sampleTime, stm32mp1->regBase + MP1XX_ADC_SMPR2_OFFSET); +} + +static void Mp1xxAdcCalibration(struct Mp1xxAdcDevice *stm32mp1) +{ + uint32_t value; + uint32_t delay = 0; + + OSAL_WRITEL(0, stm32mp1->regBase + MP1XX_ADC_CR_OFFSET); + OSAL_WRITEL(MP1XX_ADC_REGULATOR_EN, stm32mp1->regBase + MP1XX_ADC_CR_OFFSET); + while (1) { + value = OSAL_READL(stm32mp1->regBase + MP1XX_ADC_ISR_OFFSET); + if (((value >> MP1XX_ADC_REGULATOR_RDY_SHIFT) & 0x1U) == 1 || delay > MP1XX_ADC_CAL_TIME_OUT) { + break; + } + OsalMDelay(1); + delay++; + } + delay = 0; + value = OSAL_READL(stm32mp1->regBase + MP1XX_ADC_CR_OFFSET); + value |= 0x1U << MP1XX_ADC_ADCAL_SHIFT; + OSAL_WRITEL(value, stm32mp1->regBase + MP1XX_ADC_CR_OFFSET); + while (1) { + value = OSAL_READL(stm32mp1->regBase + MP1XX_ADC_CR_OFFSET); + if (((value >> MP1XX_ADC_ADCAL_SHIFT) & 0x1U) == 0 || delay > MP1XX_ADC_CAL_TIME_OUT) { + break; + } + OsalMDelay(1); + delay++; + } +} + +static inline void Mp1xxAdcClkEnable(struct Mp1xxAdcDevice *stm32mp1) +{ + static bool hasInit = false; + if (hasInit == true) { + return; + } + + __HAL_RCC_ADC12_CLK_ENABLE(); + hasInit = true; +} + +static inline void Mp1xxAdcEnable(struct Mp1xxAdcDevice *stm32mp1) +{ + uint32_t value = 0; + + value = OSAL_READL(stm32mp1->regBase + MP1XX_ADC_CR_OFFSET); + OSAL_WRITEL((value | 1), stm32mp1->regBase + MP1XX_ADC_CR_OFFSET); +} + +static inline void Mp1xxAdcDeviceInit(struct Mp1xxAdcDevice *stm32mp1) +{ + if (!stm32mp1->adcEnable) { + return; + } + Mp1xxAdcClkEnable(stm32mp1); + Mp1xxAdcPinInit(stm32mp1); + Mp1xxAdcCalibration(stm32mp1); + Mp1xxAdcReset(stm32mp1); + Mp1xxAdcSetConfig(stm32mp1); + Mp1xxAdcSetSampleTime(stm32mp1); + Mp1xxAdcEnable(stm32mp1); +} + +static inline void Mp1xxAdcStart(struct Mp1xxAdcDevice *stm32mp1) +{ + uint32_t value; + + value = OSAL_READL(stm32mp1->regBase + MP1XX_ADC_CR_OFFSET); + + value |= 0x1U << MP1XX_ADC_ADSTART_SHIFT; + value |= MP1XX_ADC_ENABLE; + OSAL_WRITEL(value, stm32mp1->regBase + MP1XX_ADC_CR_OFFSET); +} + +static int32_t Mp1xxAdcOpen(struct AdcDevice *device) +{ + struct Mp1xxAdcDevice *stm32mp1 = NULL; + + if (device == NULL) { + HDF_LOGE("%s: device is NULL!", __func__); + return HDF_ERR_INVALID_OBJECT; + } + + stm32mp1 = (struct Mp1xxAdcDevice *)device; + if (!stm32mp1->adcEnable) { + HDF_LOGE("%s: ADC %u is disabled!", __func__, stm32mp1->devNum); + return HDF_ERR_NOT_SUPPORT; + } + + Mp1xxAdcStart(stm32mp1); + return HDF_SUCCESS; +} + +static int32_t Mp1xxAdcClose(struct AdcDevice *device) +{ + (void)device; + return HDF_SUCCESS; +} + +static inline void Mp1xxAdcSetSequence(struct Mp1xxAdcDevice *stm32mp1, uint32_t channel) +{ + uint32_t value; + + if (channel >= MP1XX_ADC_CHANNEL_COUNT_MAX) { + return; + } + value = channel << MP1XX_ADC_SQ1_SHIFT; + OSAL_WRITEL(value, stm32mp1->regBase + MP1XX_ADC_SQR1_OFFSET); + + value = 0x1U << channel; + OSAL_WRITEL(value, stm32mp1->regBase + MP1XX_ADC_PCSEL_OFFSET); +} + + + +static int32_t Mp1xxAdcRead(struct AdcDevice *device, uint32_t channel, uint32_t *val) +{ + uint32_t value; + uint32_t delay = 0; + struct Mp1xxAdcDevice *stm32mp1 = NULL; + + if (device == NULL || val == NULL) { + HDF_LOGE("%s: device or val is NULL!", __func__); + return HDF_ERR_INVALID_OBJECT; + } + + if (channel >= MP1XX_ADC_CHANNEL_COUNT_MAX) { + HDF_LOGE("%s: invalid channel: %u!", __func__, channel); + return HDF_ERR_INVALID_PARAM; + } + + stm32mp1 = (struct Mp1xxAdcDevice *)device; + if (!stm32mp1->adcEnable) { + HDF_LOGE("%s: ADC %u is disabled!", __func__, stm32mp1->devNum); + return HDF_ERR_NOT_SUPPORT; + } + + Mp1xxAdcSetSequence(stm32mp1, channel); + Mp1xxAdcStart(stm32mp1); + while (true) { + value = OSAL_READL(stm32mp1->regBase + MP1XX_ADC_ISR_OFFSET); + if ((value & MP1XX_ADC_EOC_MASK) != 0 || delay > MP1XX_ADC_CONV_TIME_OUT) { + OSAL_WRITEL(value, stm32mp1->regBase + MP1XX_ADC_ISR_OFFSET); + break; + } + OsalUDelay(1); + delay++; + } + + value = OSAL_READL(stm32mp1->regBase + MP1XX_ADC_DR_OFFSET); + *val = value >> (MP1XX_ADC_DATA_WIDTH_MAX - stm32mp1->dataWidth); + + return HDF_SUCCESS; +} + +static const struct AdcMethod g_method = { + .start = Mp1xxAdcOpen, + .stop = Mp1xxAdcClose, + .read = Mp1xxAdcRead, +}; + +static int32_t Mp1xxAdcReadDrs(struct Mp1xxAdcDevice *stm32mp1, const struct DeviceResourceNode *node) +{ + int32_t ret; + struct DeviceResourceIface *drsOps = NULL; + + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetUint8Array == NULL || drsOps->GetBool == NULL) { + HDF_LOGE("%s: invalid drs ops", __func__); + return HDF_ERR_NOT_SUPPORT; + } + + ret = drsOps->GetUint32(node, "reg_pbase", &stm32mp1->regBasePhy, 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read regBasePhy failed", __func__); + return ret; + } + + ret = drsOps->GetUint32(node, "reg_size", &stm32mp1->regSize, 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read regSize failed", __func__); + return ret; + } + + ret = drsOps->GetUint32(node, "dev_num", &stm32mp1->devNum, 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read devNum failed", __func__); + return ret; + } + + ret = drsOps->GetUint8Array(node, "channel_enable", stm32mp1->validChannel, MP1XX_ADC_CHANNEL_COUNT_MAX, 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read validChannel failed", __func__); + return ret; + } + + ret = drsOps->GetUint32(node, "sample_time", &stm32mp1->sampleTime, 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read sampleTime failed", __func__); + return ret; + } + + ret = drsOps->GetUint32(node, "data_width", &stm32mp1->dataWidth, 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read dataWidth failed", __func__); + return ret; + } + + stm32mp1->adcEnable = drsOps->GetBool(node, "adc_enable"); + + ret = drsOps->GetUint8Array(node, "pins", stm32mp1->pins, MP1XX_ADC_CHANNEL_COUNT_MAX, 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read pin failed", __func__); + return ret; + } + + return HDF_SUCCESS; +} + +static int32_t Mp1xxAdcParseInit(struct HdfDeviceObject *device, struct DeviceResourceNode *node) +{ + int32_t ret; + struct Mp1xxAdcDevice *stm32mp1 = NULL; + (void)device; + + stm32mp1 = (struct Mp1xxAdcDevice *)OsalMemCalloc(sizeof(*stm32mp1)); + if (stm32mp1 == NULL) { + HDF_LOGE("%s: alloc stm32mp1 failed", __func__); + return HDF_ERR_MALLOC_FAIL; + } + + ret = Mp1xxAdcReadDrs(stm32mp1, node); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read drs failed:%d", __func__, ret); + goto ERR; + } + + stm32mp1->regBase = OsalIoRemap(stm32mp1->regBasePhy, stm32mp1->regSize); + if (stm32mp1->regBase == NULL) { + HDF_LOGE("%s: remap regbase failed", __func__); + ret = HDF_ERR_IO; + goto ERR; + } + + Mp1xxAdcDeviceInit(stm32mp1); + stm32mp1->device.priv = (void *)node; + stm32mp1->device.devNum = stm32mp1->devNum; + stm32mp1->device.ops = &g_method; + ret = AdcDeviceAdd(&stm32mp1->device); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: add adc device:%u failed", __func__, stm32mp1->devNum); + goto ERR; + } + return HDF_SUCCESS; + +ERR: + if (stm32mp1 != NULL) { + if (stm32mp1->regBase != NULL) { + OsalIoUnmap((void *)stm32mp1->regBase); + stm32mp1->regBase = NULL; + } + AdcDeviceRemove(&stm32mp1->device); + OsalMemFree(stm32mp1); + } + return ret; +} + +/* HdfDriverEntry hook function implementations */ +static int32_t Mp1xxAdcBind(struct HdfDeviceObject *device) +{ + (void)device; + return HDF_SUCCESS; + +} +static int32_t Mp1xxAdcInit(struct HdfDeviceObject *device) +{ + int32_t ret; + struct DeviceResourceNode *childNode = NULL; + + HDF_LOGE("%s: Enter", __func__); + if (device == NULL || device->property == NULL) { + HDF_LOGE("%s: device or property is null", __func__); + return HDF_ERR_INVALID_OBJECT; + } + + ret = HDF_SUCCESS; + DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { + ret = Mp1xxAdcParseInit(device, childNode); + if (ret != HDF_SUCCESS) { + break; + } + } + return ret; +} + +static void Mp1xxAdcRemoveByNode(const struct DeviceResourceNode *node) +{ + int32_t ret; + int32_t devNum; + struct AdcDevice *device = NULL; + struct Mp1xxAdcDevice *stm32mp1 = NULL; + struct DeviceResourceIface *drsOps = NULL; + + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetUint32 == NULL) { + HDF_LOGE("%s: invalid drs ops", __func__); + return; + } + + ret = drsOps->GetUint32(node, "dev_num", (uint32_t *)&devNum, 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read devNum failed", __func__); + return; + } + + device = AdcDeviceGet(devNum); + if (device != NULL && device->priv == node) { + AdcDevicePut(device); + AdcDeviceRemove(device); + stm32mp1 = (struct Mp1xxAdcDevice *)device; + OsalIoUnmap((void *)stm32mp1->regBase); + OsalMemFree(stm32mp1); + } + return; +} + +static void Mp1xxAdcRelease(struct HdfDeviceObject *device) +{ + const struct DeviceResourceNode *childNode = NULL; + + HDF_LOGI("%s: enter", __func__); + if (device == NULL || device->property == NULL) { + HDF_LOGE("%s: device or property is null", __func__); + return; + } + DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { + Mp1xxAdcRemoveByNode(childNode); + } +} + +static struct HdfDriverEntry g_stm32mp1AdcDriverEntry = { + .moduleVersion = 1, + .Bind = Mp1xxAdcBind, + .Init = Mp1xxAdcInit, + .Release = Mp1xxAdcRelease, + .moduleName = "stm32mp157_adc_driver", +}; +HDF_INIT(g_stm32mp1AdcDriverEntry); diff --git a/device/st/drivers/adc/stm32mp1_adc.h b/device/st/drivers/adc/stm32mp1_adc.h new file mode 100755 index 0000000000000000000000000000000000000000..43dd52d621a9d0d2e7b5fec33b6341b8f567a91a --- /dev/null +++ b/device/st/drivers/adc/stm32mp1_adc.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2022 Nanjing Xiaoxiongpai Intelligent Technology CO., LIMITED. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __STM32MP1_ADC_H__ +#define __STM32MP1_ADC_H__ + +#include "adc_core.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define MP1XX_ADC_CHANNEL_COUNT_MAX 20 + +#define MP1_ADC_PIN_DATA_WIDTH 2 +#define MP1XX_ADC_GPIO_A 0 +#define MP1XX_ADC_GPIO_B 1 +#define MP1XX_ADC_GPIO_C 2 +#define MP1XX_ADC_GPIO_D 3 +#define MP1XX_ADC_GPIO_E 4 +#define MP1XX_ADC_GPIO_F 5 +#define MP1XX_ADC_INJECTED_CHANNEL_TAG 253 +#define MP1XX_ADC_DEDICATED_PIN_TAG 254 +#define MP1XX_ADC_UNAVAILABLE_CHANNEL_TAG 255 + +#define MP1XX_ADC_DEVICE_1 1 +#define MP1XX_ADC_DEVICE_2 2 + +/* EACH ADC REGISITERS OFFSET */ +#define MP1XX_ADC_ISR_OFFSET 0x00 // ADC 中断和状态寄存器 (ADC_ISR) +#define MP1XX_ADC_IER_OFFSET 0x04 // ADC 中断使能寄存器(ADC_IER) +#define MP1XX_ADC_CR_OFFSET 0x08 // ADC 控制寄存器(ADC_CR) +#define MP1XX_ADC_CFGR_OFFSET 0x0C // ADC 配置寄存器(ADC_CFGR) +#define MP1XX_ADC_CFGR2_OFFSET 0x10 // ADC 配置寄存器 2 (ADC_CFGR2) +#define MP1XX_ADC_SMPR1_OFFSET 0x14 // ADC 采样时间寄存器 1 (ADC_SMPR1) +#define MP1XX_ADC_SMPR2_OFFSET 0x18 // ADC 采样时间寄存器 2 (ADC_SMPR2) +#define MP1XX_ADC_PCSEL_OFFSET 0x1C // ADC 通道预选寄存器(ADC_PCSEL) +#define MP1XX_ADC_LTR1_OFFSET 0x20 // ADC 看门狗阈值寄存器 1 (ADC_LTR1) +#define MP1XX_ADC_HTR1_OFFSET 0x24 // ADC 看门狗阈值寄存器 1 (ADC_HTR1) +#define MP1XX_ADC_SQR1_OFFSET 0x30 // ADC 常规序列寄存器 1 (ADC_SQR1) +#define MP1XX_ADC_SQR2_OFFSET 0x34 // ADC 常规序列寄存器 2 (ADC_SQR2) +#define MP1XX_ADC_SQR3_OFFSET 0x38 // ADC 常规序列寄存器 3 (ADC_SQR3) +#define MP1XX_ADC_SQR4_OFFSET 0x3C // ADC 常规序列寄存器 4 (ADC_SQR4) +#define MP1XX_ADC_DR_OFFSET 0x40 // ADC 常规数据寄存器 (ADC_DR) +#define MP1XX_ADC_JSQR_OFFSET 0x4C // ADC 注入序列寄存器 (ADC_JSQR) +#define MP1XX_ADC_OFR1_OFFSET 0x60 // ADC 注入通道 y 偏移寄存器 (ADC_OFR1) +#define MP1XX_ADC_OFR2_OFFSET 0x64 // ADC 注入通道 y 偏移寄存器 (ADC_OFR2) +#define MP1XX_ADC_OFR3_OFFSET 0x68 // ADC 注入通道 y 偏移寄存器 (ADC_OFR3) +#define MP1XX_ADC_OFR4_OFFSET 0x6C // ADC 注入通道 y 偏移寄存器 (ADC_OFR4) +#define MP1XX_ADC_JDR1_OFFSET 0x80 // ADC 注入通道 y 数据寄存器 (ADC_JDR1) +#define MP1XX_ADC_JDR2_OFFSET 0x84 // ADC 注入通道 y 数据寄存器 (ADC_JDR2) +#define MP1XX_ADC_JDR3_OFFSET 0x88 // ADC 注入通道 y 数据寄存器 (ADC_JDR3) +#define MP1XX_ADC_JDR4_OFFSET 0x8C // ADC 注入通道 y 数据寄存器 (ADC_JDR4) +#define MP1XX_ADC_AWD2CR_OFFSET 0xA0 // ADC 模拟看门狗 2 配置寄存器 (ADC_AWD2CR) +#define MP1XX_ADC_AWD3CR_OFFSET 0xA4 // ADC 模拟看门狗 3 配置寄存器 (ADC_AWD3CR) +#define MP1XX_ADC_LTR2_OFFSET 0xB0 // ADC 看门狗阈值下限寄存器 2 (ADC_LTR2) +#define MP1XX_ADC_HTR2_OFFSET 0xB4 // ADC 看门狗高阈值寄存器 2 (ADC_HTR2) +#define MP1XX_ADC_LTR3_OFFSET 0xB8 // ADC 看门狗阈值下限寄存器 3 (ADC_LTR3) +#define MP1XX_ADC_HTR3_OFFSET 0xBC // ADC 看门狗高阈值寄存器 3 (ADC_HTR3) +#define MP1XX_ADC_DIFSEL_OFFSET 0xC0 // ADC 差分模式选择寄存器(ADC_DIFSEL) +#define MP1XX_ADC_CALFACT_OFFSET 0xC4 // ADC 校准因子寄存器 (ADC_CALFACT) +#define MP1XX_ADC_CALFACT2_OFFSET 0xC8 // ADC 校准因子寄存器 2 (ADC_CALFACT2) +#define MP1XX_ADC_OR_OFFSET 0xD0 // ADC2 选项寄存器(ADC2_OR) + +/* MASTER AND SLAVE ADC COMMON REGISITERS OFFSET */ +#define MP1XX_ADC_COMMON_REG_BASE 0x48003300 +#define MP1XX_ADC_COMMON_REG_SIZE 0x100 +#define MP1XX_ADC_CCR_OFFSET 0x08 +#define MP1XX_ADC_CSR_OFFSET 0x00 // ADC 通用状态寄存器(ADC_CSR) +#define MP1XX_ADC_CCR_OFFSET 0x08 // ADC 通用控制寄存器(ADC_CCR) +#define MP1XX_ADC_CDR_OFFSET 0x0C // ADC 双模通用常规数据寄存器 (ADC_CDR) +#define MP1XX_ADC_CDR2_OFFSET 0x10 // 32位双模ADC常用常规数据寄存器 (ADC_CDR2) +#define MP1XX_ADC_HWCFGR0_OFFSET 0x3F0 // ADC 硬件配置寄存器(ADC_HWCFGR0) +#define MP1XX_ADC_VERR_OFFSET 0x3F4 // ADC 版本寄存器(ADC_VERR) +#define MP1XX_ADC_IPDR_OFFSET 0x3F8 // ADC 识别寄存器(ADC_IPIDR) +#define MP1XX_ADC_SIDR_OFFSET 0x3FC // ADC 大小识别寄存器(ADC_SIDR) + +#define MP1XX_GPIO_BASE 0x50003000 +#define MP1XX_GPIO_GROUP_SIZE 0x1000 +#define MP1XX_GPIO_GROUP_NUMBER 11 +#define MP1XX_GPIO_MODE_REG_OFFSET 0x0 +#define MP1XX_GPIO_ANALOG_MODE_MASK 0x3 +#define MP1XX_GPIO_REG_PIN_SHIFT 2 + +#define MP1XX_ADC_DEVICE_2 2 +#define MP1XX_ADC_DATA_WIDTH_MAX 16 +#define MP1XX_CHANNLE_NUM_PER_REG 10 +#define MP1XX_SAMPLE_TIME_MASK 0x7 +#define MP1XX_SAMPLE_TIME_BITS 3 +#define MP1XX_ADC_JQDIS_SHIFT 31 +#define MP1XX_ADC_SQ1_SHIFT 6 +#define MP1XX_ADC_ADCAL_SHIFT 31 +#define MP1XX_ADC_ADSTART_SHIFT 2 +#define MP1XX_ADC_ENABLE 0x1 +#define MP1XX_ADC_EOC_MASK (0x1 << 2) +#define MP1XX_ADC_REGULATOR_EN (0x1 << 28) +#define MP1XX_ADC_REGULATOR_RDY_SHIFT 12 +#define MP1XX_ADC_CKMODE_SEL (0x2 << 16) +#define MP1XX_ADC_CONV_TIME_OUT 100 +#define MP1XX_ADC_CAL_TIME_OUT 10 +#define MP1XX_ADC_VDDCORE_CHANNEL 19 +#define MP1XX_ADC_VREF_CHANNEL 18 +#define MP1XX_ADC_TSEN_CHANNEL 17 +#define MP1XX_ADC_VBAT_CHANNEL 16 +#define MP1XX_ADC_VREF_SHIFT 22 +#define MP1XX_ADC_TSEN_SHIFT 23 +#define MP1XX_ADC_VBAT_SHIFT 24 + +struct Mp1xxAdcDevice { + struct AdcDevice device; + uint32_t regBasePhy; + volatile unsigned char *regBase; + uint32_t regSize; + uint32_t devNum; + uint32_t dataWidth; + uint32_t sampleTime; + bool adcEnable; + uint8_t validChannel[MP1XX_ADC_CHANNEL_COUNT_MAX]; + uint8_t pins[MP1XX_ADC_CHANNEL_COUNT_MAX * MP1_ADC_PIN_DATA_WIDTH]; +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __STM32MP1_ADC_H__ */ diff --git a/device/st/drivers/pwm/stm32mp1_pwm.c b/device/st/drivers/pwm/stm32mp1_pwm.c old mode 100644 new mode 100755 index dca93174fd595e49095a8a7b09e61b312dc5b0b8..eea4020eb4c062bdf4fe4fe767f09ef618aa01fc --- a/device/st/drivers/pwm/stm32mp1_pwm.c +++ b/device/st/drivers/pwm/stm32mp1_pwm.c @@ -65,6 +65,7 @@ static inline void StmPwmAlwaysOutput(struct StmPwm *sp) static inline void StmPwmOutputNumberSquareWaves(struct StmPwm *sp,uint32_t num) { //todo using repetition counter register to implement it + (void)num; HAL_TIM_PWM_Start(&sp->htim, sp->channel); } @@ -310,7 +311,7 @@ static int Stm32PwmReadConfig(struct StmPwm *sp,struct HdfDeviceObject *obj) HDF_LOGE("%s: read channel fail", __func__); return HDF_FAILURE; } - + sp->channel = (sp->channel - 1) * 4; if (iface->GetUint32(obj->property, "tim_clk_hz", &sp->tim_clk_hz, 0) != HDF_SUCCESS) { HDF_LOGE("%s: read tim_clk_hz fail", __func__); @@ -413,7 +414,7 @@ int32_t HdfPwmDriverInit(struct HdfDeviceObject *device) sp->dev.cfg.duty = PWM_DEFAULT_DUTY; sp->dev.cfg.period = PWM_DEFAULT_PERIOD; sp->dev.cfg.polarity = PWM_DEFAULT_OCPOLARITY; - sp->dev.cfg.status = PWM_ENABLE_STATUS; + sp->dev.cfg.status = PWM_DISABLE_STATUS; sp->dev.cfg.number = PWM_DEFAULT_OUTPUT_NUM; sp->dev.busy = false; diff --git a/vendor/bearpi/bearpi_hm_micro/kernel_configs/debug_tee.config b/vendor/bearpi/bearpi_hm_micro/kernel_configs/debug_tee.config index ff502ab158bff37a515a45411130c293f735965c..9f344f2e9a8f1f42dec92e0d36a09b4a87523951 100755 --- a/vendor/bearpi/bearpi_hm_micro/kernel_configs/debug_tee.config +++ b/vendor/bearpi/bearpi_hm_micro/kernel_configs/debug_tee.config @@ -164,7 +164,7 @@ LOSCFG_DRIVERS_HDF=y LOSCFG_DRIVERS_HDF_PLATFORM=y LOSCFG_DRIVERS_HDF_PLATFORM_GPIO=y LOSCFG_DRIVERS_HDF_PLATFORM_I2C=y -# LOSCFG_DRIVERS_HDF_PLATFORM_ADC is not set +LOSCFG_DRIVERS_HDF_PLATFORM_ADC=y LOSCFG_DRIVERS_HDF_PLATFORM_MMC=y LOSCFG_DRIVERS_HDF_PLATFORM_EMMC=y LOSCFG_DRIVERS_HDF_PLATFORM_PWM=y