/** * Run diagnostic on DRAM: test all regions pass the R/W test. The 1st 1MB * of DRAM is skipped since the bootloader can't run without it being usable! */ void diag_mem(void) { int rval; u32 addr; uart_putstr("running memory test ...\r\n"); #if (CHIP_REV == I1) uart_putstr("region 0x00000000 - 0x000fffff skipped\r\n"); #else uart_putstr("region 0xc0000000 - 0xc00fffff skipped\r\n"); #endif for (addr = (DRAM_START_ADDR + 0x00100000); addr <= DRAM_END_ADDR; addr += 0x00100000) { uart_putstr("testing 0x"); uart_puthex(addr); uart_putstr(" - 0x"); uart_puthex(addr | 0x000fffff); uart_putstr(" ... "); rval = testram3(addr, 0x00100000); if (rval != 0) { uart_putstr("\r\nmemory failure at 0x"); uart_puthex(addr); uart_putstr("!\r\n"); break; } uart_putstr("done\r\n"); } }
static uint8_t ieee_talk_handler (void) { buffer_t *buf; uint8_t finalbyte; uint8_t c; uint8_t res; buf = find_buffer(ieee_data.secondary_address); if(buf == NULL) return -1; while (buf->read) { do { finalbyte = (buf->position == buf->lastused); c = buf->data[buf->position]; if (finalbyte && buf->sendeoi) { /* Send with EOI */ res = ieee_putc(c, 1); if(!res) uart_puts_p("EOI: "); } else { /* Send without EOI */ res = ieee_putc(c, 0); } if(res) { if(res==0xfc) { uart_puts_P(PSTR("*** TIMEOUT ABORT***")); uart_putcrlf(); } if(res!=0xfd) { uart_putc('c'); uart_puthex(res); } return 1; } else { uart_putc('>'); uart_puthex(c); uart_putc(' '); if(isprint(c)) uart_putc(c); else uart_putc('?'); uart_putcrlf(); } } while (buf->position++ < buf->lastused); if(buf->sendeoi && ieee_data.secondary_address != 0x0f && !buf->recordlen && buf->refill != directbuffer_refill) { buf->read = 0; break; } if (buf->refill(buf)) { return -1; } /* Search the buffer again, it can change when using large buffers */ buf = find_buffer(ieee_data.secondary_address); } return 0; }
static int cmd_hal(int argc, char *argv[]) { int i; int result; amb_hal_function_info_t *finfo; if (argc == 1) { /* Enumerate HAL */ finfo = (amb_hal_function_info_t *) (g_haladdr + 128); for (i = 0; finfo[i].function != NULL; i++) { uart_putdec(i); uart_putchar(' '); uart_puthex((u32) finfo[i].function); uart_putchar(' '); uart_putstr((char *) (g_haladdr + (u32) finfo[i].name)); uart_putstr("\r\n"); } return 0; } /* Invoke HAL */ result = hal_call_name(argc -1, &argv[1]); uart_putstr("result = "); uart_putdec(result); uart_putstr("\r\n"); return 0; }
static int cmd_exec(int argc, char *argv[]) { u32 addr; void (*jump_to_img)(void) = NULL; if (argc != 2 || strtou32(argv[1], &addr) < 0) { uart_putstr("address (eg. 0x"); uart_puthex(DRAM_START_ADDR + 0x00100000); uart_putstr(") is required\r\n"); return -1; } if (addr < (DRAM_START_ADDR + 0x00100000) || addr > (DRAM_START_ADDR + DRAM_SIZE - 1)) { uart_putstr("address out of range!\r\n"); return -1; } jump_to_img = (void *) addr; if (jump_to_img != 0x0) { uart_putstr("jumping to 0x"); uart_puthex(addr); uart_putstr(" ...\r\n"); _clean_flush_all_cache(); _disable_icache(); _disable_dcache(); disable_interrupts(); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); jump_to_img(); } return 0; }
void uart_trace(void *ptr, uint16_t start, uint16_t len) { uint16_t i; uint8_t j; uint8_t ch; uint8_t *data = ptr; data+=start; for(i=0;i<len;i+=16) { uart_puthex(start>>8); uart_puthex(start&0xff); uart_putc('|'); uart_putc(' '); for(j=0;j<16;j++) { if(i+j<len) { ch=*(data + j); uart_puthex(ch); } else { uart_putc(' '); uart_putc(' '); } uart_putc(' '); } uart_putc('|'); for(j=0;j<16;j++) { if(i+j<len) { ch=*(data++); if(ch<32 || ch>0x7e) ch='.'; uart_putc(ch); } else { uart_putc(' '); } } uart_putc('|'); uart_putcrlf(); start+=16; } }
void uart_dump(u8 *mem, int len) { int i; while(len) { uart_puthex((u32)mem); uart_puts(" "); for (i = 0; i < 16; i++) { uart_puthex8(*mem); uart_putc(' '); mem++; len --; if (len == 0) break; } uart_crlf(); } }
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() */ }
static int16_t ieee_listen_handler (uint8_t cmd) /* Receive characters from IEEE-bus and write them to the listen buffer adressed by ieee_data.secondary_address. If a new command is received (ATN set), return it */ { buffer_t *buf; int16_t c; ieee_data.secondary_address = cmd & 0x0f; buf = find_buffer(ieee_data.secondary_address); /* Abort if there is no buffer or it's not open for writing */ /* and it isn't an OPEN command */ if ((buf == NULL || !buf->write) && (cmd & 0xf0) != 0xf0) { uart_putc('c'); return -1; } switch(cmd & 0xf0) { case 0x60: uart_puts_p("DATA L "); break; case 0xf0: uart_puts_p("OPEN "); break; default: uart_puts_p("Unknown LH! "); break; } uart_puthex(ieee_data.secondary_address); uart_putcrlf(); c = -1; for(;;) { /* Get a character ignoring timeout but but watching ATN */ while((c = ieee_getc()) < 0); if (c & FLAG_ATN) return c; uart_putc('<'); if (c & FLAG_EOI) { uart_puts_p("EOI "); ieee_data.ieeeflags |= EOI_RECVD; } else ieee_data.ieeeflags &= ~EOI_RECVD; uart_puthex(c); uart_putc(' '); c &= 0xff; /* needed for isprint */ if(isprint(c)) uart_putc(c); else uart_putc('?'); uart_putcrlf(); if((cmd & 0x0f) == 0x0f || (cmd & 0xf0) == 0xf0) { if (command_length < CONFIG_COMMAND_BUFFER_SIZE) command_buffer[command_length++] = c; if (ieee_data.ieeeflags & EOI_RECVD) /* Filenames are just a special type of command =) */ ieee_data.ieeeflags |= COMMAND_RECVD; } else { /* Flush buffer if full */ if (buf->mustflush) { if (buf->refill(buf)) return -2; /* Search the buffer again, */ /* it can change when using large buffers */ buf = find_buffer(ieee_data.secondary_address); } buf->data[buf->position] = c; mark_buffer_dirty(buf); if (buf->lastused < buf->position) buf->lastused = buf->position; buf->position++; /* Mark buffer for flushing if position wrapped */ if (buf->position == 0) buf->mustflush = 1; /* REL files must be syncronized on EOI */ if(buf->recordlen && (ieee_data.ieeeflags & EOI_RECVD)) { if (buf->refill(buf)) return -2; } } /* else-buffer */ } /* for(;;) */ }
void loop(){ //one frame static uint8_t escape_state = 0; uint16_t receive_state = 1; //primitive somewhat messy state machine of the uart interface do{ //Always empty the receive buffer since there are _delay_xxs in the following code and thus this might not run all that often. receive_state = uart_getc(); char c = receive_state&0xFF; receive_state &= 0xFF00; //escape code format: // \\ - backslash // \n - newline // \[x] - x //eats [n] commands: 's' (0x73) led value sets led number [led] to [value] // 'b' (0x62) buffer buffer buffer buffer sets the whole frame buffer // 'a' (0x61) meter value sets analog meter number [meter] to [value] // 'r' (0x72) read the frame buffer // 'd' (0x64) display digit digit digit digit sets the 7-segment display (CAUTION: "display" currently is ignored) //this device will utter a "'c' (0x63) num state" when switch [num] changes state to [state] //commands are terminated by \n if(!receive_state){ if(!escape_state){ if(c == '\\'){ receive_state |= 0x02; escape_state = 1; }else if(c == '\n'){ receive_state |= 0x02; state = 0; } }else{ receive_state = 0; escape_state = 0; switch(c){ case '\\': break; case 'n': c = '\n'; break; } } } if(!receive_state){ switch(state){ case 0: //Do not assume anything about the variables used //command char switch(c){ #ifdef HAS_LED_SUPPORT case 's': state = 2; break; case 'b': nbuf = 0; state = 4; break; #endif//HAS_LED_SUPPORT #ifdef HAS_PWM_SUPPORT case 'a': state = 5; nbuf = 0; break; #endif//HAS_PWM_SUPPORT #ifdef HAS_NOISE_MAKER_SUPPORT case 'x': //DDRF |= 0x01; //PORTF |= 0x01; break; case 'X': //DDRF &= 0xFE; //PORTF &= 0xFE; break; #endif//HAS_NOISE_MAKER_SUPPORT #ifdef HAS_LED_SUPPORT case 'r': uart_putc('r'); for(uint8_t i=0; i<sizeof(frameBuffer); i++){ uart_puthex(frameBuffer[i]); } uart_putc('\n'); break; #endif//HAS_LED_SUPPORT #ifdef HAS_7SEG_SUPPORT case 'd': nbuf = 0; bpos = 0; state = 7; #endif//HAS_7SEG_SUPPORT } break; #ifdef HAS_LED_SUPPORT case 2: nbuf=c; state = 3; break; case 3: setLED(nbuf, c); state = 0; break; case 4: secondFrameBuffer[(uint8_t) nbuf] = c; nbuf++; if(nbuf == 7){ swapBuffers(); state = 0; } break; #endif//HAS_LED_SUPPORT #ifdef HAS_PWM_SUPPORT case 5: if(c > PWM_COUNT) c = 0; nbuf = c; if(nbuf >= PWM_COUNT) nbuf = 0; state = 6; break; case 6: pwm_val[(uint8_t) nbuf] = c; uart_puts_p(PSTR("ACK\n")); state = 0; break; #endif//HAS_PWM_SUPPORT #ifdef HAS_7SEG_SUPPORT case 7: nbuf = c; state = 8; break; case 8: l7seg_buf[(uint8_t)bpos] = c; bpos++; if(bpos == 4){ state = 0; } break; #endif//HAS_7SEG_SUPPORT } } }while(!receive_state); led_loop(); r0ketbeam_loop(); l7seg_loop(); input_loop(); pwm_loop(); config_loop(); _delay_ms(1); }
static int cmd_dump(int argc, char *argv[]) { u32 val; u32 _saddr; u32 _eaddr; u32 _caddr; u32 _taddr; int num; int count = 0; int flag = 1; if (argc == 3 || argc == 5) { if (argc == 3) flag = 0; if (strcmp("8", argv[1]) == 0) { num = 1; } else if (strcmp("16", argv[1]) == 0) { num = 2; } else if (strcmp("32", argv[1]) == 0) { num = 4; } else { uart_putstr("2nd argument be [8|16|32]!\r\n"); return -1; } /* Get start address */ if (strtou32(argv[2], &_saddr) < 0) { uart_putstr("invalid start sddress!\r\n"); return -2; } _taddr = _saddr & 0xf0000000; if (_taddr != AHB_BASE && _taddr != APB_BASE && _taddr != DRAM_START_ADDR) { uart_putstr("start address out of range!\r\n"); return -3; } /* Check for '-' */ if (flag == 1 && strcmp("-", argv[3]) != 0) { uart_putstr("syntax error!\r\n"); return -4; } /* Get end address */ if (flag == 1 && strtou32(argv[4], &_eaddr) < 0) { uart_putstr("invalid end address!\r\n"); return -5; } if (flag == 0) _eaddr = _saddr + num - 1; /* Check end address range */ _taddr = _eaddr & 0xf0000000; if (_taddr != AHB_BASE && _taddr != APB_BASE && _taddr != DRAM_START_ADDR) { uart_putstr("end address out of range!\r\n"); return -6; } /* Check address range */ if (_eaddr < _saddr) { uart_putstr("end address must be larger than "); uart_putstr("start address\r\n"); return -7; } /* Dump memory */ for (_caddr = _saddr; _caddr <= _eaddr; ) { if ((count % 16) == 0){ if (count != 0) uart_putstr("\r\n"); uart_putstr("0x"); uart_puthex(_caddr); uart_putstr(" "); } if (num == 1) { val = readb(_caddr); uart_putbyte(val); uart_putstr(" "); _caddr += 1; count += 1; } else if (num == 2) { val = readb(_caddr); uart_putbyte(val); uart_putstr(" "); val = readb(_caddr + 1); uart_putbyte(val); uart_putstr(" "); _caddr += 2; count += 2; } else if (num == 4) { val = readb(_caddr); uart_putbyte(val); uart_putstr(" "); val = readb(_caddr + 1); uart_putbyte(val); uart_putstr(" "); val = readb(_caddr + 2); uart_putbyte(val); uart_putstr(" "); val = readb(_caddr + 3); uart_putbyte(val); uart_putstr(" "); _caddr += 4; count += 4; } } uart_putstr("\r\n"); } else { uart_putstr("Type 'help dump' for help\r\n"); return -8; } return 0; }
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); }