diff --git a/include/platform/adc_if.h b/include/platform/adc_if.h index 5ce22546..c5794c97 100644 --- a/include/platform/adc_if.h +++ b/include/platform/adc_if.h @@ -28,6 +28,16 @@ void AdcClose(DevHandle handle); int32_t AdcRead(DevHandle handle, uint32_t channel, uint32_t *val); +/** + * @brief Enumerates ADC I/O commands. + * + * @since 1.0 + */ +enum AdcIoCmd { + ADC_IO_READ = 0, /**< Read the A/D data. */ + ADC_IO_OPEN, /**< Open the ADC device. */ + ADC_IO_CLOSE, /**< Close the ADC device. */ +}; #ifdef __cplusplus #if __cplusplus } diff --git a/support/platform/include/adc/adc_core.h b/support/platform/include/adc/adc_core.h index c6890dfd..5719ef13 100644 --- a/support/platform/include/adc/adc_core.h +++ b/support/platform/include/adc/adc_core.h @@ -46,12 +46,6 @@ struct AdcLockMethod { void (*unlock)(struct AdcDevice *device); }; -enum AdcIoCmd { - ADC_IO_READ = 0, - ADC_IO_OPEN, - ADC_IO_CLOSE, -}; - int32_t AdcDeviceAdd(struct AdcDevice *device); void AdcDeviceRemove(struct AdcDevice *device); diff --git a/support/platform/src/adc/adc_core.c b/support/platform/src/adc/adc_core.c index f53fecae..032fc154 100644 --- a/support/platform/src/adc/adc_core.c +++ b/support/platform/src/adc/adc_core.c @@ -18,6 +18,8 @@ #define LOCK_WAIT_SECONDS_M 1 #define ADC_BUFF_SIZE 4 +#define ADC_HANDLE_SHIFT 0xFF00U + struct AdcManager { struct IDeviceIoService service; struct HdfDeviceObject *device; @@ -48,6 +50,69 @@ static const struct AdcLockMethod g_adcLockOpsDefault = { .unlock = AdcDeviceUnlockDefault, }; +static inline int32_t AdcDeviceLock(struct AdcDevice *device) +{ + if (device->lockOps == NULL || device->lockOps->lock == NULL) { + return HDF_ERR_NOT_SUPPORT; + } + return device->lockOps->lock(device); +} + +static inline void AdcDeviceUnlock(struct AdcDevice *device) +{ + if (device->lockOps != NULL && device->lockOps->unlock != NULL) { + device->lockOps->unlock(device); + } +} + +int32_t AdcDeviceStart(struct AdcDevice *device) +{ + int32_t ret; + + if (device == NULL) { + HDF_LOGE("%s: device is null", __func__); + return HDF_ERR_INVALID_OBJECT; + } + + if (device->ops == NULL || device->ops->start == NULL) { + HDF_LOGE("%s: ops or start is null", __func__); + return HDF_ERR_NOT_SUPPORT; + } + + if (AdcDeviceLock(device) != HDF_SUCCESS) { + HDF_LOGE("%s: lock add device failed", __func__); + return HDF_ERR_DEVICE_BUSY; + } + + ret = device->ops->start(device); + AdcDeviceUnlock(device); + return ret; +} + +int32_t AdcDeviceStop(struct AdcDevice *device) +{ + int32_t ret; + + if (device == NULL) { + HDF_LOGE("%s: device is null", __func__); + return HDF_ERR_INVALID_OBJECT; + } + + if (device->ops == NULL || device->ops->stop == NULL) { + HDF_LOGE("%s: ops or stop is null", __func__); + return HDF_ERR_NOT_SUPPORT; + } + + if (AdcDeviceLock(device) != HDF_SUCCESS) { + HDF_LOGE("%s: lock add device failed", __func__); + return HDF_ERR_DEVICE_BUSY; + } + + ret = device->ops->stop(device); + AdcDeviceUnlock(device); + return ret; +} + static int32_t AdcManagerAddDevice(struct AdcDevice *device) { int32_t ret; @@ -134,6 +199,45 @@ static struct AdcDevice *AdcManagerFindDevice(uint32_t number) return device; } +struct AdcDevice *AdcDeviceGet(uint32_t number) +{ + return AdcManagerFindDevice(number); +} + +void AdcDevicePut(struct AdcDevice *device) +{ + (void)device; +} + +static struct AdcDevice *AdcDeviceOpen(uint32_t number) +{ + int32_t ret; + struct AdcDevice *device = NULL; + + device = AdcDeviceGet(number); + if (device == NULL) { + return NULL; + } + + ret = AdcDeviceStart(device); + if (ret != HDF_SUCCESS) { + return NULL; + } + + return device; +} + +static void AdcDeviceClose(struct AdcDevice *device) +{ + if (device == NULL) { + HDF_LOGE("%s: close adc device fail", __func__); + return; + } + + (void)AdcDeviceStop(device); + AdcDevicePut(device); +} + int32_t AdcDeviceAdd(struct AdcDevice *device) { int32_t ret; @@ -173,31 +277,6 @@ void AdcDeviceRemove(struct AdcDevice *device) (void)OsalSpinDestroy(&device->spin); } -struct AdcDevice *AdcDeviceGet(uint32_t number) -{ - return AdcManagerFindDevice(number); -} - -void AdcDevicePut(struct AdcDevice *device) -{ - (void)device; -} - -static inline int32_t AdcDeviceLock(struct AdcDevice *device) -{ - if (device->lockOps == NULL || device->lockOps->lock == NULL) { - return HDF_ERR_NOT_SUPPORT; - } - return device->lockOps->lock(device); -} - -static inline void AdcDeviceUnlock(struct AdcDevice *device) -{ - if (device->lockOps != NULL && device->lockOps->unlock != NULL) { - device->lockOps->unlock(device); - } -} - int32_t AdcDeviceRead(struct AdcDevice *device, uint32_t channel, uint32_t *val) { int32_t ret; @@ -227,73 +306,36 @@ int32_t AdcDeviceRead(struct AdcDevice *device, uint32_t channel, uint32_t *val) return ret; } -int32_t AdcDeviceStart(struct AdcDevice *device) -{ - int32_t ret; - - if (device == NULL) { - HDF_LOGE("%s: device is null", __func__); - return HDF_ERR_INVALID_OBJECT; - } - - if (device->ops == NULL || device->ops->start == NULL) { - HDF_LOGE("%s: ops or start is null", __func__); - return HDF_ERR_NOT_SUPPORT; - } - - if (AdcDeviceLock(device) != HDF_SUCCESS) { - HDF_LOGE("%s: lock add device failed", __func__); - return HDF_ERR_DEVICE_BUSY; - } - - ret = device->ops->start(device); - AdcDeviceUnlock(device); - return ret; -} - -int32_t AdcDeviceStop(struct AdcDevice *device) -{ - int32_t ret; - - if (device == NULL) { - HDF_LOGE("%s: device is null", __func__); - return HDF_ERR_INVALID_OBJECT; - } - - if (device->ops == NULL || device->ops->stop == NULL) { - HDF_LOGE("%s: ops or stop is null", __func__); - return HDF_ERR_NOT_SUPPORT; - } - - if (AdcDeviceLock(device) != HDF_SUCCESS) { - HDF_LOGE("%s: lock add device failed", __func__); - return HDF_ERR_DEVICE_BUSY; - } - - ret = device->ops->stop(device); - AdcDeviceUnlock(device); - return ret; -} - static int32_t AdcManagerIoOpen(struct HdfSBuf *data, struct HdfSBuf *reply) { uint32_t number; + if (data == NULL || reply == NULL) { + HDF_LOGE("%s: invalid data or reply!", __func__); + return HDF_ERR_INVALID_PARAM; + } + if (!HdfSbufReadUint32(data, &number)) { + HDF_LOGE("%s: read data failed!", __func__); return HDF_ERR_IO; } if (number < 0 || number >= ADC_DEVICES_MAX || reply == NULL) { + HDF_LOGE("%s: invalid number!", __func__); return HDF_ERR_INVALID_PARAM; } - if (AdcDeviceGet(number) == NULL) { + if (AdcDeviceOpen(number) == NULL) { + HDF_LOGE("%s: get device %u failed", __func__, number); return HDF_ERR_NOT_SUPPORT; } - if (!HdfSbufWriteUint32(reply, number)) { + number = (uint32_t)(number + ADC_HANDLE_SHIFT); + if (!HdfSbufWriteUint32(reply, (uint32_t)(uintptr_t)number)) { + HDF_LOGE("%s: write reply failed!", __func__); return HDF_ERR_IO; } + return HDF_SUCCESS; } @@ -301,28 +343,66 @@ static int32_t AdcManagerIoClose(struct HdfSBuf *data, struct HdfSBuf *reply) { uint32_t number; + if (data == NULL) { + HDF_LOGE("%s: invalid data!", __func__); + return HDF_ERR_INVALID_PARAM; + } + if (!HdfSbufReadUint32(data, &number)) { + HDF_LOGE("%s: read data failed!", __func__); return HDF_ERR_IO; } + number = (uint32_t)(number - ADC_HANDLE_SHIFT); if (number < 0 || number >= ADC_DEVICES_MAX) { + HDF_LOGE("%s: get device %u failed", __func__, number); return HDF_ERR_INVALID_PARAM; } - AdcDevicePut(AdcManagerFindDevice(number)); + + AdcDeviceClose(AdcManagerFindDevice(number)); return HDF_SUCCESS; } static int32_t AdcManagerIoRead(struct HdfSBuf *data, struct HdfSBuf *reply) { - (void)data; - (void)reply; - return HDF_SUCCESS; + int32_t ret; + uint32_t number; + uint32_t channel; + uint32_t val; + + if (data == NULL || reply == NULL) { + HDF_LOGE("%s: invalid data or reply!", __func__); + return HDF_ERR_INVALID_PARAM; + } + + if (!HdfSbufReadUint32(data, &number)) { + HDF_LOGE("AdcManagerIoRead: read handle failed!"); + return HDF_ERR_IO; + } + + if (!HdfSbufReadUint32(data, &channel)) { + HDF_LOGE("AdcManagerIoRead: read handle failed!"); + return HDF_ERR_IO; + } + + number = (uint32_t)(number - ADC_HANDLE_SHIFT); + ret = AdcDeviceRead(AdcManagerFindDevice(number), channel, &val); + if(ret != HDF_SUCCESS) { + HDF_LOGE("AdcManagerIoRead: read val failed!"); + return HDF_ERR_IO; + } + + if (!HdfSbufWriteUint32(reply, val)) { + HDF_LOGE("%s: write val fail!", __func__); + return HDF_ERR_IO; + } + + return ret; } static int32_t AdcManagerDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply) { - int32_t ret; switch (cmd) { case ADC_IO_OPEN: @@ -332,10 +412,15 @@ static int32_t AdcManagerDispatch(struct HdfDeviceIoClient *client, int cmd, case ADC_IO_READ: return AdcManagerIoRead(data, reply); default: - ret = HDF_ERR_NOT_SUPPORT; - break; + return HDF_ERR_NOT_SUPPORT; } - return ret; + return HDF_SUCCESS; +} + +static int32_t AdcManagerBind(struct HdfDeviceObject *device) +{ + (void)device; + return HDF_SUCCESS; } static int32_t AdcManagerInit(struct HdfDeviceObject *device) @@ -391,6 +476,7 @@ static void AdcManagerRelease(struct HdfDeviceObject *device) struct HdfDriverEntry g_adcManagerEntry = { .moduleVersion = 1, + .Bind = AdcManagerBind, .Init = AdcManagerInit, .Release = AdcManagerRelease, .moduleName = "HDF_PLATFORM_ADC_MANAGER", diff --git a/support/platform/src/adc/adc_if_u.c b/support/platform/src/adc/adc_if_u.c new file mode 100644 index 00000000..e369d114 --- /dev/null +++ b/support/platform/src/adc/adc_if_u.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#include "hdf_io_service_if.h" +#include "hdf_log.h" +#include "adc_if.h" + +#define HDF_LOG_TAG adc_if_u_c +#define ADC_SERVICE_NAME "HDF_PLATFORM_ADC_MANAGER" + +static void *AdcManagerGetService(void) +{ + static void *manager = NULL; + + if (manager != NULL) { + return manager; + } + manager = (void *)HdfIoServiceBind(ADC_SERVICE_NAME); + if (manager == NULL) { + HDF_LOGE("%s: fail to get adc manager!", __func__); + } + return manager; +} + +DevHandle AdcOpen(uint32_t number) +{ + int32_t ret; + struct HdfIoService *service = NULL; + struct HdfSBuf *data = NULL; + struct HdfSBuf *reply = NULL; + uint32_t handle; + + service = (struct HdfIoService *)AdcManagerGetService(); + if (service == NULL) { + return NULL; + } + data = HdfSbufObtainDefaultSize(); + if (data == NULL) { + HDF_LOGE("%s: malloc data fail!", __func__); + return NULL; + } + reply = HdfSbufObtainDefaultSize(); + if (reply == NULL) { + HDF_LOGE("%s: malloc reply fail!", __func__); + HdfSbufRecycle(data); + return NULL; + } + + if (!HdfSbufWriteUint32(data, (uint32_t)number)) { + HDF_LOGE("%s: write number fail!", __func__); + goto ERR; + } + + ret = service->dispatcher->Dispatch(&service->object, ADC_IO_OPEN, data, reply); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: service call open fail:%d", __func__, ret); + goto ERR; + } + + if (!HdfSbufReadUint32(reply, &handle)) { + HDF_LOGE("%s: read handle fail!", __func__); + goto ERR; + } + HdfSbufRecycle(data); + HdfSbufRecycle(reply); + return (DevHandle)(uintptr_t)handle; +ERR: + HdfSbufRecycle(data); + HdfSbufRecycle(reply); + return NULL; +} + +void AdcClose(DevHandle handle) +{ + int32_t ret; + struct HdfIoService *service = NULL; + struct HdfSBuf *data = NULL; + + service = (struct HdfIoService *)AdcManagerGetService(); + if (service == NULL) { + return; + } + + data = HdfSbufObtainDefaultSize(); + if (data == NULL) { + return; + } + + if (!HdfSbufWriteUint32(data, (uint32_t)(uintptr_t)handle)) { + HDF_LOGE("%s: write handle fail!", __func__); + HdfSbufRecycle(data); + return; + } + + ret = service->dispatcher->Dispatch(&service->object, ADC_IO_CLOSE, data, NULL); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: close handle fail:%d", __func__, ret); + } + HdfSbufRecycle(data); +} + +int32_t AdcRead(DevHandle handle, uint32_t channel, uint32_t *val) +{ + int32_t ret; + struct HdfSBuf *data = NULL; + struct HdfSBuf *reply = NULL; + struct HdfIoService *service = NULL; + + service = (struct HdfIoService *)AdcManagerGetService(); + if (service == NULL) { + return HDF_PAL_ERR_DEV_CREATE; + } + + data = HdfSbufObtainDefaultSize(); + if (data == NULL) { + HDF_LOGE("%s: failed to obtain data!", __func__); + return HDF_ERR_MALLOC_FAIL; + } + + reply = HdfSbufObtainDefaultSize(); + if (reply == NULL) { + HdfSbufRecycle(data); + return HDF_ERR_MALLOC_FAIL; + } + + if (!HdfSbufWriteUint32(data, (uint32_t)(uintptr_t)handle)) { + HDF_LOGE("%s: write handle fail!", __func__); + ret = HDF_ERR_IO; + goto EXIT; + } + if (!HdfSbufWriteUint32(data, (uint32_t)channel)) { + HDF_LOGE("%s: write adc number failed!", __func__); + ret = HDF_ERR_IO; + goto EXIT; + } + ret = service->dispatcher->Dispatch(&service->object, ADC_IO_READ, data, reply); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: failed to send service call:%d", __func__, ret); + goto EXIT; + } + + if (!HdfSbufReadUint32(reply, val)) { + HDF_LOGE("%s: read sbuf failed", __func__); + ret = HDF_ERR_IO; + goto EXIT; + } + + goto EXIT; +EXIT: + HdfSbufRecycle(data); + HdfSbufRecycle(reply); + return ret; +} diff --git a/support/platform/test/unittest/common/hdf_adc_test.cpp b/support/platform/test/unittest/common/hdf_adc_test.cpp index a486d7ea..0521591c 100644 --- a/support/platform/test/unittest/common/hdf_adc_test.cpp +++ b/support/platform/test/unittest/common/hdf_adc_test.cpp @@ -55,6 +55,11 @@ HWTEST_F(HdfLiteAdcTest, AdcTestRead001, TestSize.Level1) { struct HdfTestMsg msg = {TEST_PAL_ADC_TYPE, ADC_TEST_CMD_READ, -1}; EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); + + printf("%s: kernel test done, then for user...\n", __func__); + EXPECT_EQ(0, AdcTestExecute(ADC_TEST_CMD_READ)); + printf("%s: exit!\n", __func__); + } /** @@ -67,6 +72,11 @@ HWTEST_F(HdfLiteAdcTest, AdcTestMultiThread001, TestSize.Level1) { struct HdfTestMsg msg = {TEST_PAL_ADC_TYPE, ADC_TEST_CMD_MULTI_THREAD, -1}; EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); + + printf("%s: kernel test done, then for user...\n", __func__); + EXPECT_EQ(0, AdcTestExecute(ADC_TEST_CMD_MULTI_THREAD)); + printf("%s: exit!\n", __func__); + } /** @@ -79,5 +89,10 @@ HWTEST_F(HdfLiteAdcTest, AdcTestReliability001, TestSize.Level1) { struct HdfTestMsg msg = {TEST_PAL_ADC_TYPE, ADC_TEST_CMD_RELIABILITY, -1}; EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); + + printf("%s: kernel test done, then for user...\n", __func__); + EXPECT_EQ(0, AdcTestExecute(ADC_TEST_CMD_RELIABILITY)); + printf("%s: exit!\n", __func__); + } diff --git a/test/unittest/platform/common/adc_test.c b/test/unittest/platform/common/adc_test.c index 3cdc10f0..718b1864 100644 --- a/test/unittest/platform/common/adc_test.c +++ b/test/unittest/platform/common/adc_test.c @@ -37,7 +37,7 @@ static int32_t AdcTestGetConfig(struct AdcTestConfig *config) return HDF_ERR_NOT_SUPPORT; } - reply = HdfSBufObtain(sizeof(*config) + sizeof(uint64_t)); + reply = HdfSbufObtain(sizeof(*config) + sizeof(uint64_t)); if (reply == NULL) { HDF_LOGE("%s: failed to obtain reply", __func__); return HDF_ERR_MALLOC_FAIL; @@ -113,7 +113,7 @@ int32_t AdcTestRead(void) value[i] = 0; ret = AdcRead(tester->handle, tester->config.channel, &value[i]); if (ret != HDF_SUCCESS || value[i] >= (1U << tester->config.dataWidth)) { - HDF_LOGE("%s: read value invalid:%u, ret:%d", __func__, value[i], ret); + HDF_LOGE("%s: read value failed, ret:%d", __func__, ret); return HDF_ERR_IO; } } @@ -141,6 +141,7 @@ static int AdcTestThreadFunc(void *param) ret = AdcRead(tester->handle, tester->config.channel, &val); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: AdcRead failed, ret:%d", __func__, ret); + *((int32_t *)param) = 1; return HDF_ERR_IO; } } @@ -155,9 +156,9 @@ int32_t AdcTestMultiThread(void) int32_t ret; struct OsalThread thread1, thread2; struct OsalThreadParam cfg1, cfg2; - int32_t count1, count2; + int32_t count1 = 0; + int32_t count2 = 0; - count1 = count2 = 0; HDF_LOGI("%s: enter", __func__); ret = OsalThreadCreate(&thread1, (OsalThreadEntry)AdcTestThreadFunc, (void *)&count1); if (ret != HDF_SUCCESS) {