• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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