Firmware for Nucleo boards for the SLab system Description at http://r6500.blogspot.com.es/2018/02/slab-first-release.html All associated files at https://github.com/R6500/SLab

Dependencies:   mbed

Revision:
1:d81bef65eece
Parent:
0:39a545e08ccd
--- a/main.cpp	Sat Feb 10 09:43:16 2018 +0000
+++ b/main.cpp	Sun Feb 11 16:14:51 2018 +0000
@@ -68,6 +68,10 @@
                  Wave play: No ADC (11us)  
                  Dual wave play: No ADC (11us)      
      
+  10/02/2018 : v1.2  
+               Addition of halt button/interrupt
+  11/02/2018 : Correction of bug in return code from dualWavePlay             
+          
 ********************************************************/
 
 #include "mbed.h"
@@ -75,7 +79,7 @@
 /***************** MAIN DEFINES *************************************/
 
 // Version string
-#define VSTRING " v1.1"
+#define VSTRING " v1.2"
 
 // Major number version changes when new commands are added
 #define VERSION 1
@@ -103,6 +107,7 @@
 #define TRAN_OK       0  // Ok
 #define TRAN_OVERRUN  1  // Sample overrun
 #define TRAN_TIMEOUT  2  // Triggered timeout
+#define TRAN_HALT     3  // Halt interrupt generated
 
 // Magic data is different for each firmware
 #define MAGIC_SIZE 4
@@ -196,6 +201,8 @@
 int w_s2 = 0;            // Secondary wavetable size (in samples)
 volatile int w_pos2 = 0; // Current secondary wave position
 
+int infiniteWave = 0;   // Flag for infinite wave play
+
 // Globals for CRC
 int crcTx,crcRx;
 
@@ -205,6 +212,15 @@
 // Indicate that board status is at reset condition
 int resetState=1;
 
+// Halt interrupt (if enabled)
+#ifdef HALT_PIN
+InterruptIn haltInt(HALT_PIN);
+#endif
+
+// Halt condition flag
+volatile int halt = 0;
+
+
 /****************** HARDWARE PROFILING *********************************/
 // Uses GPIO lines to show system activity
 
@@ -474,6 +490,12 @@
   int ia,is;    
       
   // Response code
+  if (halt)
+        {
+        sendByte(TRAN_HALT);
+        return;
+        }
+       
   if (overrun_error)
         {
         sendByte(TRAN_OVERRUN);
@@ -498,6 +520,12 @@
   int is;    
       
   // Response code
+  if (halt)
+        {
+        sendByte(TRAN_HALT);
+        return;
+        } 
+       
   if (overrun_error)
         {
         sendByte(TRAN_OVERRUN);
@@ -542,6 +570,16 @@
     return;
     }   
     
+ // Check for halt
+ if (halt)
+    {
+    // Disable ticker
+    ticR.detach();     
+    // Signal end
+    endTicker = 1;
+    PRO1_CLEAR // Profiling          
+    }       
+    
  // Check for overrun
  if (overrun)
     {
@@ -554,6 +592,8 @@
  PRO1_CLEAR            
  }    
  
+#ifdef FAST_ADC 
+ 
 // ISR for the asyncRead function
 // Optimized timing when only reading one input
 // Used only for one input and stime < 25us
@@ -581,6 +621,16 @@
     PRO1_CLEAR // Profiling   
     return;
     }   
+   
+ // Check for halt
+ if (halt)
+    {
+    // Disable ticker
+    ticR.detach();     
+    // Signal end
+    endTicker = 1;
+    PRO1_CLEAR // Profiling          
+    }   
     
  // Check for overrun
  if (overrun)
@@ -591,7 +641,9 @@
  
  PRO2_SET    // Profiling
  PRO1_CLEAR         
- }   
+ }  
+ 
+#endif  //FAST_ADC
 
 // Implements command 'Y'
 // Async read
@@ -619,6 +671,8 @@
  overrun = 0;   
  PRO2_CLEAR   // Profiling     
      
+ #ifdef FAST_ADC     
+     
  // Check if we only read one channel and stime is less than 41us
  if ((n_ai==1)&&(stime<25e-6f))
     {
@@ -633,6 +687,13 @@
     ticR.attach(&asyncReadISR,stime);
     }
  
+ #else // No FAST_ADC ISR
+ 
+ // Programs the ticker for several inputs
+ ticR.attach(&asyncReadISR,stime);
+ 
+ #endif //FAST_ADC
+ 
  // Wait till end
  while (!endTicker) { overrun = 0; PRO2_CLEAR }
  
