2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
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>
9 * Licensed under the Apache License, Version 2.0 (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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 #include <peripheral_io.h>
24 #include <system_info.h>
25 #include "resource/resource_co2_sensor.h"
28 #define MCP3008_SPEED 3600000
31 #define MCP3008_TX_WORD1 0x01 /* 0b00000001 */
32 #define MCP3008_TX_CH0 0x80 /* 0b10000000 */
33 #define MCP3008_TX_CH1 0x90 /* 0b10010000 */
34 #define MCP3008_TX_CH2 0xA0 /* 0b10100000 */
35 #define MCP3008_TX_CH3 0xB0 /* 0b10110000 */
36 #define MCP3008_TX_CH4 0xC0 /* 0b11000000 */
37 #define MCP3008_TX_CH5 0xD0 /* 0b11010000 */
38 #define MCP3008_TX_CH6 0xE0 /* 0b11100000 */
39 #define MCP3008_TX_CH7 0xF0 /* 0b11110000 */
40 #define MCP3008_TX_WORD3 0x00 /* 0b00000000 */
42 #define MCP3008_RX_WORD1_MASK 0x00 /* 0b00000000 */
43 #define MCP3008_RX_WORD2_NULL_BIT_MASK 0x04 /* 0b00000100 */
44 #define MCP3008_RX_WORD2_MASK 0x03 /* 0b00000011 */
45 #define MCP3008_RX_WORD3_MASK 0xFF /* 0b11111111 */
46 #define UINT10_VALIDATION_MASK 0x3FF
48 #define MODEL_NAME_KEY "http://tizen.org/system/model_name"
49 #define MODEL_NAME_RPI3 "rpi3"
50 #define MODEL_NAME_ARTIK "artik"
52 static peripheral_spi_h MCP3008_H = NULL;
53 static unsigned int ref_count = 0;
55 #define retv_if(expr, val) do { \
57 ERR("(%s) -> %s() return", #expr, __FUNCTION__); \
62 int resource_adc_mcp3008_init(void)
66 char *model_name = NULL;
69 DBG("SPI device already initialized [ref_count : %u]", ref_count);
76 system_info_get_platform_string(MODEL_NAME_KEY, &model_name);
78 ERR("fail to get model name");
82 if (!strcmp(model_name, MODEL_NAME_RPI3)) {
84 } else if (!strcmp(model_name, MODEL_NAME_ARTIK)) {
87 ERR("unknown model name : %s", model_name);
91 DBG("%s model_name: %s, bus: %d", __func__, model_name, bus);
95 ret = peripheral_spi_open(bus, 0, &MCP3008_H);
96 if (PERIPHERAL_ERROR_NONE != ret) {
97 ERR("spi open failed :%s ", get_error_message(ret));
101 ret = peripheral_spi_set_mode(MCP3008_H, PERIPHERAL_SPI_MODE_0);
102 if (PERIPHERAL_ERROR_NONE != ret) {
103 ERR("peripheral_spi_set_mode failed :%s ", get_error_message(ret));
104 goto error_after_open;
106 ret = peripheral_spi_set_bit_order(MCP3008_H, PERIPHERAL_SPI_BIT_ORDER_MSB);
107 if (PERIPHERAL_ERROR_NONE != ret) {
108 ERR("peripheral_spi_set_bit_order failed :%s ", get_error_message(ret));
109 goto error_after_open;
112 ret = peripheral_spi_set_bits_per_word(MCP3008_H, MCP3008_BPW);
113 if (PERIPHERAL_ERROR_NONE != ret) {
114 ERR("peripheral_spi_set_bits_per_word failed :%s ", get_error_message(ret));
115 goto error_after_open;
118 ret = peripheral_spi_set_frequency(MCP3008_H, MCP3008_SPEED);
119 if (PERIPHERAL_ERROR_NONE != ret) {
120 ERR("peripheral_spi_set_frequency failed :%s ", get_error_message(ret));
121 goto error_after_open;
123 DBG("%s success: %d", __func__, ref_count);
132 DBG("%s error: %d", __func__, ref_count);
133 peripheral_spi_close(MCP3008_H);
138 int resource_read_adc_mcp3008(int ch_num, unsigned int *out_value)
140 static int spi_read_cnt = 0;
141 static int spi_err_cnt = 0;
142 unsigned char rx[3] = {0, };
143 unsigned char tx[3] = {0, };
144 unsigned char rx_w1 = 0;
145 unsigned char rx_w2 = 0;
146 unsigned char rx_w2_nb = 0;
147 unsigned char rx_w3 = 0;
148 unsigned short int result = 0;
150 retv_if(MCP3008_H == NULL, -1);
151 retv_if(out_value == NULL, -1);
152 retv_if((ch_num < 0 || ch_num > 7), -1);
154 tx[0] = MCP3008_TX_WORD1;
157 tx[1] = MCP3008_TX_CH0;
160 tx[1] = MCP3008_TX_CH1;
163 tx[1] = MCP3008_TX_CH2;
166 tx[1] = MCP3008_TX_CH3;
169 tx[1] = MCP3008_TX_CH4;
172 tx[1] = MCP3008_TX_CH5;
175 tx[1] = MCP3008_TX_CH6;
178 tx[1] = MCP3008_TX_CH7;
181 tx[1] = MCP3008_TX_CH0;
184 tx[2] = MCP3008_TX_WORD3;
186 peripheral_spi_transfer(MCP3008_H, tx, rx, 3);
188 rx_w1 = rx[0] & MCP3008_RX_WORD1_MASK;
189 rx_w2_nb = rx[1] & MCP3008_RX_WORD2_NULL_BIT_MASK;
191 // retv_if(rx_w1 != 0, -1);
192 // retv_if(rx_w2_nb != 0, -1);
194 if (rx_w1 != 0 || rx_w2_nb != 0)
197 if (spi_err_cnt >= 100)
199 DBG("resource_read_adc_mcp3008 rx_w2_nb is not 0 -> rx: %02x, count: %d", rx[1], spi_read_cnt);
205 rx_w2 = rx[1] & MCP3008_RX_WORD2_MASK;
206 rx_w3 = rx[2] & MCP3008_RX_WORD3_MASK;
208 result = ((rx_w2 << 8) | (rx_w3)) & UINT10_VALIDATION_MASK;
215 void resource_adc_mcp3008_fini(void)
225 if (ref_count == 0) {
226 peripheral_spi_close(MCP3008_H);