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 &quot;kill -s 2 \`pidof matrixGpioDemo\` 2&gt;/dev/null&quot;; scp matrixGpioDemo root@192.168.7.2:~/beaglert/ ; echo 'done copying' | wall&#10;">
 					<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="&quot;${workspace_loc:/${ProjName}/libprussdrv.a}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/libNE10.a}&quot;"/>
@@ -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.
+	 */
+}