OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [soc/] [sw/] [sd_boot_loader/] [main.c] - Rev 22

Compare with Previous | Blame | View Log

 /*
 * SD/MMC card bootloader for OR1k SoC
 *
 * Copyright (c) 2008 by:
 *      Xianfeng Zeng <xianfeng.zeng@gmail.com, Xianfeng.zeng@SierraAtlantic.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the BSD Licence, GNU General Public License
 * as published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version
 *
 * ChangeLog:
 *      2009-10-05 12:56:55   xzeng
 *          Init.
 *
 */
 
 
#define INCLUDED_FROM_C_FILE
 
#include "orsocdef.h"
#include "board.h"
 
 
#define DEBUG 1
 
#define barrier() __asm__ __volatile__("": : :"memory")
 
#ifdef DEBUG
void or1k_putc(int c)
{
	while ( 0x20 != (REG8(UART_BASE_ADD+5) & 0x20) )
		;
 
	REG8(UART_BASE_ADD) = c;
}
 
void print(unsigned char *c)
{
	uint32 i;
 
	if (c == NULL)
		return;
 
	for (i = 0; c[i] != 0; i++) {
		or1k_putc(c[i]);
	}
}
 
void print32bit (long unsigned int val)
{
  int i;
  unsigned long int myNibble;
  char myChar;
 
  for (i=0;i<8;i++) {
    myNibble =  (val >> 28) & 0xfUL;
    if (myNibble <= 0x9)
      myChar = (char) myNibble + 0x30;
    else
      myChar = (char) myNibble + 0x37;
    or1k_putc (myChar);
    val = val << 4;
  }
  or1k_putc ('\n');
  or1k_putc ('\r');
}
 
 
#else
#define or1k_putc(a)
#define print(a)
#endif
 
 
void do_sleep()
{
	uint32 i;
	for (i = 0; i < 200000; i++)
		;
}
 
void do_sleep2()
{
	uint32 i;
	for (i = 0; i < 1000; i++)
		;
}
 
/******************************************************************************/
/*                           G P I O   W  R I T E                             */
/******************************************************************************/
 
// Write to the GPIO (32 bits)
 
void GPIO_Write(uint32 GPIO_data)
{   
   REG32(GPIO_BASE + RGPIO_OUT) = GPIO_data;
}
 
 
/******************************************************************************/
/*                           F O R   s p i M A S T E R                        */
/******************************************************************************/
 
//Initialize
int spiMaster_init()
{
	uint8 data;
	int   i;
 
	REG8(SD_BASE_ADD + SD_CLK_DEL_REG) = 0x1;
 
	for (i = 0; i < 5; i++) {
		REG8(SD_BASE_ADD + SD_TRANS_TYPE_REG) = SD_INIT_SD;
		REG8(SD_BASE_ADD + SD_TRANS_CTRL_REG) = 1; // TRANS_START;
 
		do_sleep();
 
		while (REG8(SD_BASE_ADD + SD_TRANS_STS_REG) & 0x1) { // exit while !TRABS_BUSY
			;
		}
 
		data = REG8(SD_BASE_ADD + SD_TRANS_ERROR_REG) & 0x3;
 
		if (data == 0) {
			return 0;
		}
	}
	return data;
}
 
unsigned char data[512];
 
int copy_sd2ddr(void)
{
 
	int i, j;
	uint8 data;
	unsigned char transError;
 
	uint32 blockCnt;
	uint32 numBlocks = 2 * 1024 * 10; // How mang blocks will be copied
 
	uint32 ddr_offset = 0;
 
	print("\n\r");
	print("Copying SD image to DDR SDRAM...\n\r");
	print("Blocks:");
	print32bit((long unsigned int)numBlocks);
 
	for (blockCnt = 0; blockCnt < numBlocks; blockCnt++) {
		REG8(SD_BASE_ADD + SD_ADDR_7_0_REG)   = 0;
		REG8(SD_BASE_ADD + SD_ADDR_15_8_REG)  = (unsigned char) ((ddr_offset >> 8) & 0xff);
		REG8(SD_BASE_ADD + SD_ADDR_23_16_REG) = (unsigned char) ((ddr_offset >> 16) & 0xff);
		REG8(SD_BASE_ADD + SD_ADDR_31_24_REG) = (unsigned char) ((ddr_offset >> 24) & 0xff);
 
 
		REG8(SD_BASE_ADD + SD_TRANS_TYPE_REG) = SD_RW_READ_SD_BLOCK;
		REG8(SD_BASE_ADD + SD_RX_FIFO_CONTROL_REG) = 0x1; // Clean the RX FIFO
		REG8(SD_BASE_ADD + SD_TRANS_CTRL_REG) = 0x1; //TRANS_START
		while (REG8(SD_BASE_ADD + SD_TRANS_STS_REG) & 0x1) { // exit while !TRABS_BUSY
			;
		}
 
		transError = REG8(SD_BASE_ADD + SD_TRANS_ERROR_REG) & 0xc;
		if ( transError == SD_READ_NO_ERROR) {
			for (i = 0; i < 512; i++) {
				data = REG8(SD_BASE_ADD + SD_RX_FIFO_DATA_REG) ;			
				REG8(DDR_SDRAM_BASE_ADDR + ddr_offset + i) = data ;
//				print32bit((long unsigned int)data);
			}
			if ((blockCnt % 0x40) == 0) {
				or1k_putc('.');
				j++;
			}
			if (j == 20) {
				j = 0;
				print("\n\r");
			}
 
			ddr_offset += 512;		
		} else {
			or1k_putc('R');
			j++;
                        if (j == 20) {
                                j = 0;
                                print("\n\r");
                        }
			spiMaster_init(); // Init again and retry
			blockCnt--; // read the same block again
		}
	}
 
	print("\r\nSD Copy Done!\n\r");
}
 
 
/******************************************************************************/
/*                        TEST EXTERNAL DDR SDRAM                             */
/******************************************************************************/
 
