Add APIs and functions for the spi device 06/131106/10
authorjino.cho <jino.cho@samsung.com>
Thu, 25 May 2017 10:50:58 +0000 (19:50 +0900)
committerjino.cho <jino.cho@samsung.com>
Wed, 31 May 2017 07:21:47 +0000 (16:21 +0900)
This patch support the spi device. And, it should work properly
if the patch for peripheral-bus is applied together.

Change-Id: Ia0094e516d5dff9fba1e2d40170dc7cce844d347
Signed-off-by: jino.cho <jino.cho@samsung.com>
CMakeLists.txt
include/peripheral_gdbus.h
include/peripheral_gdbus_spi.h [new file with mode: 0644]
include/peripheral_internal.h
include/peripheral_io.h
src/peripheral_gdbus_spi.c [new file with mode: 0644]
src/peripheral_io.xml
src/peripheral_spi.c
test/peripheral-io-test.c

index d051617..ebacf9e 100644 (file)
@@ -47,10 +47,12 @@ SET(SOURCES src/peripheral_gpio.c
                        src/peripheral_pwm.c
                        src/peripheral_adc.c
                        src/peripheral_uart.c
+                       src/peripheral_spi.c
                        src/peripheral_gdbus_gpio.c
                        src/peripheral_gdbus_i2c.c
                        src/peripheral_gdbus_pwm.c
                        src/peripheral_gdbus_uart.c
+                       src/peripheral_gdbus_spi.c
                        src/peripheral_io_gdbus.c
                        src/peripheral_spi.c)
 
index aefe770..ff726de 100644 (file)
@@ -23,6 +23,7 @@
 #define PERIPHERAL_GDBUS_I2C_PATH      "/Org/Tizen/Peripheral_io/I2c"
 #define PERIPHERAL_GDBUS_PWM_PATH      "/Org/Tizen/Peripheral_io/Pwm"
 #define PERIPHERAL_GDBUS_UART_PATH     "/Org/Tizen/Peripheral_io/Uart"
+#define PERIPHERAL_GDBUS_SPI_PATH      "/Org/Tizen/Peripheral_io/Spi"
 #define PERIPHERAL_GDBUS_NAME          "org.tizen.peripheral_io"
 
 #endif /* __PERIPHERAL_GDBUS_H__ */
diff --git a/include/peripheral_gdbus_spi.h b/include/peripheral_gdbus_spi.h
new file mode 100644 (file)
index 0000000..78e7e97
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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_GDBUS_SPI_H_
+#define __PERIPHERAL_GDBUS_SPI_H_
+
+void spi_proxy_init(void);
+void spi_proxy_deinit();
+
+int peripheral_gdbus_spi_open(peripheral_spi_h spi, int bus, int cs);
+int peripheral_gdbus_spi_close(peripheral_spi_h spi);
+int peripheral_gdbus_spi_set_mode(peripheral_spi_h spi, peripheral_spi_mode_e mode);
+int peripheral_gdbus_spi_get_mode(peripheral_spi_h spi, peripheral_spi_mode_e *mode);
+int peripheral_gdbus_spi_set_lsb_first(peripheral_spi_h spi, bool lsb);
+int peripheral_gdbus_spi_get_lsb_first(peripheral_spi_h spi, bool *lsb);
+int peripheral_gdbus_spi_set_bits(peripheral_spi_h spi, unsigned char bits);
+int peripheral_gdbus_spi_get_bits(peripheral_spi_h spi, unsigned char *bits);
+int peripheral_gdbus_spi_set_frequency(peripheral_spi_h spi, unsigned int freq);
+int peripheral_gdbus_spi_get_frequency(peripheral_spi_h spi, unsigned int *freq);
+int peripheral_gdbus_spi_read(peripheral_spi_h spi, unsigned char *data, int length);
+int peripheral_gdbus_spi_write(peripheral_spi_h spi, unsigned char *data, int length);
+int peripheral_gdbus_spi_read_write(peripheral_spi_h spi, unsigned char *tx_data, unsigned char *rx_data, int length);
+
+#endif /* __PERIPHERAL_GDBUS_SPI_H_ */
index 34f09b0..ae4f47e 100644 (file)
@@ -46,4 +46,11 @@ struct _peripheral_uart_s {
        uint handle;
 };
 
+/**
+ * @brief Internal struct for spi context
+ */
+struct _peripheral_spi_s {
+       uint handle;
+};
+
 #endif /* __PERIPHERAL_INTERNAL_H__ */