@@ -657,6 +718,12 @@
   postsamples = n_s - presamples;   // Number of samples after trigger    
   
   // Response code
+  if (halt)
+        {
+        sendByte(TRAN_HALT);
+        return;
+        }
+  
   if (overrun_error)
         {
         sendByte(TRAN_OVERRUN);
@@ -704,6 +771,16 @@
  // Decrease timeout
  timeOut--;
  
+ // Check halt
+ if (halt)
+    {
+    // Disable ticker
+    ticR.detach();     
+    // Signal end
+    endTicker = 1;  
+    return;  
+    }
+ 
  // Check phase
  switch(samplePhase)
     {
@@ -780,6 +857,8 @@
  PRO1_CLEAR       
  }    
  
+#ifdef FAST_ADC 
+ 
 // ISR for the triggeredRead function
 // Version optimized for only one channel
 // Only used for single channel and stime < 30us
@@ -804,6 +883,16 @@
  // Decrease timeout
  timeOut--;
  
+ // Check halt
+ if (halt)
+    {
+    // Disable ticker
+    ticR.detach();     
+    // Signal end
+    endTicker = 1;  
+    return;  
+    }
+ 
  // Check phase
  switch(samplePhase)
     {
@@ -880,6 +969,8 @@
  PRO1_CLEAR       
  }   
  
+#endif //FAST_ADC 
+ 
 // Implements command 'G'
 // Triggered read
 void triggeredRead()
@@ -935,6 +1026,8 @@
  overrun_error = 0;
  overrun = 0;  
 
+ #ifdef FAST_ADC
+
  // Check if we only read one channel
  if ((n_ai==1)&&(stime<30e-6f))
     {
@@ -948,6 +1041,13 @@
     // Programs the ticker for several inputs
     ticR.attach(&triggeredReadISR,stime);
     }
+    
+ #else // No FAST_ADC code
+ 
+ // Programs the ticker for several inputs
+ ticR.attach(&triggeredReadISR,stime);
+ 
+ #endif //FAST_ADC   
   
  // Wait till end
  while (!endTicker) { overrun = 0; PRO2_CLEAR }
@@ -976,6 +1076,15 @@
  // Check trigger position
  if (samples == triggerSample) aout1 = stepValue / MAX16F;
      
+ // Check halt
+ if (halt)
+    {
+    // Disable ticker
+    ticR.detach();     
+    // Signal end
+    endTicker = 1;  
+    }     
+     
  // Check if we should end
  if (samples >= n_s)
     {
@@ -992,10 +1101,12 @@
  overrun = 1;   
  }    
 
-// ISR for the stepResponse function
-// Time optimized version
-// Only used for one channel and stime < 30us
-void stepResponseSingleISR()
+#ifdef FAST_ADC
+
+ // ISR for the stepResponse function
+ // Time optimized version
+ // Only used for one channel and stime < 30us
+ void stepResponseSingleISR()
  {
  // Direct access to ADC registers 
  ADC1->CR |= ADC_CR_ADSTART;           
@@ -1011,6 +1122,15 @@
  if (samples == triggerSample)
        DAC->DHR12R1 = (stepValue>>4);
      
+ // Check halt
+ if (halt)
+    {
+    // Disable ticker
+    ticR.detach();     
+    // Signal end
+    endTicker = 1;  
+    }       
+     
  // Check if we should end
  if (samples >= n_s)
     {
@@ -1026,6 +1146,8 @@
     
  overrun = 1;   
  }    
+ 
+#endif //FAST_ADC 
 
 // Implements command 'P'
 // Step response
@@ -1052,6 +1174,8 @@
  overrun_error = 0;
  overrun = 0;    
      
+ #ifdef FAST_ADC    
+     
  // Check if we only read one channel
  if ((n_ai==1)&&(stime<30e-6f))
     {
@@ -1065,6 +1189,13 @@
     // Programs the ticker
     ticR.attach(&stepResponseISR,stime);
     }
+    
+ #else // No FAST_ADC code
+ 
+ // Programs the ticker
+ ticR.attach(&stepResponseISR,stime);
+ 
+ #endif //FAST_ADC   
  
  // Wait till end
  while (!endTicker) overrun = 0;
@@ -1200,6 +1331,16 @@
                  
  // Check wave rollover
  // if (w_pos == w_s) w_pos = 0;
+       
+ // Check halt
+ if (halt)
+    {
+    // Disable ticker
+    ticR.detach();     
+    // Signal end
+    endTicker = 1;       
+    return;
+    }          
         
  // Check for overrun
  if (overrun)
@@ -1208,6 +1349,8 @@
  overrun = 1;   
  }    
 
+#ifdef FAST_ADC
+
 // ISR for the waveResponse function
 // Time optimized version
 // Only used for single ADC and stime < 30us
@@ -1254,12 +1397,24 @@
  // Check wave rollover
  // if (w_pos == w_s) w_pos = 0;
         
+ // Check halt
+ if (halt)
+    {
+    // Disable ticker
+    ticR.detach();     
+    // Signal end
+    endTicker = 1;       
+    return;
+    }         
+        
  // Check for overrun
  if (overrun)
     overrun_error = 1;
     
  overrun = 1;   
  }    
