From: jino.cho Date: Tue, 18 Apr 2017 03:37:53 +0000 (+0900) Subject: Import source codes from iotbus X-Git-Tag: submit/tizen/20170426.072600~13 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e20ef7112da9a4b98c3fd4c78f54e093e88ba1df;p=platform%2Fcore%2Fsystem%2Fperipheral-bus.git Import source codes from iotbus - Import server source codes from below https://github.com/tizen-artik/iotbus - Fix coding style and Svace issues - Fix build warnings and clean up codes - Rename peripheral_server to peripheral_bus Change-Id: Ic6918f28cc8055f6a4cacba4c94ec45247e9b959 Signed-off-by: jino.cho --- diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..c38fa08 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,42 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +PROJECT(peripheral-bus C) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(VERSION 0.0.1) + +SET(dependents "dlog glib-2.0 gio-2.0") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/daemon) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/interface/include) + +SET(PERIPHERAL-BUS "peripheral-bus") +SET(SRCS + src/daemon/peripheral_bus.c + src/daemon/peripheral_bus_pwm.c + src/daemon/peripheral_bus_i2c.c + src/daemon/peripheral_bus_gpio.c + src/interface/adc.c + src/interface/gpio.c + src/interface/i2c.c + src/interface/pwm.c + src/interface/uart.c) + +INCLUDE(FindPkgConfig) +pkg_check_modules(pbus_pkgs REQUIRED ${dependents}) + +FOREACH(flag ${pbus_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pbus_pkg_LDFLAGS}) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic -Wall -Werror-implicit-function-declaration -fvisibility=hidden") +SET(ARM_CFLAGS "${ARM_CFLAGS} -mapcs -mabi=aapcs-linux -msoft-float -Uarm -fpic") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +SET(CMAKE_EXE_LINKER_FLAGS " -Wl,--as-needed -pie -Wl,--hash-style=both") + +ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pbus_pkgs_LDFLAGS}) + +INSTALL(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) diff --git a/LICENSE.APLv2 b/LICENSE.APLv2 new file mode 100644 index 0000000..6b524fa --- /dev/null +++ b/LICENSE.APLv2 @@ -0,0 +1,204 @@ +Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/packaging/peripheral-bus.manifest b/packaging/peripheral-bus.manifest new file mode 100644 index 0000000..a76fdba --- /dev/null +++ b/packaging/peripheral-bus.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/peripheral-bus.service b/packaging/peripheral-bus.service new file mode 100644 index 0000000..c3d8841 --- /dev/null +++ b/packaging/peripheral-bus.service @@ -0,0 +1,13 @@ +[Unit] +Description=Peripheral Service Daemon +Requires=dbus.service + +[Service] +SmackProcessLabel=System +Type=simple +ExecStart=/usr/bin/peripheral-bus +Restart=always +RestartSec=0 + +[Install] +WantedBy=tizen-system.target diff --git a/packaging/peripheral-bus.spec b/packaging/peripheral-bus.spec new file mode 100644 index 0000000..e74cf88 --- /dev/null +++ b/packaging/peripheral-bus.spec @@ -0,0 +1,48 @@ +Name: peripheral-bus +Summary: Tizen Peripheral Input & Output Service Daemon +Version: 0.0.1 +Release: 0 +Group: System & System Tools +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +Source1: %{name}.manifest +Source2: %{name}.service +BuildRequires: cmake +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(gio-2.0) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(capi-system-peripheral-io) + +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description +Tizen Peripheral Input & Output Service Daemon + +%prep +%setup -q +cp %{SOURCE1} ./ +cp %{SOURCE2} ./ + +%build +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` +%cmake . -DMAJORVER=${MAJORVER} -DFULLVER=%{version} + +%install + +%make_install +mkdir -p %{buildroot}%{_unitdir}/multi-user.target.wants +install -m 0644 %SOURCE2 %{buildroot}%{_unitdir}/peripheral-bus.service +%install_service multi-user.target.wants peripheral-bus.service + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE.APLv2 +%{_bindir}/peripheral-bus +%{_unitdir}/peripheral-bus.service +%{_unitdir}/multi-user.target.wants/peripheral-bus.service diff --git a/src/daemon/peripheral_bus.c b/src/daemon/peripheral_bus.c new file mode 100644 index 0000000..5e8ef1e --- /dev/null +++ b/src/daemon/peripheral_bus.c @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "peripheral_bus.h" +#include "peripheral_bus_gpio.h" +#include "peripheral_bus_i2c.h" +#include "peripheral_bus_pwm.h" +#include "peripheral_common.h" + + +static GDBusNodeInfo *introspection_data = NULL; + +static void handle_request_gpio(GDBusMethodInvocation *invocation, + GVariant *parameters, + gpointer user_data) +{ + gchar *function; + gint32 ret = PERIPHERAL_ERROR_NONE; + gint32 pin; + gint32 direction; + gint32 edge; + gint32 read_value = 0; + gint32 write_value; + struct _peripheral_gpio_s st_gpio; + + g_variant_get(parameters, "(siiii)", &function, &pin, &direction, &edge, &write_value); + + st_gpio.pin = pin; + st_gpio.edge = edge; + st_gpio.direction = direction; + + ret = peripheral_bus_gpio_process(&st_gpio, function, write_value, &read_value); + + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(iiiii)", st_gpio.pin, st_gpio.direction, st_gpio.edge, read_value, ret)); + + g_free(function); +} + +static void handle_request_i2c(GDBusMethodInvocation *invocation, + GVariant *parameters, + gpointer user_data) +{ + gchar *function; + gint32 ret = PERIPHERAL_ERROR_NONE; + gint32 fd; + GVariantIter *data; + guint8 str; + unsigned char data_value[100]; + GVariantBuilder *builder; + gint32 value = 0; + gint32 addr; + int i = 0; + struct _peripheral_i2c_s st_i2c; + + g_variant_get(parameters, "(siiayi)", &function, &value, &fd, &data, &addr); + + if (!strcmp(function, "READ") || !strcmp(function, "WRITE")) { + while (g_variant_iter_loop(data, "y", &str)) { + data_value[i] = str; + i++; + } + } + + g_variant_iter_free(data); + + st_i2c.fd = fd; + + ret = peripheral_bus_i2c_process(&st_i2c, function, value, data_value, addr); + + builder = g_variant_builder_new(G_VARIANT_TYPE("ay")); + + if (!strcmp(function, "READ") || !strcmp(function, "WRITE")) { + for (i = 0; i < value; i++) + g_variant_builder_add(builder, "y", data_value[i]); + } else { + g_variant_builder_add(builder, "y", 0x10); + g_variant_builder_add(builder, "y", 0x10); + } + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(iayi)", st_i2c.fd, builder, ret)); + + g_free(function); +} + +static void handle_request_pwm(GDBusMethodInvocation *invocation, + GVariant *parameters, + gpointer user_data) +{ + gchar *function; + gint32 ret = PERIPHERAL_ERROR_NONE; + struct _peripheral_pwm_s st_pwm; + + g_variant_get(parameters, "(siiiii)", &function, &st_pwm.device, + &st_pwm.channel, &st_pwm.period, &st_pwm.duty_cycle, &st_pwm.enabled); + + ret = peripheral_bus_pwm_process(&st_pwm, function); + + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(iii)", st_pwm.period, st_pwm.duty_cycle, ret)); + + g_free(function); +} + +static void handle_request_spi(GDBusMethodInvocation *invocation, + GVariant *parameters, + gpointer user_data) +{ +} + +static void handle_request_uart(GDBusMethodInvocation *invocation, + GVariant *parameters, + gpointer user_data) +{ +} + + +static void handle_method_call(GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + + if (parameters == NULL) { + _E("Client : parameters Null !"); + return; + } + + if (invocation == NULL) { + _E("client : invocation NULL !"); + return; + } + + if (method_name == NULL) { + _E("Client : method_name NULL !"); + return; + } + + if (!strcmp(method_name, PERIPHERAL_METHOD_GPIO)) + handle_request_gpio(invocation, parameters, user_data); + else if (!strcmp(method_name, PERIPHERAL_METHOD_I2C)) + handle_request_i2c(invocation, parameters, user_data); + else if (!strcmp(method_name, PERIPHERAL_METHOD_PWM)) + handle_request_pwm(invocation, parameters, user_data); + else if (!strcmp(method_name, PERIPHERAL_METHOD_SPI)) + handle_request_spi(invocation, parameters, user_data); + else if (!strcmp(method_name, PERIPHERAL_METHOD_UART)) + handle_request_uart(invocation, parameters, user_data); +} + +static const GDBusInterfaceVTable interface_vtable = { + handle_method_call, + NULL, + NULL, +}; + +guint registration_id = 0; + +static void on_bus_acquired(GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + guint registration_id; + + if (!connection) { + _E("connection is null"); + return; + } + + registration_id = g_dbus_connection_register_object(connection, + PERIPHERAL_DBUS_PATH, + introspection_data->interfaces[0], + &interface_vtable, + NULL, /* user_data */ + NULL, /* user_data_free_func */ + NULL); /* GError** */ + + if (registration_id == 0) + _E("Failed to g_dbus_connection_register_object"); + + _D("Gdbus method call registered"); +} + +static void on_name_acquired(GDBusConnection *conn, + const gchar *name, gpointer user_data) +{ +} + +static void on_name_lost(GDBusConnection *conn, + const gchar *name, gpointer user_data) +{ + _E("Dbus name is lost!"); +} + +int main(int argc, char *argv[]) +{ + GMainLoop *loop; + guint owner_id; + + introspection_data = g_dbus_node_info_new_for_xml(peripheral_data_xml, NULL); + g_assert(introspection_data != NULL); + + owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, + PERIPHERAL_DBUS_NAME, + (GBusNameOwnerFlags) (G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT + | G_BUS_NAME_OWNER_FLAGS_REPLACE), + on_bus_acquired, + on_name_acquired, + on_name_lost, + NULL, + NULL); + _D("owner_id : %d", owner_id); + + loop = g_main_loop_new(NULL, FALSE); + + _D("Enter main loop!"); + g_main_loop_run(loop); + + if (loop != NULL) + g_main_loop_unref(loop); + + return 0; +} diff --git a/src/daemon/peripheral_bus.h b/src/daemon/peripheral_bus.h new file mode 100644 index 0000000..6164a26 --- /dev/null +++ b/src/daemon/peripheral_bus.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PERIPHERAL_BUS_H__ +#define __PERIPHERAL_BUS_H__ + +const gchar peripheral_data_xml[] = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " // read value + " " // return value + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " //return value + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " //return value + " " + " " + ""; +#endif /* __PERIPHERAL_BUS_H__ */ diff --git a/src/daemon/peripheral_bus_gpio.c b/src/daemon/peripheral_bus_gpio.c new file mode 100644 index 0000000..b7ee47c --- /dev/null +++ b/src/daemon/peripheral_bus_gpio.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include + +#include "gpio.h" +#include "peripheral_common.h" + + +int peripheral_bus_gpio_open(peripheral_gpio_h gpio) +{ + gpio_edge_e edge; + gpio_direction_e direction; + + if (gpio_open(gpio->pin) < 0) { + _E("gpio_open error"); + return PERIPHERAL_ERROR_INVALID_PARAMETER; + } + + if (gpio_get_edge_mode(gpio->pin, (gpio_edge_e*)&edge) < 0) { + gpio_close(gpio->pin); + _E("gpio_get_edge_mode error"); + return PERIPHERAL_ERROR_INVALID_PARAMETER; + } + gpio->edge = edge; + + if (gpio_get_direction(gpio->pin, (gpio_direction_e*)&direction) < 0) { + gpio_close(gpio->pin); + _E("gpio_get_direction error"); + return PERIPHERAL_ERROR_INVALID_PARAMETER; + } + gpio->direction = direction; + + return PERIPHERAL_ERROR_NONE; +} + +int peripheral_bus_gpio_set_direction(peripheral_gpio_h gpio) +{ + return gpio_set_direction(gpio->pin, (gpio_direction_e)gpio->direction); +} + +int peripheral_bus_gpio_get_direction(peripheral_gpio_h gpio) +{ + return gpio_get_direction(gpio->pin, (gpio_direction_e*)&gpio->direction); +} + +int peripheral_bus_gpio_set_edge(peripheral_gpio_h gpio) +{ + return gpio_set_edge_mode(gpio->pin, (gpio_edge_e)gpio->edge); +} + +int peripheral_bus_gpio_get_edge(peripheral_gpio_h gpio) +{ + return gpio_get_edge_mode(gpio->pin, (gpio_edge_e*)&gpio->edge); +} + +int peripheral_bus_gpio_write(peripheral_gpio_h gpio, int value) +{ + return gpio_write(gpio->pin, value); +} + +int peripheral_bus_gpio_read(peripheral_gpio_h gpio, int *read_value) +{ + return gpio_read(gpio->pin, read_value); +} + +int peripheral_bus_gpio_close(peripheral_gpio_h gpio) +{ + return gpio_close(gpio->pin); +} + +int peripheral_bus_gpio_process(peripheral_gpio_h gpio, char *func_name, int write_value, int * read_value) +{ + int ret = PERIPHERAL_ERROR_NONE; + + if (gpio == NULL) { + _E("gpio null error"); + return PERIPHERAL_ERROR_INVALID_PARAMETER; + } + + if (!g_strcmp0(func_name, "OPEN")) + ret = peripheral_bus_gpio_open(gpio); + else if (!g_strcmp0(func_name, "SET_DIR")) + ret = peripheral_bus_gpio_set_direction(gpio); + else if (!g_strcmp0(func_name, "GET_DIR")) + ret = peripheral_bus_gpio_get_direction(gpio); + else if (!g_strcmp0(func_name, "SET_EDGE")) + ret = peripheral_bus_gpio_set_edge(gpio); + else if (!g_strcmp0(func_name, "GET_EDGE")) + ret = peripheral_bus_gpio_get_edge(gpio); + else if (!g_strcmp0(func_name, "WRITE")) + ret = peripheral_bus_gpio_write(gpio, write_value); + else if (!g_strcmp0(func_name, "READ")) + ret = peripheral_bus_gpio_read(gpio, read_value); + else if (!g_strcmp0(func_name, "CLOSE")) + ret = peripheral_bus_gpio_close(gpio); + + return ret; +} diff --git a/src/daemon/peripheral_bus_gpio.h b/src/daemon/peripheral_bus_gpio.h new file mode 100644 index 0000000..f299733 --- /dev/null +++ b/src/daemon/peripheral_bus_gpio.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PERIPHERAL_BUS_GPIO_H__ +#define __PERIPHERAL_BUS_GPIO_H__ + +int peripheral_bus_gpio_process(peripheral_gpio_h dev, char *func_name, int write_value, int * read_value); + +#endif /* __PERIPHERAL_BUS_GPIO_H__ */ diff --git a/src/daemon/peripheral_bus_i2c.c b/src/daemon/peripheral_bus_i2c.c new file mode 100644 index 0000000..391d442 --- /dev/null +++ b/src/daemon/peripheral_bus_i2c.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include + +#include "i2c.h" +#include "peripheral_common.h" + +int peripheral_bus_i2c_init(peripheral_i2c_context_h dev, int bus) +{ + return i2c_open(bus, &dev->fd); +} + +int peripheral_bus_i2c_set_freq(peripheral_i2c_context_h dev, int mode) +{ + return i2c_set_frequency(dev->fd, mode); +} + +int peripheral_bus_i2c_set_addr(peripheral_i2c_context_h dev, int addr) +{ + return i2c_set_address(dev->fd, addr); +} + +int peripheral_bus_i2c_read(peripheral_i2c_context_h dev, int length, unsigned char * data, int addr) +{ + return i2c_read(dev->fd, data, length, addr); +} + +int peripheral_bus_i2c_write(peripheral_i2c_context_h dev, int length, unsigned char * data, int addr) +{ + return i2c_write(dev->fd, data, length, addr); +} + +int peripheral_bus_i2c_stop(peripheral_i2c_context_h dev) +{ + return i2c_close(dev->fd); +} + +int peripheral_bus_i2c_process(peripheral_i2c_context_h dev, char *func_name, int value, unsigned char *data, int addr) +{ + int ret = PERIPHERAL_ERROR_NONE; + + if (dev == NULL) { + _E("dev null error"); + return PERIPHERAL_ERROR_INVALID_PARAMETER; + } + + if (!g_strcmp0(func_name, "INIT")) + ret = peripheral_bus_i2c_init(dev, value); + else if (!g_strcmp0(func_name, "SET_FREQ")) + ret = peripheral_bus_i2c_set_freq(dev, value); + else if (!g_strcmp0(func_name, "SET_ADDR")) + ret = peripheral_bus_i2c_set_addr(dev, value); + else if (!g_strcmp0(func_name, "READ")) + ret = peripheral_bus_i2c_read(dev, value, data, addr); + else if (!g_strcmp0(func_name, "WRITE")) + ret = peripheral_bus_i2c_write(dev, value, data, addr); + else if (!g_strcmp0(func_name, "STOP")) + ret = peripheral_bus_i2c_stop(dev); + + return ret; +} diff --git a/src/daemon/peripheral_bus_i2c.h b/src/daemon/peripheral_bus_i2c.h new file mode 100644 index 0000000..230cad8 --- /dev/null +++ b/src/daemon/peripheral_bus_i2c.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PERIPHERAL_BUS_I2C_H__ +#define __PERIPHERAL_BUS_I2C_H__ + +int peripheral_bus_i2c_process(peripheral_i2c_context_h dev, char *func_name, int value, unsigned char *data, int addr); + +#endif /* __PERIPHERAL_BUS_I2C_H__ */ diff --git a/src/daemon/peripheral_bus_pwm.c b/src/daemon/peripheral_bus_pwm.c new file mode 100644 index 0000000..093918e --- /dev/null +++ b/src/daemon/peripheral_bus_pwm.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include + +#include "pwm.h" +#include "peripheral_common.h" + +int peripheral_bus_pwm_open(int device, int channel) +{ + return pwm_open(device, channel); +} + +int peripheral_bus_pwm_close(int device, int channel) +{ + return pwm_close(device, channel); +} + +int peripheral_bus_pwm_setduty(int device, int channel, int duty_cycle) +{ + return pwm_set_duty_cycle(device, channel, duty_cycle); +} + +int peripheral_bus_pwm_setperiod(int device, int channel, int period) +{ + return pwm_set_period(device, channel, period); +} + +int peripheral_bus_pwm_setenable(int device, int channel, int enable) +{ + return pwm_set_enabled(device, channel, enable); +} + +int peripheral_bus_pwm_getduty(int device, int channel, int * duty_cycle) +{ + return pwm_get_duty_cycle(device, channel, duty_cycle); +} + +int peripheral_bus_pwm_getperiod(int device, int channel, int *period) +{ + return pwm_get_period(device, channel, period); +} + +int peripheral_bus_pwm_process(peripheral_pwm_context_h dev, char *function) +{ + int ret = PERIPHERAL_ERROR_NONE; + + if (dev == NULL) { + _E("dev null error"); + return PERIPHERAL_ERROR_INVALID_PARAMETER; + } + + if (!g_strcmp0(function, "OPEN")) + ret = peripheral_bus_pwm_open(dev->device, dev->channel); + else if (!g_strcmp0(function, "CLOSE")) + ret = peripheral_bus_pwm_close(dev->device, dev->channel); + else if (!g_strcmp0(function, "SET_DUTY")) + ret = peripheral_bus_pwm_setduty(dev->device, dev->channel, dev->duty_cycle); + else if (!g_strcmp0(function, "SET_PERIOD")) + ret = peripheral_bus_pwm_setperiod(dev->device, dev->channel, dev->period); + else if (!g_strcmp0(function, "SET_ENABLE")) + ret = peripheral_bus_pwm_setenable(dev->device, dev->channel, dev->enabled); + else if (!g_strcmp0(function, "GET_DUTY")) + ret = peripheral_bus_pwm_getduty(dev->device, dev->channel, &dev->duty_cycle); + else if (!g_strcmp0(function, "GET_PERIOD")) + ret = peripheral_bus_pwm_getperiod(dev->device, dev->channel, &dev->period); + + return ret; +} diff --git a/src/daemon/peripheral_bus_pwm.h b/src/daemon/peripheral_bus_pwm.h new file mode 100644 index 0000000..b6d77a3 --- /dev/null +++ b/src/daemon/peripheral_bus_pwm.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PERIPHERAL_BUS_PWM_H__ +#define __PERIPHERAL_BUS_PWM_H__ + +int peripheral_bus_pwm_process(peripheral_pwm_context_h dev, char *function); + +#endif /* __PERIPHERAL_BUS_PWM_H__ */ diff --git a/src/daemon/peripheral_common.h b/src/daemon/peripheral_common.h new file mode 100644 index 0000000..905189f --- /dev/null +++ b/src/daemon/peripheral_common.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __PERIPHERAL_COMMON_H__ +#define __PERIPHERAL_COMMON_H__ + +#include +#include + +#undef LOG_TAG +#define LOG_TAG "PERIPHERAL-BUS" + +#define _E(fmt, arg...) LOGE(fmt, ##arg) +#define _D(fmt, arg...) LOGD(fmt, ##arg) +#define _W(fmt, arg...) LOGW(fmt, ##arg) + +#endif /* __PERIPHERAL_COMMON_H__ */ diff --git a/src/interface/adc.c b/src/interface/adc.c new file mode 100644 index 0000000..93f7797 --- /dev/null +++ b/src/interface/adc.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +#include "adc.h" +#include "peripheral_common.h" + +#define SYSFS_ADC_PATH "/sys/bus/iio/devices/iio:device" + +#define PATH_BUF_MAX 64 +#define ADC_BUF_MAX 16 + +int adc_get_device_name(char *devName) +{ + int fd; + int device = 0; /* for get adc device name, /sys/bus/iio/devices/iio:device"0" */ + char fName[PATH_BUF_MAX] = {0}; + int bytes; + + snprintf(fName, PATH_BUF_MAX, "%s%d%s", SYSFS_ADC_PATH, device, "/name"); + if ((fd = open(fName, O_RDONLY)) < 0) { + _E("Error[%d]: can't open adc device name, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -ENODEV; + } + bytes = read(fd, devName, PATH_BUF_MAX); + if (bytes == -1) { + close(fd); + return -EIO; + } + + devName[strlen(devName) - 1] = '\0'; + close(fd); + + return 0; +} + +int adc_get_data(int channel, char *devName, int *data) +{ + int fd; + int device = 0; /* for get adc device name, /sys/devices/[devName]/iio:device"0" */ + char fName[PATH_BUF_MAX] = {0}; + char voltage[ADC_BUF_MAX] = {0}; + int bytes; + + snprintf(fName, PATH_BUF_MAX, "%s%s%s%d%s%d%s", "/sys/devices/", devName, "/iio:device", device, "/in_voltage", channel, "_raw"); + if ((fd = open(fName, O_RDONLY)) < 0) { + _E("Error[%d]: can't open adc%d channel, %s--[%d]\n", errno, channel, __FUNCTION__, __LINE__); + return -ENODEV; + } + bytes = read(fd, voltage, ADC_BUF_MAX); + if (bytes == -1) { + close(fd); + return -EIO; + } + + *data = atoi(voltage); + close(fd); + + return 0; +} diff --git a/src/interface/gpio.c b/src/interface/gpio.c new file mode 100644 index 0000000..434e764 --- /dev/null +++ b/src/interface/gpio.c @@ -0,0 +1,369 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "gpio.h" +#include "peripheral_common.h" + +#define MAX_ERR_LEN 255 + +int gpio_get_edge_mode(int gpiopin, gpio_edge_e *edge) +{ + int fd, len; + char gpio_dev[GPIO_BUFFER_MAX] = {0, }; + char gpio_buf[GPIO_BUFFER_MAX] = {0, }; + + snprintf(gpio_dev, GPIO_BUFFER_MAX, SYSFS_GPIO_DIR"/gpio%d/edge", gpiopin); + fd = open(gpio_dev, O_RDONLY); + + if (fd < 0) { + char errmsg[MAX_ERR_LEN]; + strerror_r(errno, errmsg, MAX_ERR_LEN); + _E("Can't Open /sys/class/gpio/gpio%d/edge: %s\n", gpiopin, errmsg); + return -ENODEV; + } + + len = read(fd, &gpio_buf, GPIO_BUFFER_MAX); + if (len <= 0) { + close(fd); + _E("Error: gpio edge read error\n"); + return -EIO; + } + + if (0 == strncmp(gpio_buf, "none", strlen("none"))) + *edge = GPIO_EDGE_NONE; + else if (0 == strncmp(gpio_buf, "both", strlen("both"))) + *edge = GPIO_EDGE_BOTH; + else if (0 == strncmp(gpio_buf, "rising", strlen("rising"))) + *edge = GPIO_EDGE_RISING; + else if (0 == strncmp(gpio_buf, "falling", strlen("falling"))) + *edge = GPIO_EDGE_FALLING; + else { + close(fd); + _E("Error: gpio edge is wrong\n"); + return -EIO; + } + + close(fd); + + return 0; +} + +int gpio_get_direction(int gpiopin, gpio_direction_e *dir) +{ + int fd, len; + char gpio_dev[GPIO_BUFFER_MAX] = {0, }; + char gpio_buf[GPIO_BUFFER_MAX] = {0, }; + + snprintf(gpio_dev, GPIO_BUFFER_MAX, SYSFS_GPIO_DIR"/gpio%d/direction", gpiopin); + fd = open(gpio_dev, O_RDONLY); + + if (fd < 0) { + char errmsg[MAX_ERR_LEN]; + strerror_r(errno, errmsg, MAX_ERR_LEN); + _E("Can't Open /sys/class/gpio/gpio%d/direction: %s\n", gpiopin, errmsg); + return -ENODEV; + } + + len = read(fd, &gpio_buf, GPIO_BUFFER_MAX); + if (len <= 0) { + close(fd); + _E("Error: gpio direction read error\n"); + return -EIO; + } + + if (0 == strncmp(gpio_buf, "in", strlen("in"))) + *dir = GPIO_DIRECTION_IN; + else if (0 == strncmp(gpio_buf, "out", strlen("out"))) + *dir = GPIO_DIRECTION_OUT; + else { + close(fd); + _E("Error: gpio direction is wrong\n"); + return -EIO; + } + + close(fd); + + return 0; +} + +int gpio_read(int gpiopin, int *value) +{ + int fd, len; + char gpio_dev[GPIO_BUFFER_MAX] = {0, }; + char gpio_buf[GPIO_BUFFER_MAX] = {0, }; + + snprintf(gpio_dev, GPIO_BUFFER_MAX, SYSFS_GPIO_DIR"/gpio%d/value", gpiopin); + fd = open(gpio_dev, O_RDONLY); + if (fd < 0) { + char errmsg[MAX_ERR_LEN]; + strerror_r(errno, errmsg, MAX_ERR_LEN); + _E("Can't Open /sys/class/gpio/gpio%d pin value: %s\n", gpiopin, errmsg); + return -ENODEV; + } + + len = read(fd, &gpio_buf, 1); + close(fd); + + if (len <= 0) { + _E("Error: gpio read error \n"); + return -EIO; + } + + if (0 == strncmp(gpio_buf, "1", strlen("1"))) + *value = 1; + else if (0 == strncmp(gpio_buf, "0", strlen("0"))) + *value = 0; + else { + _E("Error: gpio value is error \n"); + return -EIO; + } + + return 0; +} + + +int gpio_open(int gpiopin) +{ + int fd, len, status; + char gpio_export[GPIO_BUFFER_MAX] = {0, }; + + gpio_close(gpiopin); + + fd = open(SYSFS_GPIO_DIR "/export", O_WRONLY); + + if (fd < 0) { + char errmsg[MAX_ERR_LEN]; + strerror_r(errno, errmsg, MAX_ERR_LEN); + _E("Can't Open /sys/class/gpio/export :%s\n", errmsg); + return -ENODEV; + } + + len = snprintf(gpio_export, GPIO_BUFFER_MAX, "%d", gpiopin); + status = write(fd, gpio_export, len); + + if (status != len) { + close(fd); + _E("Error: gpio open error \n"); + return -EIO; + } + + close(fd); + + return 0; +} + +int gpio_close(int gpiopin) +{ + int fd, len, status; + char gpio_unexport[GPIO_BUFFER_MAX] = {0, }; + + fd = open(SYSFS_GPIO_DIR "/unexport", O_WRONLY); + if (fd < 0) { + char errmsg[MAX_ERR_LEN]; + strerror_r(errno, errmsg, MAX_ERR_LEN); + _E("Can't Open /sys/class/gpio/unexport %s\n", errmsg); + return -ENODEV; + } + + len = snprintf(gpio_unexport, GPIO_BUFFER_MAX, "%d", gpiopin); + status = write(fd, gpio_unexport, len); + + if (status != len) { + close(fd); + _E("Error: gpio open error \n"); + return -EIO; + } + + close(fd); + + return 0; +} + + +int gpio_set_edge_mode(int gpiopin, gpio_edge_e edge) +{ + int fd, status; + char gpio_dev[GPIO_BUFFER_MAX] = {0, }; + + snprintf(gpio_dev, GPIO_BUFFER_MAX, SYSFS_GPIO_DIR"/gpio%d/edge", gpiopin); + fd = open(gpio_dev, O_WRONLY); + if (fd < 0) { + char errmsg[MAX_ERR_LEN]; + strerror_r(errno, errmsg, MAX_ERR_LEN); + _E("Can't Open /sys/class/gpio/gpio%d/edge: %s\n", gpiopin, errmsg); + return -ENODEV; + } + + if (edge == GPIO_EDGE_NONE) + status = write(fd, "none", strlen("none")+1); + else if (edge == GPIO_EDGE_RISING) + status = write(fd, "rising", strlen("rising")+1); + else if (edge == GPIO_EDGE_FALLING) + status = write(fd, "falling", strlen("falling")+1); + else if (edge == GPIO_EDGE_BOTH) + status = write(fd, "both", strlen("both")+1); + else { + close(fd); + _E("Error: gpio edge is wrong\n"); + return -EIO; + } + + if (status <= 0) { + close(fd); + _E("Error: gpio edge set error\n"); + return -EIO; + } + + close(fd); + + return 0; +} + +int gpio_set_direction(int gpiopin, gpio_direction_e dir) +{ + int fd, status; + char gpio_dev[GPIO_BUFFER_MAX] = {0, }; + + snprintf(gpio_dev, GPIO_BUFFER_MAX, SYSFS_GPIO_DIR"/gpio%d/direction", gpiopin); + fd = open(gpio_dev, O_WRONLY); + if (fd < 0) { + char errmsg[MAX_ERR_LEN]; + strerror_r(errno, errmsg, MAX_ERR_LEN); + _E("Can't Open /sys/class/gpio/gpio%d/direction: %s\n", gpiopin, errmsg); + return -ENODEV; + } + + if (dir == GPIO_DIRECTION_OUT) + status = write(fd, "out", strlen("out")+1); + else if (dir == GPIO_DIRECTION_IN) + status = write(fd, "in", strlen("in")+1); + else { + close(fd); + _E("Error: gpio direction is wrong\n"); + return -EIO; + } + + if (status <= 0) { + close(fd); + _E("Error: gpio direction set error\n"); + return -EIO; + } + + close(fd); + + return 0; +} + +int gpio_write(int gpiopin, int value) +{ + int fd, status; + char gpio_dev[GPIO_BUFFER_MAX] = {0, }; + + snprintf(gpio_dev, GPIO_BUFFER_MAX, SYSFS_GPIO_DIR"/gpio%d/value", gpiopin); + fd = open(gpio_dev, O_WRONLY); + + if (fd < 0) { + char errmsg[MAX_ERR_LEN]; + strerror_r(errno, errmsg, MAX_ERR_LEN); + _E("Can't Open /sys/class/gpio/gpio%d/value: %s\n", gpiopin, errmsg); + return -ENODEV; + } + + if (value == 1) + status = write(fd, "1", strlen("1")+1); + else if (value == 0) + status = write(fd, "0", strlen("0")+1); + else { + close(fd); + _E("Error: gpio write value error \n"); + return -EIO; + } + + if (status <= 0) { + close(fd); + _E("Error: gpio write error\n"); + return -EIO; + } + + close(fd); + + return 0; +} + +int gpio_open_isr(int gpiopin) +{ + int fd; + char gpio_dev[GPIO_BUFFER_MAX] = {0, }; + + snprintf(gpio_dev, sizeof(gpio_dev)-1, SYSFS_GPIO_DIR"/gpio%d/value", gpiopin); + + _D("open isr string [%s]", gpio_dev); + + fd = open(gpio_dev, O_RDONLY); + if (fd < 0) { + char errmsg[MAX_ERR_LEN]; + strerror_r(errno, errmsg, MAX_ERR_LEN); + _E("Can't Open /sys/class/gpio/gpio%d pin value: %s\n", gpiopin, errmsg); + return -ENODEV; + } + + return fd; +} + +int gpio_close_isr(int file_hndl) +{ + if (file_hndl == (int)NULL) + return -EINVAL; + + close(file_hndl); + + return 0; +} + +int gpio_read_isr(void *fdset, char *rev_buf, int length) +{ + int poll_state = 0; + int len; + struct pollfd poll_events; + + poll_events.fd = ((struct pollfd*)fdset)->fd; + poll_events.events = POLLPRI; + poll_events.revents = ((struct pollfd*)fdset)->revents; + + poll_state = poll((struct pollfd*)&poll_events, 1, -1); // 0 is going to return directly. + + if (poll_state < 0) { + _E("poll() failed!\n"); + return -EIO; + } + + if (poll_events.revents & POLLPRI) { + lseek(poll_events.fd, 0, SEEK_SET); + len = read(poll_events.fd, rev_buf, length); + if (len == -1) + return -EIO; + } + + return poll_state; +} diff --git a/src/interface/i2c.c b/src/interface/i2c.c new file mode 100644 index 0000000..d9b7614 --- /dev/null +++ b/src/interface/i2c.c @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "i2c.h" +#include "peripheral_common.h" + +#define MAX_ERR_LEN 255 + +int i2c_open(int bus, int *file_hndl) +{ + int fd; + char i2c_dev[I2C_BUFFER_MAX] = {0,}; + + snprintf(i2c_dev, sizeof(i2c_dev)-1, SYSFS_I2C_DIR"-%d", bus); + + fd = open(i2c_dev, O_RDWR); + if (fd < 0) { + char errmsg[MAX_ERR_LEN]; + strerror_r(errno, errmsg, MAX_ERR_LEN); + _E("Can't Open /dev/i2c-%d : %s\n", bus, errmsg); + return -ENODEV; + } + + *file_hndl = fd; + //*file_hndl = bus; + //close(fd); + + return 0; +} + +int i2c_close(int file_hndl) +{ + if (file_hndl == (int)NULL) + return -EINVAL; + + close(file_hndl); + + return 0; +} + +int i2c_set_frequency(int file_hndl, i2c_mode_e speed) +{ + int status; + int fd; + char i2c_dev[I2C_BUFFER_MAX] = {0,}; + int frequency = 0; + + snprintf(i2c_dev, sizeof(i2c_dev)-1, SYSFS_I2C_DIR"-%d", file_hndl); + fd = open(i2c_dev, O_RDWR); + + if (fd < 0) + return -ENODEV; + + if (speed == I2C_STD) { + frequency = 10000; + } else if (speed == I2C_FAST) { + frequency = 400000; + } else if (speed == I2C_HIGH) { + frequency = 3400000; + } else { + _E("Error: speed is not supported [%d]\n", speed); + close(fd); + return -EINVAL; + } + + status = ioctl(fd, I2C_FREQUENCY, (unsigned long)((unsigned int*)&frequency)); + + if (status < 0) { + _E("Error I2C_FREQUENCY, speed[%d]:\n", speed); + close(fd); + return -EIO; + } + close(fd); + return 0; +} + +int i2c_set_address(int file_hndl, int address) +{ + int status; + + _D("I2C SLAVE address = [%x]\n", address); + + status = ioctl(file_hndl, I2C_SLAVE, address); + + if (status < 0) { + _E("Error I2C_SLAVE, address[%x]:\n", address); + return -EIO; + } + + return 0; +} + +int i2c_read(int file_hndl, unsigned char *data, int length, int addr) +{ + int status; + //int fd; + //char i2c_dev[I2C_BUFFER_MAX] = {0,}; + + //snprintf(i2c_dev, sizeof(i2c_dev)-1, SYSFS_I2C_DIR"-%d", file_hndl); + + //fd = open(i2c_dev, O_RDWR); + + //if (fd < 0) { + // _E("Can't Open /dev/i2c-%d : %s\n", file_hndl, strerror(errno)); + // return PERIPHERAL_ERROR_INVALID_PARAMETER; + //} + //status = ioctl(fd, I2C_SLAVE, addr); + //if (status < 0) { + // _E("Error I2C_SLAVE, address[%x]:\n", addr); + // return PERIPHERAL_ERROR_UNKNOWN; + //} + _D("[Read] file_hndle = %d\n", file_hndl); + status = read(file_hndl, data, length); + + if (status != length) { + _E("i2c transaction read failed\n"); + return -EIO; + } else + _D("[SUCCESS] data[%02x][%02x]\n", data[0], data[1]); + + //close(fd); + + return 0; +} + +int i2c_write(int file_hndl, const unsigned char *data, int length, int addr) +{ + int status; + //int fd; + //char i2c_dev[I2C_BUFFER_MAX] = {0,}; + + //snprintf(i2c_dev, sizeof(i2c_dev)-1, SYSFS_I2C_DIR"-%d", file_hndl); + + //fd = open(i2c_dev, O_RDWR); + + //if (fd < 0) { + // _E("Can't Open /dev/i2c-%d : %s\n", file_hndl, strerror(errno)); + // return PERIPHERAL_ERROR_INVALID_PARAMETER; + //} + +// status = ioctl(fd, I2C_SLAVE, addr); + //if (status < 0) { + // _E("Error I2C_SLAVE, address[%x]:\n", addr); + // return PERIPHERAL_ERROR_UNKNOWN; + //} + + status = write(file_hndl, data, length); + + if (status != length) { + _E("i2c transaction wrtie failed \n"); + // close(fd); + return -EIO; + } + + //close(fd); + + return 0; +} diff --git a/src/interface/include/adc.h b/src/interface/include/adc.h new file mode 100644 index 0000000..1d54f2a --- /dev/null +++ b/src/interface/include/adc.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ADC_H__ +#define __ADC_H__ + +/** +* @brief adc_init() find adc device name. +* +* @param[in] *devName adc device name +* @return On success, 0 is returned. On failure, a negative value is returned. +*/ +int adc_get_device_name(char *devName); + +/** +* @brief adc_get_data() get adc data. +* +* @param[in] channel adc channel number +* @param[in] *devName adc device name +* @param[in] *data adc value +* @return On success, voltage is returned. On failure, a negative value is returned. +*/ +int adc_get_data(int channel, char *devName, int *data); + +#endif /* __ADC_H__ */ diff --git a/src/interface/include/gpio.h b/src/interface/include/gpio.h new file mode 100644 index 0000000..a7cb530 --- /dev/null +++ b/src/interface/include/gpio.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GPIO_H__ +#define __GPIO_H__ + +#define SYSFS_GPIO_DIR "/sys/class/gpio" +#define GPIO_BUFFER_MAX 64 + +typedef enum { + GPIO_DIRECTION_IN = 0, + GPIO_DIRECTION_OUT = 1, + GPIO_DIRECTION_OUT_HIGH = 2, +} gpio_direction_e; + +typedef enum { + GPIO_EDGE_NONE = 0, + GPIO_EDGE_RISING = 1, + GPIO_EDGE_FALLING = 2, + GPIO_EDGE_BOTH = 3, +} gpio_edge_e; + +int gpio_get_edge_mode(int gpiopin, gpio_edge_e *edge); +int gpio_get_direction(int gpiopin, gpio_direction_e *dir); +int gpio_read(int gpiopin, int *value); +int gpio_open(int gpiopin); +int gpio_close(int gpiopin); +int gpio_set_edge_mode(int gpiopin, gpio_edge_e edge); +int gpio_set_direction(int gpiopin, gpio_direction_e dir); +int gpio_write(int gpiopin, int value); + +int gpio_open_isr(int gpiopin); +int gpio_close_isr(int file_hndl); +int gpio_read_isr(void *fdset, char *rev_buf, int length); +//int gpio_read_isr(void *fdset, char *rev_buf, int length); +#endif/*__GPIO_H__*/ diff --git a/src/interface/include/i2c.h b/src/interface/include/i2c.h new file mode 100644 index 0000000..78ff48e --- /dev/null +++ b/src/interface/include/i2c.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __I2C_H_ +#define __I2C_H__ + +/* Define *******************************************************************/ +#define SYSFS_I2C_DIR "/dev/i2c" +#define I2C_BUFFER_MAX 64 +#define I2C_FREQUENCY 0X801 +#define I2C_SLAVE 0x0703 + +typedef enum { + I2C_STD = 0, + I2C_FAST = 1, + I2C_HIGH = 2 +} i2c_mode_e; + +int i2c_open(int bus, int *file_hndl); +int i2c_close(int file_hndl); +int i2c_set_frequency(int file_hndl, i2c_mode_e speed); +int i2c_set_address(int file_hndl, int address); +int i2c_read(int file_hndl, unsigned char *data, int length, int addr); +int i2c_write(int file_hndl, const unsigned char *data, int length, int addr); + +#endif/*__I2C_H_*/ diff --git a/src/interface/include/pwm.h b/src/interface/include/pwm.h new file mode 100644 index 0000000..7591697 --- /dev/null +++ b/src/interface/include/pwm.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PWM_H__ +#define __PWM_H__ + +/** +* @brief pwm_open() init pwm channel. +* +* @param[in] device pwm chip number +* @param[in] channel pwm channel number +* @return On success, 0 is returned. On failure, a negative value is returned. +*/ +int pwm_open(int device, int channel); + +/** +* @brief pwm_close() deinit pwm channel. +* +* @param[in] device pwm chip number +* @param[in] channel pwm channel number +* @return On success, 0 is returned. On failure, a negative value is returned. +*/ +int pwm_close(int device, int channel); + +/** +* @brief pwm_set_period() sets the pwm period. +* +* @param[in] device pwm chip number +* @param[in] channel pwm channel number +* @param[in] period pwm period +* @return On success, 0 is returned. On failure, a negative value is returned. +*/ +int pwm_set_period(int device, int channel, int period); + +/** +* @brief pwm_set_duty_cycle() sets the pwm duty cycle. +* +* @param[in] device pwm chip number +* @param[in] channel pwm channel number +* @param[in] duty_cycle pwm duty cycle +* @return On success, 0 is returned. On failure, a negative value is returned. +*/ +int pwm_set_duty_cycle(int device, int channel, int duty_cycle); + +/** +* @brief pwm_set_enabled() sets the pwm state. +* +* @param[in] device pwm chip number +* @param[in] channel pwm channel number +* @param[in] enable pwm enable/disabled state value +* @return On success, 0 is returned. On failure, a negative value is returned. +*/ +int pwm_set_enabled(int device, int channel, int enable); + +/** +* @brief pwm_is_enabled() checks if pwm state is enabled. +* +* @param[in] device pwm chip number +* @param[in] channel pwm channel number +* @param[in] enable pwm enable/disabled state value +* @return On success, current pwm state value is returned. On failure, a negative value is returned. +*/ +int pwm_get_enabled(int device, int channel, int *enable); + +/** +* @brief pwm_get_period() gets the pwm period. +* +* @param[in] device pwm chip number +* @param[in] channel pwm channel number +* @param[in] period pwm period +* @return On success, current pwm period is returned. On failure, a negative value is returned. +*/ +int pwm_get_period(int device, int channel, int *period); + +/** +* @brief pwm_get_duty_cycle() gets the pwm duty cycle. +* +* @param[in] device pwm chip number +* @param[in] channel pwm channel number +* @param[in] duty_cycle pwm duty cycle +* @return On success, current pwm duty cycle is returned. On failure, a negative value is returned. +*/ +int pwm_get_duty_cycle(int device, int channel, int *duty_cycle); + +#endif /* __PWM_H__ */ diff --git a/src/interface/include/spi.h b/src/interface/include/spi.h new file mode 100644 index 0000000..0ff0c44 --- /dev/null +++ b/src/interface/include/spi.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SPI_H__ +#define __SPI_H__ + +#define SYSFS_SPI_DIR "/dev/spidev" +#define SPI_BUFFER_MAX 64 +#define SPI_CR1_LSBFIRST (1 << 7) /* Bit 7: Frame Format */ + +typedef enum { + SPI_MODE0 = 0, + SPI_MODE1, + SPI_MODE2, + SPI_MODE3 +} spi_mode_e; + +int spi_open(unsigned int bus, int *file_hndl); +int spi_close(int file_hndl); +int spi_set_mode(int file_hndl, spi_mode_e mode); +int spi_set_bits(int file_hndl, int bits); +int spi_set_frequency(int file_hndl, int freq); +int spi_set_chip_select(int file_hndl, int cs); +int spi_get_mode(int file_hndl, spi_mode_e *mode); +int spi_get_bits(int file_hndl, int *bits); +int spi_get_frequency(int file_hndl, int *freq); +int spi_get_lsb(int file_hndl, int *lsb); + +int spi_write_data(int file_hndl, char *txbuf, int length); +int spi_read_data(int file_hndl, char *rxbuf, int length); +int spi_exchange_data(int file_hndl, char *txbuf, char *rxbuf, int length); + +#endif /* __SPI_H__ */ diff --git a/src/interface/include/uart.h b/src/interface/include/uart.h new file mode 100644 index 0000000..a181708 --- /dev/null +++ b/src/interface/include/uart.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UART_H__ +#define __UART_H__ + +#include + +/** + * @brief Enumeration of UART parity type + */ +typedef enum { + PERIPHERAL_UART_PARITY_NONE = 0, + PERIPHERAL_UART_PARITY_EVEN = 1, + PERIPHERAL_UART_PARITY_ODD = 2, +} peripheral_uart_parity_e; + +/** +* @brief uart_valid_baudrate() validation check of input baudrate +* +* @param[in] baudrate baudrate for uart +* @return On success, valid input. On failure, NULL is returned. +*/ +int uart_valid_baudrate(unsigned int baudrate); + +/** +* @brief uart_open() initializes uart port. +* +* @param[in] port uart port +* @param[in] file_hndl handle of uart port +* @return On success, handle of uart_context is returned. On failure, NULL is returned. +*/ +int uart_open(int port, int *file_hndl); + +/** +* @brief uart_close() closes uart port. +* +* @param[in] file_hndl handle of uart_context +* @return On success, 0 is returned. On failure, a negative value is returned. +*/ +int uart_close(int file_hndl); + +/** +* @brief uart_flush() flushes uart buffer. +* +* @param[in] file_hndl handle of uart_context +* @return On success, 0 is returned. On failure, a negative value is returned. +*/ +int uart_flush(int file_hndl); + +/** +* @brief uart_set_baudrate() sets uart baud rate. +* +* @param[in] file_hndl handle of uart_context +* @param[in] baud uart baud rate +* @return On success, 0 is returned. On failure, a negative value is returned. +*/ +int uart_set_baudrate(int file_hndl, unsigned int baud); + +/** +* @brief uart_set_mode() sets byte size, parity bit and stop bits. +* +* @param[in] file_hndl handle of uart_context +* @param[in] bytesize uart byte size +* @param[in] parity uart parity type (even/odd/none) +* @param[in] stopbits uart stop bits +* @return On success, 0 is returned. On failure, a negative value is returned. +*/ +int uart_set_mode(int file_hndl, int bytesize, char *parity, int stopbits); + +/** +* @brief uart_set_flowcontrol() set flow control settings. +* +* @param[in] file_hndl handle of uart_context +* @param[in] xonxoff ixon/ixoff +* @param[in] rtscts rts/cts +* @return On success, 0 is returned. On failure, a negative value is returned. +*/ +int uart_set_flowcontrol(int file_hndl, int xonxoff, int rtscts); + +/** +* @brief uart_read() reads data over uart bus. +* +* @param[in] file_hndl handle of uart_context +* @param[in] buf the pointer of data buffer +* @param[in] length size to read +* @return On success, 0 is returned. On failure, a negative value is returned. +*/ +int uart_read(int file_hndl, char *buf, unsigned int length); + +/** +* @brief uart_write() writes data over uart bus. +* +* @param[in] file_hndl handle of uart_context +* @param[in] buf the pointer of data buffer +* @param[in] length size to write +* @return On success, 0 is returned. On failure, a negative value is returned. +*/ +int uart_write(int file_hndl, char *buf, unsigned int length); + +#endif /* __UART_H__ */ + diff --git a/src/interface/pwm.c b/src/interface/pwm.c new file mode 100644 index 0000000..32994eb --- /dev/null +++ b/src/interface/pwm.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +#include "pwm.h" +#include "peripheral_common.h" + +#define SYSFS_PWM_PATH "/sys/class/pwm" + +#define PATH_BUF_MAX 64 +#define PWM_BUF_MAX 16 + +int pwm_open(int device, int channel) +{ + int fd, len, ret; + char buff[PWM_BUF_MAX] = {0}; + char fName[PATH_BUF_MAX] = {0}; + + pwm_close(device, channel); + + snprintf(fName, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/export", device); + if ((fd = open(fName, O_WRONLY)) < 0) { + _E("Error[%d]: can't open %s, %s--[%d]\n", errno, fName, __FUNCTION__, __LINE__); + return -ENOENT; + } + + len = snprintf(buff, sizeof(buff), "%d", channel); + if ((ret = write(fd, buff, len)) < 0) { + _E("Error[%d]: can't write %s, %s--[%d]\n", errno, fName, __FUNCTION__, __LINE__); + close(fd); + return -EIO; + } + close(fd); + return 0; +} + +int pwm_close(int device, int channel) +{ + int fd, len, ret; + char buff[PWM_BUF_MAX] = {0}; + char fName[PATH_BUF_MAX] = {0}; + + pwm_set_enabled(device, channel, 0); // disable + + _D("[PWM] close!!\n"); + snprintf(fName, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/unexport", device); + if ((fd = open(fName, O_WRONLY)) < 0) { + _E("Error[%d]: can't open %s, %s--[%d]\n", errno, fName, __FUNCTION__, __LINE__); + return -ENOENT; + } + + len = snprintf(buff, sizeof(buff), "%d", channel); + + if ((ret = write(fd, buff, len)) < 0) { + _E("Error[%d]: can't write %s, %s--[%d]\n", errno, fName, __FUNCTION__, __LINE__); + close(fd); + return -EIO; + } + close(fd); + return 0; +} + +int pwm_set_period(int device, int channel, int period) +{ + int fd, len, ret; + char buff[PWM_BUF_MAX] = {0}; + char fName[PATH_BUF_MAX] = {0}; + + snprintf(fName, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/period", device, channel); + if ((fd = open(fName, O_WRONLY)) < 0) { + _E("Error[%d]: can't open %s, %s--[%d]\n", errno, fName, __FUNCTION__, __LINE__); + return -ENOENT; + } + _D("[PWM] period = %d\n", period); + len = snprintf(buff, sizeof(buff), "%d", period); + if ((ret = write(fd, buff, len)) < 0) { + _E("Error[%d]: can't write %s, %s--[%d]\n", errno, fName, __FUNCTION__, __LINE__); + close(fd); + return -EIO; + } + close(fd); + return 0; +} + +int pwm_set_duty_cycle(int device, int channel, int duty_cycle) +{ + int fd, len, ret; + char buff[PWM_BUF_MAX] = {0}; + char fName[PATH_BUF_MAX] = {0}; + + snprintf(fName, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/duty_cycle", device, channel); + if ((fd = open(fName, O_WRONLY)) < 0) { + _E("Error[%d]: can't open %s, %s--[%d]\n", errno, fName, __FUNCTION__, __LINE__); + return -ENOENT; + } + _D("[PWM] duty_cycle = %d\n", duty_cycle); + + len = snprintf(buff, sizeof(buff), "%d", duty_cycle); + if ((ret = write(fd, buff, len)) < 0) { + _E("Error[%d]: can't write %s, %s--[%d]\n", errno, fName, __FUNCTION__, __LINE__); + close(fd); + return -EIO; + } + close(fd); + + return 0; +} + +int pwm_set_enabled(int device, int channel, int enable) +{ + int fd, len, ret; + char buff[PWM_BUF_MAX] = {0}; + char fName[PATH_BUF_MAX] = {0}; + + _D("[PWM] set enable = %d!!\n", enable); + snprintf(fName, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/enable", device, channel); + if ((fd = open(fName, O_WRONLY)) < 0) { + _E("Error[%d]: can't open %s, %s--[%d]\n", errno, fName, __FUNCTION__, __LINE__); + return -ENOENT; + } + + len = snprintf(buff, sizeof(buff), "%d", enable); + if ((ret = write(fd, buff, len)) < 0) { + _E("Error[%d]: can't write %s, %s--[%d]\n", errno, fName, __FUNCTION__, __LINE__); + close(fd); + return -EIO; + } + close(fd); + return 0; +} + +int pwm_get_enabled(int device, int channel, int *enable) +{ + int fd, result, ret; + char buff[PWM_BUF_MAX] = {0}; + char fName[PATH_BUF_MAX] = {0}; + + snprintf(fName, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/enable", device, channel); + if ((fd = open(fName, O_RDONLY)) < 0) { + _E("Error[%d]: can't open %s, %s--[%d]\n", errno, fName, __FUNCTION__, __LINE__); + return -ENOENT; + } + + if ((ret = read(fd, buff, PWM_BUF_MAX)) < 0) { + _E("Error[%d]: can't read %s, %s--[%d]\n", errno, fName, __FUNCTION__, __LINE__); + close(fd); + return -EIO; + } + result = atoi(buff); + enable = &result; + close(fd); + + return 0; +} + +int pwm_get_period(int device, int channel, int *period) +{ + int fd, result, ret; + char buff[PWM_BUF_MAX] = {0}; + char fName[PATH_BUF_MAX] = {0}; + + snprintf(fName, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/period", device, channel); + if ((fd = open(fName, O_RDONLY)) < 0) { + _E("Error[%d]: can't open %s, %s--[%d]\n", errno, fName, __FUNCTION__, __LINE__); + return -ENOENT; + } + + if ((ret = read(fd, buff, PWM_BUF_MAX)) < 0) { + _E("Error[%d]: can't read %s, %s--[%d]\n", errno, fName, __FUNCTION__, __LINE__); + close(fd); + return -EIO; + } + result = atoi(buff); + *period = result; + close(fd); + + return 0; +} + +int pwm_get_duty_cycle(int device, int channel, int *duty_cycle) +{ + int fd, result, ret; + char buff[PWM_BUF_MAX] = {0}; + char fName[PATH_BUF_MAX] = {0}; + + snprintf(fName, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/duty_cycle", device, channel); + if ((fd = open(fName, O_RDONLY)) < 0) { + _E("Error[%d]: can't open %s, %s--[%d]\n", errno, fName, __FUNCTION__, __LINE__); + return -ENOENT; + } + + if ((ret = read(fd, buff, PWM_BUF_MAX)) < 0) { + _E("Error[%d]: can't open %s, %s--[%d]\n", errno, fName, __FUNCTION__, __LINE__); + close(fd); + return -EIO; + } + result = atoi(buff); + *duty_cycle = result; + close(fd); + + return 0; +} diff --git a/src/interface/spi.c b/src/interface/spi.c new file mode 100644 index 0000000..49da2e6 --- /dev/null +++ b/src/interface/spi.c @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "spi.h" +#include "peripheral_common.h" + +int spi_open(unsigned int bus, int *file_hndl) +{ + int fd = 0; + char spi_dev[SPI_BUFFER_MAX] = {0,}; + + snprintf(spi_dev, sizeof(spi_dev)-1, SYSFS_SPI_DIR"%d", bus); + + fd = open(spi_dev, O_RDWR); + if (file_hndl < 0) { + _E("Can't Open /dev/spidev%d.0 :%s\n", bus, strerror(errno)); + return -ENOENT; + } + + *file_hndl = fd; + + return 0; +} + +int spi_close(int file_hndl) +{ + if (file_hndl == (int)NULL) + return -EINVAL; + + close(file_hndl); + + return 0; +} + +int spi_set_mode(int file_hndl, spi_mode_e mode) +{ + int status; + + if (file_hndl == (int)NULL) + return -EINVAL; + + status = ioctl(file_hndl, SPI_IOC_WR_MODE, &mode); + if (status < 0) { + _E("Error: spi_set_mode %d fail\n", mode); + return -1; + } + + return 0; +} + +int spi_set_bits(int file_hndl, int bits) +{ + int status; + + if (file_hndl == (int)NULL) + return -EINVAL; + + status = ioctl(file_hndl, SPI_IOC_WR_BITS_PER_WORD, &bits); + + if (status < 0) { + _E("Error: spi_set_bits %d fail\n", bits); + return -1; + } + + return 0; +} + +int spi_set_frequency(int file_hndl, int freq) +{ + int status; + + if (file_hndl == (int)NULL) + return -EINVAL; + + status = ioctl(file_hndl, SPI_IOC_WR_MAX_SPEED_HZ, &freq); + + if (status < 0) { + _E("Error: spi_set_frequency %d fail\n", freq); + return -1; + } + + return 0; +} + +int spi_set_chip_select(int file_hndl, int cs) +{ + int mode = 0; + int status; + + if (file_hndl == (int)NULL) + return -EINVAL; + + status = ioctl(file_hndl, SPI_IOC_RD_MODE, &mode); + if (status < 0) { + _E("Error: Get: spi_set_chip_select fail\n"); + return -1; + } + + if (cs == 1) + mode |= SPI_CS_HIGH; + else + mode &= SPI_CS_HIGH; + + _D("mode[%x]\n", mode); + + status = ioctl(file_hndl, SPI_IOC_WR_MODE, &mode); + if (status < 0) { + _E("Error: Set : spi_set_chip_select %d fail\n", mode); + return -1; + } + + return 0; +} + +int spi_get_mode(int file_hndl, spi_mode_e *mode) +{ + int value = 0; + int status; + + if (file_hndl == (int)NULL) + return -EINVAL; + + status = ioctl(file_hndl, SPI_IOC_RD_MODE, &value); + if (status < 0) { + _E("Error: spi_get_mode fail\n"); + return -1; + } + + *mode = value; + + return 0; +} + +int spi_get_bits(int file_hndl, int *bits) +{ + int value = 0; + int status; + + if (file_hndl == (int)NULL) + return -EINVAL; + + status = ioctl(file_hndl, SPI_IOC_RD_BITS_PER_WORD, &value); + if (status < 0) { + _E("Error: spi_get_bits fail\n"); + return -1; + } + + *bits = value; + + return 0; +} + +int spi_get_frequency(int file_hndl, int *freq) +{ + int value = 0; + int status; + + if (file_hndl == (int)NULL) + return -EINVAL; + + status = ioctl(file_hndl, SPI_IOC_RD_MAX_SPEED_HZ, &value); + + if (status < 0) { + _E("Error: spi_get_frequency fail\n"); + return -1; + } + + *freq = value; + + return 0; +} + +int spi_get_lsb(int file_hndl, int *lsb) +{ + int value = 0; + int status; + + if (file_hndl == (int)NULL) + return -EINVAL; + + status = ioctl(file_hndl, SPI_IOC_RD_LSB_FIRST, &value); + + if (status < 0) { + _E("Error: spi_get_lsb fail\n"); + return -1; + } + + *lsb = value; + + return 0; +} + +int spi_write_data(int file_hndl, char *txbuf, int length) +{ + int status; + struct spi_ioc_transfer xfer; + + if (file_hndl == (int)NULL) + return -EINVAL; + + memset(&xfer, 0, sizeof(xfer)); + xfer.tx_buf = (unsigned long)txbuf; + xfer.len = length; + + status = ioctl(file_hndl, SPI_IOC_MESSAGE(1), xfer); + if (status < 0) { + _E("Error: spi_write_data fail\n"); + return -1; + } + + return 0; +} + +int spi_read_data(int file_hndl, char *rxbuf, int length) +{ + int status; + struct spi_ioc_transfer xfer; + + if (file_hndl == (int)NULL) + return -EINVAL; + + memset(&xfer, 0, sizeof(xfer)); + xfer.rx_buf = (unsigned long)rxbuf; + xfer.len = length; + + status = ioctl(file_hndl, SPI_IOC_MESSAGE(1), &xfer); + if (status < 0) { + _E("Error: spi_read_data fail\n"); + return -1; + } + return 0; +} + +int spi_exchange_data(int file_hndl, char *txbuf, char *rxbuf, int length) +{ + int status; + struct spi_ioc_transfer xfer[2]; + + if (file_hndl == (int)NULL) + return -EINVAL; + + if (!txbuf || length < 0) + return -EINVAL; + + memset(xfer, 0, sizeof(xfer)); + xfer[0].tx_buf = (unsigned long)txbuf; + xfer[0].len = length; + + xfer[1].rx_buf = (unsigned long)rxbuf; + xfer[1].len = length; + + status = ioctl(file_hndl, SPI_IOC_MESSAGE(2), xfer); + if (status < 0) { + _E("Error: spi_exchange_data fail\n"); + return -1; + } + + return 0; +} diff --git a/src/interface/uart.c b/src/interface/uart.c new file mode 100644 index 0000000..1828381 --- /dev/null +++ b/src/interface/uart.c @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "uart.h" +#include "peripheral_common.h" + +#define SYSFS_UART_PATH "/dev/ttySAC" + +#define PATH_BUF_MAX 64 +#define UART_BUF_MAX 16 + +#define UART_BAUDRATE_SIZE 19 + +int g_peripheral_uart_br_input[UART_BAUDRATE_SIZE] = { + 0, 50, 75, 110, 134, + 150, 200, 300, 600, 1200, + 1800, 2400, 4800, 9600, 19200, + 38400, 57600, 115200, 230400 +}; +int g_peripheral_uart_br[UART_BAUDRATE_SIZE] = { + B0, B50, B75, B110, B134, + B150, B200, B300, B600, B1200, + B1800, B2400, B4800, B9600, B19200, + B38400, B57600, B115200, B230400 +}; + +int uart_valid_baudrate(unsigned int baudrate) +{ + int i; + for (i = 0; i < UART_BAUDRATE_SIZE; i++) { + if (baudrate == g_peripheral_uart_br_input[i]) + return g_peripheral_uart_br[i]; + } + return -1; +} + +int uart_open(int port, int *file_hndl) +{ + int fd; + char fName[PATH_BUF_MAX] = {0}; + + snprintf(fName, PATH_BUF_MAX, SYSFS_UART_PATH "%d", port); + if ((fd = open(fName, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) { + _E("Error[%d]: can't open %s, %s--[%d]\n", errno, fName, __FUNCTION__, __LINE__); + return -ENOENT; + } + *file_hndl = fd; + return 0; +} + +int uart_close(int file_hndl) +{ + if (!file_hndl) { + _E("Error[%d]: Invalid parameter, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -EINVAL; + } + close(file_hndl); + return 0; +} + +int uart_flush(int file_hndl) +{ + int ret; + if (!file_hndl) { + _E("Error[%d]: Invalid parameter, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -EINVAL; + } + + ret = tcflush(file_hndl, TCIOFLUSH); + if (ret < 0) { + _E("FAILED[%d]: tcflush, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -1; + } + + return 0; +} + +int uart_set_baudrate(int file_hndl, unsigned int baud) +{ + int ret, baudrate; + struct termios tio; + + memset(&tio, 0, sizeof(tio)); + if (!file_hndl) { + _E("Error[%d]: Invalid parameter, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -EINVAL; + } + + if ((baudrate = uart_valid_baudrate(baud)) < 0) { + _E("Error[%d]: Invalid parameter, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -EINVAL; + } + + ret = tcgetattr(file_hndl, &tio); + if (ret) { + _E("Error[%d]: tcgetattr, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -1; + } + tio.c_cflag = baudrate; + tio.c_iflag = IGNPAR; + tio.c_oflag = 0; + tio.c_lflag = 0; + tio.c_cc[VMIN] = 1; + tio.c_cc[VTIME] = 0; + + uart_flush(file_hndl); + ret = tcsetattr(file_hndl, TCSANOW, &tio); + if (ret) { + _E("Error[%d]: tcsetattr, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -1; + } + + return 0; +} + +int uart_set_mode(int file_hndl, int bytesize, char *parity, int stopbits) +{ + int ret; + struct termios tio; + int byteinfo[4] = {CS5, CS6, CS7, CS8}; + peripheral_uart_parity_e parityinfo; + + if (!file_hndl) { + _E("Error[%d]: Invalid parameter, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -EINVAL; + } + + ret = tcgetattr(file_hndl, &tio); + if (ret) { + _E("Error[%d]: tcgetattr, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -1; + } + + /* set byte size */ + if (bytesize < 5 || bytesize > 8) { + _E("Error[%d]: Invalid parameter bytesize, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -EINVAL; + } + tio.c_cflag &= ~CSIZE; + tio.c_cflag |= byteinfo[bytesize - 5]; + tio.c_cflag |= (CLOCAL | CREAD); + + /* set parity info */ + if (strcmp(parity, "even") == 0) + parityinfo = PERIPHERAL_UART_PARITY_EVEN; + else if (strcmp(parity, "odd") == 0) + parityinfo = PERIPHERAL_UART_PARITY_ODD; + else + parityinfo = PERIPHERAL_UART_PARITY_NONE; + + switch (parityinfo) { + case PERIPHERAL_UART_PARITY_EVEN: + tio.c_cflag |= PARENB; + tio.c_cflag &= ~PARODD; + break; + case PERIPHERAL_UART_PARITY_ODD: + tio.c_cflag |= PARENB; + tio.c_cflag |= PARODD; + break; + case PERIPHERAL_UART_PARITY_NONE: + tio.c_cflag &= ~PARENB; + tio.c_cflag &= ~PARODD; + break; + } + + /* set stop bit */ + switch (stopbits) { + case 1: + tio.c_cflag &= ~CSTOPB; + break; + case 2: + tio.c_cflag |= CSTOPB; + break; + default: + _E("Error[%d]: Invalid parameter stopbits, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -EINVAL; + } + + uart_flush(file_hndl); + ret = tcsetattr(file_hndl, TCSANOW, &tio); + if (ret) { + _E("Error[%d]: tcsetattr, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -1; + } + + return 0; +} + +int uart_set_flowcontrol(int file_hndl, int xonxoff, int rtscts) +{ + int ret; + struct termios tio; + + if (!file_hndl) { + _E("Error[%d]: Invalid parameter, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -EINVAL; + } + + ret = tcgetattr(file_hndl, &tio); + if (ret) { + _E("Error[%d]: tcgetattr, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -1; + } + + /* rtscts => 1: rts/cts on, 0: off */ + if (rtscts == 1) { + tio.c_cflag |= CRTSCTS; + } else if (rtscts == 0) { + tio.c_cflag &= ~CRTSCTS; + } else { + _E("Error[%d]: Invalid parameter rtscts, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -1; + } + + /* xonxoff => 1: xon/xoff on, 0: off */ + if (xonxoff == 1) { + tio.c_iflag |= (IXON | IXOFF | IXANY); + } else if (xonxoff == 0) { + tio.c_iflag &= ~(IXON | IXOFF | IXANY); + } else { + _E("Error[%d]: Invalid parameter xonxoff, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -1; + } + + ret = tcsetattr(file_hndl, TCSANOW, &tio); + if (ret) { + _E("Error[%d]: tcsetattr, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -1; + } + + return 0; +} + +int uart_read(int file_hndl, char *buf, unsigned int length) +{ + int ret; + if (!file_hndl) { + _E("Error[%d]: Invalid parameter, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -EINVAL; + } + + ret = read(file_hndl, (void *)buf, length); + if ((errno != EAGAIN && errno != EINTR) && ret < 0) { + _E("Error[%d]: read, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -EIO; + } + + return ret; +} + +int uart_write(int file_hndl, char *buf, unsigned int length) +{ + int ret; + if (!file_hndl) { + _E("Error[%d]: Invalid parameter, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -EINVAL; + } + + ret = write(file_hndl, buf, length); + if (ret < 0) { + _E("Error[%d]: write, %s--[%d]\n", errno, __FUNCTION__, __LINE__); + return -EIO; + } + + return ret; +}