1 /* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors
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
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #ifndef IOTJS_MODULE_SPI_LINUX_GENERAL_INL_H
17 #define IOTJS_MODULE_SPI_LINUX_GENERAL_INL_H
21 #include <linux/spi/spidev.h>
22 #include <sys/ioctl.h>
24 #include "iotjs_def.h"
25 #include "iotjs_systemio-linux.h"
26 #include "module/iotjs_module_buffer.h"
27 #include "module/iotjs_module_spi.h"
29 #define ADC_DEVICE_PATH_FORMAT "/dev/spidev%d.%d"
30 #define ADC_DEVICE_PATH_BUFFER_SIZE 16
33 static bool iotjs_spi_set_configuration(iotjs_spi_t* spi) {
34 IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_t, spi);
36 int fd = _this->device_fd;
43 switch (_this->mode) {
59 if (_this->loopback) {
63 if (_this->chip_select == kSpiCsHigh) {
67 if (ioctl(fd, SPI_IOC_WR_MODE, &_this->mode) < 0) {
72 if (_this->bit_order == kSpiOrderLsb) {
74 if (ioctl(fd, SPI_IOC_WR_LSB_FIRST, &data) < 0) {
79 if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &_this->bits_per_word) < 0) {
83 if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &_this->max_speed) < 0) {
88 "SPI Options \n mode: %d\n chipSelect: %d\n bitOrder: %d\n "
89 "maxSpeed: %d\n bitPerWord: %d\n loopback: %d",
90 _this->mode, _this->chip_select, _this->bit_order, _this->max_speed,
91 _this->bits_per_word, _this->loopback);
97 bool iotjs_spi_transfer(iotjs_spi_t* spi) {
98 IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_t, spi);
100 struct spi_ioc_transfer data = {.tx_buf = (unsigned long)_this->tx_buf_data,
101 .rx_buf = (unsigned long)_this->rx_buf_data,
102 .len = _this->buf_len,
103 .speed_hz = _this->max_speed,
104 .bits_per_word = _this->bits_per_word,
108 int err = ioctl(_this->device_fd, SPI_IOC_MESSAGE(1), &data);
110 DDLOG("%s - transfer failed: %d", __func__, err);
118 bool iotjs_spi_close(iotjs_spi_t* spi) {
119 IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_t, spi);
121 if (_this->device_fd >= 0) {
122 const iotjs_environment_t* env = iotjs_environment_get();
123 uv_loop_t* loop = iotjs_environment_loop(env);
124 uv_fs_t fs_close_req;
126 int err = uv_fs_close(loop, &fs_close_req, _this->device_fd, NULL);
127 uv_fs_req_cleanup(&fs_close_req);
129 DDLOG("%s - close failed: %d", __func__, err);
132 _this->device_fd = -1;
139 void iotjs_spi_open_worker(uv_work_t* work_req) {
141 IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_t, spi);
143 const char* device_path = iotjs_string_data(&_this->device);
144 if (iotjs_systemio_check_path(device_path)) {
146 const iotjs_environment_t* env = iotjs_environment_get();
147 uv_loop_t* loop = iotjs_environment_loop(env);
150 int result = uv_fs_open(loop, &open_req, device_path, O_RDONLY, 0666, NULL);
151 uv_fs_req_cleanup(&open_req);
153 req_data->result = false;
155 _this->device_fd = open_req.result;
158 if (!iotjs_spi_set_configuration(spi)) {
159 req_data->result = false;
162 req_data->result = true;
164 req_data->result = false;
169 #endif /* IOTJS_MODULE_SPI_LINUX_GENERAL_INL_H */