uint8_t menu_edit_value(uint8_t v, uint8_t min, uint8_t max) { uint8_t x = lcd_x; uint8_t y = lcd_y; lcd_locate(x, y); lcd_cursor(true); set_busy_led(true); for (;;) { lcd_printf("%02d", v); lcd_locate(x, y); for (;;) { if (get_key_autorepeat(KEY_PREV)) { if (v <= min) v = max; else --v; break; } if (get_key_autorepeat(KEY_NEXT)) { if (v >= max) v = min; else ++v; break; } if (get_key_press(KEY_SEL)) { lcd_cursor(false); set_busy_led(false); return v; } } } }
uint8_t menu_edit_month(uint8_t m) { for (;;) { lcd_locate(3, 0); menu_print_month(m); lcd_locate(3, 0); set_busy_led(true); lcd_cursor(true); for (;;) { if (get_key_autorepeat(KEY_PREV)) { if (m == 0) m = 11; else --m; break; } if (get_key_autorepeat(KEY_NEXT)) { if (m == 11) m = 0; else ++m; break; } if (get_key_press(KEY_SEL)) { set_busy_led(false); lcd_cursor(false); return m; } } } }
static void m2i_rename(path_t *path, cbmdirent_t *dent, uint8_t *newname) { uint16_t offset; uint8_t *ptr; set_busy_led(1); /* Locate entry in the M2I file */ offset = dent->pvt.m2i.offset; if (load_entry(path->part, offset)) { update_leds(); return; } /* Re-load the entry because load_entry modifies it */ /* Assume this never fails because load_entry was successful */ image_read(path->part, offset, ops_scratch, M2I_ENTRY_LEN); /* Copy the new filename */ ptr = ops_scratch + M2I_CBMNAME_OFFSET; memset(ptr, ' ', CBM_NAME_LENGTH); while (*newname) *ptr++ = *newname++; /* Write new entry */ image_write(path->part, offset, ops_scratch, M2I_ENTRY_LEN, 1); update_leds(); }
static void cmd_handler (void) { /* Handle commands and filenames */ if (ieee_data.ieeeflags & COMMAND_RECVD) { # ifdef HAVE_HOTPLUG /* This seems to be a nice point to handle card changes */ if (disk_state != DISK_OK) { set_busy_led(1); /* If the disk was changed the buffer contents are useless */ if (disk_state == DISK_CHANGED || disk_state == DISK_REMOVED) { free_multiple_buffers(FMB_ALL); change_init(); filesystem_init(0); } else { /* Disk state indicated an error, try to recover by initialising */ filesystem_init(1); } update_leds(); } # endif if (ieee_data.secondary_address == 0x0f) { parse_doscommand(); /* Command channel */ } else { datacrc = 0xffff; /* Filename in command buffer */ file_open(ieee_data.secondary_address); } command_length = 0; ieee_data.ieeeflags &= (uint8_t) ~COMMAND_RECVD; } /* COMMAND_RECVD */ /* We're done, clean up unused buffers */ free_multiple_buffers(FMB_UNSTICKY); d64_bam_commit(); }
void menu_adjust_brightness(void) { uint8_t i; uint8_t min = 0; uint8_t max = 255; uint8_t res; uint8_t step; lcd_clear(); lcd_puts_P(PSTR("Adjust brightness")); lcd_locate(0, 1); lcd_cursor(false); set_busy_led(true); for (;;) { lcd_locate(0, 1); lcd_putc('['); for (i = 0; i < 18; i++) { lcd_putc(i >= (lcd_brightness / 14) ? ' ' : 0xFF); } lcd_putc(']'); res = lcd_set_brightness(lcd_brightness); if (res) break; for (;;) { step = 10; if (lcd_brightness < 20 || lcd_brightness > 235) step = 1; if (get_key_autorepeat(KEY_PREV)) { if (lcd_brightness <= min) lcd_brightness = max; else lcd_brightness -= step; break; } if (get_key_autorepeat(KEY_NEXT)) { if (lcd_brightness >= max) lcd_brightness = min; else lcd_brightness += step; break; } if (get_key_press(KEY_SEL)) { lcd_cursor(false); set_busy_led(false); menu_ask_store_settings(); return; } } } pwm_error(); }
/** * alloc_buffer - allocates a buffer * * This function allocates a buffer and marks it as used. It will also * turn on the busy LED to notify the user. Returns a pointer to the * buffer structure or NULL if no buffer is free. */ buffer_t *alloc_buffer(void) { buffer_t *buf = alloc_system_buffer(); if (buf != NULL) { buf->secondary = 0; active_buffers++; set_busy_led(1); } return buf; }
void menu_adjust_contrast(void) { uint8_t i; uint8_t min = 0; uint8_t max = LCD_COLS - 2; uint8_t res; lcd_clear(); lcd_puts_P(PSTR("Adjust LCD contrast")); lcd_locate(0, 1); lcd_cursor(false); set_busy_led(true); for (;;) { lcd_locate(0, 1); lcd_putc('['); for (i = 0; i < LCD_COLS - 2; i++) { lcd_putc(i >= lcd_contrast ? ' ' : 0xFF); } lcd_putc(']'); res = lcd_set_contrast(lcd_contrast); if (res) break; for (;;) { if (get_key_autorepeat(KEY_PREV)) { if (lcd_contrast <= min) lcd_contrast = max; else --lcd_contrast; break; } if (get_key_autorepeat(KEY_NEXT)) { if (lcd_contrast >= max) lcd_contrast = min; else ++lcd_contrast; break; } if (get_key_press(KEY_SEL)) { lcd_cursor(false); set_busy_led(false); menu_ask_store_settings(); return; } } } pwm_error(); }
static void confirm_blink(uint8_t type) { uint8_t i; for (i=0;i<2;i++) { tick_t targettime; #ifdef SINGLE_LED set_dirty_led(1); #else if (!i || type & 1) set_dirty_led(1); if (!i || type & 2) set_busy_led(1); #endif targettime = ticks + MS_TO_TICKS(100); while (time_before(ticks,targettime)) ; set_dirty_led(0); set_busy_led(0); targettime = ticks + MS_TO_TICKS(100); while (time_before(ticks,targettime)) ; } }
/** * alloc_linked_buffers - allocates linked buffers * @count : Number of buffers to allocate * * This function allocates count buffers, marks them as used and * links them. It will also turn on the busy LED to notify the user. * Returns a pointer to the first buffer structure or NULL if * not enough buffers are free. The data segments of the allocated * buffers are guaranteed to be continuous. */ buffer_t *alloc_linked_buffers(uint8_t count) { uint8_t i,freebufs,start; freebufs = 0; start = 0; for (i=0;i<CONFIG_BUFFER_COUNT;i++) { if (buffers[i].allocated) { /* Look for continuous buffers */ /* Switching data segments is possible, but probably not required */ freebufs = 0; } else { if (freebufs == 0) start = i; freebufs++; /* Found enough free space */ if (freebufs == count) break; } } if (freebufs < count) { set_error(ERROR_NO_CHANNEL); return NULL; } /* Chain the buffers */ for (i=0;i<count;i++) { alloc_specific_buffer(start+i); active_buffers++; buffers[start+i].secondary = 0; buffers[start+i].pvt.buffer.next = &buffers[start+i+1]; buffers[start+i].pvt.buffer.first = &buffers[start]; buffers[start+i].pvt.buffer.size = count; } set_busy_led(1); buffers[start+count-1].pvt.buffer.next = NULL; return &buffers[start]; }
int main(void) { /* Early system initialisation */ early_board_init(); system_init_early(); leds_init(); set_busy_led(1); set_dirty_led(0); /* Due to an erratum in the LPC17xx chips anything that may change */ /* peripheral clock scalers must come before system_init_late() */ uart_init(); #ifndef SPI_LATE_INIT spi_init(SPI_SPEED_SLOW); #endif timer_init(); i2c_init(); /* Second part of system initialisation, switches to full speed on ARM */ system_init_late(); enable_interrupts(); /* Prompt software name and version string */ uart_puts_P(PSTR("\r\nNODISKEMU " VERSION "\r\n")); /* Internal-only initialisation, called here because it's faster */ buffers_init(); buttons_init(); /* Anything that does something which needs the system clock */ /* should be placed after system_init_late() */ rtc_init(); // accesses I2C disk_init(); // accesses card read_configuration(); // restores configuration, may change device address filesystem_init(0); // FIXME: change_init(); #ifdef CONFIG_REMOTE_DISPLAY /* at this point all buffers should be free, */ /* so just use the data area of the first to build the string */ uint8_t *strbuf = buffers[0].data; ustrcpy_P(strbuf, versionstr); ustrcpy_P(strbuf+ustrlen(strbuf), longverstr); if (display_init(ustrlen(strbuf), strbuf)) { display_address(device_address); display_current_part(0); } #endif set_busy_led(0); #if defined(HAVE_SD) /* card switch diagnostic aid - hold down PREV button to use */ if (menu_system_enabled && get_key_press(KEY_PREV)) board_diagnose(); #endif if (menu_system_enabled) lcd_splashscreen(); bus_interface_init(); bus_init(); read_configuration(); late_board_init(); for (;;) { if (menu_system_enabled) lcd_refresh(); else { lcd_clear(); lcd_printf("#%d", device_address); } /* Unit number may depend on hardware and stored settings */ /* so present it here at last */ printf("#%02d\r\n", device_address); bus_mainloop(); bus_interface_init(); bus_init(); // needs delay, inits device address with HW settings } }
static inline __attribute__((always_inline)) void update_leds(void) { set_busy_led(active_buffers != 0); }
/** * create_changelist - create a swap list in a directory * @path : path where the swap list should be created * @filename: name of the swap list file * * This function creates a swap list in @path by scanning that * directory and writing the names of all disk images it finds * into @filename. Returns nonzero if at least one image was found. */ static uint8_t create_changelist(path_t *path, uint8_t *filename) { FRESULT res; FILINFO finfo; DIR dh; FIL fh; UINT byteswritten; uint8_t *name; uint8_t found = 0; /* open directory */ res = l_opendir(&partition[path->part].fatfs, path->dir.fat, &dh); if (res != FR_OK) return 0; /* open file */ res = f_open(&partition[path->part].fatfs, &fh, filename, FA_WRITE | FA_CREATE_ALWAYS); if (res != FR_OK) return 0; /* scan directory */ set_busy_led(1); finfo.lfn = ops_scratch; while (1) { res = f_readdir(&dh, &finfo); if (res != FR_OK) break; if (finfo.fname[0] == 0) break; if (!(finfo.fattrib & AM_DIR)) { if (check_imageext(finfo.fname) == IMG_IS_DISK) { /* write the name of disk image to file */ found = 1; if (ops_scratch[0] != 0) name = ops_scratch; else name = finfo.fname; res = f_write(&fh, name, ustrlen(name), &byteswritten); if (res != FR_OK || byteswritten == 0) break; /* add line terminator */ finfo.fname[0] = 0x0d; finfo.fname[1] = 0x0a; res = f_write(&fh, finfo.fname, 2, &byteswritten); if (res != FR_OK || byteswritten == 0) break; } } } f_close(&fh); set_busy_led(0); return found; }
void menu_browse_files(void) { buffer_t *buf; buffer_t *buf_tbl; buffer_t *buf_cur; buffer_t *first_buf; path_t path; cbmdirent_t dent; uint16_t entries; uint8_t entry_num; bool fat_filesystem; uint8_t i; uint8_t my; uint16_t mp; bool action; uint16_t stack_mp[MAX_LASTPOS]; uint8_t stack_my[MAX_LASTPOS]; uint8_t pos_stack; uint8_t save_active_buffers; pos_stack = 0; memset(stack_mp, 0, sizeof(stack_mp)); memset(stack_my, 0, sizeof(stack_my)); save_active_buffers = active_buffers; start: lcd_clear(); lcd_puts_P(PSTR("Reading...")); buf = buf_tbl = buf_cur = first_buf = NULL; entries = entry_num = mp = 0; fat_filesystem = false; // Allocate one buffer, used to read a single directory entry if ((buf = alloc_system_buffer()) == NULL) return; // Allocate buffers with continuous data segments // Stores pointers to directory entries for qsort if ((buf_tbl = alloc_linked_buffers(CONFIG_DIR_BUFFERS)) == NULL) return; // Buffers to store the actual diretory entries. // Whilst the directory grows, new buffers get allocated and linked if ((buf_cur = alloc_system_buffer()) == NULL) return; first_buf = buf_cur; // Allocating buffers affects the LEDs set_busy_led(false); set_dirty_led(true); path.part = current_part; path.dir = partition[path.part].current_dir; uart_trace(&path.dir, 0, sizeof(dir_t)); uart_putcrlf(); uart_flush(); if (opendir(&buf->pvt.dir.dh, &path)) return; for (;;) { if (next_match(&buf->pvt.dir.dh, buf->pvt.dir.matchstr, buf->pvt.dir.match_start, buf->pvt.dir.match_end, buf->pvt.dir.filetype, &dent) == 0) { uint8_t e_flags = 0; if (dent.opstype == OPSTYPE_FAT) { fat_filesystem = true; if (check_imageext(dent.pvt.fat.realname) != IMG_UNKNOWN) e_flags |= E_IMAGE; } // Current block full? if (entry_num == ENTRIES_PER_BLOCK) { entry_num = 0; buffer_t *old_buf = buf_cur; if ((buf_cur = alloc_system_buffer()) == NULL) { printf("alloc buf_cur failed, %d entries", entries); goto cleanup; } set_busy_led(false); set_dirty_led(true); buf_cur->pvt.buffer.next = NULL; old_buf->pvt.buffer.next = buf_cur; } // Store entry ep[entries] = (entry_t *) (buf_cur->data + entry_num * sizeof(entry_t)); ustrncpy(ep[entries]->filename, dent.name, 16); ep[entries]->filesize = dent.blocksize; if ((dent.typeflags & EXT_TYPE_MASK) == TYPE_DIR) e_flags |= E_DIR; ep[entries]->flags = e_flags; entries++; entry_num++; } else { // No more directory entries to read break; } } printf("%d entries\r\n", entries); if (fat_filesystem) qsort(ep, entries, sizeof(entry_t*), compare); for (uint16_t i = 0; i < entries; i++) { printf("%3u: ", i); if (ep[i]->flags & E_DIR) uart_puts_P(PSTR(" DIR ")); else if (ep[i]->flags & E_IMAGE) uart_puts_P(PSTR(" IMG ")); else printf("%4u ", ep[i]->filesize); uint8_t filename[16 + 1]; ustrncpy(filename, ep[i]->filename, 16); filename[16] = '\0'; pet2asc(filename); printf("%s\r\n", filename); uart_flush(); } uart_putcrlf(); #define DIRNAV_OFFSET 2 #define NAV_ABORT 0 #define NAV_PARENT 1 mp = stack_mp[pos_stack]; my = stack_my[pos_stack]; printf("mp set to %d\r\n", mp); if (mp < (LCD_LINES - 1)) my = mp; else my = 0; action = false; for (i=0; i < MAX_LASTPOS; i++) { if (pos_stack == i) uart_putc('>'); printf("%d ", stack_mp[i]); } uart_putcrlf(); for (;;) { lcd_clear(); for (i = 0; i < LCD_LINES; i++) { lcd_locate(0, i); int8_t y = mp - my + i; if (y < 0) return; // should not happen! if (y < DIRNAV_OFFSET) { rom_menu_browse(y); } else { y -= DIRNAV_OFFSET; if (y >= entries) { lcd_puts_P(PSTR("-- End of dir --")); break; } else { lcd_print_dir_entry(y); } } } lcd_cursor(true); for (;;) { lcd_locate(0, my); //printf("mp: %u my: %u\r\n", mp, my); //while (!get_key_state(KEY_ANY)); if (get_key_autorepeat(KEY_PREV)) { if (mp > 0) { --mp; if (my > 0) --my; else { my = LCD_LINES - 1; if (mp < LCD_LINES) { while ((mp - my) >= DIRNAV_OFFSET) { --my; // TODO: is this really necessary? uart_puts_P(PSTR("my fixed\r\n")); } } break; } } else { my = LCD_LINES - 2; mp = entries + DIRNAV_OFFSET - 1; break; } } if (get_key_autorepeat(KEY_NEXT)) { if (mp < (entries -1 + DIRNAV_OFFSET)) { ++mp; if (my < (LCD_LINES - 1)) ++my; else { my = 0; break; } } else { mp = 0; my = 0; break; } } if (get_key_press(KEY_SEL)) { action = true; break; } } lcd_cursor(false); if (!action) continue; if (mp == NAV_ABORT) goto cleanup; if (mp == NAV_PARENT) { uart_puts_P(PSTR("CD_\r\n")); ustrcpy_P(command_buffer, PSTR("CD_")); command_length = 3; parse_doscommand(); clear_command_buffer(); stack_mp[pos_stack] = 0; stack_my[pos_stack] = 0; if (pos_stack > 0) --pos_stack; printf("pos_stack set to %d\r\n", pos_stack); if (current_error != ERROR_OK) goto cleanup; goto reread; } if (ep[mp - DIRNAV_OFFSET]->flags & E_DIR || ep[mp - DIRNAV_OFFSET]->flags & E_IMAGE) { clear_command_buffer(); ustrcpy_P(command_buffer, PSTR("CD:")); ustrncpy(command_buffer + 3, ep[mp - DIRNAV_OFFSET]->filename, 16); command_length = ustrlen(command_buffer); parse_doscommand(); clear_command_buffer(); if (current_error != ERROR_OK) goto cleanup; if (pos_stack < MAX_LASTPOS) { stack_mp[pos_stack] = mp; stack_my[pos_stack++] = my; printf("pos_stack set to %d\r\n", pos_stack); } goto reread; } } reread: free_buffer(buf); buffer_t *p = buf_tbl; do { p->allocated = 0; p = p->pvt.buffer.next; } while (p != NULL); p = first_buf; if (p != NULL) do { p->allocated = 0; p = p->pvt.buffer.next; } while (p != NULL); set_busy_led(false); set_dirty_led(true); active_buffers = save_active_buffers; if (mp == NAV_ABORT) return; goto start; cleanup: mp = NAV_ABORT; goto reread; }
/** * update_leds - set LEDs to correspond to the buffer status * * This function sets the busy/dirty LEDs to correspond to the current state * of the buffers, i.e. busy on of at least one non-system buffer is * allocated and dirty on if at least one buffer is dirty. * Call if you have manually changed the LEDs and you want to restore the * "default" state. */ void update_leds(void) { set_busy_led(active_buffers != 0); set_dirty_led(get_dirty_buffer_count() != 0); }
bool menu(void) { uint8_t mp = 0; uint8_t my = 0; uint8_t i; uint8_t old_bus; bool action; old_bus = active_bus; bus_sleep(true); menu_select_status(); // disable splash screen if still active set_error(ERROR_OK); for (;;) { set_busy_led(false); set_dirty_led(true); lcd_clear(); for (i = 0; i < LCD_LINES; i++) { lcd_locate(0, i); rom_menu_main(mp - my + i); } lcd_cursor(true); for (;;) { action = false; lcd_locate(0, my); //printf("mp: %u my: %u\r\n", mp, my); //while (!get_key_state(KEY_ANY)); if (get_key_autorepeat(KEY_PREV)) { if (mp > 0) { // Move up --mp; if (my > 0) { --my; // Move within same page } else { mp = LCD_LINES - 1; my = LCD_LINES - 1; // page up break; } } else { // flip down to last menu entry my = MAIN_MENU_LAST_ENTRY % LCD_LINES; mp = MAIN_MENU_LAST_ENTRY; break; } } if (get_key_autorepeat(KEY_NEXT)) { if (mp < MAIN_MENU_LAST_ENTRY) { ++mp; if (my < (LCD_LINES - 1)) { ++my; // Move within same page } else { my = 0; // page down break; } } else { // flip up to first menu entry mp = 0; my = 0; break; } } if (get_key_press(KEY_SEL)) { action = true; break; } } lcd_cursor(false); if (!action) continue; lcd_clear(); if (mp == 1) menu_browse_files(); else if (mp == 2) menu_device_number(); else if (mp == 3) menu_set_clock(); else if (mp == 4) menu_select_bus(); else if (mp == 5) menu_adjust_contrast(); else if (mp == 6) menu_adjust_brightness(); else break; if (current_error != ERROR_OK) break; } bus_sleep(false); lcd_draw_screen(SCRN_STATUS); update_leds(); return old_bus != active_bus; }
void ieee_mainloop(void) { int16_t cmd = 0; set_error(ERROR_DOSVERSION); ieee_data.bus_state = BUS_IDLE; ieee_data.device_state = DEVICE_IDLE; for(;;) { switch(ieee_data.bus_state) { case BUS_SLEEP: /* BUS_SLEEP */ set_atn_irq(0); ieee_bus_idle(); set_error(ERROR_OK); set_busy_led(0); uart_puts_P(PSTR("ieee.c/sleep ")); set_dirty_led(1); /* Wait until the sleep key is used again */ while (!key_pressed(KEY_SLEEP)) system_sleep(); reset_key(KEY_SLEEP); set_atn_irq(1); update_leds(); ieee_data.bus_state = BUS_IDLE; break; case BUS_IDLE: /* BUS_IDLE */ ieee_bus_idle(); while(IEEE_ATN) { ; /* wait for ATN */ if (key_pressed(KEY_NEXT | KEY_PREV | KEY_HOME)) { change_disk(); } else if (key_pressed(KEY_SLEEP)) { reset_key(KEY_SLEEP); ieee_data.bus_state = BUS_SLEEP; break; } else if (display_found && key_pressed(KEY_DISPLAY)) { display_service(); reset_key(KEY_DISPLAY); } system_sleep(); } if (ieee_data.bus_state != BUS_SLEEP) ieee_data.bus_state = BUS_FOUNDATN; break; case BUS_FOUNDATN: /* BUS_FOUNDATN */ ieee_data.bus_state = BUS_ATNPROCESS; cmd = ieee_getc(); break; case BUS_ATNPROCESS: /* BUS_ATNPROCESS */ if(cmd < 0) { uart_putc('c'); ieee_data.bus_state = BUS_IDLE; break; } else cmd &= 0xFF; uart_puts_p("ATN "); uart_puthex(cmd); uart_putcrlf(); if (cmd == 0x3f) { /* UNLISTEN */ if(ieee_data.device_state == DEVICE_LISTEN) { ieee_data.device_state = DEVICE_IDLE; uart_puts_p("UNLISTEN\r\n"); } ieee_data.bus_state = BUS_IDLE; break; } else if (cmd == 0x5f) { /* UNTALK */ if(ieee_data.device_state == DEVICE_TALK) { ieee_data.device_state = DEVICE_IDLE; uart_puts_p("UNTALK\r\n"); } ieee_data.bus_state = BUS_IDLE; break; } else if (cmd == (0x40 + device_address)) { /* TALK */ uart_puts_p("TALK "); uart_puthex(device_address); uart_putcrlf(); ieee_data.device_state = DEVICE_TALK; /* disk drives never talk immediatly after TALK, so stay idle and wait for a secondary address given by 0x60-0x6f DATA */ ieee_data.bus_state = BUS_IDLE; break; } else if (cmd == (0x20 + device_address)) { /* LISTEN */ ieee_data.device_state = DEVICE_LISTEN; uart_puts_p("LISTEN "); uart_puthex(device_address); uart_putcrlf(); ieee_data.bus_state = BUS_IDLE; break; } else if ((cmd & 0xf0) == 0x60) { /* DATA */ /* 8250LP sends data while ATN is still active, so wait for bus controller to release ATN or we will misinterpret data as a command */ while(!IEEE_ATN); if(ieee_data.device_state == DEVICE_LISTEN) { cmd = ieee_listen_handler(cmd); cmd_handler(); break; } else if (ieee_data.device_state == DEVICE_TALK) { ieee_data.secondary_address = cmd & 0x0f; uart_puts_p("DATA T "); uart_puthex(ieee_data.secondary_address); uart_putcrlf(); if(ieee_talk_handler() == TIMEOUT_ABORT) { ieee_data.device_state = DEVICE_IDLE; } ieee_data.bus_state = BUS_IDLE; break; } else { ieee_data.bus_state = BUS_IDLE; break; } } else if (ieee_data.device_state == DEVICE_IDLE) { ieee_data.bus_state = BUS_IDLE; break; /* ----- if we reach this, we're LISTENer or TALKer ----- */ } else if ((cmd & 0xf0) == 0xe0) { /* CLOSE */ ieee_data.secondary_address = cmd & 0x0f; uart_puts_p("CLOSE "); uart_puthex(ieee_data.secondary_address); uart_putcrlf(); /* Close all buffers if sec. 15 is closed */ if(ieee_data.secondary_address == 15) { free_multiple_buffers(FMB_USER_CLEAN); } else { /* Close a single buffer */ buffer_t *buf; buf = find_buffer (ieee_data.secondary_address); if (buf != NULL) { buf->cleanup(buf); free_buffer(buf); } } ieee_data.bus_state = BUS_IDLE; break; } else if ((cmd & 0xf0) == 0xf0) { /* OPEN */ cmd = ieee_listen_handler(cmd); cmd_handler(); break; } else { /* Command for other device or unknown command */ ieee_data.bus_state = BUS_IDLE; } break; } /* switch */ } /* for() */ }
int main(void) { /* Early system initialisation */ board_init(); system_init_early(); leds_init(); set_busy_led(1); set_dirty_led(0); /* Due to an erratum in the LPC17xx chips anything that may change */ /* peripheral clock scalers must come before system_init_late() */ uart_init(); #ifndef SPI_LATE_INIT spi_init(SPI_SPEED_SLOW); #endif timer_init(); bus_interface_init(); i2c_init(); /* Second part of system initialisation, switches to full speed on ARM */ system_init_late(); enable_interrupts(); /* Internal-only initialisation, called here because it's faster */ buffers_init(); buttons_init(); /* Anything that does something which needs the system clock */ /* should be placed after system_init_late() */ bus_init(); // needs delay rtc_init(); // accesses I2C disk_init(); // accesses card read_configuration(); fatops_init(0); change_init(); uart_puts_P(PSTR("\r\nsd2iec " VERSION " #")); uart_puthex(device_address); uart_putcrlf(); #ifdef CONFIG_REMOTE_DISPLAY /* at this point all buffers should be free, */ /* so just use the data area of the first to build the string */ uint8_t *strbuf = buffers[0].data; ustrcpy_P(strbuf, versionstr); ustrcpy_P(strbuf+ustrlen(strbuf), longverstr); if (display_init(ustrlen(strbuf), strbuf)) { display_address(device_address); display_current_part(0); } #endif set_busy_led(0); #if defined(HAVE_SD) && BUTTON_PREV != 0 /* card switch diagnostic aid - hold down PREV button to use */ if (!(buttons_read() & BUTTON_PREV)) { while (buttons_read() & BUTTON_NEXT) { set_dirty_led(sdcard_detect()); # ifndef SINGLE_LED set_busy_led(sdcard_wp()); # endif } reset_key(0xff); } #endif bus_mainloop(); while (1); }