lab

Fork of Adafruit_GFX by Neal Horman

Files at this revision

API Documentation at this revision

Comitter:
chaolyu14
Date:
Wed May 04 17:52:57 2016 +0000
Parent:
17:4191e754fe07
Commit message:
main

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed May 04 17:52:57 2016 +0000
@@ -0,0 +1,227 @@
+#include "mbed.h"
+#include "Adafruit_SSD1306.h"
+
+//Switch input definition
+#define SW_PIN_0 p21
+#define SW_PIN_1 p22
+#define SW_PIN_2 p23
+#define SW_PIN_3 p24
+
+#define Digital_Out_1 p17
+//Sampling period for the switch oscillator (us)
+#define SW_PERIOD 20000 
+
+//Display interface pin definitions
+#define D_MOSI_PIN p5
+#define D_CLK_PIN p7
+#define D_DC_PIN p8
+#define D_RST_PIN p9
+#define D_CS_PIN p10
+
+//an SPI sub-class that sets up format and clock speed
+class SPIPreInit : public SPI
+{
+public:
+    SPIPreInit(PinName mosi, PinName miso, PinName clk) : SPI(mosi,miso,clk)
+    {
+        format(8,3);
+        frequency(2000000);
+    };
+};
+
+bool status(volatile uint16_t scount, bool preVal);
+
+//Interrupt Service Routine prototypes (functions defined below)
+void sedge0();
+void sedge1();
+void sedge2();
+void sedge3();
+void tout();
+void flip();
+void incrementer(uint8_t& x);
+
+//Output for the alive LED
+DigitalOut alive(LED1);
+DigitalOut OUT_1(Digital_Out_1);
+
+//External interrupt input from the switch oscillator
+InterruptIn sw0in(SW_PIN_0);
+InterruptIn sw1in(SW_PIN_1);
+InterruptIn sw2in(SW_PIN_2);
+InterruptIn sw3in(SW_PIN_3);
+
+//Switch sampling timer
+Ticker swtimer;
+Ticker flipper;
+//Registers for the switch counter, switch counter latch register and update flag
+volatile uint16_t scounter0=0;volatile uint16_t scounter1=0;volatile uint16_t scounter2=0;volatile uint16_t scounter3=0;
+
+volatile uint16_t scount0=0;volatile uint16_t scount1=0;volatile uint16_t scount2=0;volatile uint16_t scount3=0;
+
+volatile uint16_t update=0;
+
+//Initialise SPI instance for communication with the display
+SPIPreInit gSpi(D_MOSI_PIN,NC,D_CLK_PIN); //MOSI,MISO,CLK
+
+//Initialise display driver instance
+Adafruit_SSD1306_Spi gOled1(gSpi,D_DC_PIN,D_RST_PIN,D_CS_PIN,64,128); //SPI,DC,RST,CS,Height,Width
+
+int main() { 
+    //Initialisation
+    gOled1.setRotation(2); //Set display rotation
+    
+    //Attach switch oscillator counter ISR to the switch input instance for a rising edge
+    sw0in.rise(&sedge0);sw1in.rise(&sedge1);sw2in.rise(&sedge2);sw3in.rise(&sedge3);
+    
+    //Attach switch sampling timer ISR to the timer instance with the required period
+    swtimer.attach_us(&tout, SW_PERIOD); 
+    //Main loop
+    bool preVal0 = false;
+    bool preVal1 = false;
+    bool preVal2 = false;
+    bool preVal3 = false;
+                
+    uint8_t out_period_3 = 0;
+    uint8_t out_period_2 = 0;
+    uint8_t out_period_1 = 0;
+    uint8_t out_period_0 = 0; 
+    
+    uint16_t out_period = 0; 
+
+    while(1)
+    {
+        //Has the update flag been set?       
+        if (update) {
+            //Clear the update flag
+            update = 0;
+            
+            //Set text cursor
+            gOled1.setTextCursor(0,0);
+           
+            //Write the latest switch osciallor count   
+            gOled1.printf("F_sw0: ");
+            gOled1.printf("%02u", scount0);
+            gOled1.printf(" kHz" );
+
+            if(status(scount0,preVal0)){
+                if(preVal0 == false ){
+                    incrementer(out_period_3);
+                }
+                preVal0 = true;
+                gOled1.printf("  ON" ); 
+
+            }else{
+                preVal0 = false;
+                gOled1.printf(" OFF" );
+            }
+            
+            gOled1.printf("\nF_sw1: ");
+            gOled1.printf("%02u", scount1);
+            gOled1.printf(" kHz" );
+            if(status(scount1,preVal1)){
+                if(preVal1 == false){
+                    incrementer(out_period_2);
+                }
+               preVal1 = true;
+               gOled1.printf("  ON" ); 
+            }else{
+                preVal1 = false;
+                gOled1.printf(" OFF" );
+            }
+            
+            gOled1.printf("\nF_sw2: ");
+            gOled1.printf("%02u", scount2);
+            gOled1.printf(" kHz" );
+            if(status(scount2,preVal2)){
+                if(preVal2 == false){
+                    incrementer(out_period_1);
+                }
+                preVal2 = true;
+                gOled1.printf("  ON" ); 
+            }else{
+                preVal2 = false;
+                gOled1.printf(" OFF" );
+            }
+            
+            gOled1.printf("\nF_sw3: ");
+            gOled1.printf("%02u", scount3);
+            gOled1.printf(" kHz" );
+            if(status(scount3,preVal3)){
+                if(preVal3 == false){
+                    incrementer(out_period_0);
+                }
+                preVal3 = true;              
+                gOled1.printf("  ON" ); 
+            }else{
+                preVal3 = false;
+                gOled1.printf(" OFF" );
+            }
+            gOled1.printf("\n\nOutput Frequency : ");
+            out_period = out_period_3*1000 + out_period_2*100 + out_period_1*10 + out_period_0;
+            gOled1.printf("\n%04u", out_period);
+            gOled1.printf(" kHz");
+            if(out_period != 0){
+                flipper.attach(&flip, float(0.5/out_period));
+            }
+            //Copy the display buffer to the display
+            gOled1.display();
+            
+            //Toggle the alive LED
+            alive = !alive;
+        }
+    }
+}
+
+void flip() {
+    OUT_1 = !OUT_1;
+}
+
+//Interrupt Service Routine for rising edge on the switch oscillator input
+void sedge0() {
+    //Increment the edge counter
+    scounter0++;    
+}
+void sedge1() {
+    //Increment the edge counter
+    scounter1++;    
+}
+void sedge2() {
+    //Increment the edge counter
+    scounter2++;    
+}
+void sedge3() {
+    //Increment the edge counter
+    scounter3++;    
+}
+
+void incrementer(uint8_t& x){
+    if(x < 9){
+        x++;
+    }else{
+        x=0;
+    }    
+}
+
+//Interrupt Service Routine for the switch sampling timer
+void tout() {
+    //Read the edge counter into the output register
+    scount0 = scounter0 / 20;scount1 = scounter1 / 20;scount2 = scounter2 / 20;scount3 = scounter3 / 20;
+    
+    //Reset the edge counter
+    scounter0 = 0;scounter1 = 0;scounter2 = 0; scounter3 = 0;
+
+    //Trigger a display update in the main loop
+    update = 1;
+}
+
+bool status(volatile uint16_t scount, bool preVal)
+{
+    if(scount <= 55){
+        return true;
+    }else if(scount >= 65){
+        return false;
+    }else{
+        return preVal;
+    }
+}
+