OpenCores
URL https://opencores.org/ocsvn/hf-risc/hf-risc/trunk

Subversion Repositories hf-risc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /hf-risc/trunk
    from Rev 5 to Rev 6
    Reverse comparison

Rev 5 → Rev 6

/software/boot/monitor.c
0,0 → 1,346
#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;
}
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.