diff --git a/CMakeLists.txt b/CMakeLists.txt index 8dcd5ff..d3503d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,8 +167,10 @@ elseif (DETECTED_ARCH MATCHES "arm.*") set (ARMPLAT ON) elseif (DETECTED_ARCH STREQUAL "MOCK") set (MOCKPLAT ON) +elseif (DETECTED_ARCH STREQUAL "PERIPHERALMAN") + set (PERIPHERALMAN ON) else () - message (FATAL_ERROR "Only x86, arm and mock platforms currently supported") + message (FATAL_ERROR "Only x86, arm, peripheral manager and mock platforms currently supported") endif() if (BUILDSWIGPYTHON OR BUILDTESTS) diff --git a/api/mraa/types.h b/api/mraa/types.h index 773649e..2d0a217 100644 --- a/api/mraa/types.h +++ b/api/mraa/types.h @@ -63,6 +63,7 @@ typedef enum { // contains bit 9 so is subplatform MRAA_GENERIC_FIRMATA = 1280, /**< Firmata uart platform/bridge */ + MRAA_ANDROID_PERIPHERALMANAGER = 95, /**< Android Things peripheral manager platform */ MRAA_MOCK_PLATFORM = 96, /**< Mock platform, which requires no real hardware */ MRAA_JSON_PLATFORM = 97, /**< User initialised platform from json*/ MRAA_NULL_PLATFORM = 98, /**< Platform with no capabilities that hosts a sub platform */ diff --git a/docs/building.md b/docs/building.md index 6cfa245..80a69eb 100644 --- a/docs/building.md +++ b/docs/building.md @@ -184,3 +184,9 @@ build machine. ~~~~~~~~~~~~~{.sh} cmake -DRPM=ON -DCMAKE_INSTALL_PREFIX=/usr .. ~~~~~~~~~~~~~ + +## Building for Peripheralmanager Android Things + +~~~~~~~~~~~~~{.sh} +cmake -DBUILDSWIG=OFF -DBUILDARCH=PERIPHERALMAN -DCMAKE_TOOLCHAIN_FILE=/opt/android-ndk-r13b/build/cmake/android.toolchain.cmake .. +~~~~~~~~~~~~~ diff --git a/include/mraa_internal.h b/include/mraa_internal.h index 7f1ed74..08b6709 100644 --- a/include/mraa_internal.h +++ b/include/mraa_internal.h @@ -38,7 +38,9 @@ extern "C" { extern mraa_board_t* plat; extern char* platform_name; +#if !defined(PERIPHERALMAN) extern mraa_iio_info_t* plat_iio; +#endif extern mraa_lang_func_t* lang_func; /** diff --git a/include/mraa_internal_types.h b/include/mraa_internal_types.h index f5061e8..adb97a2 100644 --- a/include/mraa_internal_types.h +++ b/include/mraa_internal_types.h @@ -25,10 +25,16 @@ #pragma once +#ifdef PERIPHERALMAN +#include +#endif + #include "common.h" #include "mraa.h" #include "mraa_adv_func.h" +#if !defined(PERIPHERALMAN) #include "iio.h" +#endif // Bionic does not implement pthread cancellation API #ifndef __BIONIC__ @@ -124,6 +130,9 @@ struct _gpio { int mock_state; /**< mock state of the pin */ #endif /*@}*/ +#ifdef PERIPHERALMAN + BGpio *bgpio; +#endif }; /** @@ -143,6 +152,10 @@ struct _i2c { uint8_t* mock_dev_data; /**< mock device data register block contents */ #endif /*@}*/ +#ifdef PERIPHERALMAN + BI2cDevice *bi2c; + char bus_name[256]; +#endif }; /** @@ -157,6 +170,9 @@ struct _spi { unsigned int bpw; /**< Bits per word */ mraa_adv_func_t* advance_func; /**< override function table */ /*@}*/ +#ifdef PERIPHERALMAN + BSpiDevice *bspi; +#endif }; /** @@ -195,8 +211,12 @@ struct _uart { int fd; /**< file descriptor for device. */ mraa_adv_func_t* advance_func; /**< override function table */ /*@}*/ +#if defined(PERIPHERALMAN) + struct BUartDevice *buart; +#endif }; +#if !defined(PERIPHERALMAN) /** * A structure representing an IIO device */ @@ -215,6 +235,7 @@ struct _iio { mraa_iio_event* events; int datasize; }; +#endif /** * A bitfield representing the capabilities of a pin. @@ -377,7 +398,9 @@ typedef struct _board_t { /*@}*/ } mraa_board_t; +#if !defined(PERIPHERALMAN) typedef struct { struct _iio* iio_devices; /**< Pointer to IIO devices */ uint8_t iio_device_count; /**< IIO device count */ } mraa_iio_info_t; +#endif diff --git a/include/peripheralman.h b/include/peripheralman.h new file mode 100644 index 0000000..4d838ac --- /dev/null +++ b/include/peripheralman.h @@ -0,0 +1,38 @@ +/* + * Author: Brendan Le Foll + * Copyright (c) 2016 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mraa_internal.h" + +mraa_platform_t +mraa_peripheralman_platform(); + +#ifdef __cplusplus +} +#endif diff --git a/include/peripheralmanager/gpio.h b/include/peripheralmanager/gpio.h new file mode 100644 index 0000000..5019fe8 --- /dev/null +++ b/include/peripheralmanager/gpio.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * 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 SYSTEM_PERIPHERALMANAGER_GPIO_H_ +#define SYSTEM_PERIPHERALMANAGER_GPIO_H_ + +#include +#include + +__BEGIN_DECLS + +/// @defgroup Gpio Gpio Interface +/// @brief Functions to control GPIO pins. +/// +/// These functions can be used to control GPIO. +/// @{ + +/// Edge trigger types. +enum { + NONE_EDGE, /**< None */ + RISING_EDGE, /**< Rising edge */ + FALLING_EDGE, /**< Falling edge */ + BOTH_EDGE /**< Both edges */ +}; + +/// GPIO direction types. +enum { + DIRECTION_IN, /**< Input mode */ + DIRECTION_OUT_INITIALLY_HIGH, /**< Output mode, initially set to high */ + DIRECTION_OUT_INITIALLY_LOW /**< Output mode, initially set to low */ +}; + +/// Possible active types. +enum { + ACTIVE_LOW, /**< Active Low */ + ACTIVE_HIGH /**< Active High */ +}; + +typedef struct BGpio BGpio; + +/// Sets the GPIO direction to output. +/// @param gpio Pointer to the BGpio struct +/// @param direction One of DIRECTION_IN, +/// DIRECTION_OUT_INITIALLY_HIGH, DIRECTION_OUT_INITIALLY_LOW. +/// @return 0 on success, errno on error. +int BGpio_setDirection(const BGpio* gpio, int direction); + +/// Sets the interrupt edge trigger type. +/// @param gpio Pointer to the BGpio struct +/// @param type One of NONE_EDGE, RISING_EDGE, FALLING_EDGE or BOTH_EDGE. +/// @return 0 on success, errno on error. +int BGpio_setEdgeTriggerType(const BGpio* gpio, int type); + +/// Sets the GPIO’s active low/high status. +/// @param gpio Pointer to the BGpio struct. +/// @param type One of ACTIVE_HIGH, ACTIVE_LOW. +/// @return 0 on success, errno on error. +int BGpio_setActiveType(const BGpio* gpio, int type); + +/// Sets the GPIO value (for output GPIO only). +/// @param gpio Pointer to the BGpio struct. +/// @param value Value to set. +/// @return 0 on success, errno on error. +int BGpio_setValue(const BGpio* gpio, int value); + +/// Gets the GPIO value (for input GPIO only). +/// @param gpio Pointer to the BGpio struct. +/// @param value Output pointer to the value of the GPIO. +/// @return 0 on success, errno on error. +int BGpio_getValue(const BGpio* gpio, int* value); + +/// Returns a file descriptor that can be used to poll on new data. +/// Can be passed to select/epoll to wait for data to become available. +/// @param gpio Pointer to the BGpio struct. +/// @param fd Output pointer to the file descriptor number. +/// @return 0 on success, errno on error. +int BGpio_getPollingFd(const BGpio* gpio, int* fd); + +/// Acknowledges the interrupt and resets the file descriptor. +/// This must be called after each event triggers in order to be able to +/// poll/select for another event. +/// @param fd Polling file descriptor to reset. +/// @return 0 on success, errno on error. +int BGpio_ackInterruptEvent(int fd); + +/// Destroys a BGpio struct. +/// @param gpio Pointer to the BGpio struct. +void BGpio_delete(BGpio* gpio); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_GPIO_H_ diff --git a/include/peripheralmanager/i2c_device.h b/include/peripheralmanager/i2c_device.h new file mode 100644 index 0000000..569272e --- /dev/null +++ b/include/peripheralmanager/i2c_device.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * 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 SYSTEM_PERIPHERALMANAGER_I2C_DEVICE_H_ +#define SYSTEM_PERIPHERALMANAGER_I2C_DEVICE_H_ + +#include +#include + +__BEGIN_DECLS + +/// @defgroup I2c I2c device interface +/// @brief Functions to control an I2C device. +/// +/// These functions can be used to control an I2C device. +/// @{ + +typedef struct BI2cDevice BI2cDevice; + +/// Reads from the device. +/// @param device Pointer to the BI2cDevice struct. +/// @param data Output buffer to write the data to. +/// @param len Number of bytes to read. +/// @return 0 on success, errno on error +int BI2cDevice_read(const BI2cDevice* device, void* data, uint32_t len); + +/// Reads a byte from an I2C register. +/// @param device Pointer to the BI2cDevice struct. +/// @param reg Register to read from. +/// @param val Output pointer to value to read. +/// @return 0 on success, errno on error +int BI2cDevice_readRegByte(const BI2cDevice* device, uint8_t reg, uint8_t* val); + +/// Reads a word from an I2C register. +/// @param device Pointer to the BI2cDevice struct. +/// @param reg Register to read from. +/// @param val Output pointer to value to read. +/// @return 0 on success, errno on error +int BI2cDevice_readRegWord(const BI2cDevice* device, + uint8_t reg, + uint16_t* val); + +/// Reads from an I2C register. +/// @param device Pointer to the BI2cDevice struct. +/// @param reg Register to read from. +/// @param data Output buffer to write the data to. +/// @param len Number of bytes to read. +/// @return 0 on success, errno on error +int BI2cDevice_readRegBuffer(const BI2cDevice* device, + uint8_t reg, + void* data, + uint32_t len); + +/// Writes to the device. +/// @param device Pointer to the BI2cDevice struct. +/// @param data Buffer to write. +/// @param len Number of bytes to write. +/// @return 0 on success, errno on error +int BI2cDevice_write(const BI2cDevice* device, const void* data, uint32_t len); + +/// Writes a byte to an I2C register. +/// @param device Pointer to the BI2cDevice struct. +/// @param reg Register to write to. +/// @param val Value to write. +/// @return 0 on success, errno on error +int BI2cDevice_writeRegByte(const BI2cDevice* device, uint8_t reg, uint8_t val); + +/// Writes a word to an I2C register. +/// @param device Pointer to the BI2cDevice struct. +/// @param reg Register to write to. +/// @param val Value to write. +/// @return 0 on success, errno on error +int BI2cDevice_writeRegWord(const BI2cDevice* device, + uint8_t reg, + uint16_t val); + +/// Writes to an I2C register. +/// @param device Pointer to the BI2cDevice struct. +/// @param reg Register to write to. +/// @param data Data to write. +/// @param len Number of bytes to write. +/// @return 0 on success, errno on error +int BI2cDevice_writeRegBuffer(const BI2cDevice* device, + uint8_t reg, + const void* data, + uint32_t len); + +/// Destroys a BI2cDevice struct. +/// @param device Pointer to the BI2cDevice struct. +void BI2cDevice_delete(BI2cDevice* device); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_I2C_DEVICE_H_ diff --git a/include/peripheralmanager/peripheral_manager_client.h b/include/peripheralmanager/peripheral_manager_client.h new file mode 100644 index 0000000..1628471 --- /dev/null +++ b/include/peripheralmanager/peripheral_manager_client.h @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * 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 SYSTEM_PERIPHERALMANAGER_PERIPHERAL_MANAGER_CLIENT_H_ +#define SYSTEM_PERIPHERALMANAGER_PERIPHERAL_MANAGER_CLIENT_H_ + +#include + +#include "peripheralmanager/gpio.h" +#include "peripheralmanager/i2c_device.h" +#include "peripheralmanager/pwm.h" +#include "peripheralmanager/spi_device.h" +#include "peripheralmanager/uart_device.h" + +__BEGIN_DECLS + +/// @defgroup PeripheralManagerClient Peripheral client functions +/// @brief Functions to access embedded peripherals +/// @{ + +typedef struct BPeripheralManagerClient BPeripheralManagerClient; + +/// Returns the list of GPIOs. +/// This does not take ownership into account. +/// The list must be freed by the caller. +/// @param client Pointer to the BPeripheralManagerClient struct. +/// @param num_gpio Output pointer to the number of elements in the list. +/// @return The list of gpios. +char** BPeripheralManagerClient_listGpio(const BPeripheralManagerClient* client, + int* num_gpio); + +/// Opens a GPIO and takes ownership of it. +/// @param client Pointer to the BPeripheralManagerClient struct. +/// @param name Name of the GPIO. +/// @param gpio Output pointer to the BGpio struct. Empty on error. +/// @return 0 on success, errno on error. +int BPeripheralManagerClient_openGpio(const BPeripheralManagerClient* client, + const char* name, + BGpio** gpio); + +/// Returns the list of PWMs. +/// This does not take ownership into account. +/// The list must be freed by the caller. +/// @param client Pointer to the BPeripheralManagerClient struct. +/// @param num_gpio Output pointer to the number of elements in the list. +/// @return The list of pwms. +char** BPeripheralManagerClient_listPwm(const BPeripheralManagerClient* client, + int* num_pwm); + +/// Opens a PWM and takes ownership of it. +/// @param client Pointer to the BPeripheralManagerClient struct. +/// @param name Name of the PWM. +/// @param gpio Output pointer to the BGpio struct. Empty on error. +/// @return 0 on success, errno on error. +int BPeripheralManagerClient_openPwm(const BPeripheralManagerClient* client, + const char* name, + BPwm** pwm); + +/// Returns the list of SPI buses. +/// This does not take ownership into account. +/// The list must be freed by the caller. +/// @param client Pointer to the BPeripheralManagerClient struct. +/// @param num_spi_buses Output pointer to the number of elements in the list. +/// @return The list of spi buses. +char** BPeripheralManagerClient_listSpiBuses( + const BPeripheralManagerClient* client, + int* num_spi_buses); + +/// Opens a SPI device and takes ownership of it. +/// @oaram client Pointer to the BPeripheralManagerClient struct. +/// @param name Name of the SPI device. +/// @param dev Output pointer to the BSpiDevice struct. Empty on error. +/// @return 0 on success, errno on error. +int BPeripheralManagerClient_openSpiDevice( + const BPeripheralManagerClient* client, + const char* name, + BSpiDevice** dev); + +/// Returns the list of I2C buses. +/// This does not take ownership into account. +/// The list must be freed by the caller. +/// @param client Pointer to the BPeripheralManagerClient struct. +/// @param num_i2c_buses Output pointer to the number of elements in the list. +/// @return The list of i2c buses. +char** BPeripheralManagerClient_listI2cBuses( + const BPeripheralManagerClient* client, + int* num_i2c_buses); + +/// Opens an I2C device and takes ownership of it. +/// @param client Pointer to the BPeripheralManagerClient struct. +/// @param name Name of the I2C bus. +/// @param address Address of the I2C device. +/// @param dev Output pointer to the BI2cDevice struct. Empty on error. +/// @return 0 on success, errno on error +int BPeripheralManagerClient_openI2cDevice( + const BPeripheralManagerClient* client, + const char* name, + uint32_t address, + BI2cDevice** dev); + +/// Returns the list of UART buses. +/// This does not take ownership into account. +/// The list must be freed by the caller. +/// @param client Pointer to the BPeripheralManagerClient struct. +/// @param num_uart_buses Output pointer to the number of elements in the list. +/// @return The list of uart buses. +char** BPeripheralManagerClient_listUartDevices( + const BPeripheralManagerClient* client, int* num_uart_buses); + +/// Opens an UART device and takes ownership of it. +/// @param client Pointer to the BPeripheralManagerClient struct. +/// @param name Name of the UART device. +/// @param dev Output pointer to the BUartDevice struct. Empty on error. +/// @return 0 on success, errno on error +int BPeripheralManagerClient_openUartDevice( + const BPeripheralManagerClient* client, + const char* name, + BUartDevice** dev); + +/// Creates a new client. +/// @return A pointer to the created client. nullptr on errors. +BPeripheralManagerClient* BPeripheralManagerClient_new(); + +/// Destroys the peripheral manager client. +/// @param client Pointer to the BPeripheralManagerClient struct. +void BPeripheralManagerClient_delete(BPeripheralManagerClient* client); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_PERIPHERAL_MANAGER_CLIENT_H_ diff --git a/include/peripheralmanager/pwm.h b/include/peripheralmanager/pwm.h new file mode 100644 index 0000000..26aae3b --- /dev/null +++ b/include/peripheralmanager/pwm.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * 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 SYSTEM_PERIPHERALMANAGER_PWM_H_ +#define SYSTEM_PERIPHERALMANAGER_PWM_H_ + +#include +#include + +__BEGIN_DECLS + +/// @defgroup Pwm Pwm Interface +/// @brief Functions to control PWM pins. +/// +/// These functions can be used to control PWM. +/// @{ + +typedef struct BPwm BPwm; + +/// Sets the PWM duty cycle. +/// @param gpio Pointer to the BPwm struct +/// @param duty_cycle Double between 0 and 100 inclusive. +/// @return 0 on success, errno on error. +int BPwm_setDutyCycle(const BPwm* pwm, double duty_cycle); + +/// Sets the PWM frequency. +/// @param gpio Pointer to the BPwm struct +/// @param freq Double denoting the frequency in Hz. +/// @return 0 on success, errno on error. +int BPwm_setFrequencyHz(const BPwm* pwm, double frequency); + +/// Enables the PWM. +/// @param gpio Pointer to the BPwm struct +/// @return 0 on success, errno on error. +int BPwm_enable(const BPwm* pwm); + +/// Disables the PWM. +/// @param gpio Pointer to the BPwm struct +/// @return 0 on success, errno on error. +int BPwm_disable(const BPwm* pwm); + +/// Destroys a BPwm struct. +/// @param pwm Pointer to the BPwm struct. +void BPwm_delete(BPwm* pwm); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_PWM_H_ diff --git a/include/peripheralmanager/spi_device.h b/include/peripheralmanager/spi_device.h new file mode 100644 index 0000000..6e01ed1 --- /dev/null +++ b/include/peripheralmanager/spi_device.h @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * 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 SYSTEM_PERIPHERALMANAGER_SPI_DEVICE_H_ +#define SYSTEM_PERIPHERALMANAGER_SPI_DEVICE_H_ + +#include +#include + +__BEGIN_DECLS + +/// @defgroup Spi Spi device interface +/// @brief Functions to control an SPI device. +/// +/// These functions can be used to control an SPI device. +/// @{ + +/// Endianness. +enum { + SPI_LSB_FIRST, /**< Least significant bits first */ + SPI_MSB_FIRST /**< Most significant bits first */ +}; + +/// SPI phase modes. +enum { + SPI_CPHA = 0x01, /**< Clock phase */ + SPI_CPOL = 0x02 /**< Clock polarity */ +}; + +/// SPI modes (similar to the Linux kernel's modes). +enum { + SPI_MODE0 = 0, /**< CPHA=0, CPOL=0 */ + SPI_MODE1 = SPI_CPHA, /**< CPHA=1, CPOL=0 */ + SPI_MODE2 = SPI_CPOL, /**< CPHA=0, CPOL=1 */ + SPI_MODE3 = SPI_CPHA + SPI_CPOL /**< CPHA=1, CPOL=1 */ +}; + +typedef struct BSpiDevice BSpiDevice; + +/// Writes a buffer to the device. +/// @param device Pointer to the BSpiDevice struct. +/// @param data Buffer to write. +/// @param len Length of the buffer. +/// @return 0 on success, errno on error. +int BSpiDevice_writeBuffer(const BSpiDevice* device, + const void* data, + size_t len); + +/// Reads a buffer from the device. +/// @param device Pointer to the BSpiDevice struct. +/// @param data Buffer to read into. +/// @param len Length of the buffer. +/// @return 0 on success, errno on error. +int BSpiDevice_readBuffer(const BSpiDevice* device, + void* data, + size_t len); + +/// Transfer data to the device. +/// @param device Pointer to the BSpiDevice struct. +/// @param tx_data Buffer to write. +/// @param rx_data Buffer to read data in. If NULL, no data will be read. +/// @param len Length of the buffers. +/// @return 0 on success, errno on error. +int BSpiDevice_transfer(const BSpiDevice* device, + const void* tx_data, + void* rx_data, + size_t len); + +/// Sets the frequency in Hertz. +/// @param device Pointer to the BSpiDevice struct. +/// @param freq_hz Frequency to set. +/// @return 0 on success, errno on error. +int BSpiDevice_setFrequency(const BSpiDevice* device, uint32_t freq_hz); + +/// Sets the SPI mode. +/// @param device Pointer to the BSpiDevice struct. +/// @param mode Mode to use. One of SPI_MODE0, SPI_MODE1, SPI_MODE2, SPI_MODE3. +/// @return 0 on success, errno on error. +int BSpiDevice_setMode(const BSpiDevice* device, int mode); + +/// Sets the bit justification. +/// @param device Pointer to the BSpiDevice struct. +/// @param bit_justification One of SPI_LSB_FIRST OR SPI_MSB_FIRST. +/// @return 0 on success, errno on error. +int BSpiDevice_setBitJustification(const BSpiDevice* device, + int bit_justification); + +/// Sets the number of bits per words. +/// @param device Pointer to the BSpiDevice struct. +/// @param bits_per_word Number of bits per word. +/// @return 0 on success, errno on error. +int BSpiDevice_setBitsPerWord(const BSpiDevice* device, uint8_t bits_per_word); + +/// Sets the delay to wait after each transfer. +/// @param device Pointer to the BSpiDevice struct. +/// @param delay_usecs Delay in microseconds. +/// @return 0 on success, errno on error. +int BSpiDevice_setDelay(const BSpiDevice* device, uint16_t delay_usecs); + +/// Sets the chip select behavior after each transfer. +/// @param device Pointer to the BSpiDevice struct. +/// @param change If set, cs will be active between transfers. +/// @return 0 on success, errno on error. +int BSpiDevice_setCsChange(const BSpiDevice* device, int change); + +/// Destroys a BSpiDevice struct. +/// @param device Pointer to the BSpiDevice struct. +void BSpiDevice_delete(BSpiDevice* device); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_SPI_DEVICE_H_ diff --git a/include/peripheralmanager/uart_device.h b/include/peripheralmanager/uart_device.h new file mode 100644 index 0000000..a68c57c --- /dev/null +++ b/include/peripheralmanager/uart_device.h @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * 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 SYSTEM_PERIPHERALMANAGER_UART_DEVICE_H_ +#define SYSTEM_PERIPHERALMANAGER_UART_DEVICE_H_ + +#include +#include +#include +#include + +__BEGIN_DECLS + +/// @defgroup Uart Uart device interface +/// @brief Functions to control an UART device. +/// +/// These functions can be used to control an UART device. +/// @{ + +/// UART Parity +enum UartParity { + UART_PARITY_NONE, /**< No parity */ + UART_PARITY_EVEN, /**< Even parity */ + UART_PARITY_ODD, /**< Odd parity */ + UART_PARITY_MARK, /**< Mark parity, always 1 */ + UART_PARITY_SPACE /**< Space parity, always 0 */ +}; + +/// Modem control Bits +enum UartModemControlBits { + UART_MC_LE = TIOCM_LE, /**< Data set ready/Line enable */ + UART_MC_DTR = TIOCM_DTR, /**< Data terminal ready */ + UART_MC_RTS = TIOCM_RTS, /**< Request to send */ + UART_MC_ST = TIOCM_ST, /**< Secondary TXD */ + UART_MC_SR = TIOCM_SR, /**< Secondary RXD */ + UART_MC_CTS = TIOCM_CTS, /**< Clear to send */ + UART_MC_CD = TIOCM_CAR, /**< Data carrier detect */ + UART_MC_RI = TIOCM_RI, /**< Ring */ + UART_MC_DSR = TIOCM_DSR /**< Data set ready */ +}; + +// Hardware Flow Control +enum UartHardwareFlowControlType { + UART_HW_FLOW_NONE, /**< No hardware flow control */ + UART_HW_FLOW_AUTO_RTSCTS /**< Auto RTS/CTS */ +}; + +/// Flush queue selection +enum UartFlushQueueSelection { + UART_FLUSH_IN = TCIFLUSH, /**< Flushes data received but not read */ + UART_FLUSH_OUT = TCOFLUSH, /**< Flushes data written but not transmitted */ + UART_FLUSH_IN_OUT = TCIOFLUSH /**< Flushes both in and out */ +}; + +typedef struct BUartDevice BUartDevice; + +/// Writes to a UART device. +/// @param device Pointer to the BUartDevice struct. +/// @param data Data to write. +/// @param len Size of the data to write. +/// @param bytes_written Output pointer to the number of bytes written. +/// @return 0 on success, errno on error. +int BUartDevice_write(const BUartDevice* device, + const void* data, + uint32_t len, + uint32_t* bytes_written); + +/// Reads from a UART device. +/// @param device Pointer to the BUartDevice struct. +/// @param data Buffer to read the data into. +/// @param len Number of bytes to read. +/// @param bytes_read Output pointer to the number of bytes read. +/// @return 0 on success, errno on error. +int BUartDevice_read(const BUartDevice* device, + void* data, + uint32_t len, + uint32_t* bytes_read); + +/// Sets the input and output speed of a UART device. +/// @param device Pointer to the BUartDevice struct. +/// @param baudrate Speed in baud. +/// @return 0 on success, errno on error. +int BUartDevice_setBaudrate(const BUartDevice* device, uint32_t baudrate); + +/// Sets number of stop bits for the UART device. +/// @param device Pointer to the BUartDevice struct. +/// @param stop_bits Number of stop bits. Typically 1 or 2. +/// @return 0 on success, errno on error. +int BUartDevice_setStopBits(const BUartDevice* device, uint32_t stop_bits); + +/// Sets the data size of a character for the UART device. +/// @param device Pointer to the BUartDevice struct. +/// @param data_size Number of bits per character. Typically between 5 and 8. +/// @return 0 on success, errno on error. +int BUartDevice_setDataSize(const BUartDevice* device, uint32_t data_size); + +/// Sets the parity mode for the UART device. +/// @param device Pointer to the BUartDevice struct. +/// @param mode Parity mode. One of UART_PARITY_NONE, UART_PARITY_EVEN, +/// UART_PARITY_ODD, UART_PARITY_MARK, UART_PARITY_SPACE. +/// @return 0 on success, errno on error. +int BUartDevice_setParity(const BUartDevice* device, uint32_t mode); + +/// Sets the hardware flow control mode for the UART device. +/// @param device Pointer to the BUartDevice struct. +/// @param mode Flow control mode. Either UART_HW_FLOW_NONE or +/// UART_HW_FLOW_AUTO_RTSCTS. +/// @return 0 on success, errno on error. +int BUartDevice_setHardwareFlowControl(const BUartDevice* device, + uint32_t mode); + +/// Sets the modem control bits for the UART device. +/// @param device Pointer to the BUartDevice struct. +/// @param bits Modem control bits to set. +/// @return 0 on success, errno on error. +int BUartDevice_setModemControl(const BUartDevice* device, uint32_t bits); + +/// Clears the modem control bits for the UART device. +/// @param device Pointer to the BUartDevice struct. +/// @param bits Modem control bits to clear. +/// @return 0 on success, errno on error. +int BUartDevice_clearModemControl(const BUartDevice* device, uint32_t bits); + +/// Sends a break to the UART device. +/// @param device Pointer to the BUartDevice struct. +/// @param duration Duration of break transmission in milliseconds. If 0, +/// transmits zero-valued bits for at least 0.25 seconds, and not more +/// than 0.5 seconds. +/// @return 0 on success, errno on error. +int BUartDevice_sendBreak(const BUartDevice* device, uint32_t duration_msecs); + +/// Flushes specified queue for the UART device. +/// @param device Pointer to the BUartDevice struct. +/// @param queue Queue to flush. One of UART_FLUSH_IN, UART_FLUSH_OUT, +/// UART_FLUSH_IN_OUT. +/// @return 0 on success, errno on error. +int BUartDevice_flush(const BUartDevice* device, uint32_t queue); + +/// Gets a file descriptor to be notified when data can be read. +/// +/// You can use this file descriptor to poll on incoming data instead of +/// actively reading for new data. +/// +/// @param device Pointer to the BUartDevice struct. +/// @param fd Output pointer to the file descriptor. +/// @return 0 on success, errno on error. +int BUartDevice_getPollingFd(const BUartDevice* device, int* fd); + +/// Acknowledges an input event. +/// +/// This must be called after receiving an event notification on the polling +/// file descriptor. +/// If you don't acknowledge an event, peripheral manager will assume you are +/// still processing it and you will not receive any more events. +/// If you acknowledge an event before reading the data from the device, you +/// will receive an event immediately as there will still be data available. +/// +/// @param fd File descriptor to acknowledge the event on. +/// @return 0 on success, errno on error. +int BUartDevice_ackInputEvent(int fd); + +/// Destroys a BUartDevice struct. +/// @param device Pointer to the BUartDevice struct. +void BUartDevice_delete(BUartDevice* device); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_UART_DEVICE_H_ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2efb1cd..7842963 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,10 +26,16 @@ set (mraa_LIB_SRCS_NOAUTO ${PROJECT_SOURCE_DIR}/src/spi/spi.c ${PROJECT_SOURCE_DIR}/src/aio/aio.c ${PROJECT_SOURCE_DIR}/src/uart/uart.c - ${PROJECT_SOURCE_DIR}/src/iio/iio.c ${mraa_LIB_SRCS_NOAUTO} ) +if (NOT PERIPHERALMAN) + set (mraa_LIB_SRCS_NOAUTO + ${mraa_LIB_SRCS_NOAUTO} + ${PROJECT_SOURCE_DIR}/src/iio/iio.c + ) +endif () + set (mraa_LIB_X86_SRCS_NOAUTO ${PROJECT_SOURCE_DIR}/src/x86/x86.c ${PROJECT_SOURCE_DIR}/src/x86/intel_galileo_rev_d.c @@ -96,6 +102,16 @@ set (mraa_LIB_MOCK_SRCS_NOAUTO ${PROJECT_SOURCE_DIR}/src/mock/mock_board_uart.c ) +set (mraa_LIB_PERIPHERALMAN_SRCS_NOAUTO + ${PROJECT_SOURCE_DIR}/src/peripheralman/peripheralman.c + ${PROJECT_SOURCE_DIR}/src/peripheralman/peripheralman_aio.c + ${PROJECT_SOURCE_DIR}/src/peripheralman/peripheralman_gpio.c + ${PROJECT_SOURCE_DIR}/src/peripheralman/peripheralman_i2c.c + ${PROJECT_SOURCE_DIR}/src/peripheralman/peripheralman_pwm.c + ${PROJECT_SOURCE_DIR}/src/peripheralman/peripheralman_spi.c + ${PROJECT_SOURCE_DIR}/src/peripheralman/peripheralman_uart.c +) + if (JSONPLAT) find_package (JSON-C QUIET) if (${JSON-C_FOUND}) @@ -108,7 +124,6 @@ endif () set (mraa_LIBS ${CMAKE_THREAD_LIBS_INIT}) - if (X86PLAT) add_subdirectory(x86) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DX86PLAT=1") @@ -127,6 +142,11 @@ if (MOCKPLAT) endif () endif() +if (PERIPHERALMAN) + add_subdirectory(peripheralman) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPERIPHERALMAN=1") +endif() + if (USBPLAT) message (STATUS "INFO - Adding USB platforms") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSBPLAT=1") diff --git a/src/mraa.c b/src/mraa.c index 51f2d63..3f8968b 100644 --- a/src/mraa.c +++ b/src/mraa.c @@ -33,8 +33,10 @@ #include #include #include +#if !defined(PERIPHERALMAN) #include #include +#endif #include #include #include @@ -61,17 +63,20 @@ #include "spi.h" #include "uart.h" +#if defined(PERIPHERALMAN) +#include "peripheralman.h" +#elif #define IIO_DEVICE_WILDCARD "iio:device*" - mraa_board_t* plat = NULL; mraa_iio_info_t* plat_iio = NULL; -mraa_lang_func_t* lang_func = NULL; - -char* platform_name = NULL; static int num_i2c_devices = 0; static int num_iio_devices = 0; +#endif +mraa_lang_func_t* lang_func = NULL; + +char* platform_name = NULL; const char* mraa_get_version() @@ -141,6 +146,9 @@ imraa_init() #elif defined(MOCKPLAT) // Use mock platform platform_type = mraa_mock_platform(); +#elif defined(PERIPHERALMAN) + // Use peripheralmanager + platform_type = mraa_peripheralman_platform(); #else #error mraa_ARCH NOTHING #endif @@ -182,6 +190,7 @@ imraa_init() mraa_add_from_lockfile(subplatform_lockfile); #endif +#if !defined(PLATFORMAN) // Look for IIO devices mraa_iio_detect(); @@ -198,6 +207,7 @@ imraa_init() strncpy(platform_name, plat->platform_name, length); } } +#endif lang_func = (mraa_lang_func_t*) calloc(1, sizeof(mraa_lang_func_t)); if (lang_func == NULL) { @@ -225,7 +235,6 @@ mraa_init() void mraa_deinit() { - int i = 0; if (plat != NULL) { if (plat->pins != NULL) { free(plat->pins); @@ -249,6 +258,7 @@ mraa_deinit() free(plat->platform_name); plat->platform_name = NULL; + int i = 0; // Free the UART device path for (i = 0; i < plat->uart_dev_count; i++) { if (plat->uart_dev[i].device_path != NULL) { @@ -270,10 +280,12 @@ mraa_deinit() platform_name = NULL; } } +#if !defined(PERIPHERALMAN) if (plat_iio != NULL) { free(plat_iio); plat_iio = NULL; } +#endif closelog(); } @@ -292,6 +304,8 @@ mraa_set_priority(const int priority) return sched_setscheduler(0, SCHED_RR, &sched_s); } +#if !defined(PERIPHERALMAN) + static int mraa_count_iio_devices(const char* path, const struct stat* sb, int flag, struct FTW* ftwb) { @@ -507,6 +521,7 @@ mraa_setup_mux_mapped(mraa_pin_t meta) return MRAA_SUCCESS; } +#endif void mraa_result_print(mraa_result_t result) @@ -809,6 +824,7 @@ mraa_get_default_i2c_bus(uint8_t platform_offset) } } +#if !defined(PERIPHERALMAN) mraa_boolean_t mraa_file_exist(const char* filename) @@ -1071,6 +1087,8 @@ mraa_find_i2c_bus(const char* devname, int startfrom) return ret; } +#endif + mraa_boolean_t mraa_is_sub_platform_id(int pin_or_bus) { @@ -1092,7 +1110,11 @@ mraa_get_sub_platform_index(int pin_or_bus) int mraa_get_iio_device_count() { +#if defined(PERIPHERALMAN) + return -1; +#else return plat_iio->iio_device_count; +#endif } mraa_result_t diff --git a/src/peripheralman/CMakeLists.txt b/src/peripheralman/CMakeLists.txt new file mode 100644 index 0000000..98d8ffe --- /dev/null +++ b/src/peripheralman/CMakeLists.txt @@ -0,0 +1,3 @@ +message (INFO " - Adding Peripheral Manager platform") +set (mraa_LIB_PLAT_SRCS_NOAUTO ${mraa_LIB_SRCS_NOAUTO} + ${mraa_LIB_PERIPHERALMAN_SRCS_NOAUTO} PARENT_SCOPE) diff --git a/src/peripheralman/mraa.c b/src/peripheralman/mraa.c new file mode 100644 index 0000000..abd0a64 --- /dev/null +++ b/src/peripheralman/mraa.c @@ -0,0 +1,371 @@ +/* + * Author: Constantin Musca + * Author: Brendan Le Foll + * Author: Thomas Ingleby + * Copyright (c) 2014-2016 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include "mraa_internal.h" +#include "gpio.h" +#include "version.h" +#include + +BPeripheralManagerClient *client = NULL; +char **gpios = NULL; +int gpios_count = 0; +char **i2c_busses = NULL; +int i2c_busses_count = 0; +char **spi_busses = NULL; +int spi_busses_count = 0; +char **uart_devices = NULL; +int uart_busses_count = 0; +mraa_lang_func_t* lang_func = NULL; + +const char* +mraa_get_version() +{ + return gVERSION; +} + +mraa_result_t +mraa_set_log_level(int level) +{ + syslog(LOG_WARNING, "mraa: function not implementedin PMRAA"); + return MRAA_ERROR_INVALID_PARAMETER; +} + +static void free_resources(char ***resources, int count) +{ + int i; + + if (*resources != NULL) { + for(i = 0; i < count; i++) { + free((*resources)[i]); + } + free(*resources); + } + + *resources = NULL; +} + +mraa_result_t +mraa_init() +{ + if (client != NULL) { + BPeripheralManagerClient_delete(client); + } + + client = BPeripheralManagerClient_new(); + if (client == NULL) { + return MRAA_ERROR_PLATFORM_NOT_INITIALISED; + } + + gpios = BPeripheralManagerClient_listGpio(client, &gpios_count); + i2c_busses = BPeripheralManagerClient_listI2cBuses(client, &i2c_busses_count); + spi_busses = BPeripheralManagerClient_listSpiBuses(client, &spi_busses_count); + uart_devices = BPeripheralManagerClient_listUartDevices(client, &uart_busses_count); + //lang_func + lang_func = (mraa_lang_func_t*) calloc(1, sizeof(mraa_lang_func_t)); + if (lang_func == NULL) { + return MRAA_ERROR_NO_RESOURCES; + } + + return MRAA_SUCCESS; +} + +void +mraa_deinit() +{ + free_resources(&uart_devices, uart_busses_count); + free_resources(&spi_busses, spi_busses_count); + free_resources(&i2c_busses, i2c_busses_count); + free_resources(&gpios, gpios_count); + + if (client != NULL) { + BPeripheralManagerClient_delete(client); + client = NULL; + } +} + + +mraa_platform_t +mraa_get_platform_type() +{ + syslog(LOG_WARNING, "mraa: function not implementedin PMRAA"); + return -1; +} + +int mraa_get_default_i2c_bus(uint8_t platform_offset) { + // return first bus available + return 0; +} + +unsigned int +mraa_adc_raw_bits() +{ + syslog(LOG_WARNING, "mraa: function not implementedin PMRAA"); + return 0; + +} + +unsigned int +mraa_adc_supported_bits() +{ + syslog(LOG_WARNING, "mraa: function not implementedin PMRAA"); + return 0; +} + +int +mraa_set_priority(const int priority) +{ + syslog(LOG_WARNING, "mraa: function not implementedin PMRAA"); + return -1; +} + +const char* +mraa_get_platform_name() +{ + syslog(LOG_WARNING, "mraa: function not implementedin PMRAA"); + return NULL; +} + +const char* +mraa_get_platform_version(int platform_offset) +{ + syslog(LOG_WARNING, "mraa: function not implementedin PMRAA"); + return NULL; +} + +unsigned int +mraa_get_pin_count() +{ + syslog(LOG_WARNING, "mraa: function not implementedin PMRAA"); + return 0; +} + +int +mraa_get_i2c_bus_count() +{ + syslog(LOG_WARNING, "mraa: function not implementedin PMRAA"); + return -1; +} + +int +mraa_get_i2c_bus_id(int i2c_bus) +{ + syslog(LOG_WARNING, "mraa: function not implementedin PMRAA"); + return -1; +} + +mraa_boolean_t +mraa_pin_mode_test(int pin, mraa_pinmodes_t mode) +{ + syslog(LOG_WARNING, "mraa: function not implementedin PMRAA"); + return 0; +} + +char* +mraa_get_pin_name(int pin) +{ + syslog(LOG_WARNING, "mraa: function not implementedin PMRAA"); + return 0; +} + +mraa_boolean_t +mraa_has_sub_platform() +{ + syslog(LOG_WARNING, "mraa: function not implementedin PMRAA"); + return 0; +} + +mraa_boolean_t +mraa_is_sub_platform_id(int pin_or_bus) +{ + syslog(LOG_WARNING, "mraa: function not implementedin PMRAA"); + return 0; +} + +int +mraa_get_sub_platform_id(int pin_or_bus) +{ + syslog(LOG_WARNING, "mraa: function not implementedin PMRAA"); + return -1; +} + +int +mraa_get_sub_platform_index(int pin_or_bus) +{ + syslog(LOG_WARNING, "mraa: function not implementedin PMRAA"); + return -1; +} + +mraa_result_t +mraa_add_subplatform(mraa_platform_t subplatformtype, const char* uart_dev) +{ + syslog(LOG_WARNING, "mraa: function not implementedin PMRAA"); + return MRAA_ERROR_INVALID_PARAMETER; +} + +mraa_result_t +mraa_remove_subplatform(mraa_platform_t subplatformtype) +{ + return MRAA_ERROR_INVALID_PARAMETER; +} + +void +mraa_result_print(mraa_result_t result) +{ + syslog(LOG_WARNING, "mraa: function not implementedin PMRAA"); + fprintf(stdout, "MRAA: Unrecognised error."); +} + +void +mraa_to_upper(char* s) +{ + char* t = s; + for (; *t; ++t) { + *t = toupper(*t); + } +} + +mraa_result_t +mraa_atoi(char* intStr, int* value) +{ + char* end; + // here 10 determines the number base in which strol is to work + long val = strtol(intStr, &end, 10); + if (*end != '\0' || errno == ERANGE || end == intStr || val > INT_MAX || val < INT_MIN) { + *value = 0; + return MRAA_ERROR_UNSPECIFIED; + } + *value = (int) val; + return MRAA_SUCCESS; +} + +void* +mraa_init_io(const char* desc) +{ + void* dev; + int rc; + const char* delim = "-"; + int length = 0; + // 256 denotes the maximum size of our buffer + // 8 denotes the maximum size of our type rounded to the nearest power of 2 + // max size is 4 + 1 for the \0 = 5 rounded to 8 + char buffer[256] = { 0 }, type[8] = { 0 }; + char *token = 0, *str = 0; + if (desc == NULL) { + return NULL; + } + length = strlen(desc); + // Check to see the length is less than or equal to 255 which means + // byte 256 is supposed to be \0 + if (length > 255 || length == 0) { + return NULL; + } + strncpy(buffer, desc, length); + + str = buffer; + token = strsep(&str, delim); + length = strlen(token); + // Check to see they haven't given us a type whose length is greater than the + // largest type we know about + if (length > 4) { + syslog(LOG_ERR, "mraa_init_io: An invalid IO type was provided"); + return NULL; + } + strncpy(type, token, length); + mraa_to_upper(type); + token = strsep(&str, delim); + // Check that they've given us more information than just the type + if (token == NULL) { + syslog(LOG_ERR, "mraa_init_io: Missing information after type"); + return NULL; + } + + if (strncmp(type, "GPIO", 4) == 0) { + if ((dev = calloc(sizeof(struct _gpio), 1)) == NULL) { + syslog(LOG_ERR, "mraa_init_io: cannot allocate memory for GPIO %s", token); + return NULL; + } + + rc = BPeripheralManagerClient_openGpio(client, token, &((mraa_gpio_context)dev)->bgpio); + if (rc != 0) { + syslog(LOG_ERR, "mraa_init_io: cannot open GPIO %s", token); + free(dev); + return NULL; + } + + return dev; + } else if (strncmp(type, "I2C", 3) == 0) { + dev = calloc(1, sizeof(struct _i2c)); + if (dev == NULL) { + syslog(LOG_ERR, "mraa_init_io: cannot allocate memory for I2C %s", token); + return NULL; + } + + strncpy(((mraa_i2c_context)dev)->bus_name, token, MAX_I2C_BUS_NAME - 1); + return dev; + } else if (strncmp(type, "SPI", 3) == 0) { + dev = calloc(1, sizeof(struct _spi)); + if (dev == NULL) { + syslog(LOG_ERR, "mraa_init_io: cannot allocate memory for SPI %s", token); + return NULL; + } + + rc = BPeripheralManagerClient_openSpiDevice(client, token, &((mraa_spi_context)dev)->bspi); + if (rc != 0) { + syslog(LOG_ERR, "mraa_init_io: cannot open SPI %s", token); + free(dev); + return NULL; + } + + return dev; + } else if (strncmp(type, "UART", 4) == 0) { + dev = calloc(1, sizeof(struct _uart)); + if (dev == NULL) { + syslog(LOG_ERR, "mraa_init_io: cannot allocate memory for UART %s", token); + return NULL; + } + + rc = BPeripheralManagerClient_openUartDevice(client, token, &((mraa_uart_context)dev)->buart); + if (rc != 0) { + syslog(LOG_ERR, "mraa_init_io: cannot open UART %s", token); + free(dev); + return NULL; + } + } + + syslog(LOG_ERR, "mraa_init_io: Invalid IO type given."); + return NULL; +} + +#ifndef JSONPLAT +mraa_result_t +mraa_init_json_platform(const char* desc) +{ + return MRAA_ERROR_FEATURE_NOT_SUPPORTED; +} +#endif diff --git a/src/peripheralman/peripheralman.c b/src/peripheralman/peripheralman.c new file mode 100644 index 0000000..2b74c85 --- /dev/null +++ b/src/peripheralman/peripheralman.c @@ -0,0 +1,197 @@ +/* + * Author: Brendan Le Foll + * Copyright (c) 2016 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include "mraa_internal.h" +#include "peripheralman.h" + +BPeripheralManagerClient *client = NULL; + +mraa_board_t* +mraa_peripheralman_plat_init() +{ + mraa_board_t* b = (mraa_board_t*) calloc(1, sizeof(mraa_board_t)); + if (b == NULL) { + return NULL; + } + + if (client != NULL) { + BPeripheralManagerClient_delete(client); + } + + client = BPeripheralManagerClient_new(); + if (client == NULL) { + return NULL; + } + + int gpios_count, i2c_busses_count, spi_busses_count, uart_busses_count; + int gpios = BPeripheralManagerClient_listGpio(client, &gpios_count); + int i2c_busses = BPeripheralManagerClient_listI2cBuses(client, &i2c_busses_count); + int spi_busses = BPeripheralManagerClient_listSpiBuses(client, &spi_busses_count); + int uart_devices = BPeripheralManagerClient_listUartDevices(client, &uart_busses_count); + + b->platform_name = "peripheralmanager"; + // query this from peripheral manager? + b->platform_version = "1.0"; + b->gpio_count = 14; + // disable AIO support + b->aio_count = 0; + b->adc_supported = 0; + + // get this from PM + b->phy_pin_count = 20; + b->i2c_bus_count = 1; + b->def_i2c_bus = 0; + b->i2c_bus[0].bus_id = 0; + b->pwm_min_period = 2048; + b->pwm_max_period = 2048; + + b->pins = (mraa_pininfo_t*) calloc(b->phy_pin_count, sizeof(mraa_pininfo_t)); + if (b->pins == NULL) { + free(b); + return NULL; + } + +#if 0 + strncpy(b->pins[0].name, "IO0", 8); + b->pins[0].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[0].gpio.pinmap = 0; + strncpy(b->pins[1].name, "IO1", 8); + b->pins[1].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[1].gpio.pinmap = 1; + strncpy(b->pins[2].name, "IO2", 8); + b->pins[2].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[2].gpio.pinmap = 2; + strncpy(b->pins[3].name, "IO3", 8); + b->pins[3].capabilities = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 }; + b->pins[3].gpio.pinmap = 3; + strncpy(b->pins[4].name, "IO4", 8); + b->pins[4].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[4].gpio.pinmap = 4; + strncpy(b->pins[5].name, "IO5", 8); + b->pins[5].capabilities = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 }; + b->pins[5].gpio.pinmap = 5; + strncpy(b->pins[6].name, "IO6", 8); + b->pins[6].capabilities = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 }; + b->pins[6].gpio.pinmap = 6; + strncpy(b->pins[7].name, "IO7", 8); + b->pins[7].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[7].gpio.pinmap = 7; + strncpy(b->pins[8].name, "IO8", 8); + b->pins[8].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[8].gpio.pinmap = 8; + strncpy(b->pins[9].name, "IO9", 8); + b->pins[9].capabilities = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 }; + b->pins[9].gpio.pinmap = 9; + strncpy(b->pins[10].name, "IO10", 8); + b->pins[10].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[10].gpio.pinmap = 10; + strncpy(b->pins[11].name, "IO11", 8); + b->pins[11].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[11].gpio.pinmap = 11; + strncpy(b->pins[12].name, "IO12", 8); + b->pins[12].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[12].gpio.pinmap = 12; + strncpy(b->pins[13].name, "IO13", 8); + b->pins[13].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[13].gpio.pinmap = 13; + strncpy(b->pins[10].name, "A0", 8); + b->pins[14].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 1, 0 }; + b->pins[14].gpio.pinmap = 14; + b->pins[14].aio.pinmap = 14; + strncpy(b->pins[11].name, "A1", 8); + b->pins[15].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 1, 0 }; + b->pins[15].gpio.pinmap = 15; + b->pins[15].aio.pinmap = 15; + strncpy(b->pins[12].name, "A2", 8); + b->pins[16].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 1, 0 }; + b->pins[16].gpio.pinmap = 16; + b->pins[16].aio.pinmap = 16; + strncpy(b->pins[13].name, "A3", 8); + b->pins[17].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 1, 0 }; + b->pins[17].gpio.pinmap = 17; + b->pins[17].aio.pinmap = 17; + strncpy(b->pins[13].name, "A4", 8); + b->pins[18].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 1, 0 }; + b->pins[18].gpio.pinmap = 18; + b->pins[18].aio.pinmap = 18; + strncpy(b->pins[13].name, "A5", 8); + b->pins[19].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 1, 0 }; + b->pins[19].gpio.pinmap = 19; + b->pins[19].aio.pinmap = 19; +#endif + + b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t)); + if (b->adv_func == NULL) { + free(b->pins); + free(b); + return NULL; + } + +#if 0 + b->adv_func->gpio_init_internal_replace = &mraa_firmata_gpio_init_internal_replace; + b->adv_func->gpio_mode_replace = &mraa_firmata_gpio_mode_replace; + b->adv_func->gpio_dir_replace = &mraa_firmata_gpio_dir_replace; + b->adv_func->gpio_edge_mode_replace = &mraa_firmata_gpio_edge_mode_replace; + b->adv_func->gpio_interrupt_handler_init_replace = &mraa_firmata_gpio_interrupt_handler_init_replace; + b->adv_func->gpio_wait_interrupt_replace = &mraa_firmata_gpio_wait_interrupt_replace; + b->adv_func->gpio_read_replace = &mraa_firmata_gpio_read_replace; + b->adv_func->gpio_write_replace = &mraa_firmata_gpio_write_replace; + b->adv_func->gpio_close_replace = &mraa_firmata_gpio_close_replace; + + b->adv_func->aio_init_internal_replace = &mraa_firmata_aio_init_internal_replace; + b->adv_func->aio_read_replace = &mraa_firmata_aio_read; + + b->adv_func->pwm_init_internal_replace = &mraa_firmata_pwm_init_internal_replace; + b->adv_func->pwm_write_replace = &mraa_firmata_pwm_write_replace; + b->adv_func->pwm_read_replace = &mraa_firmata_pwm_read_replace; + b->adv_func->pwm_enable_replace = &mraa_firmata_pwm_enable_replace; + + b->adv_func->i2c_init_bus_replace = &mraa_firmata_i2c_init_bus_replace; + b->adv_func->i2c_set_frequency_replace = &mraa_firmata_i2c_frequency; + b->adv_func->i2c_address_replace = &mraa_firmata_i2c_address; + b->adv_func->i2c_read_replace = &mraa_firmata_i2c_read; + b->adv_func->i2c_read_byte_replace = &mraa_firmata_i2c_read_byte; + b->adv_func->i2c_read_byte_data_replace = &mraa_firmata_i2c_read_byte_data; + b->adv_func->i2c_read_word_data_replace = &mraa_firmata_i2c_read_word_data; + b->adv_func->i2c_read_bytes_data_replace = &mraa_firmata_i2c_read_bytes_data; + b->adv_func->i2c_write_replace = &mraa_firmata_i2c_write; + b->adv_func->i2c_write_byte_replace = &mraa_firmata_i2c_write_byte; + b->adv_func->i2c_write_byte_data_replace = &mraa_firmata_i2c_write_byte_data; + b->adv_func->i2c_write_word_data_replace = &mraa_firmata_i2c_write_word_data; + b->adv_func->i2c_stop_replace = &mraa_firmata_i2c_stop; +#endif + return b; +} + +mraa_platform_t +mraa_peripheralman_platform() +{ + plat = mraa_peripheralman_plat_init(); + + return MRAA_ANDROID_PERIPHERALMANAGER; +} diff --git a/src/peripheralman/peripheralman_aio.c b/src/peripheralman/peripheralman_aio.c new file mode 100644 index 0000000..ff1b3b0 --- /dev/null +++ b/src/peripheralman/peripheralman_aio.c @@ -0,0 +1,64 @@ +/* + * Author: Sanrio Alvares + * Copyright (c) 2016 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "aio.h" +#include "mraa_internal.h" +#include + +mraa_aio_context +mraa_aio_init(unsigned int aio) +{ + return NULL; +} + +unsigned int +mraa_aio_read(mraa_aio_context dev) +{ + return -1; +} + +float +mraa_aio_read_float(mraa_aio_context dev) +{ + return -1; +} + +mraa_result_t +mraa_aio_close(mraa_aio_context dev) +{ + return -1; +} + +mraa_result_t +mraa_aio_set_bit(mraa_aio_context dev, int bits) +{ + return -1; +} + +int +mraa_aio_get_bit(mraa_aio_context dev) +{ + return -1; +} + diff --git a/src/peripheralman/peripheralman_gpio.c b/src/peripheralman/peripheralman_gpio.c new file mode 100644 index 0000000..6307add --- /dev/null +++ b/src/peripheralman/peripheralman_gpio.c @@ -0,0 +1,222 @@ +/* + * Author: Constantin Musca + * Copyright (c) 2016 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +// API +#include "mraa/gpio.h" + +// mraa internals +#include "mraa_internal.h" + +extern BPeripheralManagerClient *client; +extern char **gpios; +extern int gpios_count; + +mraa_gpio_context +mraa_gpio_init_raw(int pin) +{ + return NULL; +} + +mraa_gpio_context +mraa_gpio_init(int pin) +{ + mraa_gpio_context dev; + int rc; + + if (pin > gpios_count) { + // invalid pin number specified + return NULL; + } + + if ((dev = (mraa_gpio_context)calloc(sizeof(struct _gpio), 1)) == NULL) { + return NULL; + } + + rc = BPeripheralManagerClient_openGpio(client, gpios[pin], &dev->bgpio); + if (rc != 0) { + free(dev); + return NULL; + } + dev->pin = pin; + + return dev; +} + +mraa_result_t +mraa_gpio_close(mraa_gpio_context dev) +{ + if (dev->bgpio != NULL) { + BGpio_delete(dev->bgpio); + } + + free(dev); + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_gpio_dir(mraa_gpio_context dev, mraa_gpio_dir_t dir) +{ + int rc; + + if (dev->bgpio == NULL) { + return MRAA_ERROR_INVALID_HANDLE; + } + + switch (dir) { + case MRAA_GPIO_IN: + rc = BGpio_setDirection(dev->bgpio, DIRECTION_IN); + break; + case MRAA_GPIO_OUT: + case MRAA_GPIO_OUT_HIGH: + rc = BGpio_setDirection(dev->bgpio, DIRECTION_OUT_INITIALLY_HIGH); + break; + case MRAA_GPIO_OUT_LOW: + rc = BGpio_setDirection(dev->bgpio, DIRECTION_OUT_INITIALLY_LOW); + break; + } + if (rc != 0) { + return MRAA_ERROR_INVALID_HANDLE; + } + + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_gpio_read_dir(mraa_gpio_context dev, mraa_gpio_dir_t *dir) +{ + syslog(LOG_WARNING, "gpio mraa: function not implemented in PMRAA\n"); + return MRAA_ERROR_FEATURE_NOT_IMPLEMENTED; +} + +mraa_result_t +mraa_gpio_write(mraa_gpio_context dev, int val) +{ + int rc; + + if (dev->bgpio == NULL) { + return MRAA_ERROR_INVALID_HANDLE; + } + + rc = BGpio_setValue(dev->bgpio, val); + if (rc != 0) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + return MRAA_SUCCESS; +} + +int +mraa_gpio_read(mraa_gpio_context dev) +{ + int rc, val; + + if (dev->bgpio == NULL) { + return -1; + } + + rc = BGpio_getValue(dev->bgpio, &val); + if (rc != 0) { + return -1; + } + + return val; +} + +mraa_result_t +mraa_gpio_edge_mode(mraa_gpio_context dev, mraa_gpio_edge_t mode) +{ + int rc; + + if (dev->bgpio == NULL) { + return MRAA_ERROR_INVALID_HANDLE; + } + + switch (mode) { + case MRAA_GPIO_EDGE_BOTH: + rc = BGpio_setEdgeTriggerType(dev->bgpio, BOTH_EDGE); + break; + case MRAA_GPIO_EDGE_FALLING: + rc = BGpio_setEdgeTriggerType(dev->bgpio, FALLING_EDGE); + break; + case MRAA_GPIO_EDGE_RISING: + rc = BGpio_setEdgeTriggerType(dev->bgpio, RISING_EDGE); + break; + case MRAA_GPIO_EDGE_NONE: + rc = BGpio_setEdgeTriggerType(dev->bgpio, NONE_EDGE); + break; + } + if (rc != 0) { + return MRAA_ERROR_INVALID_HANDLE; + } + + return MRAA_SUCCESS; +}; + +mraa_result_t +mraa_gpio_isr(mraa_gpio_context dev, mraa_gpio_edge_t edge, void (*fptr)(void*), void* args) +{ + return MRAA_ERROR_FEATURE_NOT_IMPLEMENTED; +} + +mraa_result_t +mraa_gpio_isr_exit(mraa_gpio_context dev) +{ + return MRAA_ERROR_FEATURE_NOT_IMPLEMENTED; +} + +mraa_result_t +mraa_gpio_owner(mraa_gpio_context dev, mraa_boolean_t own) +{ + syslog(LOG_WARNING, "gpio mraa: function not implemented in PMRAA"); + return MRAA_ERROR_FEATURE_NOT_IMPLEMENTED; +} + +mraa_result_t +mraa_gpio_mode(mraa_gpio_context dev, mraa_gpio_mode_t mode) +{ + return MRAA_ERROR_FEATURE_NOT_IMPLEMENTED; +} + +mraa_result_t +mraa_gpio_use_mmaped(mraa_gpio_context dev, mraa_boolean_t mmap_en) +{ + syslog(LOG_WARNING, "gpio mraa: function not implemented in PMRAA"); + return MRAA_ERROR_FEATURE_NOT_IMPLEMENTED; +} + +int +mraa_gpio_get_pin(mraa_gpio_context dev) +{ + return dev->pin; +} +int +mraa_gpio_get_pin_raw(mraa_gpio_context dev) +{ + syslog(LOG_WARNING, "mraa: function not implemented in PMRAA"); + return -1; +} diff --git a/src/peripheralman/peripheralman_i2c.c b/src/peripheralman/peripheralman_i2c.c new file mode 100644 index 0000000..ddad35a --- /dev/null +++ b/src/peripheralman/peripheralman_i2c.c @@ -0,0 +1,238 @@ +/* + * Author: Constantin Musca + * Copyright (c) 2016 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "i2c.h" +#include "mraa_internal.h" +#include + +extern BPeripheralManagerClient *client; +extern char **i2c_busses; +extern int i2c_busses_count; + +mraa_i2c_context mraa_i2c_init_raw(unsigned int bus) +{ + mraa_i2c_context dev; + + if ((int)bus > i2c_busses_count) { + return NULL; + } + + dev = (mraa_i2c_context) calloc(1, sizeof(struct _i2c)); + if (dev == NULL) { + syslog(LOG_CRIT, "i2c: Failed to allocate memory for context"); + return NULL; + } + + dev->busnum = bus; + return dev; +} + +mraa_i2c_context mraa_i2c_init(int bus) +{ + return mraa_i2c_init_raw(bus); +} + + +mraa_result_t +mraa_i2c_frequency(mraa_i2c_context dev, mraa_i2c_mode_t mode) +{ + return MRAA_ERROR_FEATURE_NOT_SUPPORTED; +} + +int +mraa_i2c_read(mraa_i2c_context dev, uint8_t* data, int length) +{ + int rc; + + if (dev->bi2c == NULL) { + return 0; + } + + rc = BI2cDevice_read(dev->bi2c, data, length); + + return rc; +} + +int +mraa_i2c_read_byte(mraa_i2c_context dev) +{ + int rc; + uint8_t val; + + if (dev->bi2c == NULL) { + return 0; + } + + rc = BI2cDevice_read(dev->bi2c, &val, 1); + if (rc != 0 ) { + return rc; + } + + return val; +} + +int +mraa_i2c_read_byte_data(mraa_i2c_context dev, uint8_t command) +{ + int rc; + uint8_t val; + + if (dev->bi2c == NULL) { + return 0; + } + + rc = BI2cDevice_readRegByte(dev->bi2c, command, &val); + if (rc != 0) { + return 0; + } + + return val; +} + +int +mraa_i2c_read_word_data(mraa_i2c_context dev, uint8_t command) +{ + int rc; + uint16_t val; + + if (dev->bi2c == NULL) { + return 0; + } + + rc = BI2cDevice_readRegWord(dev->bi2c, command, &val); + if (rc != 0) { + return 0; + } + + return val; +} + +int +mraa_i2c_read_bytes_data(mraa_i2c_context dev, uint8_t command, uint8_t* data, int length) +{ + int rc; + + if (dev->bi2c == NULL) { + return -1; + } + + rc = BI2cDevice_readRegBuffer(dev->bi2c, command, data, length); + + return rc; +} + +mraa_result_t +mraa_i2c_write(mraa_i2c_context dev, const uint8_t* data, int length) +{ + int rc; + + if (dev->bi2c == NULL) { + return MRAA_ERROR_INVALID_HANDLE; + } + + rc = BI2cDevice_write(dev->bi2c, data, length); + if (rc != 0) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_i2c_write_byte(mraa_i2c_context dev, const uint8_t data) +{ + return mraa_i2c_write(dev, &data, 1); +} + +mraa_result_t +mraa_i2c_write_byte_data(mraa_i2c_context dev, const uint8_t data, const uint8_t command) +{ + int rc; + + if (dev->bi2c == NULL) { + return MRAA_ERROR_INVALID_HANDLE; + } + + rc = BI2cDevice_writeRegByte(dev->bi2c, command, data); + if (rc != 0) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_i2c_write_word_data(mraa_i2c_context dev, const uint16_t data, const uint8_t command) +{ + int rc; + + if (dev->bi2c == NULL) { + return MRAA_ERROR_INVALID_HANDLE; + } + + rc = BI2cDevice_writeRegWord(dev->bi2c, command, data); + if (rc != 0) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_i2c_address(mraa_i2c_context dev, uint8_t addr) +{ + int rc; + + if (dev == NULL || dev->busnum > (int)i2c_busses_count) { + return MRAA_ERROR_INVALID_HANDLE; + } + + dev->addr = (int) addr; + + if (strlen(dev->bus_name) > 0) { + rc = BPeripheralManagerClient_openI2cDevice(client, + dev->bus_name, addr, &dev->bi2c); + } else { + rc = BPeripheralManagerClient_openI2cDevice(client, + i2c_busses[dev->busnum], addr, &dev->bi2c); + } + if (rc != 0) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + return MRAA_SUCCESS; +} + + +mraa_result_t +mraa_i2c_stop(mraa_i2c_context dev) +{ + if (dev->bi2c != NULL) { + BI2cDevice_delete(dev->bi2c); + dev->bi2c = NULL; + } + + free(dev); + return MRAA_SUCCESS; +} diff --git a/src/peripheralman/peripheralman_pwm.c b/src/peripheralman/peripheralman_pwm.c new file mode 100644 index 0000000..441aedf --- /dev/null +++ b/src/peripheralman/peripheralman_pwm.c @@ -0,0 +1,117 @@ +/* + * Author: Sanrio Alvares + * Copyright (c) 2016 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "pwm.h" +#include "mraa_internal.h" +#include + +mraa_pwm_context +mraa_pwm_init(int pin) +{ + return NULL; +} + +mraa_pwm_context +mraa_pwm_init_raw(int chipid, int pin) +{ + return NULL; +} + +mraa_result_t +mraa_pwm_write(mraa_pwm_context dev, float percentage) +{ + return -1; +} + +float +mraa_pwm_read(mraa_pwm_context dev) +{ + return -1; +} + +mraa_result_t +mraa_pwm_period(mraa_pwm_context dev, float seconds) +{ + return -1; +} + +mraa_result_t +mraa_pwm_period_ms(mraa_pwm_context dev, int ms) +{ + return -1; +} + +mraa_result_t +mraa_pwm_period_us(mraa_pwm_context dev, int us) +{ + return -1; +} + +mraa_result_t +mraa_pwm_pulsewidth(mraa_pwm_context dev, float seconds) +{ + return -1; +} + +mraa_result_t +mraa_pwm_pulsewidth_ms(mraa_pwm_context dev, int ms) +{ + return -1; +} + +mraa_result_t +mraa_pwm_pulsewidth_us(mraa_pwm_context dev, int us) +{ + return -1; +} + +mraa_result_t +mraa_pwm_enable(mraa_pwm_context dev, int enable) +{ + return -1; +} + +mraa_result_t +mraa_pwm_owner(mraa_pwm_context dev, mraa_boolean_t owner) +{ + return -1; +} + +mraa_result_t +mraa_pwm_close(mraa_pwm_context dev) +{ + return -1; +} + +int +mraa_pwm_get_max_period(mraa_pwm_context dev) +{ + return -1; +} + +int +mraa_pwm_get_min_period(mraa_pwm_context dev) +{ + return -1; +} diff --git a/src/peripheralman/peripheralman_spi.c b/src/peripheralman/peripheralman_spi.c new file mode 100644 index 0000000..14252a1 --- /dev/null +++ b/src/peripheralman/peripheralman_spi.c @@ -0,0 +1,257 @@ +/* + * Author: Constantin Musca + * Copyright (c) 2016 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "spi.h" +#include "mraa_internal.h" + +extern BPeripheralManagerClient *client; +extern char **spi_busses; +extern int spi_busses_count; + +mraa_spi_context +mraa_spi_init(int bus) +{ + int rc; + mraa_spi_context dev; + + if (bus > spi_busses_count) { + return NULL; + } + + dev = (mraa_spi_context) calloc(1, sizeof(struct _spi)); + if (dev == NULL) { + return NULL; + } + + rc = BPeripheralManagerClient_openSpiDevice(client, spi_busses[bus], &dev->bspi); + if (rc != 0) { + free(dev); + return NULL; + } + + return dev; +} + +mraa_spi_context +mraa_spi_init_raw(unsigned int bus, unsigned int cs) +{ + return NULL; +} + +mraa_result_t +mraa_spi_mode(mraa_spi_context dev, mraa_spi_mode_t mode) +{ + int rc; + + if (dev->bspi == NULL) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + switch (mode) { + case MRAA_SPI_MODE0: + rc = BSpiDevice_setMode(dev->bspi, SPI_MODE0); + break; + case MRAA_SPI_MODE1: + rc = BSpiDevice_setMode(dev->bspi, SPI_MODE1); + break; + case MRAA_SPI_MODE2: + rc = BSpiDevice_setMode(dev->bspi, SPI_MODE2); + break; + case MRAA_SPI_MODE3: + rc = BSpiDevice_setMode(dev->bspi, SPI_MODE3); + break; + default: + rc = BSpiDevice_setMode(dev->bspi, SPI_MODE0); + break; + } + if (rc != 0) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + dev->mode = mode; + + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_spi_frequency(mraa_spi_context dev, int hz) +{ + int rc; + + if (dev->bspi == NULL) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + rc = BSpiDevice_setFrequency(dev->bspi, hz); + if (rc != 0) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + dev->clock = hz; + + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_spi_lsbmode(mraa_spi_context dev, mraa_boolean_t lsb) +{ + int rc; + + if (dev->bspi == NULL) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + if (lsb) { + rc = BSpiDevice_setBitJustification(dev->bspi, SPI_LSB_FIRST); + } else { + rc = BSpiDevice_setBitJustification(dev->bspi, SPI_MSB_FIRST); + } + if (rc != 0) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + dev->lsb = lsb; + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_spi_bit_per_word(mraa_spi_context dev, unsigned int bits) +{ + if (dev->bspi == NULL) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + if (BSpiDevice_setBitsPerWord(dev->bspi, bits) != 0) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + return MRAA_SUCCESS; +} + +int +mraa_spi_write(mraa_spi_context dev, uint8_t data) +{ + int rc; + uint8_t recv = 0; + + if (dev->bspi == NULL) { + return -1; + } + + rc = BSpiDevice_transfer(dev->bspi, &data, &recv, 1); + if (rc != 0) { + return -1; + } + + return (int) recv; +} + +int +mraa_spi_write_word(mraa_spi_context dev, uint16_t data) +{ + int rc; + uint16_t recv = 0; + + if (dev->bspi == NULL) { + return -1; + } + + rc = BSpiDevice_transfer(dev->bspi, &data, &recv, 2); + if (rc != 0) { + return -1; + } + + return (int) recv; +} + +mraa_result_t +mraa_spi_transfer_buf(mraa_spi_context dev, uint8_t* data, uint8_t* rxbuf, int length) +{ + int rc; + + if (dev->bspi == NULL) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + rc = BSpiDevice_transfer(dev->bspi, data, rxbuf, length); + if (rc != 0) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_spi_transfer_buf_word(mraa_spi_context dev, uint16_t* data, uint16_t* rxbuf, int length) +{ + int rc; + + if (dev->bspi == NULL) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + // IS IT CORRECT ? + rc = BSpiDevice_transfer(dev->bspi, data, rxbuf, length * 2); + if (rc != 0) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + return MRAA_SUCCESS; +} + +uint8_t* +mraa_spi_write_buf(mraa_spi_context dev, uint8_t* data, int length) +{ + uint8_t *recv = malloc(sizeof(uint8_t) * length); + + if (mraa_spi_transfer_buf(dev, data, recv, length) != MRAA_SUCCESS) { + free(recv); + return NULL; + } + return recv; +} + +uint16_t* +mraa_spi_write_buf_word(mraa_spi_context dev, uint16_t* data, int length) +{ + uint16_t *recv = malloc(sizeof(uint16_t) * length); + + if (mraa_spi_transfer_buf_word(dev, data, recv, length) != MRAA_SUCCESS) { + free(recv); + return NULL; + } + return recv; +} + +mraa_result_t +mraa_spi_stop(mraa_spi_context dev) +{ + if (dev->bspi != NULL) { + BSpiDevice_delete(dev->bspi); + dev->bspi = NULL; + } + + free(dev); + return MRAA_SUCCESS; +} diff --git a/src/peripheralman/peripheralman_uart.c b/src/peripheralman/peripheralman_uart.c new file mode 100644 index 0000000..2984e2b --- /dev/null +++ b/src/peripheralman/peripheralman_uart.c @@ -0,0 +1,170 @@ +/* + * Author: Sanrio Alvares + * Copyright (c) 2016 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "uart.h" +#include "mraa_internal.h" +#include +#include + +extern BPeripheralManagerClient *client; +extern char **uart_devices; +extern int uart_busses_count; + +// do i need a speed(B9600) to int(9600) converter? + +mraa_uart_context +mraa_uart_init_raw(const char* path) +{ + return NULL; +} + +mraa_uart_context +mraa_uart_init(int index) +{ + int rc; + char device_name[10] = {'\0'}; + mraa_uart_context dev; + + if (index > uart_busses_count) { + return NULL; + } + + dev = (mraa_uart_context) calloc(1, sizeof(struct _uart)); + if (dev == NULL) { + return NULL; + } + + snprintf(device_name, sizeof(device_name), "UART%d", index); + + rc = BPeripheralManagerClient_openUartDevice(client, device_name, &dev->buart); + if (rc != 0) { + BUartDevice_delete(dev->buart); + free(dev); + return NULL; + } + + return dev; +} + +mraa_result_t +mraa_uart_flush(mraa_uart_context dev) +{ + return -1; +} + +mraa_result_t +mraa_uart_set_baudrate(mraa_uart_context dev, unsigned int baud) +{ + int rc; + + if (!dev) { + syslog(LOG_ERR, "uart: stop: context is NULL"); + return 0; + } + + rc = BUartDevice_setBaudrate(dev->buart, baud); + if (rc != 0) { + return 0; + } + + return MRAA_SUCCESS; +} + +int +mraa_uart_read(mraa_uart_context dev, char* buf, size_t length) +{ + int rc; + uint32_t bytes_read; + + if (dev->buart == NULL) { + return MRAA_ERROR_INVALID_HANDLE; + } + + rc = BUartDevice_read(dev->buart, buf, length, &bytes_read); + if (rc != 0) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + return bytes_read; +} + +int +mraa_uart_write(mraa_uart_context dev, const char* buf, size_t length) +{ + int rc; + uint32_t bytes_written; + + if (dev->buart == NULL) { + return MRAA_ERROR_INVALID_HANDLE; + } + + rc = BUartDevice_write(dev->buart, buf, length, &bytes_written); + if (rc != 0) { + return MRAA_ERROR_INVALID_RESOURCE; + } + + return bytes_written; +} + +mraa_result_t +mraa_uart_set_mode(mraa_uart_context dev, int bytesize, mraa_uart_parity_t parity, int stopbits) +{ + return -1; +} + +mraa_result_t +mraa_uart_set_flowcontrol(mraa_uart_context dev, mraa_boolean_t xonxoff, mraa_boolean_t rtscts) +{ + return -1; +} + +mraa_result_t +mraa_uart_set_timeout(mraa_uart_context dev, int read, int write, int interchar) +{ + return -1; +} + +mraa_result_t +mraa_uart_set_non_blocking(mraa_uart_context dev, mraa_boolean_t nonblock) +{ + return -1; +} + +const char* +mraa_uart_get_dev_path(mraa_uart_context dev) +{ + return NULL; +} + +mraa_result_t +mraa_uart_stop(mraa_uart_context dev) +{ + return -1; +} + +mraa_boolean_t +mraa_uart_data_available(mraa_uart_context dev, unsigned int millis) +{ + return 0; +} diff --git a/src/spi/spi.c b/src/spi/spi.c index d571390..15b77b4 100644 --- a/src/spi/spi.c +++ b/src/spi/spi.c @@ -29,7 +29,10 @@ #define __USE_LINUX_IOCTL_DEFS #endif #include -#if defined(MSYS) +#if defined(PERIPHERALMAN) +#include "peripheralmanager/spi_device.h" +#include "linux/spi_kernel_headers.h" +#elif defined(MSYS) // There's no spidev.h on MSYS, so we need to provide our own, // and only *after* including ioctl.h as that one contains prerequisites. #include "linux/spi_kernel_headers.h" diff --git a/src/uart/uart.c b/src/uart/uart.c index 2c6ac7f..9fe1e28 100644 --- a/src/uart/uart.c +++ b/src/uart/uart.c @@ -314,9 +314,11 @@ mraa_uart_flush(mraa_uart_context dev) return dev->advance_func->uart_flush_replace(dev); } +#if !defined(PERIPHERALMAN) if (tcdrain(dev->fd) == -1) { return MRAA_ERROR_FEATURE_NOT_SUPPORTED; } +#endif return MRAA_SUCCESS; }