Motoo Tanaka / Mbed 2 deprecated oscilloscope Featured

Dependencies:   SPI_STMPE610 UniGraphic mbed vt100

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /** mbed oscilloscope my implementation of a oscillo scope
00002  * Copyright (c) 2014, 2015 Motoo Tanaka @ Design Methodology Lab
00003  *
00004  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00005  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00006  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00007  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00008  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00009  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00010  * THE SOFTWARE.
00011  */
00012 #include "mbed.h"
00013 #include <ILI9341.h>
00014 #include "Arial12x12.h"
00015 #include "Arial24x23.h"
00016 #include "Arial28x28.h"
00017 #include "Arial43x48_numb.h"
00018 #include "SPI_STMPE610.h"
00019 #include "vt100.h"
00020 #include "TFTMenu.h"
00021 #include "menu.h"
00022 #include "trig.h"
00023 #include "view.h"
00024 #include "main.h"
00025 
00026 vt100 tty ;
00027 AnalogIn *ach[NUM_MAX_ANALOG_CH] ;
00028 Ticker timer ;
00029 DigitalOut tsc_cs(PIN_CS_TSC, 1) ;
00030 DigitalOut backlight(PIN_BL_TFT, 0) ;
00031 
00032 ILI9341 TFT(SPI_8, 10000000, 
00033     PIN_MOSI, PIN_MISO,  PIN_SCLK, 
00034     PIN_CS_TFT, PIN_RESET_TFT, PIN_DC_TFT, "Adafruit2.8") ;
00035 SPI_STMPE610 TSC(PIN_MOSI, PIN_MISO, PIN_SCLK, PIN_CS_TSC) ;
00036 TFTMenuItem *menu[NUM_MAX_MENU] ;
00037 int numMenu = 0 ;
00038 
00039 float vref = 3.28 ; // input range 0 - 3.3V
00040 uint16_t udata[2][NUM_MAX_ANALOG_CH][CHART_LEN] ; // data storage ;
00041 uint16_t bor[2] = {0, 0} ; // begin of ring buffer 
00042 int data_index = 0 ;
00043 int numAnalogIn = 2 ;
00044 int memLength = CHART_LEN ;
00045 int us_interval = MIN_INTERVAL ; // 20us = 50KHz
00046 bool frame_full = false ;
00047 int page = 0 ; // 
00048 int prev_page = 0 ;
00049 int mode = MODE_RUN ;
00050 
00051 void sampleAD(void) ;
00052 void drawMenu(void) ;
00053 // void eraseGraphFrames(void) ;
00054 
00055 /**
00056  * u2v unsigned int data value to voltage conversion 
00057  */
00058 float u2v(uint16_t uvalue)
00059 {
00060     return( vref * (float)uvalue / 65535.0 ) ;
00061 }
00062 
00063 /**
00064  * v2u voltage to unsigned int data conversion
00065  */
00066 uint16_t v2u(float voltage)
00067 {
00068     return(0xFFFF * voltage / vref) ;
00069 }
00070 
00071 /**
00072  * u2f unsigned int to float (0 - 1.0) conversion
00073  */
00074 float u2f(uint16_t value)
00075 {
00076     return( (float)value / 65535.0 ) ;
00077 }
00078 
00079 void initADC(void)
00080 {
00081     if (numAnalogIn > 0) {
00082         ach[0] = new AnalogIn(PIN_ADC_CH0) ;
00083     }
00084     if (numAnalogIn > 1) {
00085         ach[1] = new AnalogIn(PIN_ADC_CH1) ;
00086     }
00087 
00088 #if defined (TARGET_KL25Z)
00089     ADC0->CFG1 = ADC0->CFG1 & (
00090         ~(
00091           0x80 // LDLPC = 0 ; no low-power mode
00092         | 0x60 // ADIV = 1
00093         | 0x10 // Sample time short
00094         | 0x03 // input clock = BUS CLK
00095         )
00096     ) ; // clkdiv <= 1
00097     ADC0->CFG2 = ADC0->CFG2 
00098         | 0x03 ; // Logsample Time 11 = 2 extra ADCK
00099     ADC0->SC3 = ADC0->SC3 
00100         & (~(0x03)) ; // hardware avarage off
00101 #endif
00102 #if defined (TARGET_MAX32600MBED)
00103     uint32_t *pga_ctrl = (uint32_t*)0x40054004 ; /* ADC_PGA_CTRL */
00104     printf("PGA_CTRL(before) = 0x%08X\n", *pga_ctrl) ;
00105 //    *pga_ctrl |= 0x02 ; /* clear bit[1:0] to set gain x1 (default) */
00106 //    *pga_ctrl |= 0x40 ; /* skip PGA */
00107     printf("PGA_CTRL(after) = 0x%08X\n", *pga_ctrl) ;
00108 #endif
00109 }
00110 
00111 void envChanged(void)
00112 {
00113     timer.detach() ;
00114     
00115     eraseGraphFrames() ;
00116     drawGraphFrames() ;
00117     
00118     data_index = 0 ;
00119     page = 0 ; 
00120     prev_page = 0 ;
00121     frame_full = false ;
00122     if (trig_mode == TRIG_MODE_NONE) {
00123         sampling_status = ST_TRIG_HIT ;
00124         post_trig_index = 0 ;
00125     } else {
00126         sampling_status = ST_PRE_TRIG ;
00127     }
00128 /*
00129     if (mode == MODE_RUN) {
00130         timer.attach_us(&sampleAD, us_interval) ;
00131     }
00132 */
00133 }
00134 
00135 bool checkTrigger(void)
00136 {
00137     bool result = false ;
00138     int prev_index ;
00139     uint16_t current, prev ;
00140     if (data_index > 0) {
00141         prev_index = data_index - 1 ;
00142     } else {
00143         prev_index = memLength - 1 ; // memLength - 1 ;
00144     }
00145     current = udata[page][trig_ch][data_index] ;
00146     prev = udata[page][trig_ch][prev_index] ;
00147     
00148     switch(trig_mode) {
00149     case TRIG_MODE_NONE: // no trigger, return true at the beggining 
00150         trig_index = 0 ;
00151         result = true ;
00152         break ;
00153     case TRIG_MODE_RISE:
00154         if ((prev < utrig_level)&&(utrig_level <= current)) {
00155             result = true ;
00156         }
00157         break ;
00158     case TRIG_MODE_FALL:
00159         if ((prev > utrig_level)&&(utrig_level >= current)) {
00160             result = true ;
00161         } 
00162         break ;
00163     case TRIG_MODE_LEVEL:
00164         if (current > trig_level_margin) {
00165             if (((current + trig_level_margin) >= utrig_level)&&(utrig_level >= (current - trig_level_margin))) {
00166                 result = true ;
00167             }
00168         } else {
00169             if ((current + trig_level_margin) >= utrig_level) {
00170                 result = true ;
00171             }
00172         }
00173         break ;
00174     default:
00175         printf("Error: Unknown trigger mode %d\n", trig_mode) ;
00176         break ;
00177     }
00178     return( result ) ;
00179 }
00180 
00181 void sampleAD(void)
00182 {
00183     if (frame_full) {
00184         return ;
00185     }
00186 // timer.detach() ;
00187     for (int i = 0 ; i < numAnalogIn ; i++ ) {
00188         udata[page][i][data_index] = ach[i]->read_u16() ;
00189     }
00190 // timer.attach_us(&sampleAD, us_interval) ;
00191     switch(sampling_status) {
00192     case ST_PRE_TRIG:
00193         if (data_index >= trig_pos) {
00194             sampling_status = ST_TRIG_WAIT ;
00195         } else {
00196             data_index = (data_index + 1) % memLength ;
00197         }
00198         break ;
00199     case ST_TRIG_WAIT:
00200         if (checkTrigger()) {
00201             trig_index = data_index ;
00202             post_trig_index = 0 ;
00203             sampling_status = ST_TRIG_HIT ;
00204         } else {
00205             data_index = (data_index + 1) % memLength ;
00206         }
00207         break ;
00208     case ST_TRIG_HIT:
00209         post_trig_index++ ;
00210         if (post_trig_index >= post_trig_len) {
00211             sampling_status = ST_BUF_FULL ;
00212             frame_full = true ;
00213             bor[page] = (memLength + trig_index - trig_pos) % memLength ;
00214             post_trig_index = 0 ;
00215             data_index = 0 ;
00216         } else {
00217             data_index = (data_index + 1) % memLength ;
00218         }
00219         break ;
00220     case ST_BUF_FULL:
00221         printf("mode = ST_BUF_FULL\n\r") ;
00222         break ;
00223     default:
00224         printf("unknown sample status %d\n", sampling_status) ;
00225         break ;
00226     }
00227 }
00228 
00229 
00230 bool doTrigValue(int x, int y)
00231 {
00232     int i, y_offset ;
00233     bool result = false ;
00234     for (i = 0 ; i < numAnalogIn ; i++ ) {
00235         if (inChFrame(i, x, y)) {
00236             result = true ;
00237             trig_ch = i ;
00238             trig_pos = x - left_margin;
00239             post_trig_len = memLength - trig_pos ;
00240             y_offset = head_h + pane_h * i + 5 * (i - 1) + 1;
00241             trig_level = vref *(1 -  ((float)(y - y_offset) / (float)(pane_h - 2))) ;
00242             if (trig_level > vref) {
00243                 trig_level = vref ;
00244             } else if (trig_level < 0.0) {
00245                 trig_level = 0.0 ;
00246             }
00247             utrig_level = v2u( trig_level ) ; 
00248             break ;
00249         }
00250     }
00251     return( result ) ;
00252 }
00253 
00254 void hello()
00255 {
00256     printf("=== simple oscilloscope ===\n\r") ;
00257     printf("built: %s\n\r",__DATE__) ;
00258 }
00259 
00260 int main() 
00261 {
00262     int touched ;
00263     uint16_t x, y ;
00264     bool result ;
00265     tty.cls() ;
00266     backlight = 0 ;
00267     initTFT() ;
00268     initADC() ;
00269     initMenu() ;
00270     
00271     us_interval = MIN_INTERVAL ; 
00272     
00273     drawGraphFrames() ;
00274     drawMenu() ;
00275     
00276     backlight = 1 ;
00277     hello() ;
00278     timer.attach_us(&sampleAD, us_interval) ;
00279     while(1) {
00280         drawChart() ;
00281         touched = TSC.getPoint(&x, &y) ;
00282         if (touched && ((x != 0) && (y != 0))) { // discard value 0 for x, y
00283 // printf("x = %d, y = %d\n",x, y) ;
00284             if (mode == MODE_RUN) {
00285                 timer.detach() ;
00286             }
00287             result = doMenu(x, y) ;
00288             if (result != true) {
00289                 result = doTrigValue(x, y) ;
00290                 if (result) {
00291                     drawTrigMark() ;
00292                     printTrigMode() ;
00293                 }
00294             }   
00295             if (mode == MODE_RUN) {
00296                    timer.attach_us(&sampleAD, us_interval) ;
00297             }
00298         }
00299         wait(0.1) ;
00300     }
00301 }