Charles Young's development fork. Going forward I only want to push mature code to main repository.
Fork of GEO_COUNTER_L432KC by
main.cpp
- Committer:
- charlesdavidyoung
- Date:
- 2018-09-04
- Revision:
- 20:fb73eaaf0894
- Parent:
- 18:ef5678ab1889
- Child:
- 21:5640ebc362a0
File content as of revision 20:fb73eaaf0894:
// GEO COUNTER V1 firmware // This FW provides a basic operation of GEO-COUNTER // // Latest review: August 27, 2018 - Walter Trovo // // Sep 4, 2018: Charles Young: Created RotarySwitch class to manage mode selection // Feb 14, 2018: initial release aimed to test the counters, the serial port // the PWM output and the MAX7219 operation. // Feb 15, 2018: Removed MAX7219 libray (replaced with custom routine). // Added 74HC595 routine. Added beep. Added Gate_write // // this block includes key libraries #include <string> // strings management #include "RotarySwitch.hpp" // Everything associated with the rotary switch and the associated LEDs // is hidden in this class. RotarySwitch ModeSwitch; // definitions of fixed parameters #define DEC_MODE 0x09FF // BCD decoding on all digits #define BRIGHTNESS 0x0A0F // max brightness #define SCAN_LIM 0x0B07 // use all 8 digits #define TURN_ON 0x0C01 // no shutdown (operating) #define SHUTDOWN 0x0C00 // shutdown #define TEST 0x0F00 // no test #define DT 1 // delay time in us for SPI emulation #define TGATE 10 // gate time (currently fixed for testing purpose) #define MAX_VAL 999999 // Max value managed by the 6-digits display // LED on processor board DigitalOut led1(LED1); // definitions of peripherals and devices I2C i2c(D4, D5); // I2C port Ticker SecTenth_Beat; // .1 second ticker Ticker Sec_Beat; // 1 second ticker Serial PC(USBTX, USBRX); // Virtual COM via USB (PC connection) Serial GPS(D1, D0); // Serial port for GPS module // Global variables uint8_t Disp_Digit[8]; // used to manage 8-digits through MAX7219 uint16_t Stream; // used to stream out serial data to MAX7219 time_t seconds; // Real-Time Clock (RTC) timestamp unsigned int value = 0; // displayed value on the 6-digits of the display uint8_t gate = TGATE; // displayed value on the 2-digits display uint32_t Count1, Count2; // pulse counters (32-bit) char Text[40]=""; // used to send messages over the serial port uint8_t Disp_mode = 0x01, Disp_unit = 0xA0; // status of 1st row and 2nd rows of LEDs bool Stopped = 0; // status of counting activity bool StartStopPressed = 0;// status of counting activity double ADC_val; // used to read ADC value // ----- Prototypes of routines (defined below the main) ------------------- void UpdateInput(void); // periodically called by the ticker void UpdateOutput(void); // periodically called by the ticker void Count1_up(void); // called every time an edge is detected on TRIG1 pin void Count2_up(void); // called every time an edge is detected on TRIG2 pin void Beep(void); // used to generate a short beep (buzzer) void Display_init(void); // initialize MAX7219 void Display_6D_write(uint8_t); // write to MAX7219 (Main 6-digits display) void Display_2D_write(unsigned short); // write to MAX7219 (Gate 2-digits display) //============================================================================== //============================================================================== int main() { PC.baud(115200); // set baud-rate of virtual COM port (PC connection) PC.printf("\nGEO COUNTER V1 2108"); PC.printf(__DATE__); PC.printf(" "); PC.printf(__TIME__); GPS.baud(9600); // set the baud-rate of the serial port dedicated to the GPS CS1 = 1; // presets CS of MAX7219 CS2 = 1; // preset CS of 74HC595 Display_6D_write(0x543210); Display_2D_write(TGATE); Display_init(); // initialize MAX7219 // RTC is supposed to be loose time at power down (no backup battery) // An initialization is performed anyway set_time(0); // Set time PWM.period_ms(3); // set the PWM period PWM.write(0.8); // set the PWM duty-cycle Beep(); // initial beep // set the 1 sec ticker to periodically call the Update() routine // NOTE: this is also the 1-sec time base for counters. A better approach // would replace the ticker with an interrupt from the RTC (to be implemented) SecTenth_Beat.attach_us(&UpdateInput, 100000); Sec_Beat.attach_us(&UpdateOutput, 1000000); //RTC::attach(&Update, RTC::Second); //RTC::detach(RTC::Second); // main loop does nothing as all activities are interrupt driven while(1) { // dance (or drink a beer) } } //-------- END OF MAIN -------------- //============================================================================== // Definition of routines //--------------------------------------------------------------------------- // Update values to be displayed void logToPC() { PC.printf("\nADC: %.02f", ADC_val); PC.printf(Stopped ? " stopped" : " started"); // Timestamp to PC (debug) seconds = time(NULL); // get current time strftime(Text, 50, "%H:%M:%S", localtime(&seconds)); PC.printf(" RTC: %s, CNT1: %7d CNT2: %7d",Text, Count1, Count2); //PC.printf(" wheel %d %d", WheelCurrent, QEPB.read()); } void UpdateOutput() { // This must be called periodically to update the LEDs ModeSwitch.UpdateOutput(); if(Stopped) { // disable interrupts on TRIG1 and TRIG2 TRIG1.rise(NULL); TRIG2.rise(NULL); // show zero gate time gate = 0; Display_2D_write(gate); // show selected content on main display value = (int)(Count1/TGATE); Display_6D_write(value); // refresh the main display } else { // Enable interrupts on rising edge of digital inputs TRIG1 & TRIG2 TRIG1.rise(&Count1_up); TRIG2.rise(&Count2_up); if(gate==0) // show the counter value at the end of the gate time { value = (int)(Count1/TGATE); Display_6D_write(value); // refresh the main display Count1 = 0; // clear both counters Count2 = 0; gate = TGATE;// and reload the gate time } Display_2D_write(gate); // show gate time countdown gate--; } } void UpdateInput() { // This must be called periodically to monitor switch input ModeSwitch.UpdateInput(); ADC_val = KEYB.read(); // read voltage from keyboard if ( (ADC_val<0.1) // START/STOP pushbutton pressed && (!StartStopPressed)) { StartStopPressed = true; Stopped=!Stopped; // toggle status } else StartStopPressed = false; if((ADC_val>0.6)&&(ADC_val<0.7)) // CLEAR pushbutton pressed { Count1 = 0; // clear counters Count2 = 0; } logToPC(); return; } //--------------------------------------------------------------------------- // Increment CNT1 every time a rising edge is detected on TRIG1 (interrupt) void Count1_up(void) { Count1++; return; } //--------------------------------------------------------------------------- // Increment CNT1 every time a rising edge is detected on TRIG2 (interrupt) void Count2_up(void) { Count2++; return; } //--------------------------------------------------------------------------- //Generates a short beep via BUZZ void Beep(void) { BUZZ = 1; // turn-on the buzzer wait(0.3); // wait BUZZ = 0; // turn-off the buzzer return; } //--------------------------------------------------------------------------- // Initialize the MAX7219 void Display_init(void) { uint8_t i; uint16_t mask; uint16_t data_to_send[6] = {SHUTDOWN, TURN_ON, DEC_MODE, BRIGHTNESS, SCAN_LIM, TEST}; //{SHUTDOWN, TURN_ON, DEC_MODE, BRIGHTNESS, SCAN_LIM, TEST}; for(i = 0; i <6; i++) { CS1 = 0; for(mask = 0x8000; mask!= 0; mask>>= 1) { wait_us(DT); SCK = 0; if(mask & data_to_send[i]) MOSI = 1; else MOSI = 0; wait_us(DT); SCK = 1; } wait_us(DT); SCK = 0; wait_us(DT); CS1 = 1; } return; } //--------------------------------------------------------------------------- // Refresh the 6 digits of the main display void Display_6D_write(uint8_t value) { uint8_t digit; uint16_t mask, data_to_send; char TextString[6]; // int to string, then string to digits sprintf(TextString, "%6d", value); // int to string for(uint8_t i=0; i<6; i++) { if(TextString[i] == ' ') // blank empty digits Disp_Digit[i] = 0xFF; else Disp_Digit[i] = TextString[i]-'0'; } // write to chip SCK = 0; wait_us(DT); for(digit = 1; digit <7; digit++) { // each stream consists of digit address and data to show data_to_send = 7 - digit; data_to_send<<=8; data_to_send = data_to_send | Disp_Digit[digit-1]; CS1 = 0; for(mask = 0x8000; mask!= 0; mask>>= 1) { wait_us(DT); SCK = 0; if(mask & data_to_send) MOSI = 1; else MOSI = 0; wait_us(DT); SCK = 1; } wait_us(DT); SCK = 0; wait_us(DT); CS1 = 1; } return; } //--------------------------------------------------------------------------- // Refresh the 2 digits of the gate display void Display_2D_write(unsigned short value) { uint8_t digit; uint16_t mask, data_to_send; char TextString[2]; // int to string, then string to digits sprintf(TextString, "%2d", value); // int to string if(TextString[0] == ' ') // blank empty digits Disp_Digit[7] = 0xFF; else Disp_Digit[7] = TextString[0] - '0'; Disp_Digit[6] = TextString[1] - '0'; // write to chip SCK = 0; wait_us(DT); for(digit = 7; digit <9; digit++) { // each stream consists of digit address and data to show data_to_send = digit; data_to_send<<=8; data_to_send = data_to_send | Disp_Digit[digit-1]; CS1 = 0; for(mask = 0x8000; mask!= 0; mask>>= 1) { wait_us(DT); SCK = 0; if(mask & data_to_send) MOSI = 1; else MOSI = 0; wait_us(DT); SCK = 1; } wait_us(DT); SCK = 0; wait_us(DT); CS1 = 1; } return; } //-------- END OF FILE -------------- //==============================================================================