URL
https://opencores.org/ocsvn/hf-risc/hf-risc/trunk
Subversion Repositories hf-risc
[/] [hf-risc/] [trunk/] [software/] [boot/] [monitor.c] - Rev 18
Go to most recent revision | Compare with Previous | Blame | View Log
#include <hf-risc.h> /* memory mapped I/O access */ #define MemoryRead(A) (*(volatile unsigned int*)(A)) #define MemoryWrite(A,V) *(volatile unsigned int*)(A)=(V) /* SPI interface - EXTIO_OUT pins 0 (chip select), 1 (clock), 2 (master output) and 3 (chip select 2) */ #define SPI_CS 0x01 #define SPI_SCK 0x02 #define SPI_MOSI 0x04 #define SPI_CS2 0x08 /* SPI interface - EXIO_IN pin 3 (master input) */ #define SPI_MISO 0x08 /* EEPROM config / commands */ #define PAGE_SIZE 64 #define CMD_READ 0x03 #define CMD_WRITE 0x02 #define CMD_WREN 0x06 /* monitor auxiliry routines */ uint32_t getnum(void){ int32_t i; uint32_t ch, ch2, value=0; for(i = 0; i < 16; ){ ch = ch2 = getchar(); if(ch == '\n' || ch == '\r') break; if('0' <= ch && ch <= '9') ch -= '0'; else if('A' <= ch && ch <= 'Z') ch = ch - 'A' + 10; else if('a' <= ch && ch <= 'z') ch = ch - 'a' + 10; else if(ch == 8){ if(i > 0){ --i; putchar(ch); putchar(' '); putchar(ch); } value >>= 4; continue; } putchar(ch2); value = (value << 4) + ch; ++i; } return value; } void printnum(uint32_t n){ int8_t buf[30]; uint16_t i; itoa(n, buf, 10); i = 0; while (buf[i]) putchar(buf[i++]); } void printhex(uint32_t n){ int8_t buf[30]; uint16_t i; if (n < 16) putchar('0'); itoa(n, buf, 16); i = 0; while (buf[i]) putchar(buf[i++]); } int32_t printstr(const int8_t *str){ while(*str) putchar(*str++); return 0; } /* SPI low level interface driver, mode 0 */ void spi_setup(void){ EXTIO_OUT |= SPI_CS | SPI_CS2; EXTIO_OUT &= ~SPI_SCK; } void spi_start(void){ EXTIO_OUT &= ~SPI_CS2; } void spi_stop(void){ EXTIO_OUT |= SPI_CS2; } int8_t spi_sendrecv(int8_t data){ int32_t i; int8_t newdata = 0; for (i = 0; i < 8; i++){ if (data & 0x80){ EXTIO_OUT |= SPI_MOSI; }else{ EXTIO_OUT &= ~SPI_MOSI; } data <<= 1; EXTIO_OUT |= SPI_SCK; newdata <<= 1; newdata |= ((EXTIO_IN & SPI_MISO) ? 1 : 0); EXTIO_OUT &= ~SPI_SCK; } return newdata; } /* SPI EEPROM driver EEPROM should be a 25lc128 (16KB) or 25lc256 (32KB) compatible chip! if you need a different ROM size / configuration, change PAGE_SIZE accordingly. */ uint8_t spi_eeprom_readbyte(uint16_t addr){ uint8_t data; spi_start(); spi_sendrecv(CMD_READ); spi_sendrecv(addr >> 8); spi_sendrecv(addr & 0xff); data = spi_sendrecv(0); spi_stop(); return data; } void spi_eeprom_read(uint16_t addr, uint8_t *buf, uint16_t size){ uint8_t data; uint16_t i; spi_start(); spi_sendrecv(CMD_READ); spi_sendrecv(addr >> 8); spi_sendrecv(addr & 0xff); for(i = 0; i < size; i++) buf[i] = spi_sendrecv(0); spi_stop(); } void spi_eeprom_writepage(uint16_t page, uint8_t *data){ uint16_t i; spi_start(); spi_sendrecv(CMD_WREN); spi_stop(); spi_start(); spi_sendrecv(CMD_WRITE); spi_sendrecv((page * PAGE_SIZE) >> 8); spi_sendrecv((page * PAGE_SIZE) & 0xff); for (i = 0; i < PAGE_SIZE; i++) spi_sendrecv(data[i]); spi_stop(); delay_ms(10); } void boot_spi(void){ uint32_t signature, size; uint8_t *ptr1; funcptr funcPtr; /* -initialize SPI, mode 0; -try to read a 4 byte signature (0xb16b00b5). on fail (no eeprom, no valid data or no jumper) return to monitor; -read image size on next 4 bytes (e.g: 2350 bytes will be 0x0000092e; -copy ROM data to RAM, starting at 0x40000000 -jump to 0x40000000 */ spi_setup(); signature = (spi_eeprom_readbyte(0) << 24) | (spi_eeprom_readbyte(1) << 16) | (spi_eeprom_readbyte(2) << 8) | spi_eeprom_readbyte(3); if (signature != 0xb16b00b5) return; size = (spi_eeprom_readbyte(4) << 24) | (spi_eeprom_readbyte(5) << 16) | (spi_eeprom_readbyte(6) << 8) | spi_eeprom_readbyte(7); ptr1 = (uint8_t *)ADDR_RAM_BASE; // skip header and copy EEPROM data to RAM spi_eeprom_read(8, ptr1, size); funcPtr = (funcptr)ADDR_RAM_BASE; funcPtr((void *)0); } /* monitor main program. we are using the last portion of SRAM as the program stack! */ int32_t main(void){ int32_t i, j, k, l, ch; uint32_t addr, addr2, value, size = 0; funcptr funcPtr; uint32_t *ptr; uint8_t *ptr1; uint8_t eeprom_page[PAGE_SIZE]; uart_init(57600); boot_spi(); printstr("\nHF-RISC bootloader - "); printstr(__DATE__); printstr("\n"); for(;;){ printstr("\n[u, U] upload binary"); printstr("\n[b, B] boot "); printstr("\n[p ] program EEPROM"); printstr("\n[d ] mem dump"); printstr("\n[f ] mem fill"); printstr("\n[w ] write data"); printstr("\n"); ch = getchar(); getchar(); switch(ch){ case 'u': ptr1 = (uint8_t *)ADDR_RAM_BASE; goto waiting; case 'U': printstr("\naddress (hex):"); addr = getnum(); ptr1 = (uint8_t *)addr; waiting: printstr("\nwaiting for binary..."); ch = getchar(); for(i = 0; ; i++){ ptr1[i] = (uint8_t)ch; for(j = 0; j < (CPU_SPEED / 100); j++){ if(kbhit()){ ch = getchar(); break; } } if (j >= (CPU_SPEED / 100)) break; if ((i % 1024) == 0) putchar('*'); } i++; printstr("--> "); printnum(i); printstr(" bytes"); size = i; break; case 'b': funcPtr = (funcptr)ADDR_RAM_BASE; goto booting; case 'B': printstr("\naddress (hex):"); addr = getnum(); funcPtr = (funcptr)addr; booting: printstr("\nboot\n"); funcPtr((void *)0); break; case 'p': if (!size) break; ptr1 = (uint8_t *)ADDR_RAM_BASE; printstr("\nprogramming "); printnum(size); printstr(" bytes"); // signature eeprom_page[0] = 0xb1; eeprom_page[1] = 0x6b; eeprom_page[2] = 0x00; eeprom_page[3] = 0xb5; // image size eeprom_page[4] = (size >> 24) & 0xff; eeprom_page[5] = (size >> 16) & 0xff; eeprom_page[6] = (size >> 8) & 0xff; eeprom_page[7] = size & 0xff; // first page i = 0; k = 0; for (j = 8; j < PAGE_SIZE; j++){ if (i < size){ eeprom_page[j] = ptr1[i++]; }else{ eeprom_page[j] = 0x00; } } spi_eeprom_writepage(k, eeprom_page); // next pages while(i < size){ k++; for (j = 0; j < PAGE_SIZE; j++){ if (i < size){ eeprom_page[j] = ptr1[i++]; }else{ eeprom_page[j] = 0x00; } } spi_eeprom_writepage(k, eeprom_page); } break; case 'd': printstr("\naddress (hex):"); addr = getnum(); ptr1 = (uint8_t *)addr; printstr("\nlength (hex):"); i = getnum(); for(k = 0; k < i; k += 16){ printstr("\n"); printhex(addr + k); printstr(" "); for(l = 0; l < 16; l++){ printhex(ptr1[k+l]); printstr(" "); if (l == 7) printstr(" "); } printstr(" |"); for(l = 0; l < 16; l++){ ch = ptr1[k+l]; if ((ch >= 32) && (ch <= 126)) putchar((uint8_t)ch); else printstr("."); } printstr("|"); } break; case 'f': printstr("\naddress (hex):"); addr = getnum(); ptr1 = (uint8_t *)addr; printstr("\nlength (hex):"); i = getnum(); printstr("\nbyte (hex):"); ch = (uint8_t)getnum(); for (l = 0; l < i; l++) ptr1[l] = ch; break; case 'w': printstr("\naddress (hex):"); addr = getnum(); printstr("\ndata (hex):"); value = getnum(); MemoryWrite(addr, value); break; default: break; } } return 0; }
Go to most recent revision | Compare with Previous | Blame | View Log