Skip to content
Snippets Groups Projects
Commit 9a9bdf5d authored by fortissBot's avatar fortissBot
Browse files

Added untested pwm code and fixed some bugs

refs 7890
parent b925034f
No related branches found
No related tags found
No related merge requests found
Showing
with 183 additions and 28 deletions
......@@ -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,
......
#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
#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
......@@ -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...
}
......
#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
}
#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;
}
......@@ -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) {
......
......@@ -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();
}
}
......@@ -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 **/
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment