1 /* ****************************************************************
3 * Copyright 2017 Samsung Electronics All Rights Reserved.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 ******************************************************************/
21 #include <peripheral_io.h>
23 #include <system_info.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 int adc_mcp3008_init(void)
59 char *model_name = NULL;
62 _D("SPI device aleady initialized [ref_count : %u]", ref_count);
67 system_info_get_platform_string(MODEL_NAME_KEY, &model_name);
69 _E("fail to get model name");
73 if (!strcmp(model_name, MODEL_NAME_RPI3)) {
75 } else if (!strcmp(model_name, MODEL_NAME_ARTIK)) {
78 _E("unknown model name : %s", model_name);
85 ret = peripheral_spi_open(bus, 0, &MCP3008_H);
86 if (PERIPHERAL_ERROR_NONE != ret) {
87 _E("spi open failed :%s ", get_error_message(ret));
91 ret = peripheral_spi_set_mode(MCP3008_H, PERIPHERAL_SPI_MODE_0);
92 if (PERIPHERAL_ERROR_NONE != ret) {
93 _E("peripheral_spi_set_mode failed :%s ", get_error_message(ret));
94 goto error_after_open;
96 ret = peripheral_spi_set_bit_order(MCP3008_H, PERIPHERAL_SPI_BIT_ORDER_MSB);
97 if (PERIPHERAL_ERROR_NONE != ret) {
98 _E("peripheral_spi_set_bit_order failed :%s ", get_error_message(ret));
99 goto error_after_open;
102 ret = peripheral_spi_set_bits_per_word(MCP3008_H, MCP3008_BPW);
103 if (PERIPHERAL_ERROR_NONE != ret) {
104 _E("peripheral_spi_set_bits_per_word failed :%s ", get_error_message(ret));
105 goto error_after_open;
108 ret = peripheral_spi_set_frequency(MCP3008_H, MCP3008_SPEED);
109 if (PERIPHERAL_ERROR_NONE != ret) {
110 _E("peripheral_spi_set_frequency failed :%s ", get_error_message(ret));
111 goto error_after_open;
119 peripheral_spi_close(MCP3008_H);
125 int adc_mcp3008_read(int ch_num, unsigned int *out_value)
127 unsigned char rx[3] = {0, };
128 unsigned char tx[3] = {0, };
129 unsigned char rx_w1 = 0;
130 unsigned char rx_w2 = 0;
131 unsigned char rx_w2_nb = 0;
132 unsigned char rx_w3 = 0;
133 unsigned short int result = 0;
135 retv_if(MCP3008_H == NULL, -1);
136 retv_if(out_value == NULL, -1);
137 retv_if((ch_num < 0 || ch_num > 7), -1);
139 tx[0] = MCP3008_TX_WORD1;
142 tx[1] = MCP3008_TX_CH0;
145 tx[1] = MCP3008_TX_CH1;
148 tx[1] = MCP3008_TX_CH2;
151 tx[1] = MCP3008_TX_CH3;
154 tx[1] = MCP3008_TX_CH4;
157 tx[1] = MCP3008_TX_CH5;
160 tx[1] = MCP3008_TX_CH6;
163 tx[1] = MCP3008_TX_CH7;
166 tx[1] = MCP3008_TX_CH0;
169 tx[2] = MCP3008_TX_WORD3;
171 peripheral_spi_transfer(MCP3008_H, tx, rx, 3);
173 rx_w1 = rx[0] & MCP3008_RX_WORD1_MASK;
174 retv_if(rx_w1 != 0, -1);
176 rx_w2_nb = rx[1] & MCP3008_RX_WORD2_NULL_BIT_MASK;
177 retv_if(rx_w2_nb != 0, -1);
179 rx_w2 = rx[1] & MCP3008_RX_WORD2_MASK;
180 rx_w3 = rx[2] & MCP3008_RX_WORD3_MASK;
182 result = ((rx_w2 << 8) | (rx_w3)) & UINT10_VALIDATION_MASK;
189 void adc_mcp3008_fini(void)
196 if (ref_count == 0) {
197 peripheral_spi_close(MCP3008_H);