Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a C wrapper #60

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@
!.vscode/extensions.json
*.code-workspace

### CLion ###
.idea/

### VisualStudioCode Patch ###
# Ignore all local history of files
.history
Expand All @@ -76,4 +79,6 @@ CMakeLists.txt.user
# End of https://www.toptal.com/developers/gitignore/api/linux,visualstudiocode,c++

build/

include/private/Model.h
cmake-build-debug/
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ add_definitions(-Wall -O2 -fPIC -g)
# Sources
set(JetsonGPIO_LIB_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/src/JetsonGPIO.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/JetsonGPIO_C_Wrapper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/MainModule.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/PWM.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/PythonFunctions.cpp
Expand Down
139 changes: 139 additions & 0 deletions include/JetsonGPIO_C_Wrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
Copyright (c) 2012-2017 Ben Croston ben@croston.org.
Copyright (c) 2019, NVIDIA CORPORATION.
Copyright (c) 2019 Jueon Park(pjueon) bluegbg@gmail.com.
Copyright (c) 2021 Adam Rasburn blackforestcheesecake@protonmail.ch

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.
*/

#ifndef JETSON_GPIO_C_WRAPPER_H
#define JETSON_GPIO_C_WRAPPER_H

#include "stdbool.h"

#ifdef __cplusplus
extern "C"
{
#endif
enum GPIONumberingModes
{
GPIO_NUMBERING_MODES_BOARD,
GPIO_NUMBERING_MODES_BCM,
GPIO_NUMBERING_MODES_TEGRA_SOC,
GPIO_NUMBERING_MODES_CVM,
GPIO_NUMBERING_MODES_None,
GPIO_NUMBERING_MODES_SIZE // has to be in here for checking if enum is changed in c header, needs to be last
// element
};

enum GPIODirections
{
GPIO_DIRECTIONS_UNKNOWN,
GPIO_DIRECTIONS_OUT,
GPIO_DIRECTIONS_IN,
GPIO_DIRECTIONS_HARD_PWM,
GPIO_DIRECTIONS_SIZE // has to be in here for checking if enum is changed in c header, needs to be last element
};
enum GPIOEdge
{
GPIO_EDGE_UNKNOWN,
GPIO_EDGE_NONE,
GPIO_EDGE_RISING,
GPIO_EDGE_FALLING,
GPIO_EDGE_BOTH,
GPIO_EDGE_SIZE // has to be in here for checking if enum is changed in c header, needs to be last element
};

// Function used to enable/disable warnings during setup and cleanup.
void gpio_setwarnings(bool state);

// Function used to set the pin numbering mode.
// Possible mode values are BOARD, BCM, TEGRA_SOC and CVM
int gpio_setmode(enum GPIONumberingModes mode);

// Function used to get the currently set pin numbering mode
enum GPIONumberingModes gpio_getmode();

/* Function used to setup individual pins as Input or Output.
direction must be IN or OUT, initial must be
HIGH or LOW and is only valid when direction is OUT
@returns 0 on success -1 on failure
*/
int gpio_setup(const char* channel, enum GPIODirections direction, int initial);

/* Function used to cleanup channels at the end of the program.
If no channel is provided, all channels are cleaned
returns 0 on success -1 on failure*/
int gpio_cleanup(const char* channel);

/* Function used to return the current value of the specified channel.
Function returns either HIGH or LOW or -1 on failure*/
int gpio_input(const char* channel);

/* Function used to set a value to a channel.
Values must be either HIGH or LOW
returns 0 on success -1 on failure*/
int gpio_output(const char* channel, int value);

/* Function used to check the currently set function of the channel specified.
returns the function of the channel according to Directions
returns -1 on failure*/
int gpio_gpio_function(const char* channel);

/* Function used to check if an event occurred on the specified channel.
Param channel must be a string.
This function return True or False
returns -1 on failure*/
int gpio_event_detected(const char* channel);

/* Function used to add a callback function to channel, after it has been
registered for events using add_event_detect()
returns 0 on success -1 on failure*/
int gpio_add_event_callback(const char* channel, void (*callback)());

/* Function used to remove a callback function previously added to detect a channel event
* returns 0 on success -1 on failure*/
int gpio_remove_event_callback(const char* channel, void (*callback)());

/* Function used to add threaded event detection for a specified gpio channel.
@channel must be a string specifying the channel
@edge must be a member of Edge
@callback (optional) may be a callback function to be called when the event is detected (or nullptr)
@bouncetime (optional) a button-bounce signal ignore time (in milliseconds, default=none)
@return 0 on success -1 on failure*/
int gpio_add_event_detect(const char* channel, enum GPIOEdge edge, void (*callback)(), unsigned long bounce_time);

/* Function used to remove event detection for channel */
void gpio_remove_event_detect(const char* channel);

/* Function used to perform a blocking wait until the specified edge event is detected within the specified
timeout period. Returns the channel if an event is detected or 0 if a timeout has occurred.
@channel is a string specifying the channel
@edge must be a member of GPIOEdge
@bouncetime in milliseconds (optional)
@timeout in milliseconds (optional)
@returns channel number if detected, 0 on timeout, -1 on failure*/
int gpio_wait_for_edge(const char* channel, enum GPIOEdge edge, unsigned long bounce_time, unsigned long timeout);

#ifdef __cplusplus
}
#endif

#endif // JETSON_GPIO_C_WRAPPER_H
220 changes: 220 additions & 0 deletions src/JetsonGPIO_C_Wrapper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
/*
Copyright (c) 2012-2017 Ben Croston ben@croston.org.
Copyright (c) 2019, NVIDIA CORPORATION.
Copyright (c) 2019 Jueon Park(pjueon) bluegbg@gmail.com.
Copyright (c) 2021 Adam Rasburn blackforestcheesecake@protonmail.ch

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 "JetsonGPIO_C_Wrapper.h"
#include "JetsonGPIO.h"
#include <iostream>

#ifdef __cplusplus
extern "C"
{
#endif

// check if enum size of c wrapper and the cpp code has the same length at compile time
__attribute__((unused)) void check_enum_equality()
{
#define CHECK_ENUM_EQUALITY_MSG "c wrapper enum must be equal to c++ enum"

static_assert(static_cast<GPIONumberingModes>(GPIO::details::enum_size<GPIO::NumberingModes>::value) ==
GPIO_NUMBERING_MODES_SIZE,
CHECK_ENUM_EQUALITY_MSG);

static_assert(static_cast<GPIODirections>(GPIO::details::enum_size<GPIO::Directions>::value) ==
GPIO_DIRECTIONS_SIZE,
CHECK_ENUM_EQUALITY_MSG);

static_assert(static_cast<GPIOEdge>(GPIO::details::enum_size<GPIO::Edge>::value) == GPIO_EDGE_SIZE,
CHECK_ENUM_EQUALITY_MSG);

#undef CHECK_ENUM_EQUALITY_MSG
}

void gpio_setwarnings(bool state) { GPIO::setwarnings(state); }

int gpio_setmode(GPIONumberingModes mode)
{
try
{
GPIO::setmode(static_cast<GPIO::NumberingModes>(mode));
return 0;
}
catch (std::exception& e)
{
std::cerr << e.what();
return -1;
}
}

GPIONumberingModes gpio_getmode() { return static_cast<GPIONumberingModes>(GPIO::getmode()); }

int gpio_setup(const char* channel, GPIODirections direction, int initial)
{
try
{
GPIO::setup(channel, static_cast<GPIO::Directions>(direction), initial);
return 0;
}
catch (std::exception& e)
{
std::cerr << e.what();
return -1;
}
}

int gpio_cleanup(const char* channel)
{
try
{
GPIO::cleanup(channel);
return 0;
}
catch (std::exception& e)
{
std::cerr << e.what();
return -1;
}
}

int gpio_input(const char* channel)
{
try
{
return GPIO::input(channel);
}
catch (std::exception& e)
{
std::cerr << e.what();
return -1;
}
}

int gpio_output(const char* channel, int value)
{
try
{
GPIO::output(channel, value);
return 0;
}
catch (std::exception& e)
{
std::cerr << e.what();
return -1;
}
}

int gpio_gpio_function(const char* channel)
{
try
{
return static_cast<int>(GPIO::gpio_function(channel));
}
catch (std::exception& e)
{
std::cerr << e.what();
return -1;
}
}

int gpio_event_detected(const char* channel)
{
try
{
return static_cast<int>(GPIO::event_detected(channel));
}
catch (std::exception& e)
{
std::cerr << e.what();
return -1;
}
}

int gpio_add_event_callback(const char* channel, void (*callback)())
{
try
{
GPIO::add_event_callback(channel, callback);
return 0;
}
catch (std::exception& e)
{
std::cerr << e.what();
return -1;
}
}

int gpio_remove_event_callback(const char* channel, void (*callback)())
{
try
{
GPIO::remove_event_callback(channel, callback);
return 0;
}
catch (std::exception& e)
{
std::cerr << e.what();
return -1;
}
}

int gpio_add_event_detect(const char* channel, GPIOEdge edge, void (*callback)(), unsigned long bounce_time)
{
try
{
GPIO::add_event_detect(channel, static_cast<GPIO::Edge>(edge), callback, bounce_time);
return 0;
}
catch (std::exception& e)
{
std::cerr << e.what();
return -1;
}
}

void gpio_remove_event_detect(const char* channel) { GPIO::remove_event_detect(channel); }

int gpio_wait_for_edge(const char* channel, GPIOEdge edge, unsigned long bounce_time, unsigned long timeout)
{
try
{
auto wait_result = GPIO::wait_for_edge(channel, static_cast<GPIO::Edge>(edge), bounce_time, timeout);
if (wait_result.is_event_detected())
{
return std::stoi(wait_result.channel());
}
else
{
return 0;
}
}
catch (std::exception& e)
{
std::cerr << e.what();
return -1;
}
}

#ifdef __cplusplus
}
#endif
Loading