fix typo in resource_adc_mcp3008.c
[apps/native/position-finder-server.git] / src / resource / resource_adc_mcp3008.c
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3  *
4  * Contact: Jin Yoon <jinny.yoon@samsung.com>
5  *          Geunsun Lee <gs86.lee@samsung.com>
6  *          Eunyoung Lee <ey928.lee@samsung.com>
7  *          Junkyu Han <junkyu.han@samsung.com>
8  *
9  * Licensed under the Flora License, Version 1.1 (the License);
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://floralicense.org/license/
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an AS IS BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <peripheral_io.h>
25 #include <tizen.h>
26 #include <system_info.h>
27 #include <string.h>
28 #include "log.h"
29
30
31 #define MCP3008_SPEED 3600000
32 #define MCP3008_BPW 8
33
34 #define MCP3008_TX_WORD1     0x01       /* 0b00000001 */
35 #define MCP3008_TX_CH0 0x80     /* 0b10000000 */
36 #define MCP3008_TX_CH1 0x90     /* 0b10010000 */
37 #define MCP3008_TX_CH2 0xA0     /* 0b10100000 */
38 #define MCP3008_TX_CH3 0xB0     /* 0b10110000 */
39 #define MCP3008_TX_CH4 0xC0     /* 0b11000000 */
40 #define MCP3008_TX_CH5 0xD0     /* 0b11010000 */
41 #define MCP3008_TX_CH6 0xE0     /* 0b11100000 */
42 #define MCP3008_TX_CH7 0xF0     /* 0b11110000 */
43 #define MCP3008_TX_WORD3     0x00       /* 0b00000000 */
44
45 #define MCP3008_RX_WORD1_MASK 0x00      /* 0b00000000 */
46 #define MCP3008_RX_WORD2_NULL_BIT_MASK 0x04     /* 0b00000100 */
47 #define MCP3008_RX_WORD2_MASK 0x03      /* 0b00000011 */
48 #define MCP3008_RX_WORD3_MASK 0xFF      /* 0b11111111 */
49 #define UINT10_VALIDATION_MASK 0x3FF
50
51 #define MODEL_NAME_KEY "http://tizen.org/system/model_name"
52 #define MODEL_NAME_RPI3 "rpi3"
53 #define MODEL_NAME_ARTIK "artik"
54
55 static peripheral_spi_h MCP3008_H = NULL;
56 static unsigned int ref_count = 0;
57
58 int resource_adc_mcp3008_init(void)
59 {
60         int ret = 0;
61         int bus = -1;
62         char *model_name = NULL;
63
64         if (MCP3008_H) {
65                 _D("SPI device already initialized [ref_count : %u]", ref_count);
66                 ref_count++;
67                 return 0;
68         }
69
70         system_info_get_platform_string(MODEL_NAME_KEY, &model_name);
71         if (!model_name) {
72                 _E("fail to get model name");
73                 return -1;
74         }
75
76         if (!strcmp(model_name, MODEL_NAME_RPI3)) {
77                 bus = 0;
78         } else if (!strcmp(model_name, MODEL_NAME_ARTIK)) {
79                 bus = 2;
80         } else {
81                 _E("unknown model name : %s", model_name);
82                 free(model_name);
83                 return -1;
84         }
85         free(model_name);
86         model_name = NULL;
87
88         ret = peripheral_spi_open(bus, 0, &MCP3008_H);
89         if (PERIPHERAL_ERROR_NONE != ret) {
90                 _E("spi open failed :%s ", get_error_message(ret));
91                 return -1;
92         }
93
94         ret = peripheral_spi_set_mode(MCP3008_H, PERIPHERAL_SPI_MODE_0);
95         if (PERIPHERAL_ERROR_NONE != ret) {
96                 _E("peripheral_spi_set_mode failed :%s ", get_error_message(ret));
97                 goto error_after_open;
98         }
99         ret = peripheral_spi_set_bit_order(MCP3008_H, PERIPHERAL_SPI_BIT_ORDER_MSB);
100         if (PERIPHERAL_ERROR_NONE != ret) {
101                 _E("peripheral_spi_set_bit_order failed :%s ", get_error_message(ret));
102                 goto error_after_open;
103         }
104
105         ret = peripheral_spi_set_bits_per_word(MCP3008_H, MCP3008_BPW);
106         if (PERIPHERAL_ERROR_NONE != ret) {
107                 _E("peripheral_spi_set_bits_per_word failed :%s ", get_error_message(ret));
108                 goto error_after_open;
109         }
110
111         ret = peripheral_spi_set_frequency(MCP3008_H, MCP3008_SPEED);
112         if (PERIPHERAL_ERROR_NONE != ret) {
113                 _E("peripheral_spi_set_frequency failed :%s ", get_error_message(ret));
114                 goto error_after_open;
115         }
116
117         ref_count++;
118
119         return 0;
120
121 error_after_open:
122         peripheral_spi_close(MCP3008_H);
123         MCP3008_H = NULL;
124         return -1;
125 }
126
127
128 int resource_read_adc_mcp3008(int ch_num, unsigned int *out_value)
129 {
130         unsigned char rx[3] = {0, };
131         unsigned char tx[3] = {0, };
132         unsigned char rx_w1 = 0;
133         unsigned char rx_w2 = 0;
134         unsigned char rx_w2_nb = 0;
135         unsigned char rx_w3 = 0;
136         unsigned short int result = 0;
137
138         retv_if(MCP3008_H == NULL, -1);
139         retv_if(out_value == NULL, -1);
140         retv_if((ch_num < 0 || ch_num > 7), -1);
141
142         tx[0] = MCP3008_TX_WORD1;
143         switch (ch_num) {
144         case 0:
145                 tx[1] = MCP3008_TX_CH0;
146                 break;
147         case 1:
148                 tx[1] = MCP3008_TX_CH1;
149                 break;
150         case 2:
151                 tx[1] = MCP3008_TX_CH2;
152                 break;
153         case 3:
154                 tx[1] = MCP3008_TX_CH3;
155                 break;
156         case 4:
157                 tx[1] = MCP3008_TX_CH4;
158                 break;
159         case 5:
160                 tx[1] = MCP3008_TX_CH5;
161                 break;
162         case 6:
163                 tx[1] = MCP3008_TX_CH6;
164                 break;
165         case 7:
166                 tx[1] = MCP3008_TX_CH7;
167                 break;
168         default:
169                 tx[1] = MCP3008_TX_CH0;
170                 break;
171         }
172         tx[2] = MCP3008_TX_WORD3;
173
174         peripheral_spi_transfer(MCP3008_H, tx, rx, 3);
175
176         rx_w1 = rx[0] & MCP3008_RX_WORD1_MASK;
177         retv_if(rx_w1 != 0, -1);
178
179         rx_w2_nb = rx[1] & MCP3008_RX_WORD2_NULL_BIT_MASK;
180         retv_if(rx_w2_nb != 0, -1);
181
182         rx_w2 = rx[1] & MCP3008_RX_WORD2_MASK;
183         rx_w3 = rx[2] & MCP3008_RX_WORD3_MASK;
184
185         result = ((rx_w2 << 8) | (rx_w3)) & UINT10_VALIDATION_MASK;
186
187         // _D("%hu", result);
188
189         *out_value = result;
190
191         return 0;
192 }
193
194 void resource_adc_mcp3008_fini(void)
195 {
196         if (MCP3008_H)
197                 ref_count--;
198         else
199                 return;
200
201         if (ref_count == 0) {
202                 peripheral_spi_close(MCP3008_H);
203                 MCP3008_H = NULL;
204         }
205
206         return;
207 }
208