예제 #1
0
파일: start.c 프로젝트: songtzu/study
void 
cstart(void)
{
  uint16_t* p_gdt_limit;
  uint32_t* p_gdt_base;
  uint16_t* p_idt_limit;
  uint32_t* p_idt_base;

  display_str("\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
      "=====<cstart> begins=====\n");

  /* copy GDT from LOADER to new GDT */
  memcpy(&gdt, (void*)(*((uint32_t*)(&gdt_ptr[2]))), /* base of old GDT */
      *((uint16_t*)(&gdt_ptr[0])) + 1); /* limit of old GDT */
  
  p_gdt_limit = (uint16_t*)(&gdt_ptr[0]);
  p_gdt_base  = (uint32_t*)(&gdt_ptr[2]);
  *p_gdt_limit  = GDT_SIZE * sizeof(descriptor_t) - 1;
  *p_gdt_base   = (uint32_t)&gdt;

  p_idt_limit = (uint16_t*)(&idt_ptr[0]);
  p_idt_base  = (uint32_t*)(&idt_ptr[2]);
  *p_idt_limit  = IDT_SIZE * sizeof(gate_t) - 1;
  *p_idt_base   = (uint32_t)&idt;

  init_port();

  display_str("=====<cstart> ends=====\n");
}
예제 #2
0
void set_volume(void) {
  uint8_t mode = SHOW_MENU;
  uint8_t volume;

  timeoutcounter = INACTIVITYTIMEOUT;;  
  volume = eeprom_read_byte((uint8_t *)EE_VOLUME);

  while (1) {
    if (just_pressed || pressed) {
      timeoutcounter = INACTIVITYTIMEOUT;;  
      // timeout w/no buttons pressed after 3 seconds?
    } else if (!timeoutcounter) {
      //timed out!
      displaymode = SHOW_TIME;     
      return;
    }
    if (just_pressed & 0x1) { // mode change
      return;
    }
    if (just_pressed & 0x2) {
      just_pressed = 0;
      if (mode == SHOW_MENU) {
	// start!
	mode = SET_VOL;
	// display volume
	if (volume) {
	  display_str("vol high");
	  display[5] |= 0x1;
	} else {
	  display_str("vol  low");
	}
	display[6] |= 0x1;
	display[7] |= 0x1;
	display[8] |= 0x1;
      } else {	
	displaymode = SHOW_TIME;
	return;
      }
    }
    if (just_pressed & 0x4) {
      just_pressed = 0;
      if (mode == SET_VOL) {
	volume = !volume;
	if (volume) {
	  display_str("vol high");
	  display[5] |= 0x1;
	} else {
	  display_str("vol  low");
	}
	display[6] |= 0x1;
	display[7] |= 0x1;
	display[8] |= 0x1;
	eeprom_write_byte((uint8_t *)EE_VOLUME, volume);
	speaker_init();
	beep(4000, 1);
      }
    }
  }
}
예제 #3
0
void set_region(void) {
  uint8_t mode = SHOW_MENU;

  timeoutcounter = INACTIVITYTIMEOUT;;  
  region = eeprom_read_byte((uint8_t *)EE_REGION);

  while (1) {
    if (just_pressed || pressed) {
      timeoutcounter = INACTIVITYTIMEOUT;;  
      // timeout w/no buttons pressed after 3 seconds?
    } else if (!timeoutcounter) {
      //timed out!
      displaymode = SHOW_TIME;     
      return;
    }
    if (just_pressed & 0x1) { // mode change
      return;
    }
    if (just_pressed & 0x2) {
      just_pressed = 0;
      if (mode == SHOW_MENU) {
	// start!
	mode = SET_REG;
	// display region
	if (region == REGION_US) {
	  display_str("usa-12hr");
	} else {
	  display_str("eur-24hr");
	}
      } else {	
	displaymode = SHOW_TIME;
	return;
      }
    }
    if (just_pressed & 0x4) {
      just_pressed = 0;
      if (mode == SET_REG) {
	region = !region;
	if (region == REGION_US) {
	  display_str("usa-12hr");
	} else {
	  display_str("eur-24hr");
	}
	eeprom_write_byte((uint8_t *)EE_REGION, region);
      }
    }
  }
}
예제 #4
0
void set_dimmer(void) {
  uint8_t mode = SHOW_MENU;

  timeoutcounter = INACTIVITYTIMEOUT;;  

  while (1) {
    if (just_pressed || pressed) {
      timeoutcounter = INACTIVITYTIMEOUT;;  
      // timeout w/no buttons pressed after 3 seconds?
    } else if (!timeoutcounter) {
      //timed out!
      displaymode = SHOW_TIME;     
      return;
    }
    if (just_pressed & 0x1) { // mode change
      return;
    }
    if (just_pressed & 0x2) {
      just_pressed = 0;
      if (mode == SHOW_MENU) {
	// start!
	mode = SET_DIMMER;
	if (dimmer_on) {
	  display_str("dimr on ");
	} else {
	  display_str("dimr off");
	}
      } else {	
	displaymode = SHOW_TIME;
	return;
      }
    }
    if (just_pressed & 0x4) {
      just_pressed = 0;
      if (mode == SET_DIMMER) {
	dimmer_on = !dimmer_on;
	if (dimmer_on) {
	  display_str("dimr on ");
          dimmer_update();
	} else {
	  display_str("dimr off");
          set_vfd_brightness(brightness_level);
	}
	eeprom_write_byte((uint8_t *)EE_DIMMER, dimmer_on);
      }
    }
  }
}
예제 #5
0
// This turns on/off the alarm when the switch has been
// set. It also displays the alarm time
void setalarmstate(void) {
  if (ALARM_PIN & _BV(ALARM)) { 
    // Don't display the alarm/beep if we already have
    if  (!alarm_on) {
      // alarm on!
      alarm_on = 1;
      // reset snoozing
      snoozetimer = 0;
      // show the status on the VFD tube
      display_str("alarm on");
      // its not actually SHOW_SNOOZE but just anything but SHOW_TIME
      displaymode = SHOW_SNOOZE;
      delayms(1000);
      // show the current alarm time set
      display_alarm(alarm_h, alarm_m);
      delayms(1000);
      // after a second, go back to clock mode
      displaymode = SHOW_TIME;
    }
  } else {
    if (alarm_on) {
      // turn off the alarm
      alarm_on = 0;
      snoozetimer = 0;
      if (alarming) {
	// if the alarm is going off, we should turn it off
	// and quiet the speaker
	DEBUGP("alarm off");
	alarming = 0;
	TCCR1B &= ~_BV(CS11); // turn it off!
	PORTB |= _BV(SPK1) | _BV(SPK2);
      } 
    }
  }
}
예제 #6
0
// When the alarm is going off, pressing a button turns on snooze mode
// this sets the snoozetimer off in MAXSNOOZE seconds - which turns on
// the alarm again
void setsnooze(void) {
  //snoozetimer = eeprom_read_byte((uint8_t *)EE_SNOOZE);
  //snoozetimer *= 60; // convert minutes to seconds
  snoozetimer = MAXSNOOZE;
  DEBUGP("snooze");
  display_str("snoozing");
  displaymode = SHOW_SNOOZE;
  delayms(1000);
  displaymode = SHOW_TIME;
}
예제 #7
0
void
exception_handler(int vec_no, int err_code, int eip, int cs, int eflags)
{
    int i;
    int text_color = 0x74;

    char* err_msg[] = {
        "#DE divide error",
        "#DB reserved",
        "--  nmi interrupt",
        "#BP breakpoint",
        "#OF overflow",
        "#BR bound range exceeded",
        "#UD invalid opcode (undefined opcode)",
        "#NM device not available (no match coprocessor)",
        "#DF double fault",
        "    coprocessor segment overrun (reserved)",
        "#TS invalid tss",
        "#NP segment not present",
        "#SS stack segment fault",
        "#GP general protection",
        "#PF page fault",
        "--  (intel reserved. do not use)",
        "#MF x87 FPU floating-point error (math fault)",
        "#AC alignment check",
        "#MC machine check",
        "#XF SIMD floating-point exception"
    };

    disp_pos = 0;
    for (i = 0; i < 80 * 5; ++i)
        display_str(" ");
    disp_pos = 0;

    display_color_str("exception! --> ", text_color);
    display_color_str(err_msg[vec_no], text_color);
    display_color_str("\n\n", text_color);
    display_color_str("eflags: ", text_color);
    display_int(eflags);
    display_color_str("cs: ", text_color);
    display_int(cs);
    display_color_str("eip: ", text_color);
    display_int(eip);

    if (0xffffffff != err_code) {
        display_color_str("error code: ", text_color);
        display_int(err_code);
    }
}
예제 #8
0
void set_brightness(void) {
  uint8_t mode = SHOW_MENU;

  timeoutcounter = INACTIVITYTIMEOUT;;  

  while (1) {
    if (just_pressed || pressed) {
      timeoutcounter = INACTIVITYTIMEOUT;;  
      // timeout w/no buttons pressed after 3 seconds?
    } else if (!timeoutcounter) {
      //timed out!
      displaymode = SHOW_TIME;     
      eeprom_write_byte((uint8_t *)EE_BRIGHT, brightness_level);
      return;
    }
    if (just_pressed & 0x1) { // mode change
      return;
    }
    if (just_pressed & 0x2) {

      just_pressed = 0;
      if (mode == SHOW_MENU) {
	// start!
	mode = SET_BRITE;
	// display brightness
        set_vfd_brightness(brightness_level);
	display_str("brite ");
	display[7] = pgm_read_byte(numbertable_p + (brightness_level / 10)) | 0x1;
	display[8] = pgm_read_byte(numbertable_p + (brightness_level % 10)) | 0x1;
      } else {	
	displaymode = SHOW_TIME;
	eeprom_write_byte((uint8_t *)EE_BRIGHT, brightness_level);
	return;
      }
    }
    if ((just_pressed & 0x4) || (pressed & 0x4)) {
      just_pressed = 0;
      if (mode == SET_BRITE) {
	brightness_level += BRIGHTNESS_INCREMENT;
	if (brightness_level > BRIGHTNESS_MAX)
	  brightness_level = BRIGHTNESS_MIN;
	display[7] = pgm_read_byte(numbertable_p + (brightness_level / 10)) | 0x1;
	display[8] = pgm_read_byte(numbertable_p + (brightness_level % 10)) | 0x1;
        set_vfd_brightness(brightness_level);
      }
    }
  }
}
예제 #9
0
int main(void) {
  //  uint8_t i;
  uint8_t mcustate;

  // turn boost off
  TCCR0B = 0;
  BOOST_DDR |= _BV(BOOST);
  BOOST_PORT &= ~_BV(BOOST); // pull boost fet low

  // check if we were reset
  mcustate = MCUSR;
  MCUSR = 0;

  wdt_disable();
  // now turn it back on... 2 second time out
  //WDTCSR |= _BV(WDP0) | _BV(WDP1) | _BV(WDP2);
  //WDTCSR = _BV(WDE);
  wdt_enable(WDTO_2S);
  kickthedog();

  // we lost power at some point so lets alert the user
  // that the time may be wrong (the clock still works)
  timeunknown = 1;

  // have we read the time & date from eeprom?
  restored = 0;

  // setup uart
  uart_init(BRRL_192);
  //DEBUGP("VFD Clock");
  DEBUGP("!");

  //DEBUGP("turning on anacomp");
  // set up analog comparator
  ACSR = _BV(ACBG) | _BV(ACIE); // use bandgap, intr. on toggle!
  // settle!
  if (ACSR & _BV(ACO)) {
    // hmm we should not interrupt here
    ACSR |= _BV(ACI);

    // even in low power mode, we run the clock 
    DEBUGP("clock init");
    clock_init();  

  } else {
    // we aren't in low power mode so init stuff

    // init io's
    initbuttons();
    
    VFDSWITCH_PORT &= ~_BV(VFDSWITCH);
    
    DEBUGP("turning on buttons");
    // set up button interrupts
    DEBUGP("turning on alarmsw");
    // set off an interrupt if alarm is set or unset
    EICRA = _BV(ISC00);
    EIMSK = _BV(INT0);
  
    displaymode = SHOW_TIME;
    DEBUGP("vfd init");
    vfd_init();
   
    dimmer_init();
 
    DEBUGP("boost init");
    brightness_level = eeprom_read_byte((uint8_t *)EE_BRIGHT);
    boost_init(brightness_level);
    sei();

    region = eeprom_read_byte((uint8_t *)EE_REGION);
    
    DEBUGP("speaker init");
    speaker_init();

    beep(4000, 1);

    DEBUGP("clock init");
    clock_init();  

    DEBUGP("alarm init");
    setalarmstate();
  }
  DEBUGP("done");
  while (1) {
    //_delay_ms(100);
    kickthedog();
    //uart_putc_hex(ACSR);
    if (ACSR & _BV(ACO)) {
      // DEBUGP("SLEEPYTIME");
      gotosleep();
      continue;
    }
    //DEBUGP(".");
    if (just_pressed & 0x1) {
      just_pressed = 0;
      switch(displaymode) {
      case (SHOW_TIME):
	displaymode = SET_ALARM;
	display_str("set alarm");
	set_alarm();
	break;
      case (SET_ALARM):
	displaymode = SET_TIME;
	display_str("set time");
	set_time();
	timeunknown = 0;
	break;
      case (SET_TIME):
	displaymode = SET_DATE;
	display_str("set date");
	set_date();
	break;
      case (SET_DATE):
	displaymode = SET_BRIGHTNESS;
	display_str("set brit");
	set_brightness();
	break;
      case (SET_BRIGHTNESS):
	displaymode = SET_DIMMER;
	display_str("set dimr");
	set_dimmer();
	break;
      case (SET_DIMMER):
	displaymode = SET_VOLUME;
	display_str("set vol ");
	set_volume();
	break;
      case (SET_VOLUME):
	displaymode = SET_REGION;
	display_str("set regn");
	set_region();
	break;
	/*
      case (SET_REGION):
	displaymode = SET_SNOOZE;
	display_str("set snoz");
	set_snooze();
	break;
	*/
      default:
	displaymode = SHOW_TIME;
      }
    } else if ((just_pressed & 0x2) || (just_pressed & 0x4)) {
      just_pressed = 0;
      displaymode = NONE;
      display_date(DAY);

      kickthedog();
      delayms(1500);
      kickthedog();

      displaymode = SHOW_TIME;     
    } 
  }
}
예제 #10
0
// We can display the current date!
void display_date(uint8_t style) {

  // This type is mm-dd-yy OR dd-mm-yy depending on our pref.
  if (style == DATE) {
    display[0] = 0;
    display[6] = display[3] = 0x02;     // put dashes between num

    if (region == REGION_US) {
      // mm-dd-yy
      display[1] = pgm_read_byte(numbertable_p + (date_m / 10));
      display[2] = pgm_read_byte(numbertable_p + (date_m % 10));
      display[4] = pgm_read_byte(numbertable_p + (date_d / 10));
      display[5] = pgm_read_byte(numbertable_p + (date_d % 10));
    } else {
      // dd-mm-yy
      display[1] = pgm_read_byte(numbertable_p + (date_d / 10));
      display[2] = pgm_read_byte(numbertable_p + (date_d % 10));
      display[4] = pgm_read_byte(numbertable_p + (date_m / 10));
      display[5] = pgm_read_byte(numbertable_p + (date_m % 10));
    }
    // the yy part is the same
    display[7] = pgm_read_byte(numbertable_p + (date_y / 10));
    display[8] = pgm_read_byte(numbertable_p + (date_y % 10));

  } else if (style == DAY) {
    // This is more "Sunday June 21" style

    uint16_t month, year;
    uint8_t dotw;

    // Calculate day of the week
    
    month = date_m;
    year = 2000 + date_y;
    if (date_m < 3)  {
      month += 12;
      year -= 1;
    }
    dotw = (date_d + (2 * month) + (6 * (month+1)/10) + year + (year/4) - (year/100) + (year/400) + 1) % 7;

    // Display the day first
    display[8] = display[7] = 0;
    switch (dotw) {
    case 0:
      display_str("sunday"); break;
    case 1:
      display_str("monday"); break;
    case 2:
      display_str("tuesday"); break;
    case 3:
      display_str("wednsday"); break;
    case 4:
      display_str("thursday"); break;
    case 5:
      display_str("friday"); break;
    case 6:
      display_str("saturday"); break;
    }
    
    // wait one seconds about
    delayms(1000);

    // Then display the month and date
    display[6] = display[5] = display[4] = 0;
    switch (date_m) {
    case 1:
      display_str("jan"); break;
    case 2:
      display_str("feb"); break;
    case 3:
      display_str("march"); break;
    case 4:
      display_str("april"); break;
    case 5:
      display_str("may"); break;
    case 6:
      display_str("june"); break;
    case 7:
      display_str("july"); break;
    case 8:
      display_str("augst"); break;
    case 9:
      display_str("sept"); break;
    case 10:
      display_str("octob"); break;
    case 11:
      display_str("novem"); break;
    case 12:
      display_str("decem"); break;
    }
    display[7] = pgm_read_byte(numbertable_p + (date_d / 10));
    display[8] = pgm_read_byte(numbertable_p + (date_d % 10));
    
  }
}
예제 #11
0
SCSAPI_VOID telemetry_frame_end(const scs_event_t /*event*/, const void *const /*event_info*/, const scs_context_t /*context*/)
{
  if (!serial_port.is_valid())
    return;
    
  const unsigned long now = GetTickCount();
  const unsigned long diff = now - last_update;
  if (diff < 50)
    return;
    
  last_update = now;
  
  const float speed_mph = telemetry.speed * METERS_PER_SEC_TO_MILES_PER_HOUR;
  const float speed_kph = telemetry.speed * METERS_PER_SEC_TO_KM_PER_HOUR;
  
  const float fuel_ratio = telemetry.fuel /  telemetry.fuel_capacity;
  

  
  unsigned idx = 0;
  
  memset(packet, 0, PACKET_MAX_SIZE);
  
#define PUT_BYTE(X) packet[idx++] = (unsigned char)(X)
#define PUT_BYTE_FLOAT(X) packet[idx++] = (unsigned char)(float_to_byte(X))
#define GETFLTOPT(X) (option_file.get_option_float(X, 1.0f))
  
  // Packet header
  PUT_BYTE(PACKET_SYNC);
  PUT_BYTE(PACKET_VER);
  
  // Convert data for output by servos
  // Adjust the constant values to map to servo range
  
  PUT_BYTE_FLOAT(fabs(telemetry.speed) *        GETFLTOPT("factor_speed")); // Absolute value for when reversing
  PUT_BYTE_FLOAT(telemetry.engine_rpm *         GETFLTOPT("factor_engine_rpm"));
  PUT_BYTE_FLOAT(telemetry.brake_air_pressure * GETFLTOPT("factor_brake_air_pressure"));
  PUT_BYTE_FLOAT(telemetry.brake_temperature *  GETFLTOPT("factor_brake_temperature"));
  PUT_BYTE_FLOAT(fuel_ratio *                   GETFLTOPT("factor_fuel_ratio")); // Fuel level
  PUT_BYTE_FLOAT(telemetry.oil_pressure *       GETFLTOPT("factor_oil_pressure"));
  PUT_BYTE_FLOAT(telemetry.oil_temperature *    GETFLTOPT("factor_oil_temperature"));
  PUT_BYTE_FLOAT(telemetry.water_temperature *  GETFLTOPT("factor_water_temperature"));
  PUT_BYTE_FLOAT(telemetry.battery_voltage *    GETFLTOPT("factor_battery_voltage"));
  
  
  // Pack data for LEDs into bytes
  
  // Truck lights
  PUT_BYTE(PACKBOOL(
    0, telemetry.light_parking,
    telemetry.light_lblinker, telemetry.light_rblinker,
    telemetry.light_low_beam, telemetry.light_high_beam,
    telemetry.light_brake, telemetry.light_reverse));
    
  // Warning lights
  PUT_BYTE(PACKBOOL(
    telemetry.parking_brake, telemetry.motor_brake,
    telemetry.brake_air_pressure_warning, telemetry.brake_air_pressure_emergency,
    telemetry.fuel_warning, telemetry.battery_voltage_warning,
    telemetry.oil_pressure_warning, telemetry.water_temperature_warning));
  
  // Enabled flags
  PUT_BYTE(PACKBOOL(
    0,0,0,0,0, 0,
    telemetry.electric_enabled, telemetry.engine_enabled));
    

  // Build string for LCD display
    
  std::stringstream ss;
  
  ss.width(3);
  ss << abs(int(speed_mph));
  ss << " MPH";
  
  ss << "   G  ";
  
  if (telemetry.engine_gear > 0)
  {
    ss << "D";
    ss.width(2);
    ss << telemetry.engine_gear;
  }
  else if (telemetry.engine_gear == 0)
  {
    ss << "N  ";
  }
  else
  {
    ss << "R";
    ss.width(2);
    ss << abs(telemetry.engine_gear);
  }
  
  ss << "\n";
  
  ss.width(3);
  ss << abs(int(speed_kph));
  ss << " KPH";
  
  ss << "   F ";
  
  ss.width(3);
  ss << int(fuel_ratio * 100.0f) << "%";
  
  
  ss.width(3);
  ss << abs(int(speed_kph));
  
  std::string display_str(ss.str());
  
  // Write length of string
  PUT_BYTE(display_str.size());
  // Followed by string
  display_str.copy((char*)&packet[idx], PACKET_MAX_SIZE - idx);
  idx += display_str.size();
  
  
  serial_port.write(packet, idx);
}