index 7517d2a..8e126c8 100644 (file)
@@ -825,33 +825,231 @@ int peripheral_uart_write(peripheral_uart_h uart, uint8_t *data, int length);
  * @{
  */
 
+/**
+ * @brief The handle to the spi device
+ * @since_tizen 4.0
+ */
+typedef struct _peripheral_spi_s* peripheral_spi_h;
+
+/**
+ * @brief Enumeration for SPI mode.
+ */
 typedef enum {
-       PERIPHERAL_SPI_MODE0 = 0,
-       PERIPHERAL_SPI_MODE1,
-       PERIPHERAL_SPI_MODE2,
-       PERIPHERAL_SPI_MODE3
+       PERIPHERAL_SPI_MODE_0 = 0,
+       PERIPHERAL_SPI_MODE_1,
+       PERIPHERAL_SPI_MODE_2,
+       PERIPHERAL_SPI_MODE_3
 } peripheral_spi_mode_e;
 
-struct peripheral_spi_config_s {
-       int fd;
-       char bits_per_word;
-       int lsb;
-       unsigned int chip_select;
-       unsigned int frequency;
-       peripheral_spi_mode_e mode;
-};
+/**
+ * @brief Initializes spi communication and creates spi handle.
+ * @since_tizen 4.0
+ *
+ * @param[in] bus The spi bus number that the slave device is connected
+ * @param[in] cs The spi chip select number that the slave device is connected
+ * @param[out] spi The spi handle is created on success
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #PERIPHERAL_ERROR_NONE Successful
+ *
+ * @see peripheral_spi_close()
+ */
+int peripheral_spi_open(int bus, int cs, peripheral_spi_h *spi);
+
+/**
+ * @brief Destory the spi handle and release the communication.
+ * @since_tizen 4.0
+ *
+ * @param[in] spi The handle to the spi device
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #PERIPHERAL_ERROR_NONE Successful
+ * @retval #PERIPHERAL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error
+ *
+ * @see peripheral_spi_open()
+ */
+int peripheral_spi_close(peripheral_spi_h spi);
+
+/**
+ * @brief Sets mode of the spi device.
+ * @since_tizen 4.0
+ *
+ * @param[in] spi The handle to the spi device
+ * @param[in] mode The mode of the spi device
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #PERIPHERAL_ERROR_NONE Successful
+ * @retval #PERIPHERAL_ERROR_IO_ERROR I/O operation failed
+ * @retval #PERIPHERAL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error
+ * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed
+ */
+int peripheral_spi_set_mode(peripheral_spi_h spi, peripheral_spi_mode_e mode);
+
+/**
+ * @brief Gets mode of the spi device.
+ * @since_tizen 4.0
+ *
+ * @param[in] spi The handle to the spi device
+ * @param[out] mode The mode of the spi device
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #PERIPHERAL_ERROR_NONE Successful
+ * @retval #PERIPHERAL_ERROR_IO_ERROR I/O operation failed
+ * @retval #PERIPHERAL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error
+ * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed
+ */
+int peripheral_spi_get_mode(peripheral_spi_h spi, peripheral_spi_mode_e *mode);
+
+/**
+ * @brief Sets bits justification of the spi device.
+ * @since_tizen 4.0
+ *
+ * @param[in] spi The handle to the spi device
+ * @param[in] lsb The bit position to be transmitted first
+ *            true - LSB first
+ *            false - MSB first
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #PERIPHERAL_ERROR_NONE Successful
+ * @retval #PERIPHERAL_ERROR_IO_ERROR I/O operation failed
+ * @retval #PERIPHERAL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error
+ * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed
+ */
+int peripheral_spi_set_lsb_first(peripheral_spi_h spi, bool lsb);
+
+/**
+ * @brief Gets bits justification of the spi device.
+ * @since_tizen 4.0
+ *
+ * @param[in] spi The handle to the spi device
+ * @param[out] lsb The bit position to be transmitted first
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #PERIPHERAL_ERROR_NONE Successful
+ * @retval #PERIPHERAL_ERROR_IO_ERROR I/O operation failed
+ * @retval #PERIPHERAL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error
+ * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed
+ */
+int peripheral_spi_get_lsb_first(peripheral_spi_h spi, bool *lsb);
+
+/**
+ * @brief Sets the number of bits per word of the spi device
+ * @since_tizen 4.0
+ *
+ * @param[in] spi The handle to the spi device
+ * @param[in] bits The number of bits per word (in bits)
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #PERIPHERAL_ERROR_NONE Successful
+ * @retval #PERIPHERAL_ERROR_IO_ERROR I/O operation failed
+ * @retval #PERIPHERAL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error
+ * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed
+ */
+int peripheral_spi_set_bits_per_word(peripheral_spi_h spi, unsigned char bits);
 
-typedef struct peripheral_spi_config_s * peripheral_spi_context_h;
+/**
+ * @brief Gets the number of bits per word of the spi device
+ * @since_tizen 4.0
+ *
+ * @param[in] spi The handle to the spi device
+ * @param[out] bits The number of bits per word (in bits)
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #PERIPHERAL_ERROR_NONE Successful
+ * @retval #PERIPHERAL_ERROR_IO_ERROR I/O operation failed
+ * @retval #PERIPHERAL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error
+ * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed
+ */
+int peripheral_spi_get_bits_per_word(peripheral_spi_h spi, unsigned char *bits);
 
-peripheral_spi_context_h peripheral_spi_open(unsigned int bus, peripheral_spi_context_h config);
+/**
+ * @brief Sets default max speed of the spi device.
+ * @since_tizen 4.0
+ *
+ * @param[in] spi The handle to the spi device
+ * @param[in] freq Max speed (in hz)
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #PERIPHERAL_ERROR_NONE Successful
+ * @retval #PERIPHERAL_ERROR_IO_ERROR I/O operation failed
+ * @retval #PERIPHERAL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error
+ * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed
+ */
+int peripheral_spi_set_frequency(peripheral_spi_h spi, unsigned int freq);
 
-int    peripheral_spi_write(peripheral_spi_context_h hnd, char *txbuf, int length);
+/**
+ * @brief Gets default max speed of the spi device.
+ * @since_tizen 4.0
+ *
+ * @param[in] spi The handle to the spi device
+ * @param[out] freq Max speed (in hz)
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #PERIPHERAL_ERROR_NONE Successful
+ * @retval #PERIPHERAL_ERROR_IO_ERROR I/O operation failed
+ * @retval #PERIPHERAL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error
+ * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed
+ */
 
-int    peripheral_spi_recv(peripheral_spi_context_h hnd, char *rxbuf, int length);
+int peripheral_spi_get_frequency(peripheral_spi_h spi, unsigned int *freq);
 
-int peripheral_spi_transfer_buf(peripheral_spi_context_h hnd, char *txbuf, char *rxbuf, int length);
+/**
+ * @brief Reads data from the slave device.
+ * @since_tizen 4.0
+ *
+ * @param[in] spi The handle to the spi device
+ * @param[out] data The address of buffer to read
+ * @param[in] length The size of data buffer (in bytes)
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #PERIPHERAL_ERROR_NONE Successful
+ * @retval #PERIPHERAL_ERROR_IO_ERROR I/O operation failed
+ * @retval #PERIPHERAL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error
+ */
+int peripheral_spi_read(peripheral_spi_h spi, unsigned char *data, int length);
+
+/**
+ * @brief Write data to the slave device.
+ * @since_tizen 4.0
+ *
+ * @param[in] spi The handle to the spi device
+ * @param[in] data The address of buffer to write
+ * @param[in] length The size of data (in bytes)
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #PERIPHERAL_ERROR_NONE Successful
+ * @retval #PERIPHERAL_ERROR_IO_ERROR I/O operation failed
+ * @retval #PERIPHERAL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error
+ */
+int peripheral_spi_write(peripheral_spi_h spi, unsigned char *data, int length);
 
-int    peripheral_spi_close(peripheral_spi_context_h hnd);
+/**
+ * @brief Exchange data with the slave device.
+ * @since_tizen 4.0
+ *
+ * @param[in] spi The handle to the spi device
+ * @param[in] txdata The address of buffer to write
+ * @param[out] rxdata The address of buffer to read
+ * @param[in] length The size of data (in bytes)
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #PERIPHERAL_ERROR_NONE Successful
+ * @retval #PERIPHERAL_ERROR_IO_ERROR I/O operation failed
+ * @retval #PERIPHERAL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error
+ */
+int peripheral_spi_read_write(peripheral_spi_h spi, unsigned char *txdata, unsigned char *rxdata, int length);
 
 /**
 * @}
diff --git a/src/peripheral_gdbus_spi.c b/src/peripheral_gdbus_spi.c
new file mode 100644 (file)
index 0000000..b42e926
--- /dev/null
@@ -0,0 +1,406 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+
+#include "peripheral_io.h"
+#include "peripheral_gdbus.h"
+#include "peripheral_common.h"
+#include "peripheral_internal.h"
+#include "peripheral_io_gdbus.h"
+
+PeripheralIoGdbusSpi *spi_proxy = NULL;
+
+void spi_proxy_init(void)
+{
+       GError *error = NULL;
+
+       if (spi_proxy != NULL) {
+               g_object_ref(spi_proxy);
+               return;
+       }
+
+       spi_proxy = peripheral_io_gdbus_spi_proxy_new_for_bus_sync(
+               G_BUS_TYPE_SYSTEM,
+               G_DBUS_PROXY_FLAGS_NONE,
+               PERIPHERAL_GDBUS_NAME,
+               PERIPHERAL_GDBUS_SPI_PATH,
+               NULL,
+               &error);
+}
+
+void spi_proxy_deinit()
+{
+       if (spi_proxy) {
+               g_object_unref(spi_proxy);
+               if (!G_IS_OBJECT(spi_proxy))
+                       spi_proxy = NULL;
+       }
+}
+
+int peripheral_gdbus_spi_open(peripheral_spi_h spi, int bus, int cs)
+{
+       GError *error = NULL;
+       peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+
+       if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
+
+       if (peripheral_io_gdbus_spi_call_open_sync(
+                       spi_proxy,
+                       bus,
+                       cs,
+                       &spi->handle,
+                       &ret,
+                       NULL,
+                       &error) == FALSE) {
+               _E("%s", error->message);
+               g_error_free(error);
+               return PERIPHERAL_ERROR_UNKNOWN;
+       }
+
+       return ret;
+}
+
+int peripheral_gdbus_spi_close(peripheral_spi_h spi)
+{
+       GError *error = NULL;
+       peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+
+       if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
+
+       if (peripheral_io_gdbus_spi_call_close_sync(
+                       spi_proxy,
+                       spi->handle,
+                       &ret,
+                       NULL,
+                       &error) == FALSE) {
+               _E("%s", error->message);
+               g_error_free(error);
+               return PERIPHERAL_ERROR_UNKNOWN;
+       }
+
+       return ret;
+}
+
+int peripheral_gdbus_spi_set_mode(peripheral_spi_h spi, peripheral_spi_mode_e mode)
+{
+       GError *error = NULL;
+       peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+
+       if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
+
+       if (peripheral_io_gdbus_spi_call_set_mode_sync(
+                       spi_proxy,
+                       spi->handle,
+                       (guchar)mode,
+                       &ret,
+                       NULL,
+                       &error) == FALSE) {
+               _E("%s", error->message);
+               g_error_free(error);
+               return PERIPHERAL_ERROR_UNKNOWN;
+       }
+
+       return ret;
+}
+
+int peripheral_gdbus_spi_get_mode(peripheral_spi_h spi, peripheral_spi_mode_e *mode)
+{
+       GError *error = NULL;
+       peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+       guchar value;
+
+       if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
+
+       if (peripheral_io_gdbus_spi_call_get_mode_sync(
+                       spi_proxy,
+                       spi->handle,
+                       &value,
+                       &ret,
+                       NULL,
+                       &error) == FALSE) {
+               _E("%s", error->message);
+               g_error_free(error);
+               return PERIPHERAL_ERROR_UNKNOWN;
+       }
+
+       if (value <= PERIPHERAL_SPI_MODE_3)
+               *mode = value;
+       else
+               _E("Invalid mode : %d", value);
+
+       return ret;
+}
+
+int peripheral_gdbus_spi_set_lsb_first(peripheral_spi_h spi, bool lsb)
+{
+       GError *error = NULL;
+       peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+
+       if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
+
+       if (peripheral_io_gdbus_spi_call_set_lsb_first_sync(
+                       spi_proxy,
+                       spi->handle,
+                       lsb,
+                       &ret,
+                       NULL,
+                       &error) == FALSE) {
+               _E("%s", error->message);
+               g_error_free(error);
+               return PERIPHERAL_ERROR_UNKNOWN;
+       }
+
+       return ret;
+}
+
+int peripheral_gdbus_spi_get_lsb_first(peripheral_spi_h spi, bool *lsb)
+{
+       GError *error = NULL;
+       peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+       gboolean value;
+
+       if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
+
+       if (peripheral_io_gdbus_spi_call_get_lsb_first_sync(
+                       spi_proxy,
+                       spi->handle,
+                       &value,
+                       &ret,
+                       NULL,
+                       &error) == FALSE) {
+               _E("%s", error->message);
+               g_error_free(error);
+               return PERIPHERAL_ERROR_UNKNOWN;
+       }
+
+       *lsb = value ? true : false;
+
+       return ret;
+}
+
+int peripheral_gdbus_spi_set_bits(peripheral_spi_h spi, unsigned char bits)
+{
+       GError *error = NULL;
+       peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+
+       if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
+
+       if (peripheral_io_gdbus_spi_call_set_bits_sync(
+                       spi_proxy,
+                       spi->handle,
+                       bits,
+                       &ret,
+                       NULL,
+                       &error) == FALSE) {
+               _E("%s", error->message);
+               g_error_free(error);
+               return PERIPHERAL_ERROR_UNKNOWN;
+       }
+
+       return ret;
+}
+
+int peripheral_gdbus_spi_get_bits(peripheral_spi_h spi, unsigned char *bits)
+{
+       GError *error = NULL;
+       peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+       guchar value;
+
+       if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
+
+       if (peripheral_io_gdbus_spi_call_get_bits_sync(
+                       spi_proxy,
+                       spi->handle,
+                       &value,
+                       &ret,
+                       NULL,
+                       &error) == FALSE) {
+               _E("%s", error->message);
+               g_error_free(error);
+               return PERIPHERAL_ERROR_UNKNOWN;
+       }
+
+       *bits = (unsigned char)value;
+
+       return ret;
+}
+
+int peripheral_gdbus_spi_set_frequency(peripheral_spi_h spi, unsigned int freq)
+{
+       GError *error = NULL;
+       peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+
+       if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
+
+       if (peripheral_io_gdbus_spi_call_set_frequency_sync(
+                       spi_proxy,
+                       spi->handle,
+                       freq,
+                       &ret,
+                       NULL,
+                       &error) == FALSE) {
+               _E("%s", error->message);
+               g_error_free(error);
+               return PERIPHERAL_ERROR_UNKNOWN;
+       }
+
+       return ret;
+}
+
+int peripheral_gdbus_spi_get_frequency(peripheral_spi_h spi, unsigned int *freq)
+{
+       GError *error = NULL;
+       peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+       guint value;
+
+       if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
+
+       if (peripheral_io_gdbus_spi_call_get_frequency_sync(
+                       spi_proxy,
+                       spi->handle,
+                       &value,
+                       &ret,
+                       NULL,
+                       &error) == FALSE) {
+               _E("%s", error->message);
+               g_error_free(error);
+               return PERIPHERAL_ERROR_UNKNOWN;
+       }
+
+       *freq = (unsigned int)value;
+
+       return ret;
+}
+
+int peripheral_gdbus_spi_read(peripheral_spi_h spi, unsigned char *data, int length)
+{
+       GError *error = NULL;
+       peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+       GVariant *data_array;
+       GVariantIter *iter;
+       guint8 str;
+       int i = 0;
+
+       if (spi_proxy == NULL || data == NULL) return PERIPHERAL_ERROR_UNKNOWN;
+
+       if (peripheral_io_gdbus_spi_call_read_sync(
+                       spi_proxy,
+                       spi->handle,
+                       length,
+                       &data_array,
+                       &ret,
+                       NULL,
+                       &error) == FALSE) {
+               _E("%s", error->message);
+               g_error_free(error);
+               return PERIPHERAL_ERROR_UNKNOWN;
+       }
+
+       g_variant_get(data_array, "a(y)", &iter);
+       while (g_variant_iter_loop(iter, "(y)", &str)) {
+               data[i] = str;
+               if (i++ == length) break;
+       }
+       g_variant_iter_free(iter);
+       g_variant_unref(data_array);
+
+       return ret;
+}
+
+int peripheral_gdbus_spi_write(peripheral_spi_h spi, unsigned char *data, int length)
+{
+       GError *error = NULL;
+       peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+       GVariantBuilder *builder;
+       GVariant *data_array;
+       int i = 0;
+
+       if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
+
+       for (i = 0; i < length; i++)
+               g_variant_builder_add(builder, "(y)", data[i]);
+       g_variant_builder_add(builder, "(y)", 0x00);
+
+       data_array = g_variant_new("a(y)", builder);
+       g_variant_builder_unref(builder);
+
+       if (peripheral_io_gdbus_spi_call_write_sync(
+                       spi_proxy,
+                       spi->handle,
+                       length,
+                       data_array,
+                       &ret,
+                       NULL,
+                       &error) == FALSE) {
+               _E("%s", error->message);
+               g_error_free(error);
+               return PERIPHERAL_ERROR_UNKNOWN;
+       }
+
+       return ret;
+}
+
+int peripheral_gdbus_spi_read_write(peripheral_spi_h spi, unsigned char *tx_data, unsigned char *rx_data, int length)
+{
+       GError *error = NULL;
+       peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+       GVariantBuilder *builder;
+       GVariant *rx_data_array;
+       GVariant *tx_data_array;
+       GVariantIter *iter;
+       guint8 str;
+       int i = 0;
+
+       if (spi_proxy == NULL || !rx_data || !tx_data) return PERIPHERAL_ERROR_UNKNOWN;
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
+
+       for (i = 0; i < length; i++)
+               g_variant_builder_add(builder, "(y)", tx_data[i]);
+       g_variant_builder_add(builder, "(y)", 0x00);
+
+       tx_data_array = g_variant_new("a(y)", builder);
+       g_variant_builder_unref(builder);
+
+       if (peripheral_io_gdbus_spi_call_read_write_sync(
+                       spi_proxy,
+                       spi->handle,
+                       length,
+                       tx_data_array,
+                       &rx_data_array,
+                       &ret,
+                       NULL,
+                       &error) == FALSE) {
+               _E("%s", error->message);
+               g_error_free(error);
+               return PERIPHERAL_ERROR_UNKNOWN;
+       }
+
+       i = 0;
+       g_variant_get(rx_data_array, "a(y)", &iter);
+       while (g_variant_iter_loop(iter, "(y)", &str)) {
+               rx_data[i] = str;
+               if (i++ == length) break;
+       }
+       g_variant_iter_free(iter);
+       g_variant_unref(rx_data_array);
+
+       return ret;
+}
index 2480f92..c6fff55 100644 (file)
                        <arg type="i" name="result" direction="out"/>
                </method>
        </interface>
+       <interface name="org.tizen.peripheral_io.spi">
+               <method name="Open">
+                       <arg type="i" name="bus" direction="in"/>
+                       <arg type="i" name="cs" direction="in"/>
+                       <arg type="u" name="handle" direction="out"/>
+                       <arg type="i" name="result" direction="out"/>
+               </method>
+               <method name="Close">
+                       <arg type="u" name="handle" direction="in"/>
+                       <arg type="i" name="result" direction="out"/>
+               </method>
+               <method name="SetMode">
+                       <arg type="u" name="handle" direction="in"/>
+                       <arg type="y" name="mode" direction="in"/>
+                       <arg type="i" name="result" direction="out"/>
+               </method>
+               <method name="GetMode">
+                       <arg type="u" name="handle" direction="in"/>
+                       <arg type="y" name="mode" direction="out"/>
+                       <arg type="i" name="result" direction="out"/>
+               </method>
+               <method name="SetLsbFirst">
+                       <arg type="u" name="handle" direction="in"/>
+                       <arg type="b" name="lsb" direction="in"/>
+                       <arg type="i" name="result" direction="out"/>
+               </method>
+               <method name="GetLsbFirst">
+                       <arg type="u" name="handle" direction="in"/>
+                       <arg type="b" name="lsb" direction="out"/>
+                       <arg type="i" name="result" direction="out"/>
+               </method>
+               <method name="SetBits">
+                       <arg type="u" name="handle" direction="in"/>
+                       <arg type="y" name="bits" direction="in"/>
+                       <arg type="i" name="result" direction="out"/>
+               </method>
+               <method name="GetBits">
+                       <arg type="u" name="handle" direction="in"/>
+                       <arg type="y" name="bits" direction="out"/>
+                       <arg type="i" name="result" direction="out"/>
+               </method>
+               <method name="SetFrequency">
+                       <arg type="u" name="handle" direction="in"/>
+                       <arg type="u" name="freq" direction="in"/>
+                       <arg type="i" name="result" direction="out"/>
+               </method>
+               <method name="GetFrequency">
+                       <arg type="u" name="handle" direction="in"/>
+                       <arg type="u" name="freq" direction="out"/>
+                       <arg type="i" name="result" direction="out"/>
+               </method>
+               <method name="Read">
+                       <arg type="u" name="handle" direction="in"/>
+                       <arg type="i" name="length" direction="in"/>
+                       <arg type="a(y)" name="data" direction="out">
+                               <annotation name="org.gtk.GDBus.C.ForceGVariant" value="true"/>
+                       </arg>
+                       <arg type="i" name="result" direction="out"/>
+               </method>
+               <method name="Write">
+                       <arg type="u" name="handle" direction="in"/>
+                       <arg type="i" name="length" direction="in"/>
+                       <arg type="a(y)" name="data" direction="in">
+                               <annotation name="org.gtk.GDBus.C.ForceGVariant" value="true"/>
+                       </arg>
+                       <arg type="i" name="result" direction="out"/>
+               </method>
+               <method name="ReadWrite">
+                       <arg type="u" name="handle" direction="in"/>
+                       <arg type="i" name="length" direction="in"/>
+                       <arg type="a(y)" name="tx_data" direction="in">
+                               <annotation name="org.gtk.GDBus.C.ForceGVariant" value="true"/>
+                       </arg>
+                       <arg type="a(y)" name="rx_data" direction="out">
+                               <annotation name="org.gtk.GDBus.C.ForceGVariant" value="true"/>
+                       </arg>
+                       <arg type="i" name="result" direction="out"/>
+               </method>
+       </interface>
 </node>
index e2f8465..661b68a 100644 (file)
 #include <stdlib.h>
 #include <unistd.h>
 
-peripheral_spi_context_h peripheral_spi_open(unsigned int bus, peripheral_spi_context_h config)
+#include "peripheral_io.h"
+#include "peripheral_gdbus_spi.h"
+#include "peripheral_common.h"
+#include "peripheral_internal.h"
+
+int peripheral_spi_open(int bus, int cs, peripheral_spi_h *spi)
+{
+       peripheral_spi_h handle;
+       int ret = PERIPHERAL_ERROR_NONE;
+
+       if (bus < 0 || cs < 0) return PERIPHERAL_ERROR_INVALID_PARAMETER;
+
+       /* Initialize */
+       handle = (peripheral_spi_h)calloc(1, sizeof(struct _peripheral_spi_s));
+
+       if (handle == NULL) {
+               _E("Failed to allocate peripheral_spi_h");
+               return PERIPHERAL_ERROR_OUT_OF_MEMORY;
+       }
+
+       spi_proxy_init();
+
+       ret = peripheral_gdbus_spi_open(handle, bus, cs);
+
+       if (ret != PERIPHERAL_ERROR_NONE) {
+               _E("SPI open error (%d, %d)", bus, cs);
+               free(handle);
+               handle = NULL;
+       }
+       *spi = handle;
+
+       return ret;
+}
+
+int peripheral_spi_close(peripheral_spi_h spi)
+{
+       int ret = PERIPHERAL_ERROR_NONE;
+
+       if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER;
+
+       if ((ret = peripheral_gdbus_spi_close(spi)) < 0)
+               _E("Failed to close SPI device, continuing anyway");
+
+       spi_proxy_deinit();
+       free(spi);
+
+       return ret;
+}
+
+int peripheral_spi_set_mode(peripheral_spi_h spi, peripheral_spi_mode_e mode)
+{
+       if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER;
+
+       return peripheral_gdbus_spi_set_mode(spi, mode);
+}
+
+int peripheral_spi_get_mode(peripheral_spi_h spi, peripheral_spi_mode_e *mode)
+{
+       if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER;
+
+       return peripheral_gdbus_spi_get_mode(spi, mode);
+}
+
+int peripheral_spi_set_lsb_first(peripheral_spi_h spi, bool lsb)
+{
+       if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER;
+
+       return peripheral_gdbus_spi_set_lsb_first(spi, lsb);
+}
+
+int peripheral_spi_get_lsb_first(peripheral_spi_h spi, bool *lsb)
+{
+       if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER;
+
+       return peripheral_gdbus_spi_get_lsb_first(spi, lsb);
+}
+
+int peripheral_spi_set_bits_per_word(peripheral_spi_h spi, unsigned char bits)
+{
+       if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER;
+
+       return peripheral_gdbus_spi_set_bits(spi, bits);
+}
+
+int peripheral_spi_get_bits_per_word(peripheral_spi_h spi, unsigned char *bits)
+{
+       if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER;
+
+       return peripheral_gdbus_spi_get_bits(spi, bits);
+}
+
+int peripheral_spi_set_frequency(peripheral_spi_h spi, unsigned int freq)
 {
-       return NULL;
+       if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER;
+
+       return peripheral_gdbus_spi_set_frequency(spi, freq);
 }
 