void ddr_sdram_sample_test()
{
	uint32 int32;
	uint16 int16;
	uint8  int8;
	int    i;
 
	REG32(DDR_SDRAM_BASE_ADDR) = 0x12345678;
	int32 = REG32(DDR_SDRAM_BASE_ADDR);
 
	REG16(DDR_SDRAM_BASE_ADDR + 10) = 0x55aa;
	int16 = REG16(DDR_SDRAM_BASE_ADDR + 10);
 
	REG8(DDR_SDRAM_BASE_ADDR + 20) = 0x5a;
	int8 = REG8(DDR_SDRAM_BASE_ADDR + 20);
 
	if (REG8(DDR_SDRAM_BASE_ADDR + 20)  != 0x5a)
		print ("DDR SDRAM accesses short type Error:20!\n\r");
 
	REG8(DDR_SDRAM_BASE_ADDR + 100) = 0x12;
	REG8(DDR_SDRAM_BASE_ADDR + 101) = 0x34;
	REG8(DDR_SDRAM_BASE_ADDR + 102) = 0x56;
	REG8(DDR_SDRAM_BASE_ADDR + 103) = 0x78;
 
	int32 = REG32(DDR_SDRAM_BASE_ADDR + 100);
 
	if (REG8(DDR_SDRAM_BASE_ADDR + 100)  != 0x12)
		print ("DDR SDRAM accesses char type Error:100!\n\r");
	if (REG8(DDR_SDRAM_BASE_ADDR + 101)  != 0x34)
		print ("DDR SDRAM accesses char type Error:101!\n\r");
	if (REG8(DDR_SDRAM_BASE_ADDR + 102)  != 0x56)
		print ("DDR SDRAM accesses char type Error:102!\n\r");
	if (REG8(DDR_SDRAM_BASE_ADDR + 103)  != 0x78)
		print ("DDR SDRAM accesses char type Error:103!\n\r");
 
	for (i=0;i<64;i++) {
		REG8(DDR_SDRAM_BASE_ADDR + i) = i;	
	}
 
	for (i=0;i<64;i++) {
		REG8(0x3900+i) = REG8(DDR_SDRAM_BASE_ADDR + i);	
	}
 
	print ("DDR SDRAM sample test done.\n\r");
}
 
 
/*$$EXTERNAL EXEPTIONS*/
/******************************************************************************/
/*                  E X T E R N A L   E X E P T I O N S                       */
/******************************************************************************/
 
void external_exeption()
{      
  REG uint8 i;
  REG uint32 PicSr,sr;
}
 
 
/*$$MAIN*/
/******************************************************************************/
/*                                                                            */
/*                       M A I N   P R O G R A M                              */
/*                                                                            */
/******************************************************************************/
 
void Start()
{
  uint32 i;
  uint8  str[9];
 
  // Configure GPIO
  REG32(GPIO_BASE + RGPIO_OE)   = 0xff;  // bit0-7 = outputs, bit8-31 = inputs
  REG32(GPIO_BASE + RGPIO_INTE) = 0x0;   // Disable interrupts from GPIO
 
  print("\n\r\n\t");
  print("==OpenRisc 1200 SOC==\n\r\n");
  GPIO_Write(~0x0);
 
  print("\n\r");
 
  print("SD Card Bootloader, v0.2\n\r");
  print("Xianfeng Zeng, 2009 SA\n\r");
  print("Xianfeng@opencores.org\n\r");
  print("http://www.opencores.org/project,or1k_soc_on_altera_embedded_dev_kit\n\r");
 
  print("\n\r");
 
  print("System Clock: 30MHz\n\r\n");
 
  print("DDR SDRAM Base Address: 0x00000000 - 32MB\n\r");
  print("Ethernet Base Address:  0x20000000  IRQ 4\n\r");
  print("UART Base Address:      0x30000000  IRQ 2\n\r");
  print("GPIO Base Address:      0x40000000  IRQ 3\n\r");
  print("SD Card Base Address:   0x50000000\n\r");
  print("SRAM Base Address:      0xF0000000 - 16KB\n\r");
  print("\r\n\n");
 
 
  print("Init SD Card:");
  REG8(SD_BASE_ADD + SD_TRANS_CTRL_REG) = 0x1;  /* reset spiMaster */
  do_sleep();
  REG8(SD_BASE_ADD + SD_TRANS_CTRL_REG) = 0x0;
  if (spiMaster_init() == 0) {
	print("Passed!\n\r");
  } else {
	print("Failed!\n\r");
  }
 
  ddr_sdram_sample_test();
  copy_sd2ddr();
 
  GPIO_Write(~0x1);
 
  print("\n\r");
 
  print("Jump to DDR SDRAM: 0x100\n\r");
  jumpToRAM();
 
  print("Should not get here!!:\n\r");
  while(TRUE) {
	do_sleep();
	or1k_putc('.');
	GPIO_Write(~0x0);  // Test finished
	do_sleep();
    	GPIO_Write(~0x1);
	do_sleep();
	GPIO_Write(~0x2);
	do_sleep();
	GPIO_Write(~0x4);
	do_sleep();
	GPIO_Write(~0x8);
 
	if (i == 39) {
		print("\n\r");
		i = 0;
	} else 
		i++;
  }
}
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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