static int sunkbd_probe_keyboard(struct uart_devinfo *di) { int tries; for (tries = 5; tries != 0; tries--) { int ltries; uart_putc(di, SKBD_CMD_RESET); for (ltries = 1000; ltries != 0; ltries--) { if (uart_poll(di) == SKBD_RSP_RESET) break; DELAY(1000); } if (ltries == 0) continue; for (ltries = 1000; ltries != 0; ltries--) { if (uart_poll(di) == SKBD_RSP_IDLE) break; DELAY(1000); } if (ltries == 0) continue; uart_putc(di, SKBD_CMD_LAYOUT); if (uart_getc(di) != SKBD_RSP_LAYOUT) break; return (uart_getc(di)); } return (-1); }
static int sunkbd_probe_keyboard(struct uart_devinfo *di) { int c, id, ltries, tries; for (tries = 5; tries != 0; tries--) { uart_putc(di, SKBD_CMD_RESET); for (ltries = 1000; ltries != 0; ltries--) { if (uart_poll(di) == SKBD_RSP_RESET) break; DELAY(1000); } if (ltries == 0) continue; id = -1; for (ltries = 1000; ltries != 0; ltries--) { switch (c = uart_poll(di)) { case -1: break; case SKBD_RSP_IDLE: return (id); default: id = c; } DELAY(1000); } } return (-1); }
int main(void) { board_init (); /* Initialize HDLC subsystem */ sercomm_init(); /* Say hi */ puts("\n\nOSMOCOM Loader (revision " GIT_REVISION ")\n"); puts(hr); /* Identify environment */ printf("\nRunning on %s in environment %s\n", manifest_board, manifest_environment); printf("\nHW_CODE = 0x%04x", readw(MTK_CONFG_HW_CODE)); /* Set up loader communications */ sercomm_register_rx_cb(SC_DLCI_LOADER, &cmd_handler); /* Wait for events */ while (1) { uart_poll(SERCOMM_UART_NR); } }
int diag_sd_write(char *argv[]) { int rval = 0; int i, j; int total_secs; int sector, sectors; u8 *buf = (u8 *)DIAG_SD_BUF_START; rval = diag_sd_init(argv, "Write", 1); if (rval < 0) return rval; for (i = 0; i < SECTORS_PER_OP * SECTOR_SIZE / 16; i++) { for (j = 0; j < 16; j++) { buf[(i * 16) + j] = i; } } total_secs = sdmmc_get_total_sectors(); for (sector = 0, i = 0; sector < total_secs; sector += SECTORS_PER_OP, i++) { if (uart_poll()) break; if ((total_secs - sector) < SECTORS_PER_OP) sectors = total_secs - sector; else sectors = SECTORS_PER_OP; rval = sdmmc_write_sector(sector, sectors, (unsigned int *)buf); putchar('.'); if ((i & 0xf) == 0xf) { putchar(' '); putdec(sector); putchar('/'); putdec(total_secs); putstr(" ("); putdec(sector * 100 / total_secs); putstr("%)\t\t\r"); } if (rval < 0) { putstr("\r\nfailed at sector "); putdec(sector); putstr("\r\n"); } if ((sector + SECTORS_PER_OP) >= total_secs) { putstr("\r\n"); sector = -SECTORS_PER_OP; } } putstr("\r\ndone!\r\n"); return rval; }
int kb_input() { int i, timeout; if (!uart_poll()) return 0; int c = uart_read_byte(); if (c == ESC_CHAR) { c = kb_expect(); if (c < 0) return ESC_CHAR; if (c != '[') { return 0; } c = kb_expect(); if (c < 0) return 0; return (c & 0xff) | 0x1b00; } return c; }
/** * Run diagnostic on IR: continuously display the current value. */ void diag_ir(void) { int i; u32 data; /* Set IR sampling frequency */ rct_set_ir_pll(); /* config IR GPIO */ gpio_config_hw(IR_IN); uart_putstr("running IR diagnostics...\r\n"); uart_putstr("press any key to quit!\r\n"); writel(IR_CONTROL_REG, IR_CONTROL_RESET); writel(IR_CONTROL_REG, IR_CONTROL_ENB); for (i = 0; ; i++) { if (uart_poll()) break; while (readl(IR_STATUS_REG) == 0x0); data = readl(IR_DATA_REG); uart_putdec(data); uart_putchar(' '); if (i == 8) { uart_putstr("\r\n"); i = 0; } } writel(IR_CONTROL_REG, 0x0); uart_putstr("\r\ndone!\r\n"); }
static void flush_uart(void) { unsigned i; for (i = 0; i < 500; i++) { uart_poll(SERCOMM_UART_NR); delay_ms(1); } }
static void flush_uart(void) { unsigned i; for (i = 0; i < 500; i++) { uart_poll(sercomm_uart); delay_ms(1); } }
int kb_expect() { int timeout; for (timeout = ESC_TIMEOUT; timeout > 0; timeout--) if (uart_poll()) return uart_read_byte(); return -1; }
static int cmd_nand_erase(int argc, char *argv[]) { u32 start_block, block, blocks, total_blocks; int i, rval; total_blocks = flnand.blocks_per_bank * flnand.banks; if (argc != 3) { uart_putstr("nand_erase [block] [blocks]!\r\n"); uart_putstr("Total blocks: "); uart_putdec(total_blocks); uart_putstr("\r\n"); return -1; } putstr("erase nand blocks including any bad blocks...\r\n"); putstr("press enter to start!\r\n"); putstr("press any key to terminate!\r\n"); rval = uart_wait_escape(0xffffffff); if (rval == 0) return -1; strtou32(argv[1], &start_block); strtou32(argv[2], &blocks); for (i = 0, block = start_block; i < blocks; i++, block++) { if (uart_poll()) break; if (block >= total_blocks) break; rval = nand_erase_block(block); putchar('.'); if ((i & 0xf) == 0xf) { putchar(' '); putdec(i); putchar('/'); putdec(blocks); putstr(" ("); putdec(i * 100 / blocks); putstr("%)\t\t\r"); } if (rval < 0) { putstr("\r\nfailed at block "); putdec(block); putstr("\r\n"); } } putstr("\r\ndone!\r\n"); return 0; }
int diag_sd_read(char *argv[]) { int rval = 0; int i = 0; int total_secs; int sector, sectors; u8 *buf = (u8 *)DIAG_SD_BUF_START; rval = diag_sd_init(argv, "Read", 1); if (rval < 0) return rval; total_secs = sdmmc_get_total_sectors(); for (sector = 0, i = 0; sector < total_secs; sector += SECTORS_PER_OP, i++) { if (uart_poll()) break; if ((total_secs - sector) < SECTORS_PER_OP) sectors = total_secs - sector; else sectors = SECTORS_PER_OP; rval = sdmmc_read_sector(sector, sectors, (unsigned int *)buf); putchar('.'); if ((i & 0xf) == 0xf) { putchar(' '); putdec(sector); putchar('/'); putdec(total_secs); putstr(" ("); putdec(sector * 100 / total_secs); putstr("%)\t\t\r"); } if (rval < 0) { putstr("\r\nfailed at sector "); putdec(sector); putstr("\r\n"); break; } if ((sector + SECTORS_PER_OP) >= total_secs) { putstr("\r\n"); sector = -SECTORS_PER_OP; } } putstr("\r\ndone!\r\n"); return rval; }
int diag_sd_write_speed(char *argv[]) { int rval = 0; int i, j; int total_secs; int sector, sectors; u8 *buf = (u8 *)DIAG_SD_BUF_START; u32 op_size; rval = diag_sd_init(argv, "Write Speed", 1); if (rval < 0) return rval; for (i = 0; i < SECTORS_PER_OP * SECTOR_SIZE / 16; i++) { for (j = 0; j < 16; j++) { buf[(i * 16) + j] = i; } } total_secs = sdmmc_get_total_sectors(); op_size = 0; timer_reset_count(TIMER2_ID); timer_enable(TIMER2_ID); for (sector = 0; sector < total_secs; sector += SECTORS_PER_OP) { if (uart_poll()) break; if ((total_secs - sector) < SECTORS_PER_OP) sectors = total_secs - sector; else sectors = SECTORS_PER_OP; rval = sdmmc_write_sector(sector, sectors, (unsigned int *)buf); if (rval < 0) { putstr("\r\nfailed at sector "); putdec(sector); putstr("\r\n"); break; } op_size += sectors; } timer_disable(TIMER2_ID); putstr("\r\nTotally write 0x"); puthex(op_size * SECTOR_SIZE); putstr(" Bytes in "); putdec(timer_get_count(TIMER2_ID)); putstr(" mS, about "); putdec(op_size * 500 / timer_get_count(TIMER2_ID)); putstr(" KB/s!\r\n\r\n"); return rval; }
static u_int sunkbd_read_char(keyboard_t *kbd, int wait) { struct sunkbd_softc *sc; int key, release, repeated, suncode; sc = (struct sunkbd_softc *)kbd; #if defined(SUNKBD_EMULATE_ATKBD) if (sc->sc_mode == K_RAW && sc->sc_buffered_char[0]) { key = sc->sc_buffered_char[0]; if (key & SCAN_PREFIX) { sc->sc_buffered_char[0] = key & ~SCAN_PREFIX; return ((key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1); } else { sc->sc_buffered_char[0] = sc->sc_buffered_char[1]; sc->sc_buffered_char[1] = 0; return (key); } } #endif repeated = 0; if (sc->sc_repeating) { repeated = 1; sc->sc_repeating = 0; callout_reset(&sc->sc_repeat_callout, hz / 10, sunkbd_repeat, sc); suncode = sc->sc_repeat_key; goto process_code; } for (;;) { next_code: if (!(sc->sc_flags & KPCOMPOSE) && (sc->sc_composed_char > 0)) { key = sc->sc_composed_char; sc->sc_composed_char = 0; if (key > UCHAR_MAX) return (ERRKEY); return (key); } if (sc->sc_uart != NULL && !uart_rx_empty(sc->sc_uart)) { suncode = uart_rx_get(sc->sc_uart); } else if (sc->sc_polling != 0 && sc->sc_sysdev != NULL) { if (wait) suncode = uart_getc(sc->sc_sysdev); else if ((suncode = uart_poll(sc->sc_sysdev)) == -1) return (NOKEY); } else { return (NOKEY); } switch (suncode) { case SKBD_RSP_IDLE: break; default: process_code: ++kbd->kb_count; key = SKBD_KEY_CHAR(suncode); release = suncode & SKBD_KEY_RELEASE; if (!repeated) { if (release == 0) { callout_reset(&sc->sc_repeat_callout, hz / 2, sunkbd_repeat, sc); sc->sc_repeat_key = suncode; } else if (sc->sc_repeat_key == key) { callout_stop(&sc->sc_repeat_callout); sc->sc_repeat_key = -1; } } #if defined(SUNKBD_EMULATE_ATKBD) key = sunkbd_trtab[key]; if (key == NOTR) return (NOKEY); if (!repeated) { switch (key) { case 0x1d: /* ctrl */ if (release != 0) sc->sc_flags &= ~CTLS; else sc->sc_flags |= CTLS; break; case 0x2a: /* left shift */ case 0x36: /* right shift */ if (release != 0) sc->sc_flags &= ~SHIFTS; else sc->sc_flags |= SHIFTS; break; case 0x38: /* alt */ case 0x5d: /* altgr */ if (release != 0) sc->sc_flags &= ~ALTS; else sc->sc_flags |= ALTS; break; } } if (sc->sc_mode == K_RAW) { key = keycode2scancode(key, sc->sc_flags, release); if (key & SCAN_PREFIX) { if (key & SCAN_PREFIX_CTL) { sc->sc_buffered_char[0] = 0x1d | (key & SCAN_RELEASE); sc->sc_buffered_char[1] = key & ~SCAN_PREFIX; } else if (key & SCAN_PREFIX_SHIFT) { sc->sc_buffered_char[0] = 0x2a | (key & SCAN_RELEASE); sc->sc_buffered_char[1] = key & ~SCAN_PREFIX_SHIFT; } else { sc->sc_buffered_char[0] = key & ~SCAN_PREFIX; sc->sc_buffered_char[1] = 0; } return ((key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1); } return (key); } switch (key) { case 0x5c: /* print screen */ if (sc->sc_flags & ALTS) key = 0x54; /* sysrq */ break; case 0x68: /* pause/break */ if (sc->sc_flags & CTLS) key = 0x6c; /* break */ break; } if (sc->sc_mode == K_CODE) return (key | release); #else if (sc->sc_mode == K_RAW || sc->sc_mode == K_CODE) return (suncode); #endif #if defined(SUNKBD_EMULATE_ATKBD) if (key == 0x38) { /* left alt (KP compose key) */ #else if (key == 0x13) { /* left alt (KP compose key) */ #endif if (release != 0) { if (sc->sc_flags & KPCOMPOSE) { sc->sc_flags &= ~KPCOMPOSE; if (sc->sc_composed_char > UCHAR_MAX) sc->sc_composed_char = 0; } } else { if (!(sc->sc_flags & KPCOMPOSE)) { sc->sc_flags |= KPCOMPOSE; sc->sc_composed_char = 0; } } } if (sc->sc_flags & KPCOMPOSE) { switch (suncode) { case 0x44: /* KP 7 */ case 0x45: /* KP 8 */ case 0x46: /* KP 9 */ sc->sc_composed_char *= 10; sc->sc_composed_char += suncode - 0x3d; if (sc->sc_composed_char > UCHAR_MAX) return (ERRKEY); goto next_code; case 0x5b: /* KP 4 */ case 0x5c: /* KP 5 */ case 0x5d: /* KP 6 */ sc->sc_composed_char *= 10; sc->sc_composed_char += suncode - 0x58; if (sc->sc_composed_char > UCHAR_MAX) return (ERRKEY); goto next_code; case 0x70: /* KP 1 */ case 0x71: /* KP 2 */ case 0x72: /* KP 3 */ sc->sc_composed_char *= 10; sc->sc_composed_char += suncode - 0x6f; if (sc->sc_composed_char > UCHAR_MAX) return (ERRKEY); goto next_code; case 0x5e: /* KP 0 */ sc->sc_composed_char *= 10; if (sc->sc_composed_char > UCHAR_MAX) return (ERRKEY); goto next_code; case 0x44 | SKBD_KEY_RELEASE: /* KP 7 */ case 0x45 | SKBD_KEY_RELEASE: /* KP 8 */ case 0x46 | SKBD_KEY_RELEASE: /* KP 9 */ case 0x5b | SKBD_KEY_RELEASE: /* KP 4 */ case 0x5c | SKBD_KEY_RELEASE: /* KP 5 */ case 0x5d | SKBD_KEY_RELEASE: /* KP 6 */ case 0x70 | SKBD_KEY_RELEASE: /* KP 1 */ case 0x71 | SKBD_KEY_RELEASE: /* KP 2 */ case 0x72 | SKBD_KEY_RELEASE: /* KP 3 */ case 0x5e | SKBD_KEY_RELEASE: /* KP 0 */ goto next_code; default: if (sc->sc_composed_char > 0) { sc->sc_flags &= ~KPCOMPOSE; sc->sc_composed_char = 0; return (ERRKEY); } } } key = genkbd_keyaction(kbd, key, release, &sc->sc_state, &sc->sc_accents); if (key != NOKEY || repeated) return (key); } } return (0); } static int sunkbd_check_char(keyboard_t *kbd) { struct sunkbd_softc *sc; if (!KBD_IS_ACTIVE(kbd)) return (FALSE); sc = (struct sunkbd_softc *)kbd; if (!(sc->sc_flags & KPCOMPOSE) && (sc->sc_composed_char > 0)) return (TRUE); return (sunkbd_check(kbd)); } static int sunkbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data) { struct sunkbd_softc *sc; int c, error; #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) int ival; #endif sc = (struct sunkbd_softc *)kbd; error = 0; switch (cmd) { case KDGKBMODE: *(int *)data = sc->sc_mode; break; #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) case _IO('K', 7): ival = IOCPARM_IVAL(data); data = (caddr_t)&ival; /* FALLTHROUGH */ #endif case KDSKBMODE: switch (*(int *)data) { case K_XLATE: if (sc->sc_mode != K_XLATE) { /* make lock key state and LED state match */ sc->sc_state &= ~LOCK_MASK; sc->sc_state |= KBD_LED_VAL(kbd); } /* FALLTHROUGH */ case K_RAW: case K_CODE: if (sc->sc_mode != *(int *)data) { sunkbd_clear_state(kbd); sc->sc_mode = *(int *)data; } break; default: error = EINVAL; break; } break; case KDGETLED: *(int *)data = KBD_LED_VAL(kbd); break; #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) case _IO('K', 66): ival = IOCPARM_IVAL(data); data = (caddr_t)&ival; /* FALLTHROUGH */ #endif case KDSETLED: if (*(int *)data & ~LOCK_MASK) { error = EINVAL; break; } if (sc->sc_sysdev == NULL) break; c = 0; if (*(int *)data & CLKED) c |= SKBD_LED_CAPSLOCK; if (*(int *)data & NLKED) c |= SKBD_LED_NUMLOCK; if (*(int *)data & SLKED) c |= SKBD_LED_SCROLLLOCK; uart_lock(sc->sc_sysdev->hwmtx); sc->sc_sysdev->ops->putc(&sc->sc_sysdev->bas, SKBD_CMD_SETLED); sc->sc_sysdev->ops->putc(&sc->sc_sysdev->bas, c); uart_unlock(sc->sc_sysdev->hwmtx); KBD_LED_VAL(kbd) = *(int *)data; break; case KDGKBSTATE: *(int *)data = sc->sc_state & LOCK_MASK; break; #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) case _IO('K', 20): ival = IOCPARM_IVAL(data); data = (caddr_t)&ival; /* FALLTHROUGH */ #endif case KDSKBSTATE: if (*(int *)data & ~LOCK_MASK) { error = EINVAL; break; } sc->sc_state &= ~LOCK_MASK; sc->sc_state |= *(int *)data; /* set LEDs and quit */ return (sunkbd_ioctl(kbd, KDSETLED, data)); case KDSETREPEAT: case KDSETRAD: break; case PIO_KEYMAP: case OPIO_KEYMAP: case PIO_KEYMAPENT: case PIO_DEADKEYMAP: default: return (genkbd_commonioctl(kbd, cmd, data)); } return (error); } static int sunkbd_lock(keyboard_t *kbd, int lock) { TODO; return (0); }
static int uart_dbg_getc(void) { return (uart_poll(&uart_dbgport)); }
static u_int sunkbd_read_char(keyboard_t *kbd, int wait) { struct sunkbd_softc *sc; int action; int key; sc = (struct sunkbd_softc *)kbd; if (sc->sc_repeating) { sc->sc_repeating = 0; callout_reset(&sc->sc_repeat_callout, hz / 10, sunkbd_repeat, sc); key = sc->sc_repeat_key; if (sc->sc_mode == K_RAW) return (key); else return genkbd_keyaction(kbd, key & 0x7f, key & 0x80, &sc->sc_state, &sc->sc_accents); } for (;;) { /* XXX compose */ if (sc->sc_uart != NULL && !uart_rx_empty(sc->sc_uart)) { key = uart_rx_get(sc->sc_uart); } else if (sc->sc_polling != 0 && sc->sc_sysdev != NULL) { if (wait) key = uart_getc(sc->sc_sysdev); else if ((key = uart_poll(sc->sc_sysdev)) == -1) return (NOKEY); } else { return (NOKEY); } switch (key) { case SKBD_RSP_IDLE: break; default: ++kbd->kb_count; if ((key & 0x80) == 0) { callout_reset(&sc->sc_repeat_callout, hz / 2, sunkbd_repeat, sc); sc->sc_repeat_key = key; } else { if (sc->sc_repeat_key == (key & 0x7f)) { callout_stop(&sc->sc_repeat_callout); sc->sc_repeat_key = -1; } } if (sc->sc_mode == K_RAW) return (key); action = genkbd_keyaction(kbd, key & 0x7f, key & 0x80, &sc->sc_state, &sc->sc_accents); if (action != NOKEY) return (action); break; } } return (0); }
int diag_sd_verify(char *argv[]) { int rval = 0; int i; int total_secs; int sector, sectors; u8 *wbuf = (u8 *)DIAG_SD_BUF_START; u8 *rbuf = (u8 *)DIAG_SD_BUF_START + 0x100000; rval = diag_sd_init(argv, "Verify", 1); if (rval < 0) return rval; for (i = 0; i < SECTORS_PER_OP * SECTOR_SIZE; i++) { wbuf[i] = rand() / SECTORS_PER_OP; } total_secs = sdmmc_get_total_sectors(); for (i = 0, sector = 0, sectors = 0; sector < total_secs; i++, sector += SECTORS_PER_OP) { if (uart_poll()) break; sectors++; if (sectors > SECTORS_PER_OP) sectors = 1; rval = sdmmc_write_sector(sector, sectors, (unsigned int *)wbuf); if (rval != 0) { putstr("Write sector fail "); putdec(rval); putstr(" @ "); putdec(sector); putstr(" : "); putdec(sectors); putstr("\r\n"); } rval = sdmmc_read_sector(sector, sectors, (unsigned int *)rbuf); if (rval != 0) { putstr("Read sector fail "); putdec(rval); putstr(" @ "); putdec(sector); putstr(" : "); putdec(sectors); putstr("\r\n"); } rval = diag_sd_verify_data(wbuf, rbuf, (sectors * SECTOR_SIZE), sector); putchar('.'); if ((i & 0xf) == 0xf) { putchar(' '); putdec(sector); putchar('/'); putdec(total_secs); putstr(" ("); putdec(sector * 100 / total_secs); putstr("%)\t\t\r"); } if ((sector + SECTORS_PER_OP) >= total_secs) { putstr("\r\n"); sector = -SECTORS_PER_OP; } } putstr("\r\ndone!\r\n"); return rval; }
int main(void) { /* Simulate a compal loader saying "ACK" */ int i = 0; for (i = 0; i < sizeof(phone_ack); i++) { putchar_asm(phone_ack[i]); } /* Always disable wdt (some platforms enable it on boot) */ wdog_enable(0); /* Disable the bootrom mapping */ calypso_bootrom(0); /* Initialize TWL3025 for power control */ twl3025_init(); /* Backlight */ bl_mode_pwl(1); bl_level(50); /* Initialize UART without interrupts */ uart_init(SERCOMM_UART_NR, 0); uart_baudrate(SERCOMM_UART_NR, UART_115200); /* Initialize HDLC subsystem */ sercomm_init(); /* Say hi */ puts("\n\nOSMOCOM Loader (revision " GIT_REVISION ")\n"); puts(hr); /* Identify environment */ printf("Running on %s in environment %s\n", manifest_board, manifest_environment); /* Initialize flash driver */ if (flash_init(&the_flash, 0)) { puts("Failed to initialize flash!\n"); } else { printf("Found flash of %d bytes at 0x%x with %d regions\n", the_flash.f_size, the_flash.f_base, the_flash.f_nregions); int i; for (i = 0; i < the_flash.f_nregions; i++) { printf(" Region %d of %d pages with %d bytes each.\n", i, the_flash.f_regions[i].fr_bnum, the_flash.f_regions[i].fr_bsize); } } /* Set up a key handler for powering off */ keypad_set_handler(&key_handler); /* Set up loader communications */ sercomm_register_rx_cb(SC_DLCI_LOADER, &cmd_handler); /* Notify any running osmoload about our startup */ loader_send_init(SC_DLCI_LOADER); /* Wait for events */ while (1) { keypad_poll(); uart_poll(SERCOMM_UART_NR); } /* NOT REACHED */ twl3025_power_off(); }
void tty_poll(void) { uint16_t r; while((r = uart_poll()) != 0xFFFF) tty_inproc(1, r); }
static int uart_cngetc(struct consdev *cp) { return (uart_poll(cp->cn_arg)); }
int main(void) { /* Simulate a compal loader saying "ACK" */ unsigned i = 0; for (i = 0; i < sizeof(phone_ack); i++) { putchar_asm(phone_ack[i]); } /* initialize board without interrupts */ board_init(0); sercomm_uart = sercomm_get_uart(); /* Say hi */ puts("\n\nOsmocomBB Loader (revision " GIT_REVISION ")\n"); puts(hr); fb_clear(); fb_setfg(FB_COLOR_BLACK); fb_setbg(FB_COLOR_WHITE); fb_setfont(FB_FONT_HELVB14); fb_gotoxy(2,20); fb_putstr("loader",framebuffer->width-4); fb_setfg(FB_COLOR_RED); fb_setbg(FB_COLOR_BLUE); fb_gotoxy(2,25); fb_boxto(framebuffer->width-3,38); fb_setfg(FB_COLOR_WHITE); fb_setfont(FB_FONT_HELVR08); fb_gotoxy(8,33); fb_putstr("osmocom-bb",framebuffer->width-4); fb_flush(); /* Identify environment */ printf("Running on %s in environment %s\n", manifest_board, manifest_environment); /* Initialize flash driver */ if (flash_init(&the_flash, 0)) { puts("Failed to initialize flash!\n"); } else { printf("Found flash of %zu bytes at 0x%p with %zu regions\n", the_flash.f_size, the_flash.f_base, the_flash.f_nregions); for (i = 0; i < the_flash.f_nregions; i++) { printf(" Region %d of %zu pages with %zu bytes each.\n", i, the_flash.f_regions[i].fr_bnum, the_flash.f_regions[i].fr_bsize); } } /* Set up a key handler for powering off */ keypad_set_handler(&key_handler); /* Set up loader communications */ sercomm_register_rx_cb(SC_DLCI_LOADER, &cmd_handler); /* Notify any running osmoload about our startup */ loader_send_init(SC_DLCI_LOADER); /* Wait for events */ while (1) { keypad_poll(); uart_poll(sercomm_uart); } /* NOT REACHED */ twl3025_power_off(); }