+ 
+#endif //FAST_ADC 
 
 // Wave response
 void waveResponse()
@@ -1284,6 +1439,8 @@
  overrun_error = 0;
  overrun = 0;
  
+ #ifdef FAST_ADC
+ 
  // Check if we only read one channel
  if ((n_ai==1)&&(stime<30e-6f))
     {
@@ -1297,6 +1454,13 @@
     // Programs the ticker
     ticR.attach(&waveResponseISR,stime);
     }
+    
+ #else //No FAST_ADC code
+ 
+ // Programs the ticker
+ ticR.attach(&waveResponseISR,stime);
+ 
+ #endif //FAST_ADC   
    
  // Wait till end
  while (!endTicker) overrun = 0;
@@ -1352,6 +1516,16 @@
  // Check wave rollover
  //if (w_pos == w_s) w_pos = 0;
            
+ // Check halt
+ if (halt)
+    {
+    // Disable ticker
+    ticR.detach();     
+    // Signal end
+    endTicker = 1;       
+    return;
+    }            
+           
  // Check for overrun
  if (overrun)
     overrun_error = 1;
@@ -1359,6 +1533,8 @@
  overrun = 1;   
  }  
  
+#ifdef FAST_ADC 
+ 
 // ISR for the dualWaveResponse function
 // Time optimized version
 // Use only for single ADC read and stime < 35us
@@ -1408,12 +1584,24 @@
  // Check wave rollover
  //if (w_pos == w_s) w_pos = 0;
            
+ // Check halt
+ if (halt)
+    {
+    // Disable ticker
+    ticR.detach();     
+    // Signal end
+    endTicker = 1;       
+    return;
+    }            
+           
  // Check for overrun
  if (overrun)
     overrun_error = 1;
     
  overrun = 1;   
  }     
+ 
+#endif //FAST_ADC 
 
 // Dual wave response
 void dualWaveResponse()
@@ -1439,6 +1627,8 @@
  overrun_error = 0;
  overrun = 0;    
  
+ #ifdef FAST_ADC
+ 
  // Check if we only read one channel
  if ((n_ai==1)&&(stime<35e-6f))
     {
@@ -1452,6 +1642,13 @@
     // Programs the ticker
     ticR.attach(&dualWaveResponseISR,stime);
     }
+    
+ #else //No FAST_ADC code
+ 
+ // Programs the ticker
+ ticR.attach(&dualWaveResponseISR,stime);
+ 
+ #endif //FAST_ADC   
    
  // Wait till end
  while (!endTicker) overrun = 0;
@@ -1518,12 +1715,24 @@
  if (overrun)
     overrun_error = 1;
     
+ // Check halt
+ if (halt)
+    {
+    // Disable ticker
+    ticR.detach();     
+    // Signal end
+    endTicker = 1;       
+    return;
+    }     
+    
  overrun = 1;  
  
  PRO2_SET
  PRO1_CLEAR
  }   
 
+#ifdef FAST_ADC
+
 // ISR for the singleWaveResponse function
 // Time optimized version
 // Only used for stime < 30us
@@ -1573,16 +1782,28 @@
                  
  // Check wave rollover
  if (w_pos == w_s) w_pos = 0;
+    
+ // Check halt
+ if (halt)
+    {
+    // Disable ticker
+    ticR.detach();     
+    // Signal end
+    endTicker = 1;       
+    return;
+    }     
         
  // Check for overrun
  if (overrun)
     overrun_error = 1;
-    
+      
  overrun = 1;  
  
  PRO2_SET
  PRO1_CLEAR
  }  
+ 
+#endif //FAST_ADC 
 
 // Select analog channel
 // In case of error, closes the communication and returns 0
@@ -1653,6 +1874,8 @@
  overrun_error = 0;
  overrun = 0;    
  
