Mercurial > hg > beaglert
changeset 18:31503d9de101 matrix_gpio
- digitalWrite and analogWrite macros are now persistent: they write a value on the given channel from the current frame to the end of the buffer. When
this is not needed you can use digitalWriteFrame and analogWriteFrame instead.
- included the matrix_gpio_demo code
- the Eclipe project is somehow broken
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Thu, 30 Apr 2015 16:02:47 +0100 |
parents | 85e8b08a7471 |
children | c98863e63174 |
files | .cproject include/Utilities.h projects/matrix_gpio_demo/main.cpp projects/matrix_gpio_demo/render.cpp |
diffstat | 4 files changed, 221 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/.cproject Mon Apr 27 18:27:04 2015 +0100 +++ b/.cproject Thu Apr 30 16:02:47 2015 +0100 @@ -5,16 +5,16 @@ <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.528876549" moduleId="org.eclipse.cdt.core.settings" name="Debug"> <externalSettings/> <extensions> - <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/> <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/> </extensions> </storageModule> <storageModule moduleId="cdtBuildSystem" version="4.0.0"> - <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.528876549" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug"> + <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.528876549" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug" postbuildStep="ssh root@192.168.7.2 "kill -s 2 \`pidof matrixGpioDemo\` 2>/dev/null"; scp matrixGpioDemo root@192.168.7.2:~/beaglert/ ; echo 'done copying' | wall "> <folderInfo id="cdt.managedbuild.config.gnu.exe.debug.528876549." name="/" resourcePath=""> <toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.681872250" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug"> <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.295375065" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/> @@ -29,7 +29,9 @@ <option id="gnu.cpp.compiler.exe.debug.option.optimization.level.2006448218" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.more" valueType="enumerated"/> <option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1267706246" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/> <option id="gnu.cpp.compiler.option.include.paths.2031219124" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath"> + <listOptionValue builtIn="false" value="/import/teaching/ECS732/arm-gcc/arm-linux-gnueabihf/include/xenomai/include"/> <listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/xenomai/include"/> + <listOptionValue builtIn="false" value="/import/teaching/ECS732/arm-gcc/arm-linux-gnueabihf/include"/> <listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/ne10"/> </option> <option id="gnu.cpp.compiler.option.other.other.1516989263" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" value="-c -fmessage-length=0 -Wpointer-arith -Wunused-result -D_GNU_SOURCE -D_REENTRANT -D__XENO__" valueType="string"/> @@ -41,6 +43,8 @@ <option id="gnu.c.compiler.exe.debug.option.debugging.level.471732683" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/> <option id="gnu.c.compiler.option.include.paths.358825414" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath"> <listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/xenomai/include"/> + <listOptionValue builtIn="false" value="/import/teaching/ECS732/arm-gcc/arm-linux-gnueabihf/include"/> + <listOptionValue builtIn="false" value="/import/teaching/ECS732/arm-gcc/arm-linux-gnueabihf/include/xenomai/include"/> <listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/ne10"/> </option> <option id="gnu.c.compiler.option.misc.other.835792865" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0 -Wpointer-arith -Wunused-result -D_GNU_SOURCE -D_REENTRANT -D__XENO__ -std=gnu99" valueType="string"/> @@ -49,9 +53,15 @@ </tool> <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.214461086" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug"/> <tool command="arm-linux-gnueabihf-g++" id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.1669966018" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug"> - <option id="gnu.cpp.link.option.paths.462980690" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths"/> + <option id="gnu.cpp.link.option.paths.462980690" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths"> + <listOptionValue builtIn="false" value="/usr/xenomai/lib"/> + <listOptionValue builtIn="false" value="/usr/local/linaro/arm-linux-gnueabihf/include/xenomai/lib"/> + <listOptionValue builtIn="false" value="/import/teaching/ECS732/arm-gcc/arm-linux-gnueabihf/lib"/> + <listOptionValue builtIn="false" value="/usr/lib/arm-linux-gnueabihf"/> + <listOptionValue builtIn="false" value="/import/teaching/ECS732/arm-gcc/arm-linux-gnueabihf/lib/xenomai"/> + </option> <option id="gnu.cpp.link.option.libs.139390951" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs"/> - <option id="gnu.cpp.link.option.flags.2096887116" name="Linker flags" superClass="gnu.cpp.link.option.flags" value="-pthread -rdynamics" valueType="string"/> + <option id="gnu.cpp.link.option.flags.2096887116" name="Linker flags" superClass="gnu.cpp.link.option.flags" value="-pthread -rdynamic" valueType="string"/> <option id="gnu.cpp.link.option.userobjs.537608578" name="Other objects" superClass="gnu.cpp.link.option.userobjs" valueType="userObjs"> <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/libprussdrv.a}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/libNE10.a}""/> @@ -73,7 +83,7 @@ <sourceEntries> <entry excluding="audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/> - <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects/basic_analog_output"/> + <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="source"/> </sourceEntries> </configuration> </storageModule> @@ -83,12 +93,12 @@ <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.1521194538" moduleId="org.eclipse.cdt.core.settings" name="Release"> <externalSettings/> <extensions> - <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/> <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/> </extensions> </storageModule> <storageModule moduleId="cdtBuildSystem" version="4.0.0">
--- a/include/Utilities.h Mon Apr 27 18:27:04 2015 +0100 +++ b/include/Utilities.h Thu Apr 30 16:02:47 2015 +0100 @@ -16,18 +16,31 @@ // Read an analog input from input pin p at frame f #define analogRead(p, f) (matrixIn[(f)*gNumMatrixChannels + (p)]) // Write an analog output frame at output pin p, frame f, to value v -#define analogWrite(p, f, v) (matrixOut[(f)*gNumMatrixChannels + (p)] = (uint16_t)(v)) +#define analogWriteFrame(p, f, v) (matrixOut[(f)*gNumMatrixChannels + (p)] = (v)) +#define analogWrite(pin, frame, value) \ +(({do {\ + for (int _privateI=(frame); _privateI<numMatrixFrames; _privateI++){ \ + analogWriteFrame(pin,_privateI,value); \ + }\ + } while (0);}),(void)0)\ #define setBit(word,bit) ((word)|(1<<(bit))) #define clearBit(word,bit) ((word)&~(1<<(bit))) #define getBit(word,bit) (((word)>>(bit))&1) #define changeBit(word,bit,value) ((clearBit((word),(bit))) | ((value)<<(bit))) //matrixGpio API: -#define setDigitalDirection(pin,frame,direction) matrixGpio[(frame)]=changeBit(matrixGpio[(frame)],(pin),(direction)) +#define setDigitalDirectionFrame(pin,frame,direction) matrixGpio[(frame)]=changeBit(matrixGpio[(frame)],(pin),(direction)) +#define setDigitalDirection(pin,frame,direction) (for(int _privateI=(frame);_privateI<gNumGpioFrames;_privateI++) matrixGpio[_privateI]=changeBit(matrixGpio[(_privateI)],(pin),(direction))),void(0) #define digitalWriteAll(frame,value) matrixGpio[(frame)]=0xffff0000*(!(!value)); //sets the bit in the high word, clears the bit in the low word (just in case the direction was not previously set) -#define digitalWrite(pin, frame, value) matrixGpio[(frame)]=( changeBit(matrixGpio[(frame)], (pin+16), (value)) & (0xffffffff-(1<<(pin))) ) //could have been done with two subsequent assignments -#define digitalRead(pin, frame) ( getBit(matrixGpio[(frame)], pin+16) ) +#define digitalWriteFrame(pin, frame, value) matrixGpio[(frame)]=( changeBit(matrixGpio[(frame)], (pin+16), (value)) & (0xffffffff-(1<<(pin))) ) //could have been done with two subsequent assignments +#define digitalWrite(pin, frame, value) \ + (({do {\ + for (int _privateI=(frame); _privateI<gNumMatrixGpioFrames; _privateI++) \ + digitalWriteFrame(pin,_privateI,value); \ + } while (0);}),(void)0)\ + +#define digitalRead(pin, frame) ( getBit(matrixGpio[(frame)], pin+16) ) float map(float x, float in_min, float in_max, float out_min, float out_max); float constrain(float x, float min_val, float max_val);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/projects/matrix_gpio_demo/main.cpp Thu Apr 30 16:02:47 2015 +0100 @@ -0,0 +1,107 @@ +/* + * assignment1_crossover + * RTDSP 2015 + * + * First assignment for ECS732 RTDSP, to implement a 2-way audio crossover + * using the BeagleBone Black. + * + * Andrew McPherson and Victor Zappi + * Queen Mary, University of London + */ + +#include <iostream> +#include <cstdlib> +#include <libgen.h> +#include <signal.h> +#include <getopt.h> +#include "../include/RTAudio.h" +#include <unistd.h> +#include <stdlib.h> +#include <fcntl.h> + +using namespace std; + +// Handle Ctrl-C by requesting that the audio rendering stop +void interrupt_handler(int var) +{ + gShouldStop = true; +} + +// Print usage information +void usage(const char * processName) +{ + cerr << "Usage: " << processName << " [options]" << endl; + + BeagleRT_usage(); + + cerr << " --help [-h]: Print this menu\n"; +} + +int main(int argc, char *argv[]) +{ + RTAudioSettings settings; // Standard audio settings + float frequency = 1000.0; // Frequency of crossover + + struct option customOptions[] = + { + {"help", 0, NULL, 'h'}, + {"frequency", 1, NULL, 'f'}, + {NULL, 0, NULL, 0} + }; + + // Set default settings + BeagleRT_defaultSettings(&settings); + + // Parse command-line arguments + while (1) { + int c; + if ((c = BeagleRT_getopt_long(argc, argv, "hf:", customOptions, &settings)) < 0) + break; + switch (c) { + case 'h': + usage(basename(argv[0])); + exit(0); + case 'f': + frequency = atof(optarg); + if(frequency < 20.0) + frequency = 20.0; + if(frequency > 5000.0) + frequency = 5000.0; + break; + case '?': + default: + usage(basename(argv[0])); + exit(1); + } + } + + // Initialise the PRU audio device + if(BeagleRT_initAudio(&settings, &frequency) != 0) { + cout << "Error: unable to initialise audio" << endl; + return -1; + } + + // Start the audio device running + if(BeagleRT_startAudio()) { + cout << "Error: unable to start real-time audio" << endl; + return -1; + } + + // Set up interrupt handler to catch Control-C + signal(SIGINT, interrupt_handler); + signal(SIGTERM, interrupt_handler); + + // Run until told to stop + while(!gShouldStop) { + usleep(100000); + } + + // Stop the audio device + BeagleRT_stopAudio(); + + // Clean up any resources allocated for audio + BeagleRT_cleanupAudio(); + + // All done! + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/projects/matrix_gpio_demo/render.cpp Thu Apr 30 16:02:47 2015 +0100 @@ -0,0 +1,81 @@ +/* + * + * First assignment for ECS732 RTDSP, to implement a 2-way audio crossover + * using the BeagleBone Black. + * + * Andrew McPherson and Victor Zappi + * Queen Mary, University of London + */ + +#include "../include/render.h" +#include <cmath> +#include <rtdk.h> + +/* TASK: declare any global variables you need here */ + +// initialise_render() is called once before the audio rendering starts. +// Use it to perform any initialisation and allocation which is dependent +// on the period size or sample rate. +// +// userData holds an opaque pointer to a data structure that was passed +// in from the call to initAudio(). +// +// Return true on success; returning false halts the program. +int gNumMatrixGpioFrames=0; +bool initialise_render(int numMatrixChannels, int numMatrixGpioChannels, int numAudioChannels, + int numMatrixFramesPerPeriod, + int numAudioFramesPerPeriod, + float matrixSampleRate, float audioSampleRate, + void *userData) +{ + gNumMatrixChannels=numMatrixChannels; + return true; +} + +// render() is called regularly at the highest priority by the audio engine. +// Input and output are given from the audio hardware and the other +// ADCs and DACs (if available). If only audio is available, numMatrixFrames +// will be 0. + +long int gCountFrames=0; +void render(int numMatrixFrames, int numMatrixGpioFrames, int numAudioFrames, float *audioIn, float *audioOut, + float *matrixIn, float *matrixOut, uint32_t *matrixGpio) +/* + * Hey, expect buffer underruns to happen here, as we are doing lots of printfs + * */ +{ + gNumMatrixGpioFrames=numMatrixGpioFrames; + if(gCountFrames==0){ //this will be executed only on the first call to render(), but the bits will go through this cycle for every subsequent buffer + // that is, P8_29 will pulse at the beginning of each buffer + } + for(int i=1; i<gNumMatrixGpioFrames; i++) + digitalWriteAll(i, GPIO_LOW); //write all channels on the given frame. Initialize them to zero + digitalWrite(0, 4, GPIO_HIGH); // set pin 0 HIGH from the current frame to the end of the buffer + for(int n=0; n<numMatrixFrames; n++) { + for(int c=0; c<gNumMatrixChannels; c++) + analogWriteFrame(c,n,0); //set channel c on frame n to 0, equivalent to matrixOut[n*numMatrixChannels+c]=0; + } + analogWrite(0,3,0.2); //set channel 0 to 0.2 from frame 3 onwards ... + analogWrite(1,3,0.7); //set channel 1 to 0.7 from frame 3 onwards ... + analogWrite(2,6,0.5); //set channel 2 to 0.5 from frame 6 onwards ... + for(int n=0; n<numAudioFrames; n++){ + printf("Digital frame %d: 0x%08x;\n",n,matrixGpio[n]); + } + for(int n=0; n<numMatrixFrames; n++){ + printf("Analog out frame %d :",n); + for(int c=0; c<gNumMatrixChannels; c++) + printf("%.1f ",matrixOut[n*gNumMatrixChannels + c]); + printf("\n"); + } +} +// cleanup_render() is called once at the end, after the audio has stopped. +// Release any resources that were allocated in initialise_render(). + +void cleanup_render() +{ + /* TASK: + * If you allocate any memory, be sure to release it here. + * You may or may not need anything in this function, depending + * on your implementation. + */ +}