-int    peripheral_spi_write(peripheral_spi_context_h hnd, char *txbuf, int length)
+int peripheral_spi_get_frequency(peripheral_spi_h spi, unsigned int *freq)
 {
-       return PERIPHERAL_ERROR_INVALID_OPERATION;
+       if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER;
+
+       return peripheral_gdbus_spi_get_frequency(spi, freq);
 }
 
-int    peripheral_spi_recv(peripheral_spi_context_h hnd, char *rxbuf, int length)
+int peripheral_spi_read(peripheral_spi_h spi, unsigned char *data, int length)
 {
-       return PERIPHERAL_ERROR_INVALID_OPERATION;
+       if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER;
+
+       return peripheral_gdbus_spi_read(spi, data, length);
 }
 
-int peripheral_spi_transfer_buf(peripheral_spi_context_h hnd, char *txbuf, char *rxbuf, int length)
+int peripheral_spi_write(peripheral_spi_h spi, unsigned char *data, int length)
 {
-       return PERIPHERAL_ERROR_INVALID_OPERATION;
+       if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER;
+
+       return peripheral_gdbus_spi_write(spi, data, length);
 }
 
-int    peripheral_spi_close(peripheral_spi_context_h hnd)
+int peripheral_spi_read_write(peripheral_spi_h spi, unsigned char *txdata, unsigned char *rxdata, int length)
 {
-       return PERIPHERAL_ERROR_INVALID_OPERATION;
+       if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER;
+
+       return peripheral_gdbus_spi_read_write(spi, txdata, rxdata, length);
 }
