2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
4 * Contact: Jeonghoon Park <jh1979.park@samsung.com>
6 * Licensed under the Flora License, Version 1.1 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://floralicense.org/license/
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
22 #include <peripheral_io.h>
25 #define RPI3_I2C_BUS 1
28 #define PCA9685_ADDRESS 0x40
35 #define LED0_ON_L 0x06
36 #define LED0_ON_H 0x07
37 #define LED0_OFF_L 0x08
38 #define LED0_OFF_H 0x09
39 #define ALL_LED_ON_L 0xFA
40 #define ALL_LED_ON_H 0xFB
41 #define ALL_LED_OFF_L 0xFC
42 #define ALL_LED_OFF_H 0xFD
51 static peripheral_i2c_h g_i2c_h = NULL;
53 int pca9685_set_frequency(unsigned int freq_hz)
55 int ret = PERIPHERAL_ERROR_NONE;
56 double prescale_value = 0.0;
61 prescale_value = 25000000.0; // 25MHz
62 prescale_value /= 4096.0; // 12-bit
63 prescale_value /= (double)freq_hz;
64 prescale_value -= 1.0;
66 prescale = (int)floor(prescale_value + 0.5);
68 ret = peripheral_i2c_read_register_byte(g_i2c_h, MODE1, &oldmode);
69 retvm_if(ret != PERIPHERAL_ERROR_NONE, -1, "failed to read register");
71 newmode = (oldmode & 0x7F) | 0x10; // sleep
72 ret = peripheral_i2c_write_register_byte(g_i2c_h, MODE1, newmode); // go to sleep
73 retvm_if(ret != PERIPHERAL_ERROR_NONE, -1, "failed to write register");
75 ret = peripheral_i2c_write_register_byte(g_i2c_h, PRESCALE, prescale);
76 retvm_if(ret != PERIPHERAL_ERROR_NONE, -1, "failed to write register");
78 ret = peripheral_i2c_write_register_byte(g_i2c_h, MODE1, oldmode);
79 retvm_if(ret != PERIPHERAL_ERROR_NONE, -1, "failed to write register");
83 ret = peripheral_i2c_write_register_byte(g_i2c_h, MODE1, (oldmode | 0x80));
84 retvm_if(ret != PERIPHERAL_ERROR_NONE, -1, "failed to write register");
89 int pca9685_set_value_to_channel(unsigned int channel, int on, int off)
91 int ret = PERIPHERAL_ERROR_NONE;
92 retvm_if(g_i2c_h == NULL, -1, "Not initialized yet");
94 ret = peripheral_i2c_write_register_byte(g_i2c_h,
95 LED0_ON_L + 4*channel, on & 0xFF);
96 retvm_if(ret != PERIPHERAL_ERROR_NONE, -1, "failed to write register");
98 ret = peripheral_i2c_write_register_byte(g_i2c_h,
99 LED0_ON_H + 4*channel, on >> 8);
100 retvm_if(ret != PERIPHERAL_ERROR_NONE, -1, "failed to write register");
102 ret = peripheral_i2c_write_register_byte(g_i2c_h,
103 LED0_OFF_L + 4*channel, off & 0xFF);
104 retvm_if(ret != PERIPHERAL_ERROR_NONE, -1, "failed to write register");
106 ret = peripheral_i2c_write_register_byte(g_i2c_h,
107 LED0_OFF_H + 4*channel, off >> 8);
108 retvm_if(ret != PERIPHERAL_ERROR_NONE, -1, "failed to write register");
113 int pca9685_set_value_to_all(int on, int off)
115 int ret = PERIPHERAL_ERROR_NONE;
116 retvm_if(g_i2c_h == NULL, -1, "Not initialized yet");
118 ret = peripheral_i2c_write_register_byte(g_i2c_h,
119 ALL_LED_ON_L, on & 0xFF);
120 retvm_if(ret != PERIPHERAL_ERROR_NONE, -1, "failed to write register");
122 ret = peripheral_i2c_write_register_byte(g_i2c_h,
123 ALL_LED_ON_H, on >> 8);
124 retvm_if(ret != PERIPHERAL_ERROR_NONE, -1, "failed to write register");
126 ret = peripheral_i2c_write_register_byte(g_i2c_h,
127 ALL_LED_OFF_L, off & 0xFF);
128 retvm_if(ret != PERIPHERAL_ERROR_NONE, -1, "failed to write register");
130 ret = peripheral_i2c_write_register_byte(g_i2c_h,
131 ALL_LED_OFF_H, off >> 8);
132 retvm_if(ret != PERIPHERAL_ERROR_NONE, -1, "failed to write register");
137 int pca9685_init(void)
141 int ret = PERIPHERAL_ERROR_NONE;
142 ret = peripheral_i2c_open(RPI3_I2C_BUS, PCA9685_ADDRESS, &g_i2c_h);
143 if (ret != PERIPHERAL_ERROR_NONE) {
144 _E("failed to open pca9685-[bus:%d, addr:%d]",
145 RPI3_I2C_BUS, PCA9685_ADDRESS);
148 ret = pca9685_set_value_to_all(0, 0);
149 retvm_if(ret, -1, "failed to set value to register");
151 ret = peripheral_i2c_write_register_byte(g_i2c_h, MODE2, OUTDRV);
152 retvm_if(ret != PERIPHERAL_ERROR_NONE, -1, "failed to write register");
154 ret = peripheral_i2c_write_register_byte(g_i2c_h, MODE1, ALLCALL);
155 retvm_if(ret != PERIPHERAL_ERROR_NONE, -1, "failed to write register");
157 usleep(500); // wait for oscillator
159 ret = peripheral_i2c_read_register_byte(g_i2c_h, MODE1, &mode1);
160 retvm_if(ret != PERIPHERAL_ERROR_NONE, -1, "failed to read register");
162 mode1 = mode1 & (~SLEEP); // # wake up (reset sleep)
163 ret = peripheral_i2c_write_register_byte(g_i2c_h, MODE1, mode1);
164 retvm_if(ret != PERIPHERAL_ERROR_NONE, -1, "failed to write register");
166 usleep(500); // wait for oscillator
171 int pca9685_fini(void)
174 peripheral_i2c_close(g_i2c_h);