2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <peripheral_io.h>
21 #include <system_info.h>
26 #define MCP3008_SPEED 3600000
29 #define MCP3008_TX_WORD1 0x01 /* 0b00000001 */
30 #define MCP3008_TX_CH0 0x80 /* 0b10000000 */
31 #define MCP3008_TX_CH1 0x90 /* 0b10010000 */
32 #define MCP3008_TX_CH2 0xA0 /* 0b10100000 */
33 #define MCP3008_TX_CH3 0xB0 /* 0b10110000 */
34 #define MCP3008_TX_CH4 0xC0 /* 0b11000000 */
35 #define MCP3008_TX_CH5 0xD0 /* 0b11010000 */
36 #define MCP3008_TX_CH6 0xE0 /* 0b11100000 */
37 #define MCP3008_TX_CH7 0xF0 /* 0b11110000 */
38 #define MCP3008_TX_WORD3 0x00 /* 0b00000000 */
40 #define MCP3008_RX_WORD1_MASK 0x00 /* 0b00000000 */
41 #define MCP3008_RX_WORD2_NULL_BIT_MASK 0x04 /* 0b00000100 */
42 #define MCP3008_RX_WORD2_MASK 0x03 /* 0b00000011 */
43 #define MCP3008_RX_WORD3_MASK 0xFF /* 0b11111111 */
44 #define UINT10_VALIDATION_MASK 0x3FF
46 #define MODEL_NAME_KEY "http://tizen.org/system/model_name"
47 #define MODEL_NAME_RPI3 "rpi3"
48 #define MODEL_NAME_ARTIK "artik"
50 static peripheral_spi_h MCP3008_H = NULL;
51 static unsigned int ref_count = 0;
53 int adc_mcp3008_init(void)
57 char *model_name = NULL;
60 _D("SPI device aleady initialized [ref_count : %u]", ref_count);
65 system_info_get_platform_string(MODEL_NAME_KEY, &model_name);
67 _E("fail to get model name");
71 if (!strcmp(model_name, MODEL_NAME_RPI3)) {
73 } else if (!strcmp(model_name, MODEL_NAME_ARTIK)) {
76 _E("unknown model name : %s", model_name);
83 ret = peripheral_spi_open(bus, 0, &MCP3008_H);
84 if (PERIPHERAL_ERROR_NONE != ret) {
85 _E("spi open failed :%s ", get_error_message(ret));
89 ret = peripheral_spi_set_mode(MCP3008_H, PERIPHERAL_SPI_MODE_0);
90 if (PERIPHERAL_ERROR_NONE != ret) {
91 _E("peripheral_spi_set_mode failed :%s ", get_error_message(ret));
92 goto error_after_open;
94 ret = peripheral_spi_set_bit_order(MCP3008_H, PERIPHERAL_SPI_BIT_ORDER_MSB);
95 if (PERIPHERAL_ERROR_NONE != ret) {
96 _E("peripheral_spi_set_bit_order failed :%s ", get_error_message(ret));
97 goto error_after_open;
100 ret = peripheral_spi_set_bits_per_word(MCP3008_H, MCP3008_BPW);
101 if (PERIPHERAL_ERROR_NONE != ret) {
102 _E("peripheral_spi_set_bits_per_word failed :%s ", get_error_message(ret));
103 goto error_after_open;
106 ret = peripheral_spi_set_frequency(MCP3008_H, MCP3008_SPEED);
107 if (PERIPHERAL_ERROR_NONE != ret) {
108 _E("peripheral_spi_set_frequency failed :%s ", get_error_message(ret));
109 goto error_after_open;
117 peripheral_spi_close(MCP3008_H);
123 int adc_mcp3008_read(int ch_num, unsigned int *out_value)
125 unsigned char rx[3] = {0, };
126 unsigned char tx[3] = {0, };
127 unsigned char rx_w1 = 0;
128 unsigned char rx_w2 = 0;
129 unsigned char rx_w2_nb = 0;
130 unsigned char rx_w3 = 0;
131 unsigned short int result = 0;
133 retv_if(MCP3008_H == NULL, -1);
134 retv_if(out_value == NULL, -1);
135 retv_if((ch_num < 0 || ch_num > 7), -1);
137 tx[0] = MCP3008_TX_WORD1;
140 tx[1] = MCP3008_TX_CH0;
143 tx[1] = MCP3008_TX_CH1;
146 tx[1] = MCP3008_TX_CH2;
149 tx[1] = MCP3008_TX_CH3;
152 tx[1] = MCP3008_TX_CH4;
155 tx[1] = MCP3008_TX_CH5;
158 tx[1] = MCP3008_TX_CH6;
161 tx[1] = MCP3008_TX_CH7;
164 tx[1] = MCP3008_TX_CH0;
167 tx[2] = MCP3008_TX_WORD3;
169 peripheral_spi_transfer(MCP3008_H, tx, rx, 3);
171 rx_w1 = rx[0] & MCP3008_RX_WORD1_MASK;
172 retv_if(rx_w1 != 0, -1);
174 rx_w2_nb = rx[1] & MCP3008_RX_WORD2_NULL_BIT_MASK;
175 retv_if(rx_w2_nb != 0, -1);
177 rx_w2 = rx[1] & MCP3008_RX_WORD2_MASK;
178 rx_w3 = rx[2] & MCP3008_RX_WORD3_MASK;
180 result = ((rx_w2 << 8) | (rx_w3)) & UINT10_VALIDATION_MASK;
182 // _D("%hu", result);
189 void adc_mcp3008_fini(void)
196 if (ref_count == 0) {
197 peripheral_spi_close(MCP3008_H);