+ #ifdef FAST_ADC
+ 
  if (stime < 30e-6f)
      {
      // Programs the ticker with fast version
@@ -1663,6 +1886,13 @@
      // Programs the ticker with normal version
      ticR.attach(&singleWaveResponseISR,stime);
      }
+     
+ #else //No FAST_ADC code
+ 
+ // Programs the ticker with normal version
+ ticR.attach(&singleWaveResponseISR,stime);
+ 
+ #endif //FAST_ADC    
    
  // Wait till end
  while (!endTicker) { overrun = 0; PRO2_CLEAR }
@@ -1688,17 +1918,30 @@
  // Check wave rollover    
  if (w_pos == w_s)
      {
-     w_pos = 0;    
-     w_n--;
-     if (w_n <= 0)
-           {
-           // Disable ticker
-           ticR.detach();     
-           // Signal end
-           endTicker = 1;     
-           return;
-           }
+     w_pos = 0;   
+     if (!infiniteWave)
+        { 
+        w_n--;
+        if (w_n <= 0)
+             {
+             // Disable ticker
+             ticR.detach();     
+             // Signal end
+             endTicker = 1;     
+             return;
+             }
+        }     
      }
+     
+ // Check for halt
+ if (halt)
+      {
+      // Disable ticker
+      ticR.detach();     
+      // Signal end
+      endTicker = 1;     
+      return;    
+      }    
         
  // Check for overrun
  if (overrun)
@@ -1712,7 +1955,10 @@
  {
  PRO1_SET
  // Read number of waves to send    
- w_n = getU16();   
+ infiniteWave = 0;
+ w_n = getU16();  
+ if (w_n==0) 
+       infiniteWave = 1; 
 
  // Check of CRC
  if (!crcResponse()) return; 
@@ -1736,7 +1982,10 @@
  PRO1_CLEAR
  
  // Response code
- if (overrun_error)
+ if (halt)
+    sendByte(TRAN_HALT);
+    else    
+     if (overrun_error)
         sendByte(TRAN_OVERRUN);
         else
         sendByte(TRAN_OK);  
@@ -1762,18 +2011,31 @@
  if (w_pos == w_s)
      {
      w_pos = 0;    
-     w_n--;
-     if (w_n <= 0)
-           {
-           // Disable ticker
-           ticR.detach();     
-           // Signal end
-           endTicker = 1;     
-           }
+     if (!infiniteWave)
+        {
+        w_n--;
+        if (w_n <= 0)
+             {
+             // Disable ticker
+             ticR.detach();     
+             // Signal end
+             endTicker = 1;     
+             }
+        }     
      }
      
  // Check for secondary wave rollover
  if (w_pos2 == w_s2) w_pos2 = 0;   
+ 
+ // Check for halt
+ if (halt)
+      {
+      // Disable ticker
+      ticR.detach();     
+      // Signal end
+      endTicker = 1;     
+      return;    
+      }  
         
  // Check for overrun
  if (overrun)
@@ -1785,8 +2047,11 @@
 // Dual Wave Play
 void dualWavePlay()
  {
- // Read number of primary waves to send    
- w_n = getU16();   
+ // Read number of waves to send    
+ infiniteWave = 0;
+ w_n = getU16();  
+ if (w_n==0) 
+       infiniteWave = 1;  
 
  // Check of CRC
  if (!crcResponse()) return; 
@@ -1809,7 +2074,10 @@
  while (!endTicker) overrun = 0;
  
  // Response code
- if (overrun_error)
+ if (halt)
+    sendByte(TRAN_HALT);
+    else
+      if (overrun_error)
         sendByte(TRAN_OVERRUN);
         else
         sendByte(TRAN_OK);  
@@ -1998,6 +2266,14 @@
  #endif
  }
 
+
+// Halt funcion
+// Called when the halt interrupt is generated
+void haltFunction()
+ {
+ halt=1; // Just turn on the halt flag    
+ }
+
 // Process one character received from the PC
 void process(int car)
  {
@@ -2229,6 +2505,15 @@
  PRO1_CLEAR
  PRO2_CLEAR
  
+ // Program halt interrupt (if enabled)
+ #ifdef HALT_PIN
+   #ifdef HALT_RISING
+   haltInt.rise(&haltFunction);
+   #else
+   haltInt.fall(&haltFunction);
+   #endif
+ #endif
+ 
  // New ADC code
  //adc_init();
 
@@ -2237,6 +2522,7 @@
     {
     startRx();        // Init Rx CRC
     car = getByte();  // Get command
+    halt = 0;         // Remove halt condition if present
     process(car);     // Process command
     }
  }