index 1ec14eb..d0aa4c6 100644 (file)
@@ -519,6 +519,80 @@ err_open:
        return -1;
 }
 
+#define MMA7455_MCTL_SPI3W 0x20 // SPI is 3 wire mode
+#define MMA7455_MCTL_DRPD 0x40 // Data ready status is not output to INT1/DRDY PIN
+
+#define MMA7455_SPI_REGISTER_WRITE 0x40
+
+int spi_mma7455_module_test(void)
+{
+       int cnt = 0;
+       int bus_num, cs_num, ret;
+       unsigned char tx_buf[10];
+       unsigned char rx_buf[10];
+       unsigned int num;
+       peripheral_spi_h spi;
+
+       printf("        %s()\n", __func__);
+       printf("Enter SPI bus number : ");
+       if (scanf("%d", &bus_num) < 0)
+               return -1;
+
+       printf("Enter SPI cs number : ");
+       if (scanf("%d", &cs_num) < 0)
+               return -1;
+
+       if ((ret = peripheral_spi_open(bus_num, cs_num, &spi)) < 0) {
+               printf("Failed to open I2C communication, ret : %d\n", ret);
+               return -1;
+       }
+       peripheral_spi_set_mode(spi, PERIPHERAL_SPI_MODE_0);
+       peripheral_spi_set_lsb_first(spi, false);
+       peripheral_spi_set_bits_per_word(spi, 8);
+       peripheral_spi_set_frequency(spi, 100000);
+
+       printf("bus : %d, cs : %d, ", bus_num, cs_num);
+       peripheral_spi_get_mode(spi, (peripheral_spi_mode_e*)&num);
+       printf("mode : %d, ", num);
+       peripheral_spi_get_lsb_first(spi, (bool*)&num);
+       printf("lsb first : %d, ", (bool)num);
+       peripheral_spi_get_bits_per_word(spi, (unsigned char*)&num);
+       printf("bits : %d, ", (unsigned char)num);
+       peripheral_spi_get_frequency(spi, &num);
+       printf("max frequency : %d\n", num);
+
+       tx_buf[0] = (MMA7455_MCTL | MMA7455_SPI_REGISTER_WRITE) << 1;
+       tx_buf[1] = MMA7455_MCTL_DRPD | MMA7455_MCTL_SPI3W | MMA7455_MCTL_2G | MMA7455_MCTL_MEASUREMENT_MODE;
+       if ((ret = peripheral_spi_write(spi, tx_buf, 2)) < 0) {
+               printf("Failed to write, ret : %d\n", ret);
+               goto error;
+       }
+
+       while (cnt++ < 15) {
+               int i;
+               unsigned char buf[5];
+
+               sleep(1);
+               for (i = 0; i < 3; i++) {
+                       tx_buf[0] = (MMA7455_XOUT8 + i) << 1;
+                       tx_buf[1] = 0;
+                       ret = peripheral_spi_read_write(spi, tx_buf, rx_buf, 2);
+                       if (ret < 0)
+                               printf("Failed to read, ret : %d\n", ret);
+                       buf[i] = rx_buf[1];
+               }
+
+               printf("X = 0x%02X, Y = 0x%02X, Z = 0x%02X\n", buf[0], buf[1], buf[2]);
+       }
+
+       peripheral_spi_close(spi);
+       return 0;
+
+error:
+       peripheral_spi_close(spi);
+       return -1;
+}
+
 int gpio_test_get_handle_by_pin(int pin, peripheral_gpio_h *gpio)
 {
        peripheral_gpio_h handle;
@@ -851,8 +925,9 @@ tc_table_t preset_tc_table[] = {
        {"[Preset Test] PWM LED",                                       4, pwm_test_led},
        {"[Preset Test] PWM Motor",                                     5, pwm_test_motor},
        {"[Preset Test] Uart Accelerometer",            6, uart_test_accelerometer},
-       {"[Preset Test] GPIO IRQ register",                     7, gpio_irq_register},
-       {"[Preset Test] GPIO IRQ unregister",           8, gpio_irq_unregister},
+       {"[Preset Test] SPI MMA7455 Accel. sensor",     7, spi_mma7455_module_test},
+       {"[Preset Test] GPIO IRQ register",                     8, gpio_irq_register},
+       {"[Preset Test] GPIO IRQ unregister",           9, gpio_irq_unregister},
        {"Go back to main",                                                     0, enter_main},
        {NULL,  0, NULL},
 };