1 /*
2 * Copyright 2023 Unionman Technology Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "hdf_log.h" // 标准日志打印头文件
17 #include "napi/native_api.h"
18 #include "napi/native_node_api.h"
19 #include "osal_time.h" // 标准延迟&睡眠接口头文件
20 #include "spi_if.h"
21
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25
26 struct spiOnData {
27 napi_async_work asyncWork = nullptr; // 异步工作项
28 napi_deferred deferred = nullptr; // 用于Promise的resolve、reject处理
29 napi_ref callback = nullptr; // 回调函数
30 int result = 0; // 业务逻辑处理结果(返回值)
31 };
32
33
spi_test()34 static int32_t spi_test()
35 {
36 struct SpiDevInfo spiDevinfo; /* SPI设备描述符 */
37 DevHandle spiHandle = NULL; /* SPI设备句柄 */
38 spiDevinfo.busNum = 0; /* SPI设备总线号 */
39 spiDevinfo.csNum = 0; /* SPI设备片选号 */
40 spiHandle = SpiOpen(&spiDevinfo); /* 根据spiDevinfo获取SPI设备句柄 */
41 int32_t ret;
42 struct SpiMsg msg; // 自定义传输的消息
43 uint8_t rbuff[5] = { 0 };
44 uint8_t wbuff[5] = { 0x9f, 0x0, 0x0, 0x0, 0x0 };
45
46 msg.wbuf = wbuff; // 写入的数据
47 msg.rbuf = rbuff; // 读取的数据
48 msg.len = 5L; // 读取写入数据的长度为4
49 msg.keepCs = 0; // 当前传输完成后是否保持CS活动,1表述保持,0表示关闭CS
50 msg.delayUs = 1; // 进行下一次传输前不进行延时
51 msg.speed = 115200L; // 本次传输的速度
52 // 进行一次自定义传输,传输的msg个数为1
53 ret = SpiTransfer(spiHandle, &msg, 1);
54 if (ret != HDF_SUCCESS) {
55 HDF_LOGE("SpiTestSample: spi transfer fail, ret:%d!\n", ret);
56 // 销毁SPI设备句柄
57 SpiClose(spiHandle);
58 return 0;
59 }
60 HDF_LOGD("SpiTestSample: spi tests end!");
61 if (msg.rbuf[0] == 0x0 && msg.rbuf[1] == 0xef && msg.rbuf[2L] == 0x40 && msg.rbuf[3L] == 0x16) {
62 HDF_LOGD("SpiTestSample: spi tests success!");
63 return 1;
64 }
65 }
66
67 // 业务逻辑处理函数,由worker线程池调度执行。
executeCB(napi_env env,void * data)68 static void executeCB(napi_env env, void* data)
69 {
70 spiOnData* spiData = (spiOnData*)data;
71 int ret = 0;
72 ret = spi_test();
73 spiData->result = ret;
74 }
75
76 // 业务逻辑处理完成回调函数,在业务逻辑处理函数执行完成或取消后触发,由EventLoop线程中执行。
completeCBForPromise(napi_env env,napi_status status,void * data)77 static void completeCBForPromise(napi_env env, napi_status status, void* data)
78 {
79 spiOnData* spiData = (spiOnData*)data;
80 napi_value result = nullptr;
81 napi_create_int32(env, spiData->result, &result);
82 napi_resolve_deferred(env, spiData->deferred, result);
83
84 // 删除napi_ref对象
85 if (spiData->callback != nullptr) {
86 napi_delete_reference(env, spiData->callback);
87 }
88
89 // 删除异步工作项
90 napi_delete_async_work(env, spiData->asyncWork);
91 delete spiData;
92 }
93
UM_spi_test(napi_env env,napi_callback_info info)94 static napi_value UM_spi_test(napi_env env, napi_callback_info info)
95 {
96 // 创建promise
97 napi_value promise = nullptr;
98 napi_deferred deferred = nullptr;
99 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
100
101 // 异步工作项上下文用户数据,传递到异步工作项的execute、complete之间传递数据
102 auto spiData = new spiOnData {
103 .asyncWork = nullptr,
104 .deferred = deferred,
105 };
106
107 // 创建async work,创建成功后通过最后一个参数(addonData->asyncWork)返回asyncwork的handle
108 napi_value resourceName = nullptr;
109 napi_create_string_utf8(env, "UM_spi_test", NAPI_AUTO_LENGTH, &resourceName);
110 napi_create_async_work(
111 env, nullptr, resourceName, executeCB, completeCBForPromise, (void*)spiData, &spiData->asyncWork);
112
113 // 将刚创建的async work加到队列,由底层去调度执行
114 napi_queue_async_work(env, spiData->asyncWork);
115
116 // 返回promise
117 return promise;
118 }
119
120 /*
121 * 注册接口
122 */
registerspinapiApis(napi_env env,napi_value exports)123 static napi_value registerspinapiApis(napi_env env, napi_value exports)
124 {
125 napi_property_descriptor desc[] = {
126 DECLARE_NAPI_FUNCTION("UM_spi_test", UM_spi_test),
127 };
128 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
129 return exports;
130 }
131
132 /*
133 * 模块定义
134 */
135 static napi_module spinapiModule = {
136 .nm_version = 1,
137 .nm_flags = 0,
138 .nm_filename = nullptr,
139 .nm_register_func = registerspinapiApis,
140 .nm_modname = "spitest", // 模块名
141 .nm_priv = ((void*)0),
142 .reserved = { 0 },
143 };
144
145 #ifdef __cplusplus
146 }
147 #endif
148 /*
149 * 注册模块
150 */
RegisterspinapiModule(void)151 extern "C" __attribute__((constructor)) void RegisterspinapiModule(void)
152 {
153 napi_module_register(&spinapiModule); // 接口注册函数
154 }
155