void Default_Reset_Handler(void) { /* Initialize data and bss */ unsigned long *pulSrc, *pulDest; /* Copy the data segment initializers from flash to SRAM */ pulSrc = &_sidata; for(pulDest = &_sdata; pulDest < &_edata; ) { *(pulDest++) = *(pulSrc++); } /* Zero fill the bss segment. This is done with inline assembly since this will clear the value of pulDest if it is not kept in a register. */ __asm(" ldr r0, =_sbss\n" " ldr r1, =_ebss\n" " mov r2, #0\n" " .thumb_func\n" "zero_loop:\n" " cmp r0, r1\n" " it lt\n" " strlt r2, [r0], #4\n" " blt zero_loop"); #ifdef __FPU_USED /* Enable FPU.*/ __asm(" LDR.W R0, =0xE000ED88\n" " LDR R1, [R0]\n" " ORR R1, R1, #(0xF << 20)\n" " STR R1, [R0]"); #endif /* Call the application's entry point.*/ system_setup(); main(); }
void main() { color_t my_color; panel_size_t panel_size; panel_size = SMALL_PANEL; system_setup( 1, 2, panel_size ); matrixrgb_set_color( &my_color, 1, 0, 0 ); matrixrgb_scroll_img_left( MikroE_Sign_bmp, 32, 32, 35 ); matrixrgb_scroll_off_scrn_down( 35 ); matrixrgb_set_color( &my_color, 1, 1, 1 ); matrixrgb_scroll_text_right( "Matrix ", my_color, 10, 10 ); matrixrgb_set_color( &my_color, 1, 0, 0 ); matrixrgb_scroll_text_left( "R", my_color, 10, 1 ); matrixrgb_set_color( &my_color, 0, 1, 0 ); matrixrgb_scroll_text_left( "G", my_color, 10, 1 ); matrixrgb_set_color( &my_color, 0, 0, 1 ); matrixrgb_scroll_text_left( "B ", my_color, 10, 1 ); matrixrgb_set_color( &my_color, 1, 1, 1 ); matrixrgb_scroll_off_scrn_up( 10 ); while(1) { matrixrgb_set_color( &my_color, 1, 1, 1 ); matrixrgb_scroll_text_left( "Matrix", my_color, 20, 10 ); matrixrgb_set_color( &my_color, 1, 0, 0 ); matrixrgb_scroll_text_left( "R", my_color, 20, 1 ); matrixrgb_set_color( &my_color, 0, 1, 0 ); matrixrgb_scroll_text_left( "G", my_color, 20, 1 ); matrixrgb_set_color( &my_color, 0, 0, 1 ); matrixrgb_scroll_text_left( "B", my_color, 20, 1 ); // matrixrgb_refresh(); } }
int main(int argc, char *argv[]) #endif { #if !defined(SINGLE_PHASE) int ch; static struct phase_parms_s *phase; static struct phase_nv_parms_s const *phase_nv; #endif static int32_t x; int i; #if !defined(__MSP430__) if (start_host_environment(argc, argv) < 0) exit(2); #endif system_setup(); #if !defined(ESP_SUPPORT) && defined(PHASE_CORRECTION_SUPPORT) && !defined(DYNAMIC_PHASE_CORRECTION_SUPPORT) #if !defined(SINGLE_PHASE) for (ch = 0; ch < NUM_PHASES; ch++) { phase = &chan[ch]; phase_nv = &nv_parms.seg_a.s.chan[ch]; #endif #if defined(__MSP430_HAS_ADC12__) || defined(__MSP430_HAS_ADC10__) set_phase_correction(&phase->metrology.current.in_phase_correction[0], phase_nv->current.phase_correction[0]); #if GAIN_STAGES > 1 set_phase_correction(&phase->metrology.current.in_phase_correction[1], phase_nv->current.phase_correction[1]); #endif #if defined(SINGLE_PHASE) && defined(NEUTRAL_MONITOR_SUPPORT) set_phase_correction(&phase->neutral.in_phase_correction[0], nv_parms.seg_a.s.neutral.phase_correction[0]); #if GAIN_STAGES > 1 set_phase_correction(&phase->neutral.in_phase_correction[1], nv_parms.seg_a.s.neutral.phase_correction[1]); #endif #endif #else #if defined(SINGLE_PHASE) set_sd16_phase_correction(&phase->metrology.current.in_phase_correction[0], 0, phase_nv->current.phase_correction[0]); #if defined(NEUTRAL_MONITOR_SUPPORT) set_sd16_phase_correction(&phase->metrology.neutral.in_phase_correction[0], 1, nv_parms.seg_a.s.neutral.phase_correction[0]); #endif #else set_sd16_phase_correction(&phase->metrology.current.in_phase_correction[0], ch, phase_nv->current.phase_correction[0]); #endif #endif #if !defined(SINGLE_PHASE) } #endif #endif #if defined(ESP_SUPPORT) esp_init(); esp_start_measurement(); #endif #if defined(MULTI_RATE_SUPPORT) tariff_initialise(); #endif send_message(0, 1); for (;;) { kick_watchdog(); #if !defined(__MSP430__) /* In the host environment we need to simulate interrupts here */ adc_interrupt(); #endif #if !defined(SINGLE_PHASE) phase = chan; phase_nv = nv_parms.seg_a.s.chan; for (ch = 0; ch < NUM_PHASES; ch++) { #endif /* Unless we are in normal operating mode, we should wait to be woken by a significant event from the interrupt routines. */ ////#if 1 //// 0 //defined(__MSP430__) //// if (operating_mode != OPERATING_MODE_NORMAL) #ifdef USE_LPM _BIS_SR(LPM0_bits); #endif #if defined(POWER_DOWN_SUPPORT) if (operating_mode == OPERATING_MODE_POWERFAIL) switch_to_powerfail_mode(); #endif #if defined(LIMP_MODE_SUPPORT) && defined(IEC1107_SUPPORT) if (nv_parms.seg_a.s.meter_uncalibrated) enable_ir_receiver(); #endif if ((phase->status & NEW_LOG)) { /* The background activity has informed us that it is time to perform a block processing operation. */ phase->status &= ~NEW_LOG; #if defined(MAGNETIC_INTERFERENCE_SUPPORT) if ((meter_status & STATUS_HIGH_MAGNETIC_FIELD)) { /* The meter is suffering magnetic tampering, so continuously charge for a great deal of electricity. */ x = phase->readings.V_rms*MAGNETIC_INTERFERENCE_CURRENT/(10*100); } else #endif //MM Added for LCD Fix; Start #if defined(IHD430_SUPPORT) RF_Tx[12]=total_active_power_array.uint8[0]; RF_Tx[13]=total_active_power_array.uint8[1]; RF_Tx[14]=total_active_power_array.uint8[2]; RF_Tx[15]=total_active_power_array.uint8[3]; RF_Tx[16] =0x28 ^ RF_Tx[12] ^ RF_Tx[13] ^ RF_Tx[14] ^ RF_Tx[15]; for (i=0; i<17; i++) { UCA2TXBUF=RF_Tx[i]; while(!(UCA2IFG&UCTXIFG)); } #endif lcd_display_mode++; switch( lcd_display_mode ) { case DISPLAY_VOLTAGE: change_display=1; temp= phase->readings.V_rms; if (temp <0) temp=0; LCDM1=0xC; LCDM2=0x29; break; case DISPLAY_CURRENT: change_display=1; temp= phase->readings.I_rms; if (temp <0) temp=0; LCDM1=0x9C; LCDM2=0x1; //MM Take care of different decimal. break; case DISPLAY_ACTIVE_POWER: change_display=1; temp= phase->readings.active_power; if (temp <0) temp=0; LCDM1=0xCF; LCDM2=0x1; break; case DISPLAY_REACTIVE_POWER: change_display=1; temp= phase->readings.reactive_power; if (temp <0) temp=0; LCDM1=0xC7; LCDM2=0x3; break; case DISPLAY_APPARENT_POWER: change_display=1; temp= phase->readings.apparent_power; if (temp <0) temp=0; LCDM1=0xB7; LCDM2=0x1; break; case DISPLAY_FREQUENCY: change_display=1; temp= phase->readings.frequency; if (temp <0) temp=0; LCDM1=0x8F; LCDM2=0x1; break; case DISPLAY_POWER_FACTOR: change_display=1; temp= phase->readings.power_factor/10; LCDM1=0x8F; LCDM2=0x50; if (temp < 0) { temp*= -1; LCDM3=0x1C; } else { LCDM3= 0x9C; } LCDM3constant=1; //Take negative and positive case for inductive and capacitive break; case DISPLAY_ACCUMULATED_POWER_TOTAL: change_display=1; temp= phase->consumed_active_energy/10; LCDM1=0x9F; LCDM2=0x1; break; default: change_display=0; break; } //temp=12345; //total_active_power=0x12345; // MM Comment back in to display active power // if (total_active_power <0) // temp=-(total_active_power); // else // temp=total_active_power; //MM Comment in two lines below for counter test //temp=12345; // temp2++; // temp=temp2; if(change_display) { // LCDM1 = 0; // LCDM2 = 0; if(!LCDM3constant) { LCDM3 = 0; } else { LCDM3constant=0; } LCDM4 = 0; LCDM5 = 0; LCDM6 = 0; LCDM7 = 0; LCDM8 = 0; LCDM9 = 0; LCDM10 = 0; LCDM11 = 0; LCDM12 = 0; LCDM13 = 0; LCDM14 = 0; LCDM15 = 0; LCDM16 = 0; LCDM17 = 0; LCDM18 = 0; LCDM19 = 0; LCDM20 = 0; thou_thou=0; hun_thou=0; ten_thou=0; thou=0; hun=0; ten=0; unit=0; while (temp >=1000000) { thou_thou++; temp-=1000000; } while (temp >=100000) { hun_thou++; temp-=100000; } while (temp >=10000) { ten_thou++; temp-=10000; } while (temp >=1000) { thou++; temp-=1000; } while (temp >=100) { hun++; temp-=100; } while (temp >=10) { ten++; temp-=10; } while (temp >=1) { unit++; temp--; } //MM: LCD fix to display higher active power readings if(thou_thou) { LCDM11 = LCD_Char_Map[hun]; LCDM9 = LCD_Char_Map[thou]; //LCDM8 = 0x1; LCDM7 = LCD_Char_Map[ten_thou]; LCDM5 = LCD_Char_Map[hun_thou]; LCDM3 = LCD_Char_Map[thou_thou]; } else if(hun_thou) { LCDM11 = LCD_Char_Map[ten]; if (lcd_display_mode==DISPLAY_CURRENT) LCDM8 = 0x1; else if(lcd_display_mode!=DISPLAY_ACCUMULATED_POWER_TOTAL) LCDM10 = 0x1; //MM do nothing LCDM9 = LCD_Char_Map[hun]; LCDM7 = LCD_Char_Map[thou]; LCDM5 = LCD_Char_Map[ten_thou]; LCDM3 = LCD_Char_Map[hun_thou]; } else { LCDM11 = LCD_Char_Map[unit]; LCDM9 = LCD_Char_Map[ten]; if (lcd_display_mode==DISPLAY_CURRENT || lcd_display_mode==DISPLAY_POWER_FACTOR) { LCDM6 = 0x1; } else if(lcd_display_mode==DISPLAY_ACCUMULATED_POWER_TOTAL) { LCDM10 = 0x1; } else { LCDM8 = 0x1; } if (lcd_display_mode!=DISPLAY_POWER_FACTOR) { LCDM3 = LCD_Char_Map[ten_thou]; } LCDM7 = LCD_Char_Map[hun]; LCDM5 = LCD_Char_Map[thou]; } if (lcd_display_mode==DISPLAY_ACCUMULATED_POWER_TOTAL) { lcd_display_mode=-2; } } //MM end if (operating_mode == OPERATING_MODE_NORMAL) { /* We can only do real power assessment in full operating mode */ #if !defined(SINGLE_PHASE) x = active_power(phase, phase_nv); #if defined(PRECALCULATED_PARAMETER_SUPPORT) #if defined(IRMS_SUPPORT) phase->readings.I_rms = current(phase, phase_nv, ch); #endif #if defined(VRMS_SUPPORT) phase->readings.V_rms = voltage(phase, phase_nv); #endif #endif #else x = active_power(); #if defined(PRECALCULATED_PARAMETER_SUPPORT) #if defined(IRMS_SUPPORT) phase->readings.I_rms = current(); #endif #if defined(VRMS_SUPPORT) phase->readings.V_rms = voltage(); #endif #endif #endif } #if defined(LIMP_MODE_SUPPORT) else if (operating_mode == OPERATING_MODE_LIMP) { /* In limp mode we must assess estimated power from only the measured current. */ /* We cannot properly determine current reversal in this mode. Also, current imbalance is really just a measure of which lead is still connected. Just treat both the imbalance and reversal conditions as OK */ #if !defined(SINGLE_PHASE) x = current(phase, phase_nv, ch); #if defined(PRECALCULATED_PARAMETER_SUPPORT) && defined(VRMS_SUPPORT) phase->readings.V_rms = voltage(phase, phase_nv); #endif #else x = current(); #if defined(PRECALCULATED_PARAMETER_SUPPORT) && defined(VRMS_SUPPORT) phase->readings.V_rms = voltage(); #endif #endif #if defined(PRECALCULATED_PARAMETER_SUPPORT) && defined(IRMS_SUPPORT) phase->readings.I_rms = x; #endif x = x*MAINS_NOMINAL_VOLTAGE/10; } #endif if (labs(x) < RESIDUAL_POWER_CUTOFF || (phase->status & V_OVERRANGE)) { x = 0; #if defined(PRECALCULATED_PARAMETER_SUPPORT) && defined(IRMS_SUPPORT) /* Avoid displaying a residual current, which is nothing more than integrated noise. */ //phase->I_rms = 0; #endif /* Turn off the LEDs, regardless of the internal state of the reverse and imbalance assessments. */ #if defined(PHASE_REVERSED_DETECTION_SUPPORT) meter_status &= ~STATUS_REVERSED; clr_reverse_current_indicator(); #endif #if defined(POWER_BALANCE_DETECTION_SUPPORT) meter_status &= ~STATUS_EARTHED; clr_earthed_indicator(); #endif } else { if (operating_mode == OPERATING_MODE_NORMAL) { #if defined(PHASE_REVERSED_DETECTION_SUPPORT) && defined(PHASE_REVERSED_IS_TAMPERING) if ((phase->status & PHASE_REVERSED)) { meter_status |= STATUS_REVERSED; set_reverse_current_indicator(); } else { meter_status &= ~STATUS_REVERSED; clr_reverse_current_indicator(); } #endif #if defined(POWER_BALANCE_DETECTION_SUPPORT) if ((phase->status & PHASE_UNBALANCED)) { meter_status |= STATUS_EARTHED; set_earthed_indicator(); } else { meter_status &= ~STATUS_EARTHED; clr_earthed_indicator(); } #endif } #if defined(LIMP_MODE_SUPPORT) else { #if defined(PHASE_REVERSED_DETECTION_SUPPORT) /* We cannot tell forward from reverse current in limp mode, so just say it is not reversed. */ meter_status &= ~STATUS_REVERSED; clr_reverse_current_indicator(); #endif #if defined(POWER_BALANCE_DETECTION_SUPPORT) /* We are definitely in the unbalanced state, but only set the indicator if we have persistence checked, and the current is sufficient to sustain operation. */ if ((phase->status & PHASE_UNBALANCED) && phase->readings.I_rms >= LIMP_MODE_MINIMUM_CURRENT) { meter_status |= STATUS_EARTHED; set_earthed_indicator(); } else { meter_status &= ~STATUS_EARTHED; clr_earthed_indicator(); } #endif /* Only run the IR interface if we are sure there is enough power from the supply to support the additional current drain. If we have not yet been calibrated we had better keep the IR port running so we can complete the calibration. */ #if defined(LIMP_MODE_SUPPORT) && defined(IEC1107_SUPPORT) if (phase->I_rms >= LIMP_MODE_MINIMUM_CURRENT_FOR_IR || nv_parms.seg_a.s.meter_uncalibrated) { enable_ir_receiver(); } else { disable_ir_receiver(); } #endif } #endif } //x /= 10; #if defined(SINGLE_PHASE) && defined(TOTAL_ACTIVE_ENERGY_SUPPORT) total_active_power = x; #else total_active_power += (x - phase->readings.active_power); #endif #if defined(PHASE_REVERSED_DETECTION_SUPPORT) && defined(PHASE_REVERSED_IS_GENERATION) #endif #if defined(IHD430_SUPPORT) total_active_power_array.uint32=total_active_power; #endif phase->readings.active_power = x; #if defined(PRECALCULATED_PARAMETER_SUPPORT) #if defined(REACTIVE_POWER_SUPPORT) #if defined(SINGLE_PHASE) x = reactive_power(); #else x = reactive_power(phase, phase_nv); #endif #if defined(SINGLE_PHASE) && defined(TOTAL_REACTIVE_ENERGY_SUPPORT) total_reactive_power = x; #else total_reactive_power += (x - phase->readings.reactive_power); #endif phase->readings.reactive_power = x; #endif #if defined(APPARENT_POWER_SUPPORT) #if defined(SINGLE_PHASE) phase->readings.apparent_power = apparent_power(); #else phase->readings.apparent_power = apparent_power(phase, phase_nv); #endif #endif #if defined(POWER_FACTOR_SUPPORT) /* The power factor should be calculated last */ #if defined(SINGLE_PHASE) phase->readings.power_factor = power_factor(); #else phase->readings.power_factor = power_factor(phase, phase_nv); #endif #endif #endif #if defined(PER_PHASE_ACTIVE_ENERGY_SUPPORT) // phase->active_energy_counter += x*phase->metrology.dot_prod_logged.sample_count; // while (phase->active_energy_counter > ENERGY_WATT_HOUR_THRESHOLD) // { // phase->active_energy_counter -= ENERGY_WATT_HOUR_THRESHOLD; // phase->consumed_active_energy++; // } #endif #if defined(PRECALCULATED_PARAMETER_SUPPORT) && defined(MAINS_FREQUENCY_SUPPORT) #if defined(SINGLE_PHASE) phase->readings.frequency = frequency(); #else phase->readings.frequency = frequency(phase, phase_nv); #endif #endif #if defined(MAGNETIC_INTERFERENCE_SUPPORT) #if !defined(SINGLE_PHASE) if (ch == 0) #endif { if ((meter_status & STATUS_HIGH_MAGNETIC_FIELD)) { if (phase->sample_count_logged/magnetic_sensor_count_logged < MAGNETIC_INTERFERENCE_SAMPLE_RATIO) { if (--magnetic_interference_persistence <= -MAGNETIC_INTERFERENCE_PERSISTENCE_CHECK) { meter_status &= ~STATUS_HIGH_MAGNETIC_FIELD; magnetic_interference_persistence = 0; } } else { magnetic_interference_persistence = 0; } } else { if (phase->sample_count_logged/magnetic_sensor_count_logged >= MAGNETIC_INTERFERENCE_SAMPLE_RATIO) { if (++magnetic_interference_persistence >= MAGNETIC_INTERFERENCE_PERSISTENCE_CHECK) { meter_status |= STATUS_HIGH_MAGNETIC_FIELD; magnetic_interference_persistence = 0; } } else { magnetic_interference_persistence = 0; } } } #endif } #if defined(LIMP_MODE_SUPPORT) /* The voltage channel DC estimate will never move very much when the meter is operating normally. If it does move, there must be some tampering, such as a diode between the grid and the meter. */ if (operating_mode == OPERATING_MODE_NORMAL) { if (phase->readings.V_rms < LIMP_MODE_VOLTAGE_THRESHOLD*100 || phase->metrology.V_dc_estimate[0] > UPPER_TAMPER_V_DC_ESTIMATE || phase->metrology.V_dc_estimate[0] < LOWER_TAMPER_V_DC_ESTIMATE) { switch_to_limp_mode(); } } else if (operating_mode == OPERATING_MODE_LIMP) { if (phase->readings.V_rms >= NORMAL_MODE_VOLTAGE_THRESHOLD*100 && phase->metrology.V_dc_estimate[1] <= UPPER_LIMP_TAMPER_V_DC_ESTIMATE && phase->metrology.V_dc_estimate[1] >= LOWER_LIMP_TAMPER_V_DC_ESTIMATE) { /* The LCD might need to be revived */ #if defined(__MSP430__) LCDawaken(); #else /* Tell the world we are ready to start */ #endif switch_to_normal_mode(); } } #endif #if !defined(SINGLE_PHASE) phase++; phase_nv++; } #endif #if !defined(SINGLE_PHASE) && defined(NEUTRAL_MONITOR_SUPPORT) && defined(IRMS_SUPPORT) if ((neutral.status & NEW_LOG)) { /* The background activity has informed us that it is time to perform a block processing operation. */ neutral.status &= ~NEW_LOG; neutral.readings.I_rms = neutral_current(); } #endif #if defined(MULTI_RATE_SUPPORT) tariff_management(); #endif /* Do display and other housekeeping here */ if ((meter_status & TICKER)) { /* Two seconds have passed */ /* We have a 2 second tick */ meter_status &= ~TICKER; #if defined(__MSP430__) && defined(BASIC_LCD_SUPPORT) /* Update the display, cycling through the phases */ update_display(); #endif custom_2second_handler(); #if (defined(RTC_SUPPORT) || defined(CUSTOM_RTC_SUPPORT)) && defined(CORRECTED_RTC_SUPPORT) correct_rtc(); #endif } custom_keypad_handler(); custom_mainloop_handler(); #if defined(MESH_NET_SUPPORT) if (rf_service) { rf_service = 0; rf_tick_service(); } #endif } #if !defined(__AQCOMPILER__) && !defined(__IAR_SYSTEMS_ICC__) return 0; #endif }