Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 3:67b9a01ad7b0, committed 2013-06-19
- Comitter:
- jeroen3
- Date:
- Wed Jun 19 08:30:39 2013 +0000
- Parent:
- 2:edd6401d9aa0
- Commit message:
- Updated;
Changed in this revision
| main.cpp | Show annotated file Show diff for this revision Revisions of this file |
| xIFO.c | Show annotated file Show diff for this revision Revisions of this file |
--- a/main.cpp Fri May 31 14:45:27 2013 +0000
+++ b/main.cpp Wed Jun 19 08:30:39 2013 +0000
@@ -1,480 +1,481 @@
-/*
- * Demonstrates sending a buffer repeatedly to the DAC using DMA.
- * Connect an oscilloscope to Mbed pin 18. This example doesn't
- * output anything else (nothing on any serial ports).
- */
-#include "mbed.h"
-#include "MODDMA.h"
-#include <cmath>
-#include "watchdog.h"
-#include "xifo.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-Serial pc(USBTX, USBRX);
-Serial sr(p9, p10);
-Watchdog wdt;
-
-const double PI = 3.141592653589793238462;
-const float PI_F = 3.14159265358979f;
-
-// Make the buffer size match the number of degrees
-// in a circle since we are going to output a sinewave.
-#define BUFFER_SIZE 360
-
-// Set DAC output power mode.
-#define DAC_POWER_MODE (1 << 16)
-
-DigitalOut led1(LED1);
-DigitalOut led2(LED2);
-DigitalOut led3(LED3);
-DigitalOut led4(LED4);
-DigitalIn modesel(p22); // mode selector
-DigitalInOut trigger(p21); // sync trigger output
-
-uint32_t buffer[3][BUFFER_SIZE];
-
-AnalogOut signal(p18);
-
-MODDMA dma;
-MODDMA_Config *conf0, *conf1, *conf2, *conf3;
-
-// Config phase (2*pi is one period)
-double phase_master = PI * 1;
-double phase_slave = PI * 1;
-// Config amplitude, x * 3.3 Volt
-double amplitude_master = 1;
-double amplitude_slave = 1;
-// Config frequency, (if using synchronisation these must be identical)
-double freq_master = 50;
-double freq_slave = freq_master;
-// copy calc buffer[2] to ch0/1
-volatile uint32_t toch0 = 0;
-volatile uint32_t toch1 = 0;
-// Mode typedef
-typedef enum {MASTER, SLAVE} modesel_t;
-modesel_t mode;
-// Ringbuffer for cmd
-xifo_t com;
-xifo_pool_t compool[128];
-
-/* Dma callbacks */
-void TC0_callback(void);
-void ERR0_callback(void);
-
-void TC1_callback(void);
-void ERR1_callback(void);
-
-// Sync function
-void wait_for_sync(){
- switch(mode){
- case MASTER:
- // Wait a few clocks to make sure slave is waiting
- for(uint32_t i=0; i<10; i++){ __NOP(); __NOP(); __NOP(); __NOP(); }
- // Trigger toggle
- LPC_GPIO2->FIOPIN ^= (1<<5);
- break;
- case SLAVE:
- // Wait for pinchange
- {
- uint32_t pinstate = trigger;
- while( pinstate == trigger);
- }
- break;
- }
-}
-
-// Calculate function
-void calculate_sines(){
- // Create a sinewave buffer for testing.
- switch(mode){
- case MASTER:
- for (int i = 0; i <= 359; i++)
- {
- double rads = (PI/180.0 * i);
- buffer[0][i] = amplitude_master * (512*( sin( rads + phase_master ) ))+512;
- }
- break;
- case SLAVE:
- for (int i = 0; i <= 359; i++)
- {
- double rads = (PI/180.0 * i);
- buffer[0][i] = amplitude_slave * (512 * sin(rads + phase_slave)) + 512;
- }
- break;
- }
-
- // Adjust the sinewave buffer for use with DAC hardware.
- for (int i = 0; i < 360; i++) {
- if( buffer[0][i] > 1023 ) buffer[0][i] = 1023;
- buffer[0][i] = DAC_POWER_MODE | ((buffer[0][i] << 6) & 0xFFC0);
- buffer[1][i] = buffer[0][i]; // Just create a copy of buffer0 to continue sinewave.
- }
-}
-
-void copycallback(){
- if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
-}
-
-// Main
-int main() {
- volatile int life_counter = 0;
- pc.baud(115200);
-
- if(modesel == 1){
- pc.printf("slave\r\n");
- trigger.input();
- mode = SLAVE;
- led2 = 0;
- }else{
- pc.printf("master\r\n");
- trigger.output();
- led2 = 1;
- mode = MASTER;
- // Print command set
- pc.printf("Command descriptions: <[master][slave]><[frequency][amplitude][phase]> <number>\r\n");
- pc.printf("Commands: <[m][s]><[f][a][p]> <n>\r\n");
- pc.printf("Min F = 1.02 Hz\r\n");
- pc.printf("Max F limited to synchronisation and DAC speed (200 Hz with sync, max 1000 Hz without)\r\n");
- }
-
- calculate_sines();
-
- // Prepare the GPDMA system for buffer0.
- conf0 = new MODDMA_Config;
- conf0
- ->channelNum ( MODDMA::Channel_0 )
- ->srcMemAddr ( (uint32_t) &buffer[0] )
- ->dstMemAddr ( MODDMA::DAC )
- ->transferSize ( 360 )
- ->transferType ( MODDMA::m2p )
- ->dstConn ( MODDMA::DAC )
- ->attach_tc ( &TC0_callback )
- ->attach_err ( &ERR0_callback )
- ; // config end
-
- // Prepare the GPDMA system for buffer1.
- conf1 = new MODDMA_Config;
- conf1
- ->channelNum ( MODDMA::Channel_1 )
- ->srcMemAddr ( (uint32_t) &buffer[1] )
- ->dstMemAddr ( MODDMA::DAC )
- ->transferSize ( 360 )
- ->transferType ( MODDMA::m2p )
- ->dstConn ( MODDMA::DAC )
- ->attach_tc ( &TC1_callback )
- ->attach_err ( &ERR1_callback )
- ; // config end
-
-
- // Calculating the transfer frequency:
- // By default, the Mbed library sets the PCLK_DAC clock value
- // to 24MHz. One complete sinewave cycle in each buffer is 360
- // points long. So, for a 1Hz wave we would need to transfer 360
- // values per second. That would be 24000000/360 which is approx
- // 66,666. But that's no good! The count val is only 16bits in size
- // so bare this in mind. If you need to go slower you will need to
- // alter PCLK_DAC from CCLK/4 to CCLK/8.
- // For our demo we are going to have the sinewave run at 1kHz.
- // That's 24000000/360000 which is approx 66. Experimentation
- // however showed 65 to get closer to 1kHz (on my Mbed and scope
- // at least).
- const double dacclk = 24000000;
- const double dacper = dacclk / 360;
- double ddacdiv;
- switch(mode){
- case MASTER:
- ddacdiv = dacper / (freq_master);
- break;
- case SLAVE:
- ddacdiv = dacper / (freq_slave);
- break;
- }
- unsigned int dacdiv = ddacdiv;
- LPC_DAC->DACCNTVAL = dacdiv; // 6500 for 10Hz
-
- // Watchdogtimer to reset if sync failed
- wdt.kick(10.0*(1.0/(dacper/ddacdiv)));
-
- // Prepare first configuration.
- if (!dma.Prepare( conf0 )) {
- error("Doh!");
- }
- // Wait period for master (slaves waits for sync)
- if(mode == MASTER){
- wait(0.1);
- }
- wait_for_sync();
-
- // Begin (enable DMA and counter). Note, don't enable
- // DBLBUF_ENA as we are using DMA double buffering.
- LPC_DAC->DACCTRL |= (3UL << 2);
-
- // Disable copy calc buffer flags
- toch0 = 0;
- toch1 = 0;
-
- // Create ringbuffer for parsing
- xifo_init(&com, 128, (uint32_t *)&compool);
- xifo_clear(&com);
- uint32_t do_calc=0;
-
- while (1) {
- // There's not a lot to do as DMA and interrupts are
- // now handling the buffer transfers. So we'll just
- // flash led1 to show the Mbed is alive and kicking.
- if (life_counter++ > 1000000) {
- led1 = !led1; // Show some sort of life.
- life_counter = 0;
- }
-
- /* Do UART data processing */
- if(mode==MASTER){
- while(pc.readable()){
- xifo_write(&com, pc.getc());
- }
- while(sr.readable()){
- pc.putc(sr.getc());
- }
- }else{
- while(sr.readable()){
- xifo_write(&com, sr.getc());
- }
- }
-
-
-
- { /* BLOCK with command parsing */
- uint32_t do_parse=0;
- // 123456.123456 accurate
- char number[13] = {0,0,0,0,0,0,0,0,0,0,0,0,0};
- uint32_t p=0;
- // Only parse USB master commands on master mode
- if(mode==MASTER){
- // MASTER mode
- if( xifo_read_mr(&com,0) == '\n'){
- xifo_pop_mr(&com);
- // We have a line
- if( xifo_read_lr(&com,0)== 's' ){ // Slave
- xifo_pop_lr(&com);
- pc.printf("Slave ");
- // command for slave, forward over serial sr
- while(xifo_get_used(&com))
- sr.putc(xifo_pop_lr(&com));
- sr.putc('\n');
- xifo_init(&com, 128, (uint32_t *)&compool);
- xifo_clear(&com);
- } else if( xifo_read_lr(&com,0) == 'm' ){ // Master
- xifo_pop_lr(&com);
- pc.printf("Master ");
- // master
- // Parsing
- do_parse =1;
- } else if( xifo_read_lr(&com,0) == 'f' ){ // Frequency on MASTER and SLAVE
- // Parse data
- xifo_pop_lr(&com); // space
- // Get number
- while( xifo_get_used(&com) && p < sizeof(number))
- number[p++] = (char)xifo_pop_lr(&com);
- freq_master = strtod(number,0);
- int t = dacper / (freq_master);
- pc.printf("Master Frequency %f, approximate: %f\nSlave ", freq_master, dacper/t);
- sr.printf("f %f\n", freq_master);
- do_calc = 1;
- } else {
- pc.printf("fout ");
- while(xifo_get_used(&com))
- pc.putc(xifo_pop_lr(&com));
- pc.putc('\n');
- xifo_init(&com, 128, (uint32_t *)&compool);
- xifo_clear(&com);
- }}
- }else{
- // SLAVE mode
- if( xifo_read_mr(&com,0) == '\n'){
- xifo_pop_mr(&com);
- do_parse = 1;
- }
- }
- if(do_parse){
- do_parse=0;
-
- // Parse data
- char filter = xifo_pop_lr(&com);
- xifo_pop_lr(&com) ; // space
- // Get number
- while( xifo_get_used(&com) && p < sizeof(number))
- number[p++] = (char)xifo_pop_lr(&com);
-
- if(mode==MASTER){
- // frequency
- if( filter == 'f' ){
- freq_master = strtod(number,0);
- int t = dacper / (freq_master);
- pc.printf("Frequency %f, approximate: %f\n", freq_master, dacper/t);
- do_calc = 1;
- }else{
- // amplitude
- if( filter == 'a'){
- amplitude_master = strtod(number,0);
- pc.printf("Amplitude %f\n", amplitude_master);
- do_calc = 1;
- }else{
- // phase
- if( filter == 'p' ){
- phase_master = strtod(number,0) * PI;
- pc.printf("Phase %f\n", phase_master);
- do_calc = 1;
- } else{
- pc.printf("fout ");
- while(xifo_get_used(&com))
- pc.putc(xifo_pop_lr(&com));
- pc.putc('\n');
- xifo_init(&com, 128, (uint32_t *)&compool);
- xifo_clear(&com);
- }}}
- }else{
- // frequency
- if( filter == 'f' ){
- freq_slave = strtod(number,0);
- int t = dacper / (freq_slave);
- sr.printf("Frequency %f, approximate: %f\n", freq_slave, dacper/t);
- do_calc = 1;
- }else{
- // amplitude
- if( filter == 'a'){
- amplitude_slave = strtod(number,0);
- sr.printf("Amplitude %f\n", amplitude_slave);
- do_calc = 1;
- }else{
- // phase
- if( filter == 'p' ){
- phase_slave = strtod(number,0) * PI;
- sr.printf("Phase %f\n", phase_slave);
- do_calc = 1;
- } else{
- sr.printf("fout ");
- while(xifo_get_used(&com))
- sr.putc(xifo_pop_lr(&com));
- sr.putc('\n');
- xifo_init(&com, 128, (uint32_t *)&compool);
- xifo_clear(&com);
- }}}
- }
- }
- } /* BLOCK with command parsing */
-
- // recalculate
- if(do_calc){
- do_calc = 0;
- // only continue if previous update is complete
- if( !toch0 && !toch1 ){
- // calc frequency
- switch(mode){
- case MASTER:
- ddacdiv = dacper / (freq_master);
- //pc.printf("set dacdiv to %f\n",ddacdiv);
- break;
- case SLAVE:
- ddacdiv = dacper / (freq_slave);
- break;
- }
- unsigned int dacdiv = ddacdiv;
- LPC_DAC->DACCNTVAL = dacdiv; // 6500 for 10Hz
- wdt.kick(10.0*(1.0/(dacper/ddacdiv)));
- // calculate_sines sine
- switch(mode){
- case MASTER:
- for (int i = 0; i <= 359; i++)
- {
- double rads = (PI/180.0 * i);
- buffer[2][i] = amplitude_master * (512 * sin( rads + phase_master)) + 512;
- }
- break;
- case SLAVE:
- for (int i = 0; i <= 359; i++)
- {
- double rads = (PI/180.0 * i);
- buffer[2][i] = amplitude_slave * (512 * sin( rads + phase_slave)) + 512;
- }
- break;
- }
- // Adjust the sinewave buffer for use with DAC hardware.
- for (int i = 0; i < 360; i++) {
- if( buffer[2][i] > 1023 ) buffer[2][i] = 1023;
- buffer[2][i] = DAC_POWER_MODE | ((buffer[2][i] << 6) & 0xFFC0);
- }
- toch0 = 1;
- toch1 = 1;
- }
- }
- }
-}
-
-// Configuration callback on TC
-void TC0_callback(void) {
-
- // Just show sending buffer0 complete.
- led3 = !led3;
-
- // Implement wait for trigger if slave mode
- wait_for_sync();
- wdt.kick();
-
- // Get configuration pointer.
- MODDMA_Config *config = dma.getConfig();
-
- // Finish the DMA cycle by shutting down the channel.
- dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
-
- // Swap to buffer1
- dma.Prepare( conf1 );
-
- // Clear DMA IRQ flags.
- if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
-
- // Copy to channel 0?
- if ( toch0 ){
- for (int i = 0; i <= 359; i++) buffer[0][i] = buffer[2][i];
- toch0=0;
- }
-}
-
-// Configuration callback on Error
-void ERR0_callback(void) {
- error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
-}
-
-// Configuration callback on TC
-void TC1_callback(void) {
- // Just show sending buffer1 complete.
- led4 = !led4;
-
- // Implement wait for trigger if slave mode
- wait_for_sync();
- wdt.kick();
-
- // Get configuration pointer.
- MODDMA_Config *config = dma.getConfig();
-
- // Finish the DMA cycle by shutting down the channel.
- dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
-
- // Swap to buffer0
- dma.Prepare( conf0 );
-
- // Clear DMA IRQ flags.
- if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
-
- // Copy to channel 1?
- if ( toch1 ){
- for (int i = 0; i <= 359; i++) buffer[1][i] = buffer[2][i];
- toch1=0;
- }
-}
-
-// Configuration callback on Error
-void ERR1_callback(void) {
- error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
-}
+/*
+ * 2 Channel DAC WaveSimulator with 2 lpc1768 mbed's.
+ * Command line or GUI controlled.
+ */
+
+#include "mbed.h"
+#include "MODDMA.h"
+#include <cmath>
+#include "watchdog.h"
+#include "xIFO.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+Serial pc(USBTX, USBRX);
+Serial sr(p9, p10);
+Watchdog wdt;
+
+const double PI = 3.141592653589793238462;
+const float PI_F = 3.14159265358979f;
+
+// Make the buffer size match the number of degrees
+// in a circle since we are going to output a sinewave.
+#define BUFFER_SIZE 360
+
+// Set DAC output power mode.
+#define DAC_POWER_MODE (1 << 16)
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+DigitalIn modesel(p22); // mode selector
+DigitalInOut trigger(p21); // sync trigger output
+
+uint32_t buffer[3][BUFFER_SIZE];
+
+AnalogOut signal(p18); /* Do not forget output RC filter! */
+
+MODDMA dma;
+MODDMA_Config *conf0, *conf1, *conf2, *conf3;
+
+// Config phase (2*pi is one period)
+double phase_master = PI * 1;
+double phase_slave = PI * 1;
+// Config amplitude, x * 3.3 Volt
+double amplitude_master = 0.75;
+double amplitude_slave = 0.75;
+// Config frequency, (if using synchronisation these must be identical)
+double freq_master = 50;
+double freq_slave = freq_master;
+// copy calc buffer[2] to ch0/1
+volatile uint32_t toch0 = 0;
+volatile uint32_t toch1 = 0;
+// Mode typedef
+typedef enum {MASTER, SLAVE} modesel_t;
+modesel_t mode;
+// Ringbuffer for cmd
+xifo_t com;
+xifo_pool_t compool[128];
+
+/* Dma callbacks */
+void TC0_callback(void);
+void ERR0_callback(void);
+
+void TC1_callback(void);
+void ERR1_callback(void);
+
+// Sync function
+void wait_for_sync(){
+ switch(mode){
+ case MASTER:
+ // Wait a few clocks to make sure slave is waiting
+ for(uint32_t i=0; i<10; i++){ __NOP(); __NOP(); __NOP(); __NOP(); }
+ // Trigger toggle
+ LPC_GPIO2->FIOPIN ^= (1<<5);
+ break;
+ case SLAVE:
+ // Wait for pinchange
+ {
+ uint32_t pinstate = trigger;
+ while( pinstate == trigger);
+ }
+ break;
+ }
+}
+
+// Calculate function
+void calculate_sines(){
+ // Create a sinewave buffer for testing.
+ switch(mode){
+ case MASTER:
+ for (int i = 0; i <= 359; i++)
+ {
+ double rads = (PI/180.0 * i);
+ buffer[0][i] = amplitude_master * (512*( cos( rads + phase_master ) ))+512;
+ }
+ break;
+ case SLAVE:
+ for (int i = 0; i <= 359; i++)
+ {
+ double rads = (PI/180.0 * i);
+ buffer[0][i] = amplitude_slave * (512 * cos(rads + phase_slave)) + 511;
+ }
+ break;
+ }
+
+ // Adjust the sinewave buffer for use with DAC hardware.
+ for (int i = 0; i < 360; i++) {
+ if( buffer[0][i] > 1023 ) buffer[0][i] = 1023;
+ buffer[0][i] = DAC_POWER_MODE | ((buffer[0][i] << 6) & 0xFFC0);
+ buffer[1][i] = buffer[0][i]; // Just create a copy of buffer0 to continue sinewave.
+ }
+}
+
+void copycallback(){
+ if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
+}
+
+// Main
+int main() {
+ volatile int life_counter = 0;
+ pc.baud(115200);
+
+ if(modesel == 1){
+ pc.printf("slave\r\n");
+ trigger.input();
+ mode = SLAVE;
+ led2 = 0;
+ }else{
+ pc.printf("master\r\n");
+ trigger.output();
+ led2 = 1;
+ mode = MASTER;
+ // Print command set
+ pc.printf("Command descriptions: <[master][slave]><[frequency][amplitude][phase]> <number>\r\n");
+ pc.printf("Commands: <[m][s]><[f][a][p]> <n>\r\n");
+ pc.printf("Min F = 1.02 Hz\r\n");
+ pc.printf("Max F limited to synchronisation and DAC speed (200 Hz with sync, max 1000 Hz without)\r\n");
+ }
+
+ calculate_sines();
+
+ // Prepare the GPDMA system for buffer0.
+ conf0 = new MODDMA_Config;
+ conf0
+ ->channelNum ( MODDMA::Channel_0 )
+ ->srcMemAddr ( (uint32_t) &buffer[0] )
+ ->dstMemAddr ( MODDMA::DAC )
+ ->transferSize ( 360 )
+ ->transferType ( MODDMA::m2p )
+ ->dstConn ( MODDMA::DAC )
+ ->attach_tc ( &TC0_callback )
+ ->attach_err ( &ERR0_callback )
+ ; // config end
+
+ // Prepare the GPDMA system for buffer1.
+ conf1 = new MODDMA_Config;
+ conf1
+ ->channelNum ( MODDMA::Channel_1 )
+ ->srcMemAddr ( (uint32_t) &buffer[1] )
+ ->dstMemAddr ( MODDMA::DAC )
+ ->transferSize ( 360 )
+ ->transferType ( MODDMA::m2p )
+ ->dstConn ( MODDMA::DAC )
+ ->attach_tc ( &TC1_callback )
+ ->attach_err ( &ERR1_callback )
+ ; // config end
+
+
+ // Calculating the transfer frequency:
+ // By default, the Mbed library sets the PCLK_DAC clock value
+ // to 24MHz. One complete sinewave cycle in each buffer is 360
+ // points long. So, for a 1Hz wave we would need to transfer 360
+ // values per second. That would be 24000000/360 which is approx
+ // 66,666. But that's no good! The count val is only 16bits in size
+ // so bare this in mind. If you need to go slower you will need to
+ // alter PCLK_DAC from CCLK/4 to CCLK/8.
+ // For our demo we are going to have the sinewave run at 1kHz.
+ // That's 24000000/360000 which is approx 66. Experimentation
+ // however showed 65 to get closer to 1kHz (on my Mbed and scope
+ // at least).
+ const double dacclk = 24000000;
+ const double dacper = dacclk / 360;
+ double ddacdiv;
+ switch(mode){
+ case MASTER:
+ ddacdiv = dacper / (freq_master);
+ break;
+ case SLAVE:
+ ddacdiv = dacper / (freq_slave);
+ break;
+ }
+ unsigned int dacdiv = ddacdiv;
+ LPC_DAC->DACCNTVAL = dacdiv; // 6500 for 10Hz
+
+ // Watchdogtimer to reset if sync failed
+ wdt.kick(10.0*(1.0/(dacper/ddacdiv)));
+
+ // Prepare first configuration.
+ if (!dma.Prepare( conf0 )) {
+ error("Doh!");
+ }
+ // Wait period for master (slaves waits for sync)
+ if(mode == MASTER){
+ wait(0.1);
+ }
+ wait_for_sync();
+
+ // Begin (enable DMA and counter). Note, don't enable
+ // DBLBUF_ENA as we are using DMA double buffering.
+ LPC_DAC->DACCTRL |= (3UL << 2);
+
+ // Disable copy calc buffer flags
+ toch0 = 0;
+ toch1 = 0;
+
+ // Create ringbuffer for parsing
+ xifo_init(&com, 128, (uint32_t *)&compool);
+ xifo_clear(&com);
+ uint32_t do_calc=0;
+
+ while (1) {
+ // There's not a lot to do as DMA and interrupts are
+ // now handling the buffer transfers. So we'll just
+ // flash led1 to show the Mbed is alive and kicking.
+ if (life_counter++ > 1000000) {
+ //led1 = !led1; // Show some sort of life.
+ life_counter = 0;
+ }
+
+ /* Do UART data processing */
+ if(mode==MASTER){
+ while(pc.readable()){
+ xifo_write(&com, pc.getc());
+ }
+ while(sr.readable()){
+ pc.putc(sr.getc());
+ }
+ }else{
+ while(sr.readable()){
+ xifo_write(&com, sr.getc());
+ }
+ }
+
+
+
+ { /* BLOCK with command parsing */
+ uint32_t do_parse=0;
+ // 123456.123456 accurate
+ char number[13] = {0,0,0,0,0,0,0,0,0,0,0,0,0};
+ uint32_t p=0;
+ // Only parse USB master commands on master mode
+ if(mode==MASTER){
+ // MASTER mode
+ if( xifo_read_mr(&com,0) == '\n'){
+ xifo_pop_mr(&com);
+ // We have a line
+ if( xifo_read_lr(&com,0)== 's' ){ // Slave
+ xifo_pop_lr(&com);
+ pc.printf("Slave ");
+ // command for slave, forward over serial sr
+ while(xifo_get_used(&com))
+ sr.putc(xifo_pop_lr(&com));
+ sr.putc('\n');
+ xifo_init(&com, 128, (uint32_t *)&compool);
+ xifo_clear(&com);
+ } else if( xifo_read_lr(&com,0) == 'm' ){ // Master
+ xifo_pop_lr(&com);
+ pc.printf("Master ");
+ // master
+ // Parsing
+ do_parse =1;
+ } else if( xifo_read_lr(&com,0) == 'f' ){ // Frequency on MASTER and SLAVE
+ // Parse data
+ xifo_pop_lr(&com); // space
+ // Get number
+ while( xifo_get_used(&com) && p < sizeof(number))
+ number[p++] = (char)xifo_pop_lr(&com);
+ freq_master = strtod(number,0);
+ int t = dacper / (freq_master);
+ pc.printf("Master Frequency %f, approximate: %f\nSlave ", freq_master, dacper/t);
+ sr.printf("f %f\n", freq_master);
+ do_calc = 1;
+ } else {
+ pc.printf("fout ");
+ while(xifo_get_used(&com))
+ pc.putc(xifo_pop_lr(&com));
+ pc.putc('\n');
+ xifo_init(&com, 128, (uint32_t *)&compool);
+ xifo_clear(&com);
+ }}
+ }else{
+ // SLAVE mode
+ if( xifo_read_mr(&com,0) == '\n'){
+ xifo_pop_mr(&com);
+ do_parse = 1;
+ }
+ }
+ if(do_parse){
+ do_parse=0;
+
+ // Parse data
+ char filter = xifo_pop_lr(&com);
+ xifo_pop_lr(&com) ; // space
+ // Get number
+ while( xifo_get_used(&com) && p < sizeof(number))
+ number[p++] = (char)xifo_pop_lr(&com);
+
+ if(mode==MASTER){
+ // frequency
+ if( filter == 'f' ){
+ freq_master = strtod(number,0);
+ int t = dacper / (freq_master);
+ pc.printf("Frequency %f, approximate: %f\n", freq_master, dacper/t);
+ do_calc = 1;
+ }else{
+ // amplitude
+ if( filter == 'a'){
+ amplitude_master = strtod(number,0);
+ pc.printf("Amplitude %f\n", amplitude_master);
+ do_calc = 1;
+ }else{
+ // phase
+ if( filter == 'p' ){
+ phase_master = strtod(number,0) * PI;
+ pc.printf("Phase %f\n", phase_master);
+ do_calc = 1;
+ } else{
+ pc.printf("fout ");
+ while(xifo_get_used(&com))
+ pc.putc(xifo_pop_lr(&com));
+ pc.putc('\n');
+ xifo_init(&com, 128, (uint32_t *)&compool);
+ xifo_clear(&com);
+ }}}
+ }else{
+ // frequency
+ if( filter == 'f' ){
+ freq_slave = strtod(number,0);
+ int t = dacper / (freq_slave);
+ sr.printf("Frequency %f, approximate: %f\n", freq_slave, dacper/t);
+ do_calc = 1;
+ }else{
+ // amplitude
+ if( filter == 'a'){
+ amplitude_slave = strtod(number,0);
+ sr.printf("Amplitude %f\n", amplitude_slave);
+ do_calc = 1;
+ }else{
+ // phase
+ if( filter == 'p' ){
+ phase_slave = strtod(number,0) * PI;
+ sr.printf("Phase %f\n", phase_slave);
+ do_calc = 1;
+ } else{
+ sr.printf("fout ");
+ while(xifo_get_used(&com))
+ sr.putc(xifo_pop_lr(&com));
+ sr.putc('\n');
+ xifo_init(&com, 128, (uint32_t *)&compool);
+ xifo_clear(&com);
+ }}}
+ }
+ }
+ } /* BLOCK with command parsing */
+
+ // recalculate
+ if(do_calc){
+ do_calc = 0;
+ // only continue if previous update is complete
+ if( !toch0 && !toch1 ){
+ // calc frequency
+ switch(mode){
+ case MASTER:
+ ddacdiv = dacper / (freq_master);
+ //pc.printf("set dacdiv to %f\n",ddacdiv);
+ break;
+ case SLAVE:
+ ddacdiv = dacper / (freq_slave);
+ break;
+ }
+ unsigned int dacdiv = ddacdiv;
+ LPC_DAC->DACCNTVAL = dacdiv; // 6500 for 10Hz
+ wdt.kick(10.0*(1.0/(dacper/ddacdiv)));
+ // calculate_sines sine
+ switch(mode){
+ case MASTER:
+ for (int i = 0; i <= 359; i++)
+ {
+ double rads = (PI/180.0 * i);
+ buffer[2][i] = amplitude_master * (512 * cos( rads + phase_master)) + 512;
+ }
+ break;
+ case SLAVE:
+ for (int i = 0; i <= 359; i++)
+ {
+ double rads = (PI/180.0 * i);
+ buffer[2][i] = amplitude_slave * (512 * cos( rads + phase_slave)) + 512;
+ }
+ break;
+ }
+ // Adjust the sinewave buffer for use with DAC hardware.
+ for (int i = 0; i < 360; i++) {
+ if( buffer[2][i] > 1023 ) buffer[2][i] = 1023;
+ buffer[2][i] = DAC_POWER_MODE | ((buffer[2][i] << 6) & 0xFFC0);
+ }
+ toch0 = 1;
+ toch1 = 1;
+ }
+ }
+ }
+}
+
+// Configuration callback on TC
+void TC0_callback(void) {
+
+ // Just show sending buffer0 complete.
+ led3 = !led3;
+
+ // Implement wait for trigger if slave mode
+ wait_for_sync();
+ wdt.kick();
+
+ // Get configuration pointer.
+ MODDMA_Config *config = dma.getConfig();
+
+ // Finish the DMA cycle by shutting down the channel.
+ dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
+
+ // Swap to buffer1
+ dma.Prepare( conf1 );
+
+ // Clear DMA IRQ flags.
+ if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
+
+ // Copy to channel 0?
+ if ( toch0 ){
+ for (int i = 0; i <= 359; i++) buffer[0][i] = buffer[2][i];
+ toch0=0;
+ }
+}
+
+// Configuration callback on Error
+void ERR0_callback(void) {
+ error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
+}
+
+// Configuration callback on TC
+void TC1_callback(void) {
+ // Just show sending buffer1 complete.
+ //led4 = !led4;
+
+ // Implement wait for trigger if slave mode
+ wait_for_sync();
+ wdt.kick();
+
+ // Get configuration pointer.
+ MODDMA_Config *config = dma.getConfig();
+
+ // Finish the DMA cycle by shutting down the channel.
+ dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
+
+ // Swap to buffer0
+ dma.Prepare( conf0 );
+
+ // Clear DMA IRQ flags.
+ if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
+
+ // Copy to channel 1?
+ if ( toch1 ){
+ for (int i = 0; i <= 359; i++) buffer[1][i] = buffer[2][i];
+ toch1=0;
+ }
+}
+
+// Configuration callback on Error
+void ERR1_callback(void) {
+ error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
+}
+
--- a/xIFO.c Fri May 31 14:45:27 2013 +0000
+++ b/xIFO.c Wed Jun 19 08:30:39 2013 +0000
@@ -11,7 +11,7 @@
*
* @{
*/
-#include "xifo.h"
+#include "xIFO.h"
/**
* @brief Initialise buffer object structure.