From 9a9bdf5dd29423f3080f66b423c332ff84715294 Mon Sep 17 00:00:00 2001 From: Helge Brueger <noreply@fortiss.org> Date: Tue, 6 Jun 2017 19:08:36 +0000 Subject: [PATCH] Added untested pwm code and fixed some bugs refs 7890 --- .../trunk/META-INF/MANIFEST.MF | 3 - .../trunk/lib/inc/PWM.h | 36 ++++++++ .../trunk/lib/inc/libmaestro.h | 12 +++ .../trunk/lib/src/Gamepad.c | 3 + .../trunk/lib/src/PWM.c | 83 +++++++++++++++++++ .../trunk/lib/src/libmaestro.c | 36 ++++++++ .../trunk/lib/src/main.c | 5 +- .../executable/PWMActuatorExecutable.java | 14 ++-- .../executable/RaspberryPIExecutable.java | 19 +---- 9 files changed, 183 insertions(+), 28 deletions(-) create mode 100644 org.fortiss.af3.platform.raspberry/trunk/lib/inc/libmaestro.h create mode 100644 org.fortiss.af3.platform.raspberry/trunk/lib/src/libmaestro.c diff --git a/org.fortiss.af3.platform.raspberry/trunk/META-INF/MANIFEST.MF b/org.fortiss.af3.platform.raspberry/trunk/META-INF/MANIFEST.MF index 9faccfe4..0b3651d7 100644 --- a/org.fortiss.af3.platform.raspberry/trunk/META-INF/MANIFEST.MF +++ b/org.fortiss.af3.platform.raspberry/trunk/META-INF/MANIFEST.MF @@ -8,9 +8,6 @@ Bundle-Vendor: fortiss GmbH Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Export-Package: org.fortiss.af3.platform.raspberry.model, - org.fortiss.af3.platform.raspberry.model.annotation, - org.fortiss.af3.platform.raspberry.model.annotation.impl, - org.fortiss.af3.platform.raspberry.model.annotation.util, org.fortiss.af3.platform.raspberry.model.gamepad, org.fortiss.af3.platform.raspberry.model.gamepad.impl, org.fortiss.af3.platform.raspberry.model.gamepad.util, diff --git a/org.fortiss.af3.platform.raspberry/trunk/lib/inc/PWM.h b/org.fortiss.af3.platform.raspberry/trunk/lib/inc/PWM.h index e69de29b..6519009a 100644 --- a/org.fortiss.af3.platform.raspberry/trunk/lib/inc/PWM.h +++ b/org.fortiss.af3.platform.raspberry/trunk/lib/inc/PWM.h @@ -0,0 +1,36 @@ +#ifndef __PWM_H +#define __PWM_H + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <termios.h> +#include <fcntl.h> +#include <sys/stat.h> + +#include "inc-gen/data_dictionary.h" +#include "inc/libmaestro.h" + +// macros +#define PWM_ADJUST_VALUE(x) (6000 + 4 * x / 66) + +// types +typedef unsigned char PWM_CHANNEL_T; + +// constants +extern const int PWM_SLEEP_TIME; +extern const char* PWM_DEVICE_NAME; +extern const size_t PWM_MAX_NO_CHANNELS; + +// worker +void* pwm_worker(void* pt_args); + +// init, term +void pwm_init(PWM_CHANNEL_T channel); +void pwm_term(PWM_CHANNEL_T channel); + +// writers +void pwm_write(PWM_CHANNEL_T channel, GEN_TYPE_int value); +void pwm_set_noval(PWM_CHANNEL_T channel); + +#endif // __PWM_H diff --git a/org.fortiss.af3.platform.raspberry/trunk/lib/inc/libmaestro.h b/org.fortiss.af3.platform.raspberry/trunk/lib/inc/libmaestro.h new file mode 100644 index 00000000..22f83e05 --- /dev/null +++ b/org.fortiss.af3.platform.raspberry/trunk/lib/inc/libmaestro.h @@ -0,0 +1,12 @@ +#ifndef __LIBMAESTRO_H +#define __LIBMAESTRO_H + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <termios.h> + +int maestroRead(int fd, unsigned char channel); +int maestroWrite(int fd, unsigned char channel, unsigned short target); + +#endif // __LIBMAESTRO_H diff --git a/org.fortiss.af3.platform.raspberry/trunk/lib/src/Gamepad.c b/org.fortiss.af3.platform.raspberry/trunk/lib/src/Gamepad.c index 59f79911..a97edf9e 100644 --- a/org.fortiss.af3.platform.raspberry/trunk/lib/src/Gamepad.c +++ b/org.fortiss.af3.platform.raspberry/trunk/lib/src/Gamepad.c @@ -56,6 +56,8 @@ void* gp_worker(void* pt_args) { } } + close(fd); + return NULL; } @@ -67,6 +69,7 @@ void gp_init() { // important, since all btns are accessing the same method if(gp_initialized) return; + gp_initialized = true; // TODO initialize... } diff --git a/org.fortiss.af3.platform.raspberry/trunk/lib/src/PWM.c b/org.fortiss.af3.platform.raspberry/trunk/lib/src/PWM.c index e69de29b..ea6ace0f 100644 --- a/org.fortiss.af3.platform.raspberry/trunk/lib/src/PWM.c +++ b/org.fortiss.af3.platform.raspberry/trunk/lib/src/PWM.c @@ -0,0 +1,83 @@ +#include "inc/PWM.h" + +// constants +const int PWM_SLEEP_TIME = 50000; +const char* PWM_DEVICE_NAME = "/dev/ttyACM0"; +const size_t PWM_MAX_NO_CHANNELS = 4; + +// worker +GEN_TYPE_boolean pwm_is_running = true; + +GEN_TYPE_int* pwm_channel_values; +GEN_TYPE_boolean* pwm_channel_enabled; + +void pwm_send(int fd) { + size_t i; + + for(i = 0; i < PWM_MAX_NO_CHANNELS; i++) { + if(pwm_channel_enabled[i]) { + maestroWrite(fd, i, pwm_channel_values[i]); + } + } +} + +void* pwm_worker(void* pt_args) { + int fd = open(PWM_DEVICE_NAME, O_RDWR | O_NOCTTY); + + if (fd == -1) { + perror("Error while connecting to pwm device"); + return NULL; + } + + struct termios options; + tcgetattr(fd, &options); + options.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + options.c_oflag &= ~(ONLCR | OCRNL); + tcsetattr(fd, TCSANOW, &options); + + while(pwm_is_running) { + pwm_send(fd); + usleep(PWM_SLEEP_TIME); + } + + close(fd); + + return NULL; +} + +// init, term +GEN_TYPE_boolean pwm_initialized = false; +GEN_TYPE_boolean pwm_terminated = false; + +void pwm_init(PWM_CHANNEL_T channel) { + // important, since all btns are accessing the same method + if(!pwm_initialized) { + pwm_channel_values = calloc(sizeof(GEN_TYPE_int), PWM_MAX_NO_CHANNELS); + pwm_channel_enabled = calloc(sizeof(GEN_TYPE_boolean), PWM_MAX_NO_CHANNELS); + + pwm_initialized = true; + } + + pwm_channel_enabled[channel] = true; +} + +void pwm_term(PWM_CHANNEL_T channel) { + // important, since all pwms are accessing the same method + if(!pwm_terminated) return; + + free(pwm_channel_values); + free(pwm_channel_enabled); + + pwm_is_running = false; + pwm_terminated = true; +} + +// writers +void pwm_write(PWM_CHANNEL_T channel, GEN_TYPE_int value) { + pwm_channel_values[channel] = PWM_ADJUST_VALUE(value); +} + +void pwm_set_noval(PWM_CHANNEL_T channel) { + // do nothing, not used +} + diff --git a/org.fortiss.af3.platform.raspberry/trunk/lib/src/libmaestro.c b/org.fortiss.af3.platform.raspberry/trunk/lib/src/libmaestro.c new file mode 100644 index 00000000..356d5692 --- /dev/null +++ b/org.fortiss.af3.platform.raspberry/trunk/lib/src/libmaestro.c @@ -0,0 +1,36 @@ +#include "inc/libmaestro.h" + +// read from channel given a file descriptor +int maestroRead(int fd, unsigned char channel) { + unsigned char command[] = {0x90, channel}; + + if(write(fd, command, sizeof(command)) == -1) + { + perror("error writing"); + return -1; + } + + unsigned char response[2]; + + if(read(fd,response,2) != 2) + { + perror("Error reading from maestro"); + return -1; + } + + return response[0] + 256*response[1]; +} + +// write target to a channel given a file descriptor +// the units of 'target' are quarter-microseconds +int maestroWrite(int fd, unsigned char channel, unsigned short target) { + unsigned char command[] = {0x84, channel, (target & 0x7F), (target >> 7 & 0x7F)}; + + if (write(fd, command, sizeof(command)) == -1) + { + perror("Error writing to maestro"); + return -1; + } + + return 0; +} diff --git a/org.fortiss.af3.platform.raspberry/trunk/lib/src/main.c b/org.fortiss.af3.platform.raspberry/trunk/lib/src/main.c index 45c91f7e..f927d2eb 100644 --- a/org.fortiss.af3.platform.raspberry/trunk/lib/src/main.c +++ b/org.fortiss.af3.platform.raspberry/trunk/lib/src/main.c @@ -8,6 +8,7 @@ #include "inc-gen/system.h" #include "inc/Gamepad.h" +#include "inc/PWM.h" int main(int argc, char* argv[]) { // start a gamepad thread @@ -15,8 +16,8 @@ int main(int argc, char* argv[]) { pthread_create(&pt_gamepad, NULL, gp_worker, NULL); // start a rover thread - //pthread_t pt_rover; - //pthread_create(&pt_rover, NULL, rover_main, NULL); + pthread_t pt_pwm; + pthread_create(&pt_pwm, NULL, pwm_worker, NULL); // run endlessly while(1) { diff --git a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/PWMActuatorExecutable.java b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/PWMActuatorExecutable.java index 6ae59325..34c1cb46 100644 --- a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/PWMActuatorExecutable.java +++ b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/PWMActuatorExecutable.java @@ -17,10 +17,12 @@ $Id: codetemplates.xml 1 2011-01-01 00:00:01Z hoelzl $ +--------------------------------------------------------------------------*/ package org.fortiss.af3.platform.raspberry.generator.executable; +import static org.fortiss.af3.expression.utils.ExpressionModelElementFactory.funcCall; +import static org.fortiss.af3.expression.utils.ExpressionModelElementFactory.intConst; + import org.fortiss.af3.component.model.OutputPort; import org.fortiss.af3.expression.model.terms.IExpressionTerm; import org.fortiss.af3.platform.generic.generator.executable.GenericTransmitterExecutable; -import org.fortiss.af3.platform.model.generic.GenericReceiver; import org.fortiss.af3.platform.model.generic.GenericTransmitter; import org.fortiss.af3.platform.raspberry.model.ActuatorPWM; import org.fortiss.af3.platform.raspberry.model.annotation.Channel; @@ -44,28 +46,28 @@ public class PWMActuatorExecutable extends GenericTransmitterExecutable { /** {@inheritDoc} */ @Override public IExpressionTerm getInitialization() { - return super.getInitialization(); + return funcCall("pwm_init", intConst(getPWMChannelFromModelElement(modelElement))); } /** {@inheritDoc} */ @Override public IExpressionTerm getNoValWriteAccessor(OutputPort logicalSignal) { - return super.getNoValWriteAccessor(logicalSignal); + return funcCall("pwm_set_noval", intConst(getPWMChannelFromModelElement(modelElement))); } /** {@inheritDoc} */ @Override public IExpressionTerm getTermination() { - return super.getTermination(); + return funcCall("pwm_term", intConst(getPWMChannelFromModelElement(modelElement))); } /** {@inheritDoc} */ @Override public IExpressionTerm getValueWriteAccessor(OutputPort logicalSignal, IExpressionTerm value) { - return super.getValueWriteAccessor(logicalSignal, value); + return funcCall("pwm_write", intConst(getPWMChannelFromModelElement(modelElement)), value); } - private int getPWMChannelFromModelElement(GenericReceiver modelElement) { + private int getPWMChannelFromModelElement(GenericTransmitter modelElement) { return AnnotationUtils.getAnnotation(modelElement, Channel.class).getChannel(); } } diff --git a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/RaspberryPIExecutable.java b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/RaspberryPIExecutable.java index 6bd049f7..caeeca62 100644 --- a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/RaspberryPIExecutable.java +++ b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/RaspberryPIExecutable.java @@ -79,21 +79,8 @@ public class RaspberryPIExecutable extends GenericExecutionUnitExecutable { super.createExecutionUnitSourcePackage(name, deployedComponents, deployedPorts, context); - // TODO: doesn't work since not recognized by configure script - - // add src-lib/inc-lib sub packages (= folders in deployment) - // CSourcePackage sub = - // AF3GeneratorCommonLanguagesCFactory.eINSTANCE.createCSourcePackage(); - // sub.setBaseLocation(SRC_LIB_SUB_PACKAGE_NAME); - // pkg.getSubPackages().add(sub); - - // sub = AF3GeneratorCommonLanguagesCFactory.eINSTANCE.createCSourcePackage(); - // sub.setBaseLocation(INC_LIB_SUB_PACKAGE_NAME); - // pkg.getSubPackages().add(sub); - // get system.h to add references to self-defined inc files SourceUnit system = pkg.getSrcGenPackage().findSourceUnitByName("system.c"); - // pkg.getIncGenPackage().findSourceUnitByName("system.h"); // Add source/header files here to be copied into the deployment directory try { @@ -116,13 +103,11 @@ public class RaspberryPIExecutable extends GenericExecutionUnitExecutable { /** LIBRARIES **/ - // TODO: will fail during a build since not defined in Makefile - // add UART lib - // addFile(pkg, "inc-lib/uart.h"); - // addFile(pkg, "src-lib/uart.c"); addFile(pkg, "inc/libuart.h"); addFile(pkg, "src/libuart.c"); + addFile(pkg, "inc/libmaestro.h"); + addFile(pkg, "src/libmaestro.c"); /** FIXES AND PATCHES **/ -- GitLab