void system_tick_init() { Timer0_12T(); Timer0_AsTimer(); Timer0_16bitAutoReload(); Timer0_Load(T0_THL); Timer0_InterruptEnable(); Timer0_Stop(); }
// Таймаут задается в миллисекундах Status W_Wait(uint32_t Delay) { uint32_t Port; Timer0_Start(Delay); while (!Timer0_Status()) { Port = GPIO_ReadValue(WAIT_PORT); if (!(Port & (1<<WAIT_PIN))) { Timer0_Stop(); return SUCCESS; } else { Port = 0; } } Timer0_Stop(); return ERROR; }
void CANAbortCMD(void){ if((can_Status==CAN_Send)||(can_Status==CAN_Pending)){ Timer0_Stop(); can_queue[can_queue_tail]->cmd=CMD_ABORT; can_cmd(can_queue[can_queue_tail]); AddError(ERROR_CAN_SEND); can_Status=CAN_Ready; can_queue_tail=(can_queue_tail+1)%CAN_QUEUE_SIZE; } }
void CANSendNext(void){ Timer0_Stop(); #ifdef WDT_DELAY wdt_reset(); #endif can_queue[can_queue_tail]->cmd = CMD_ABORT; can_cmd(can_queue[can_queue_tail]); can_Status=CAN_Ready; can_queue_tail=(can_queue_tail+1)%CAN_QUEUE_SIZE; CANSendData(); }
void Sinus_Generator(void) { uint8_t Audio_Signal; static uint8_t tone_index = 0; if (MODEM_TRANSMITTING == true) { if (packet_pos == modem_packet_size) { MODEM_TRANSMITTING = false; //Flag to check all packet content is transmitted Timer0_Stop(); Send_Vcxo_Signal(0x10); //DAC output to Vdd/2 goto end_generator; //return from the function } // If we have changed to new baud already if (current_sample_in_baud == 0) { if ((packet_pos & 7) == 0) // Load up next byte current_byte = modem_packet[packet_pos >> 3]; else current_byte = current_byte >> 1 ; // Load up next bit if ((current_byte & 0x01) == 0) { // Toggle tone (1200 or 2200) if(tone_index){ phase_delta = PHASE_DELTA_1200; tone_index = 0; //ADF7012_SET_CLK_PIN; } else{ phase_delta = PHASE_DELTA_2200; //ADF7012_CLEAR_CLK_PIN; tone_index = 1; } } } phase += phase_delta; if(phase >= TABLE_SIZE) //No modulus instruction for CPU, takes more cycles to operate when compiling modulus operation phase = phase - TABLE_SIZE; Audio_Signal = *(sine_table2 + phase) ; //Take the appropriate Audio sample from the table Send_Vcxo_Signal(Audio_Signal); //Output the Audio sample to DAC output current_sample_in_baud++; if(Change_to_New_Baud == true) { //Change to new baud if the the required time for a single baud is spent current_sample_in_baud = 0; packet_pos++; Change_to_New_Baud = false; } }
// ************************************************************************************************* // @fn mx_time // @brief Clock set routine. // @param u8 line LINE1, LINE2 // @return none // ************************************************************************************************* void mx_time(u8 line) { u8 select; s32 timeformat; s16 timeformat1; s32 hours; s32 minutes; s32 seconds; u8 * str; // Clear display clear_display_all(); #ifdef CONFIG_USE_SYNC_TOSET_TIME if (sys.flag.low_battery) return; display_sync(LINE2, DISPLAY_LINE_UPDATE_FULL); start_simpliciti_sync(); #else // Convert global time to local variables // Global time keeps on ticking in background until it is overwritten if (sys.flag.am_pm_time) { timeformat = TIMEFORMAT_12H; } else { timeformat = TIMEFORMAT_24H; } timeformat1 = timeformat; hours = sTime.hour; minutes = sTime.minute; seconds = sTime.second; // Init value index select = 0; // Loop values until all are set or user breaks set while(1) { // Idle timeout: exit without saving if (sys.flag.idle_timeout) { // Roll back time format if (timeformat1 == TIMEFORMAT_12H) sys.flag.am_pm_time = 1; else sys.flag.am_pm_time = 0; display_symbol(LCD_SYMB_AM, SEG_OFF); break; } // Button STAR (short): save, then exit if (button.flag.star) { // Stop clock timer Timer0_Stop(); // Store local variables in global clock time sTime.hour = hours; sTime.minute = minutes; sTime.second = seconds; // Start clock timer Timer0_Start(); // Full display update is done when returning from function display_symbol(LCD_SYMB_AM, SEG_OFF); #ifdef CONFIG_SIDEREAL if(sSidereal_time.sync>0) sync_sidereal(); #endif break; } switch (select) { #if (OPTION_TIME_DISPLAY == CLOCK_DISPLAY_SELECT) case 0: // Clear LINE1 and LINE2 and AM icon - required when coming back from set_value(seconds) clear_display(); display_symbol(LCD_SYMB_AM, SEG_OFF); // Set 24H / 12H time format set_value(&timeformat, 1, 0, 0, 1, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_SELECTION + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_1, display_selection_Timeformat1); // Modify global time format variable immediately to update AM/PM icon correctly if (timeformat == TIMEFORMAT_12H) sys.flag.am_pm_time = 1; else sys.flag.am_pm_time = 0; select = 1; break; #else case 0: #endif case 1: // Display HH:MM (LINE1) and .SS (LINE2) str = itoa(hours, 2, 0); display_chars(LCD_SEG_L1_3_2, str, SEG_ON); display_symbol(LCD_SEG_L1_COL, SEG_ON); str = itoa(minutes, 2, 0); display_chars(LCD_SEG_L1_1_0, str, SEG_ON); str = itoa(seconds, 2, 0); display_chars(LCD_SEG_L2_1_0, str, SEG_ON); display_symbol(LCD_SEG_L2_DP, SEG_ON); // Set hours set_value(&hours, 2, 0, 0, 23, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_2, display_hours_12_or_24); select = 2; break; case 2: // Set minutes set_value(&minutes, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_1_0, display_value1); select = 3; break; case 3: // Set seconds set_value(&seconds, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_1_0, display_value1); select = 0; break; } } // Clear button flags button.all_flags = 0; #endif }
// ************************************************************************************************* // @fn mx_time // @brief Clock set routine. // @param u8 line LINE1, LINE2 // @return none // ************************************************************************************************* void mx_time() { u8 select; s32 timeformat; s16 timeformat1; s32 hours; s32 minutes; // Clear display clear_display_all(); // Convert global time to local variables // Global time keeps on ticking in background until it is overwritten if (sys.flag.use_metric_units) { timeformat = TIMEFORMAT_24H; } else { timeformat = TIMEFORMAT_12H; } timeformat1 = timeformat; hours = sTime.hour; minutes = sTime.minute; // Init value index select = 0; // Loop values until all are set or user breaks set while (1) { // Idle timeout: exit without saving if (sys.flag.idle_timeout) { // Roll back time format if (timeformat1 == TIMEFORMAT_24H) sys.flag.use_metric_units = 1; else sys.flag.use_metric_units = 0; display_symbol(LCD_SYMB_AM, SEG_OFF); break; } // Button STAR (short): save, then exit if (button.flag.star) { // Stop clock timer Timer0_Stop(); // Store local variables in global clock time shour = sTime.hour = hours; sminute = sTime.minute = minutes; sday = sTime.second = 0; //sidereal basis^^^ // Start clock timer Timer0_Start(); // Full display update is done when returning from function display_symbol(LCD_SYMB_AM, SEG_OFF); break; } switch (select) { case 0: // Clear LINE1 and LINE2 and AM icon - required when coming back from // set_value(seconds) clear_display(); display_symbol(LCD_SYMB_AM, SEG_OFF); // Set 24H / 12H time format set_value( &timeformat, 1, 0, 0, 1, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_SELECTION + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_1, display_selection_Timeformat1); // Modify global time format variable immediately to update AM/PM icon correctly if (timeformat == TIMEFORMAT_24H) sys.flag.use_metric_units = 1; else sys.flag.use_metric_units = 0; select = 1; break; case 1: // Display HH:MM (LINE1) and .SS (LINE2) display_chars(LCD_SEG_L1_3_2, int_to_array(hours, 2, 0), SEG_ON); display_symbol(LCD_SEG_L1_COL, SEG_ON); display_chars(LCD_SEG_L1_1_0, int_to_array(minutes, 2, 0), SEG_ON); // Set hours set_value(&hours, 2, 0, 0, 23, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_2, display_hours); select = 2; break; case 2: // Set minutes set_value(&minutes, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_1_0, display_value); select = 0; break; } } // Clear button flags button.all_flags = 0; }
// ************************************************************************************************* // @fn test_mode // @brief Manual test mode. Activated by holding buttons STAR and UP simultaneously. // Cancelled by any other button press. // @param none // @return none // ************************************************************************************************* void test_mode(void) { u8 test_step, start_next_test; u8 *str; u8 i; // Disable timer - no need for a clock tick Timer0_Stop(); // Disable LCD charge pump while in standby mode // This reduces current consumption by ca. 5�A to ca. 10�A LCDBVCTL = 0; // Show welcome screen display_chars(LCD_SEG_L1_3_0, (u8 *) " DC ", SEG_ON); display_chars(LCD_SEG_L2_4_0, (u8 *) "44 20", SEG_ON); display_symbol(LCD_SEG_L1_COL, SEG_ON); display_symbol(LCD_ICON_HEART, SEG_ON); display_symbol(LCD_ICON_STOPWATCH, SEG_ON); display_symbol(LCD_ICON_RECORD, SEG_ON); display_symbol(LCD_ICON_ALARM, SEG_ON); display_symbol(LCD_ICON_BEEPER1, SEG_ON); display_symbol(LCD_ICON_BEEPER2, SEG_ON); display_symbol(LCD_ICON_BEEPER3, SEG_ON); display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); display_symbol(LCD_SYMB_AM, SEG_ON); // Hold watchdog WDTCTL = WDTPW + WDTHOLD; // Wait for button press _BIS_SR(LPM3_bits + GIE); __no_operation(); // Clear display display_all_off(); #ifdef USE_LCD_CHARGE_PUMP // Charge pump voltage generated internally, internal bias (V2-V4) generation // This ensures that the contrast and LCD control is constant for the whole battery lifetime LCDBVCTL = LCDCPEN | VLCD_2_72; #endif // Renenable timer Timer0_Start(); // Debounce button press Timer0_A4_Delay(CONV_MS_TO_TICKS(100)); while (1) { // Check button event if (BUTTON_STAR_IS_PRESSED && BUTTON_UP_IS_PRESSED) { // Start with test #0 test_step = 0; start_next_test = 1; while (1) { if (start_next_test) { // Clean up previous test display display_all_off(); start_next_test = 0; switch (test_step) { case 0: // All LCD segments on display_all_on(); // Wait until buttons are off while (BUTTON_STAR_IS_PRESSED && BUTTON_UP_IS_PRESSED) ; break; // case 1: // Altitude measurement // display_altitude(LINE1, DISPLAY_LINE_UPDATE_FULL); // for (i = 0; i < 2; i++) // { // while ((PS_INT_IN & PS_INT_PIN) == 0) ; // do_altitude_measurement(FILTER_OFF); // display_altitude(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); // } // stop_altitude_measurement(); // break; // case 2: // Temperature measurement // display_temperature(LINE1, DISPLAY_LINE_UPDATE_FULL); // for (i = 0; i < 4; i++) // { // Timer0_A4_Delay(CONV_MS_TO_TICKS(250)); // temperature_measurement(FILTER_OFF); // display_temperature(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); // } // break; // case 3: // Acceleration measurement // as_start(); // for (i = 0; i < 4; i++) // { // Timer0_A4_Delay(CONV_MS_TO_TICKS(250)); // as_get_data(sAccel.xyz); // str = int_to_array(sAccel.xyz[0], 3, 0); // display_chars(LCD_SEG_L1_2_0, str, SEG_ON); // str = int_to_array(sAccel.xyz[2], 3, 0); // display_chars(LCD_SEG_L2_2_0, str, SEG_ON); // } // as_stop(); // break; // case 4: // BlueRobin test // button.flag.up = 1; // sx_bluerobin(LINE1); // Timer0_A4_Delay(CONV_MS_TO_TICKS(100)); // get_bluerobin_data(); // display_heartrate(LINE1, DISPLAY_LINE_UPDATE_FULL); // stop_bluerobin(); // break; } // Debounce button Timer0_A4_Delay(CONV_MS_TO_TICKS(200)); } // Check button event if (BUTTON_STAR_IS_PRESSED) { test_step = 1; start_next_test = 1; } else if (BUTTON_NUM_IS_PRESSED) { test_step = 2; start_next_test = 1; } else if (BUTTON_UP_IS_PRESSED) { test_step = 3; start_next_test = 1; } else if (BUTTON_DOWN_IS_PRESSED) { test_step = 4; start_next_test = 1; } else if (BUTTON_BACKLIGHT_IS_PRESSED) { // Wait until button has been released (avoid restart) while (BUTTON_BACKLIGHT_IS_PRESSED) ; // Disable LCD and LCD charge pump LCDBCTL0 &= ~BIT0; LCDBVCTL = 0; // Debounce button press Timer0_A4_Delay(CONV_MS_TO_TICKS(500)); // Disable timer - no need for a clock tick Timer0_Stop(); // Hold watchdog WDTCTL = WDTPW + WDTHOLD; // Sleep until button is pressed (ca. 4�A current consumption) _BIS_SR(LPM4_bits + GIE); __no_operation(); // Force watchdog reset for a clean restart WDTCTL = 1; } #ifdef USE_WATCHDOG // Service watchdog WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; #endif // To LPM3 _BIS_SR(LPM3_bits + GIE); __no_operation(); } } else { // Debounce button Timer0_A4_Delay(CONV_MS_TO_TICKS(100)); button.all_flags = 0; // Turn off backlight P2OUT &= ~BUTTON_BACKLIGHT_PIN; P2DIR &= ~BUTTON_BACKLIGHT_PIN; break; } } }
//========= Подпрограмма формирования задержки, заданной в ms================== void Wait(uint32_t Delay) { Timer0_Start(Delay); while(!Timer0_Status()); Timer0_Stop(); }
// ************************************************************************************************* // @fn mx_time // @brief Clock set routine. // @param u8 line LINE1, LINE2 // @return none // ************************************************************************************************* void mx_time(u8 line) { u8 select; s32 timeformat; s16 timeformat1; s32 hours; s32 minutes; s32 seconds; s32 DailyCorrTmp; s32 WeeklyCorrTmp; s32 DST_AutoFlagTmp; u8 * str; // Clear display TimeAdjustmentFlag = 1; clear_display_all(); // Convert global time to local variables // Global time keeps on ticking in background until it is overwritten if (sys.flag.use_metric_units) { timeformat = TIMEFORMAT_24H; } else { timeformat = TIMEFORMAT_12H; } timeformat1 = timeformat; hours = sTime.hour; minutes = sTime.minute; seconds = sTime.second; DailyCorrTmp = DailyCorr; WeeklyCorrTmp = WeeklyCorr; DST_AutoFlagTmp = DST_AutoFlag; // Init value index select = 0; // Loop values until all are set or user breaks set while(1) { // Idle timeout: exit without saving if (sys.flag.idle_timeout) { // Roll back time format if (timeformat1 == TIMEFORMAT_24H) sys.flag.use_metric_units = 1; else sys.flag.use_metric_units = 0; display_symbol(LCD_SYMB_AM, SEG_OFF); TimeAdjustmentFlag = 0; break; } // Button STAR (short): save, then exit if (button.flag.star) { // Stop clock timer Timer0_Stop(); // Store local variables in global clock time sTime.hour = hours; sTime.minute = minutes; sTime.second = seconds; DailyCorr = DailyCorrTmp; WeeklyCorr = WeeklyCorrTmp; DST_AutoFlag = DST_AutoFlagTmp; // Start clock timer Timer0_Start(); // Full display update is done when returning from function display_symbol(LCD_SYMB_AM, SEG_OFF); TimeAdjustmentFlag = 0; break; } switch (select) { case 0: // Clear LINE1 and LINE2 and AM icon - required when coming back from set_value(seconds) clear_display(); display_symbol(LCD_SYMB_AM, SEG_OFF); // Set 24H / 12H time format set_value(&timeformat, 1, 0, 0, 1, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_SELECTION + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_1, display_selection_Timeformat1); // Modify global time format variable immediately to update AM/PM icon correctly if (timeformat == TIMEFORMAT_24H) sys.flag.use_metric_units = 1; else sys.flag.use_metric_units = 0; select = 1; break; case 1: // Display HH:MM (LINE1) and .SS (LINE2) str = itoa(hours, 2, 0); display_chars(LCD_SEG_L1_3_2, str, SEG_ON); display_symbol(LCD_SEG_L1_COL, SEG_ON); str = itoa(minutes, 2, 0); display_chars(LCD_SEG_L1_1_0, str, SEG_ON); str = itoa(seconds, 2, 0); display_chars(LCD_SEG_L2_1_0, str, SEG_ON); display_symbol(LCD_SEG_L2_DP, SEG_ON); // Set hours set_value(&hours, 2, 0, 0, 23, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_2, display_hours1); select = 2; break; case 2: // Set minutes set_value(&minutes, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_1_0, display_value1); select = 3; break; case 3: // Set seconds set_value(&seconds, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_1_0, display_value1); select = 4; break; case 4: // Set daily adjusting value clear_display(); display_chars(LCD_SEG_L2_4_0, (u8 *)"ADJ-1", SEG_ON); set_value(&DailyCorrTmp, 2, 0, -10, 10, SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE + SETVALUE_DISPLAY_ARROWS, LCD_SEG_L1_3_2, display_value1); select = 5; break; case 5: // Set weekly adjusting value display_chars(LCD_SEG_L2_4_0, (u8 *)"ADJ-7", SEG_ON); set_value(&WeeklyCorrTmp, 2, 0, -30, 30, SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE + SETVALUE_DISPLAY_ARROWS, LCD_SEG_L1_3_2, display_value1); select = 6; break; case 6: // Set DST (Daylight Saving Time) automatic clear_display(); display_chars(LCD_SEG_L2_4_0, (u8 *)" DST ", SEG_ON); set_value(&DST_AutoFlagTmp, 0, 0, 0, 1, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_0, display_OFF_ON); select = 0; break; } } // Clear button flags button.all_flags = 0; }
void Sinus_Generator2(void) { uint8_t Audio_Signal; static uint8_t tone_index = 0; phase_delta = PHASE_DELTA_1000; if (!Sending_Character) return; if (tx_duration > 0) { phase += phase_delta; if(phase >= TABLE_SIZE) //No modulus instruction for CPU, takes more cycles to operate when compiling modulus operation phase = phase - TABLE_SIZE; if (!SPACE) { Audio_Signal = *(sine_table2 + phase); //Take the appropriate Audio sample from the table Send_Vcxo_Signal(Audio_Signal); //Output the Audio sample to DAC output } tx_duration = tx_duration - 1; } else //tx_duration is not >= 0 { //if (Sending_Character) if(!Inside_Character) { { unsigned char char_to_send = message[packet_pos]; if (char_to_send>96) {char_to_send-=32; } //change to uppercase a->A b->B if (((char_to_send >= '0' ) && (char_to_send <= '9' )) || ((char_to_send >= 'A' ) && (char_to_send <= 'Z' ))) { char_data = characters[char_to_send - '0']; //The list is 0,1,2,3,4,5... so first element equals to '0' char_length = char_data & 7; // beep count, 7 is 00000111, last 3 bits are length Inside_Character = true; } } } else //we're inside a character { if (SPACE) { unsigned char mask = ( 1 << (char_length + 2) ); if( char_data & mask ) { tx_duration = dit_duration * dit_dah_weight; //dah } else { tx_duration = dit_duration; //dit } SPACE = false; if (char_length <= 0) { Inside_Character = false; packet_pos++; if (packet_pos >= (sizeof(message)-1)) { packet_pos=0; Sending_Character = false; Timer0_Stop(); } tx_duration = dit_duration * dit_dah_weight; SPACE = true; } char_length -= 1; } else { tx_duration = dit_duration; SPACE = true; } //send space adter each dit/dah } } return; }