コード例 #1
0
ファイル: lcd.c プロジェクト: MightyPork/avr-lib
/** Define a glyph */
void lcd_glyph_P(const uint8_t index, const uint8_t* array)
{
	lcd_addr_cg(index * 8);
	for (uint8_t i = 0; i < 8; ++i)	{
		lcd_write(pgm_read_byte(&array[i]));
	}

	// restore previous position
	lcd_xy(_pos.x, _pos.y);
	_addrtype = TEXT;
}
コード例 #2
0
// display an icon at position x,y
void d_icon(int x,int y)                            //display first bit of 8x8 icon at x,y position
{
	char i,j;

	if (p_x%16 <8)                              //if x position is on upper byte of 16 bit
	{
		for (j=0;j<8;j++)			//repeat for 8 vertical line
		{
			lcd_xy(p_x/16,(p_y+j)%64);	//go to the location and y is re-adjust after adding j ( > 64 after adding j )
			send_char(0);			//send upperbyte with shifting according to the x position 
			send_char(0);			//send lowerbyte with shifting according to the x position 
		}
	}

	else
	{
		for (j=0;j<8;j++)
		{
			lcd_xy(p_x/16,(p_y+j)%64);		//go to the location and y is re-adjust after adding j ( > 64 after adding j )
			send_char (0);				//send dummy data to the upperbyte
			send_char(0);				//send lowerbyte data with shifting according to the x position 
			if(p_x/16 == 7) lcd_xy(0,p_y+j);
			send_char(0);				//send upperbyte of the next 'x' with shifting according to the x position 
		}
	}



	if (x%16 <8)							//if x position is on upper byte of 16 bit
	{
		for (j=0;j<8;j++)					//repeat for 8 vertical line
		{
			lcd_xy(x/16,(y+j)%64);				//go to the location and y is re-adjust after adding j ( > 64 after adding j )
			send_char(icon[j]>> x%8);			//send upperbyte with shifting according to the x position 
			send_char(icon[j]<< (8-x%8));			//send lowerbyte with shifting according to the x position 
		}
	}

	else
	{
		for (j=0;j<8;j++)
コード例 #3
0
ファイル: main.c プロジェクト: skeezix/zikzak
int main( void )
{
  uint32_t val = 0;
  char s[sizeof("4294967295")];		// ASCII space for 32 bit number
  char textbuf [ 16 + 1 ];

  //_delay_ms ( 5000 );

  lcd_init();

#if 1
  char *p;

  if ( 1 ) {
    char  *source = "68u65gujl";
    unsigned int i;
    for ( i = 0; i < strlen ( source ); i++ ) {
      textbuf [ i ] = source [ i ];
    }
    textbuf [ i ] = '\0';
    lcd_xy( 0, 0 );
    lcd_puts( textbuf );			// display number right adjusted
  }
#endif

#if 0
  for(;;){
    ultoa( val, s, 10 );
    lcd_xy( 0, 1 );
    lcd_blank( 10 - strlen( s ));	// insert spaces until number
    lcd_puts( s );			// display number right adjusted
    val++;
  }
#endif

  return ( 0 );
}
コード例 #4
0
ファイル: lcd.c プロジェクト: MightyPork/avr-lib
/** Write a data byte */
void lcd_write(uint8_t bb)
{
	if (_addrtype == TEXT) {
		if (bb == '\r') {
			// CR
			_pos.x = 0;
			lcd_xy(_pos.x, _pos.y);
			return;
		}

		if (bb == '\n') {
			// LF
			_pos.y++;
			lcd_xy(_pos.x, _pos.y);
			return;
		}

		_pos.x++;
	}

	_lcd_wait_bf();
	pin_high(LCD_RS);  // select data register
	_lcd_write_byte(bb);  // send data byte
}
コード例 #5
0
ファイル: lcd.c プロジェクト: jcmvbkbc/stove
void lcd_puts_xy(uint8_t x, uint8_t y, const char *str)
{
	for (lcd_xy(x, y); x < LCD_STRIDE && *str; ++x, ++str) {
		lcd_putc(*str);
	}
}
コード例 #6
0
ファイル: KEYPAD.c プロジェクト: ranggageni/Genius
char _key_string(char __mode) {
    unsigned char	 __chr = 0, __i = 0;
    uint8_t  __key = 0;

    if(__mode==0) {
        CURSOR_SHOW;
        while(1) {
            __key = _key_scan(_PAD_SINGLE);
            if(__key==_KEY_NULL || __key==_KEY_TIKET || __key==_KEY_MENU || __key==_KEY_SHIFT);
            else if(__key==_KEY_CANCEL) {
                __chr_count = 0;
                CURSOR_HIDE;
                _SHIFT_OFF;//
                return 1;
            }
            else if(__key==_KEY_ENTER) {
                __chr_count = 0;
                CURSOR_HIDE;
                _SHIFT_OFF;//
                return 0;
            }
            else if(__key==_KEY_CLEAR) {
                if(__chr_count>0) {
                    _LCD_LEFT;
                    _lcd(0x10);
                    _LCD_LEFT;
                    __buf_string[__chr_count-1] = '\0';
                    __chr_count--;
                }
            }
            else {
                if(__chr_count<__max_string) {
                    _lcd(_table_alphanum(0, __key, 0));
                    __buf_string[__chr_count] = _table_alphanum(0, __key, 0);
                    __buf_string[__chr_count + 1] = '\0';
                    __chr_count++;
                }
            }
        }
    }
    if(__mode==_STRING_ALPHANUM) {
        while(1) {
            CURSOR_SHOW;
            __key = _key_scan(_PAD_MULTI);
            if(__key == _KEY_NULL || __key == _KEY_TIKET || __key == _KEY_MENU);
            else if(__key == _KEY_CANCEL) {
                CURSOR_HIDE;
                _SHIFT_OFF;
                return 1;
            }
            else if(__key == _KEY_ENTER) {
                CURSOR_HIDE;
                _SHIFT_OFF;
                return 0;
            }
            else if(__key == _KEY_SHIFT) {
                __caps_lock = __caps_lock ^ 1;
            }
            else if(__key == _KEY_CLEAR) {
                if(__chr_count > 0) {
                    if(!__key_shift) {
                        _LCD_LEFT;
                        _lcd(0x10);
                        _LCD_LEFT;
                        __buf_string[__chr_count - 1] = '\0';
                        __chr_count--;
                        if(__chr_count == 19) {
                            lcd_put(2, 20, 0x10);
                            lcd_xy(2, 20);
                        }
                        _SHIFT_OFF;
                        CURSOR_SHOW;
                        //_SHIFT_FREE;
                    }
                }
            }
            else {
                if(__chr_count < __max_string) {
                    if(__key != __buf_anum) {
                        __buf_anum = __key;
                        __hit_count = 0;
                        if(__key_shift == 1 && __buf_anum != 0) {
                            _LCD_RIGHT;
                            __chr_count++;
                            if(__chr_count == 20)
                                lcd_xy(3, 1);
                        }
                    }
                    else {
                        __hit_count++;
                    }
                    __chr = _table_alphanum(__caps_lock, __key, __hit_count);
                    if(__chr == '\0') {
                        __hit_count = 0;
                        __chr = _table_alphanum(__caps_lock, __key, __hit_count);
                    }
                    if(__chr_count < __max_string) {
                        _lcd(__chr);
                        _LCD_LEFT;
                        __buf_string[__chr_count] = __chr;
                        __buf_string[__chr_count + 1] = '\0';
                    }
                }
                CURSOR_SHOW;
                //else _SHIFT_LOCK;
            }
        }
    }
    if(__mode==_STRING_PASSWORD) {
        CURSOR_SHOW;
        while(1) {
            __key = _key_scan(_PAD_SINGLE);
            if(__key==_KEY_NULL || __key==_KEY_TIKET || __key==_KEY_MENU || __key==_KEY_SHIFT);
            else if(__key==_KEY_CANCEL) {
                __chr_count = 0;
                CURSOR_HIDE;
                return 1;
            }
            else if(__key==_KEY_ENTER) {
                __chr_count = 0;
                CURSOR_HIDE;
                return 0;
            }
            else if(__key==_KEY_CLEAR) {
                if(__chr_count>0) {
                    _LCD_LEFT;
                    _lcd(0x10);
                    _LCD_LEFT;
                    __buf_string[__chr_count-1] = '\0';
                    __chr_count--;
                }
            }
            else {
                if(__chr_count<__max_string) {
                    _lcd(0x2a);
                    __buf_string[__chr_count] = _table_alphanum(0, __key, 0);
                    __buf_string[__chr_count + 1] = '\0';
                    __chr_count++;
                }
            }
        }
    }
    if(__mode==_STRING_VALUE) {
        for(__i=0; __i<__max_string; __i++)
            _lcd('0');
        while(1) {
            __key = _key_scan(_PAD_SINGLE);
            if(__key==_KEY_NULL || __key==_KEY_TIKET || __key==_KEY_MENU || __key==_KEY_SHIFT || __key==_KEY_CLEAR);
            else if(__key==_KEY_CANCEL) {
                __chr_count = 0;
                CURSOR_HIDE;
                return 1;
            }
            else if(__key==_KEY_ENTER) {
                __chr_count = 0;
                CURSOR_HIDE;
                return 0;
            }
            else {
                for(__i=0; __i<__max_string - 1; __i++)
                    __buf_string[__i] = __buf_string[__i + 1];
                __buf_string[__max_string - 1] = _table_alphanum(0, __key, 0);
                __buf_string[__max_string] = '\0';
                for(__i=0; __i<__max_string; __i++)
                    _LCD_LEFT;
                for(__i=0; __i<__max_string; __i++)
                    _lcd(__buf_string[__i]);
            }
        }
    }
    return 0;
}
コード例 #7
0
ファイル: main.c プロジェクト: skeezix/shadowcar
int main( void )
{
  uint32_t val = 0;
  char textbuf [ (2*16) + 1 ]; // lcd

  /* setup
   */

  // LCD
  lcd_init();

  // Timer: enable a timer so we can measure passage of time
  //
  // Given: 20MHz clock
  // --> if we want resolution of ms (1/1000th second) .. actually, we want us (1/10th of a ms) so we can measure partial ms
  // --> and we have 1/20000000 clock resolution
  // -----> 2000 ticks will get us there (20,000 will get us ms)
  //
  // Goal: Use CTC interupt mode (CTC -> Clear on Timer Compare)
  // So a compare matches, it clears to zero and triggers interupt
  TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode 
  OCR1A = 2000; // number to compare against
  TIMSK1 |= (1 << OCIE1A); // Enable CTC interrupt 
  TCCR1B |= (1 << CS10); // Set up timer , with no prescaler (works at full MHz of clock)

  // Receiver setup - set up pin change interupt
#if 1
  EICRA &= ~ ( (1 << ISC01) | (1 << ISC01) ); // clear ISC01+ISC00
  EICRA |= ( (1 << ISC00) ); // 00 set and 01 unset means any edge will make event
  PCMSK0 |= ( (1 << PCINT0) | (1 << PCINT1) ); // Pins to monitor: PA0 and PA1
  PCICR |= (1 << PCIE0); // PA is monitored
#endif

  // Serial - setup (for motor controller)
  mc_setup();

  // TWI - set up
  unsigned char twibuf [ TWI_BUFFER_SIZE ];
  unsigned char TWI_slaveAddress; 
  TWI_slaveAddress = 0x10; // our TWI address
  TWI_Slave_Initialise( (unsigned char)((TWI_slaveAddress<<TWI_ADR_BITS) | (TRUE<<TWI_GEN_BIT) )); // Initialise TWI module as slave; include addr+general
  unsigned char twi_heartbeat_counter = 0;

  // setup done - kick up interupts
  sei();

  // lets burn the first couple of seconds, so the receiver can get some signal
  // before we start blasting stuff into the motor controllers
  {
    unsigned int start_sec = g_time_s;
    while ( g_time_s - start_sec < 3 ) {
      nop();
    }
  }

  // Start the TWI transceiver to enable reseption of the first command from the TWI Master.
  TWI_Start_Transceiver();

#if 1 // timer test .. show per-second counter update on lcd
  if ( 1 ) {
    unsigned int last_sec = g_time_s;
    unsigned int last_us = _g_time_us_tick;

    unsigned char sent_l = 0, sent_r = 0;
    char message [ 17 ];

    while(1) {
      unsigned int ch1 = g_ch1_duration;
      unsigned int ch2 = g_ch2_duration;

      // 100ms has past?
      if ( _g_time_us_tick - last_us > 1000 ) {

        if ( g_control_twi ) {
          // we're on TWI control, but if nothing comes in.. revert back to RC
          if ( g_time_s - g_control_last_s > 2 ) {
            g_control_twi = 0;
          }
        } else {
          mc_set_by_receiver ( ch1, ch2, &sent_l, &sent_r, message );
        }

        last_us = _g_time_us_tick;
      } // .1sec tick

      // one second has past? update lcd
      if ( g_time_s != last_sec ) {
        //sprintf ( textbuf, "recv %2d %2d     ", g_ch1_duration, g_ch2_duration );
        sprintf ( textbuf, "m %2d %2d th %2d %2d #", sent_l, sent_r, ch1, ch2 );
        lcd_xy ( 0, 0 );
        lcd_puts( textbuf ); // display number right adjusted

        //sprintf ( textbuf, "t%2d #", g_time_s );
        sprintf ( textbuf, "t%2d # %s", g_time_s, message );
        lcd_xy ( 0, 1 );
        lcd_puts( textbuf ); // display number right adjusted

        last_sec = g_time_s;
      } // 1 sec tick

      // TWI/I2C stuff, talk to r-pi
      //

      // Check if the TWI Transceiver has completed an operation.
      if ( ! TWI_Transceiver_Busy() ) {

        // Check if the last operation was successful
        if ( TWI_statusReg.lastTransOK ) {

          // Check if the last operation was a reception
          if ( TWI_statusReg.RxDataInBuf ) {
            TWI_Get_Data_From_Transceiver ( twibuf, 3 );

            // Check if the last operation was a reception as General Call        
            if ( TWI_statusReg.genAddressCall ) {
              // don't care

            } else { // Ends up here if the last operation was a reception as Slave Address Match   
              // Example of how to interpret a command and respond.

#if 0            
              // TWI_CMD_MASTER_WRITE stores the data to PORTB
              if (twibuf[0] == TWI_CMD_MASTER_WRITE) {
                PORTB = twibuf[1];                            
              }
#endif

              // TWI_CMD_MASTER_READ prepares the data from PINB in the transceiver buffer for the TWI master to fetch.
              if ( twibuf[0] == tc_heartbeat ) {
                twibuf [ 0 ] = 1;
                twibuf [ 1 ] = twi_heartbeat_counter++;
                TWI_Start_Transceiver_With_Data ( twibuf, TWI_BUFFER_SIZE );

              } else if ( twibuf[0] == tc_gethello ) {
                sprintf ( twibuf + 1, "hello" );
                twibuf [ 0 ] = strlen ( twibuf + 1 ); // len
                TWI_Start_Transceiver_With_Data ( twibuf, TWI_BUFFER_SIZE );

              } else if ( twibuf[0] == tc_setmotors ) {
                g_control_last_s = g_time_s;
                mc_speed ( mcm_left, twibuf [ 1 ] );
                mc_speed ( mcm_right, twibuf [ 2 ] );

              } else if ( twibuf[0] == tc_takeover ) {
                g_control_last_s = g_time_s;
                g_control_twi = 1;

              } else if ( twibuf[0] == tc_release ) {
                g_control_twi = 0;

              } else {
                twibuf [ 0 ] = 1;
                twibuf [ 1 ] = 0xde;
                twibuf [ 2 ] = 0xad;
                twibuf [ 3 ] = 0xbe;
                twibuf [ 4 ] = 0xef;
                TWI_Start_Transceiver_With_Data ( twibuf, TWI_BUFFER_SIZE );
              }

            }

          } else { // Ends up here if the last operation was a transmission  
            // don't care
          }

          // Check if the TWI Transceiver has already been started.
          // If not then restart it to prepare it for new receptions.             
          if ( ! TWI_Transceiver_Busy() ) {
            TWI_Start_Transceiver();
          }

        } else { // Ends up here if the last operation completed unsuccessfully
          TWI_Act_On_Failure_In_Last_Transmission ( TWI_Get_State_Info() );
        } // success/fail

      } // TWI busy?

      // spin
      _delay_ms ( 20 );

    } // while forever

  } // if 1
#endif

  /* churn forever
   */
  while(1);

  return ( 0 );
}
コード例 #8
0
ファイル: menu.c プロジェクト: cscscheng/telemetry
void menu_update() {

    // czas pobrany z RTC
    time_t time;
    unsigned char n;

    // czyœæ ekran przed aktualizacj¹ menu
    if ( menu_updated ) {
        lcd_clear();
    }

    // rysuj g³ówne menu
    lcd_xy(0,0);  lcd_char(lcd_larrow);
    lcd_xy(15,0); lcd_char(lcd_rarrow);

    lcd_xy(2,0);

    // ogranicz
    if (menu_pos == 0xff) {
        menu_pos = MENU_POS_COUNT - 1; 
    }
    else if(menu_pos >= MENU_POS_COUNT) {
        menu_pos = 0;
    }

    // wybierz g³ówne menu
    switch(menu_pos) {
        
        // czas i trzy temperatury
        //
        case 0:
            // pobierz czas ...
            ds1306_time_get(&time);

            // ... i poka¿
            lcd_xy(1,0);
            lcd_int2(time.tm_hour); lcd_char(uptime%2 ? ':' : ' '); lcd_int2(time.tm_min);
            lcd_char(' ');//lcd_text_P(PSTR(" 20"));
            lcd_int2(time.tm_year);lcd_char('/');lcd_int2(time.tm_mon);lcd_char('/');lcd_int2(time.tm_mday);

            
            // ogranicz podmenu do liczby czujników
            if (menu_sub_pos == 0xff) {
                menu_sub_pos = 0;
            }
            else if ( (menu_sub_pos > ds_devices_count-3) && (ds_devices_count > 3) ) {
                menu_sub_pos = ds_devices_count-3;
            }

            // poka¿ temperatury
            lcd_xy(1,1);

            for (n=0; n<ds_devices_count && n<3; n++) {
                lcd_int2(abs(ds_temp[menu_sub_pos + n])/10); lcd_char('.'); lcd_char('0' + (abs(ds_temp[menu_sub_pos + n])%10)); lcd_char(' ');
            }

            // strza³ki
            lcd_xy(0,1);  lcd_char( (menu_sub_pos > 0)                  ? lcd_larrow : ' ');
            lcd_xy(15,1); lcd_char( (menu_sub_pos < ds_devices_count-3) ? lcd_rarrow : ' ');

            break;

        // temperatury
        //
        case 1:

            // poka¿ temperatury
            lcd_xy(1,0);

            for (n=0; n<ds_devices_count && n<3; n++) {
                lcd_int2(abs(ds_temp[n])/10); lcd_char('.'); lcd_char('0' + (abs(ds_temp[n])%10)); lcd_char(n<2 ? ' ' : lcd_rarrow);
            }

            lcd_xy(1,1);

            for (n=3; n<ds_devices_count && n<6; n++) {
                lcd_int2(abs(ds_temp[n])/10); lcd_char('.'); lcd_char('0' + (abs(ds_temp[n])%10)); lcd_char(' ');
            }

            break;

        // sieæ (IP, brama, DHCP, pakiety)
        //
        case 2:
            lcd_text_P(PSTR("Sie\x09/")); // sieæ

            // ogranicz podmenu
            if (menu_sub_pos == 0xff) {
                menu_sub_pos = 6;
            }
            else if (menu_sub_pos > 6) {
                menu_sub_pos = 0;
            }

            lcd_xy(7,0);

            switch (menu_sub_pos) {

                case 0:
                    lcd_text_P(PSTR("IP"));

                    lcd_xy(2,1);

                    for (n=0; n<4; n++) {
                        lcd_int(my_net_config.my_ip[n]);
                        lcd_char(n<3 ? '.' : ' ');
                    }
                    break;

                case 1:
                    lcd_text_P(PSTR("brama"));

                    lcd_xy(2,1);
                    for (n=0; n<4; n++) {
                        lcd_int(my_net_config.gate_ip[n]);
                        lcd_char(n<3 ? '.' : ' ');
                    }
                    break;

                case 2:
                    lcd_text_P(PSTR("DHCP"));

                    lcd_xy(2,1);

                    // DHCP
                    if (my_net_config.using_dhcp) {
                        lcd_text_P(PSTR("u\x0fywane"));
                    }
                    else {
                        lcd_text_P(PSTR("nie"));
                    }
                    break;

                case 3:
                    lcd_text_P(PSTR("\x0b\x08")); lcd_text_P(PSTR("cze"));

                    lcd_xy(2,1);

                    // stan ³¹cza
                    if ( enc28_is_link_up() ) {
                        lcd_text_P(PSTR("tak"));
                    }
                    else {
                        lcd_text_P(PSTR("brak"));
                    }
                    break;

                case 4:
                    lcd_text_P(PSTR("pakiety"));

                    lcd_xy(2,1);
                    lcd_text_P(PSTR("Tx: ")); lcd_int(net_ip_packet_id);
                    break;

                case 5:
                    lcd_text_P(PSTR("pakiety"));

                    lcd_xy(2,1);
                    lcd_text_P(PSTR("Rx: ")); lcd_int(my_net_config.pktcnt);
                    break;

                case 6:
                    lcd_text_P(PSTR("MAC"));
                    
                    lcd_xy(2,1);
                    for (n=0; n<6; n++) {
                        lcd_hex(my_net_config.my_mac[n]);
                    }
                    break;
            }

            // strza³ki
            lcd_xy(0,1);  lcd_char(lcd_larrow);
            lcd_xy(15,1); lcd_char(lcd_rarrow);

            break;

        // PID (wysterowania, nastawy, PV, SP)
        //
        /*
        case 3:
            lcd_text_P(PSTR("PID")); // PID

            break;
        */

        // PWM (wype³nienia)
        //
        case 3:
            lcd_text_P(PSTR("PWM"));

            // ogranicz podmenu do liczby kana³ów PWM
            if (menu_sub_pos == 0xff) {
                menu_sub_pos = 0;
            }
            else if (menu_sub_pos > PWM_CHANNELS-3) {
                menu_sub_pos = PWM_CHANNELS-3;
            }

            // nr pokazywanych kana³ów
            lcd_xy(11,0);
            lcd_char('1' + menu_sub_pos);
            lcd_char('-');
            lcd_char('3' + menu_sub_pos);

            // poka¿ wype³nienia
            lcd_xy(2,1);

            for (n=0; n<PWM_CHANNELS && n<3; n++) {
                lcd_char('0' + pwm_get_fill(menu_sub_pos + n)/100);lcd_int2(pwm_get_fill(menu_sub_pos + n)); lcd_char(' ');
            }

            // strza³ki
            lcd_xy(0,1);  lcd_char( (menu_sub_pos > 0)              ? lcd_larrow : ' ');
            lcd_xy(15,1); lcd_char( (menu_sub_pos < PWM_CHANNELS-3) ? lcd_rarrow : ' ');

            break;

        // informacje (wersja, ENC28J60, karta pamiêci, EEPROM)
        //
        case 4:
            lcd_text_P(PSTR("Informacje")); // sieæ

            // ogranicz podmenu
            if (menu_sub_pos == 0xff) {
                menu_sub_pos = 6;
            }
            else if (menu_sub_pos > 6) {
                menu_sub_pos = 0;
            }

            lcd_xy(2,1);

            switch (menu_sub_pos) {

                case 0:
                    lcd_text_P(PSTR(__DATE__));
                    break;

                case 1:
                    lcd_text_P(PSTR("GCC " __AVR_LIBC_VERSION_STRING__));
                    break;

                case 2:
                    //lcd_text_P(PSTR("Up "));

                    // dni
                    lcd_int((uptime/3600/24)); lcd_char('d');
                    // godziny
                    lcd_int2((uptime/3600)%24); lcd_char(':');
                    // minuty
                    lcd_int2((uptime/60)%60); lcd_char(':');
                    // sekundy
                    lcd_int2((uptime%60));

                    break;

                case 3:
                    lcd_text_P(PSTR("ENC28 rev.B"));
                    lcd_char('0' + enc28_read_rev_id());
                    break;

                case 4:
                    lcd_text_P(PSTR("Czujnik\x0dw: "));
                    lcd_int(ds_devices_count);
                    break;

                case 5:
                    lcd_text_P(PSTR("EEPROM "));
                    lcd_int(eeprom_get_size() >> 10);
                    lcd_char('k');lcd_char('B');
                    break;

                case 6:
                    if (sd_get_state() != SD_FAILED) {
                        lcd_text_P(sd_get_state() == SD_IS_SD ? PSTR("SD") : PSTR("MMC"));
                        lcd_char(' ');
                        lcd_int(sd_size >> 10); // kB
                        lcd_char('k');lcd_char('b');
                    }
                    else {
                        lcd_text_P(PSTR("SD/MMC: b\x0b\x08d"));
                    }
                    break;
            }