URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/orpsocv2/sw
- from Rev 619 to Rev 655
- ↔ Reverse comparison
Rev 619 → Rev 655
/tests/cfi_ctrl/board/cfi_ctrl-readid.c
0,0 → 1,27
#include "board.h" |
#include "cpu-utils.h" |
#include "cfi_ctrl.h" |
#include "uart.h" |
#include "printf.h" |
|
#include "orpsoc-defines.h" |
|
|
int main(void) |
{ |
uart_init(DEFAULT_UART); |
|
printf("\nReading some CFI ID\n"); |
printf("manufacturer code: %04x\n",cfi_ctrl_read_identifier(0x00)&0xffff); |
printf("Device ID: %04x\n",cfi_ctrl_read_identifier(0x01)&0xffff); |
printf("RCR: %04x\n",cfi_ctrl_read_identifier(0x05)&0xffff); |
|
printf("query info: %04x\n",cfi_ctrl_query_info(0x10)&0xffff); |
printf("query info: %04x\n",cfi_ctrl_query_info(0x11)&0xffff); |
printf("query info: %04x\n",cfi_ctrl_query_info(0x12)&0xffff); |
printf("device timing & voltage info: %04x\n", |
cfi_ctrl_query_info(0x1b)&0xffff); |
|
report(0x8000000d); |
exit(0); |
} |
/tests/cfi_ctrl/board/Makefile
0,0 → 1,13
SW_ROOT=../../.. |
|
include $(SW_ROOT)/Makefile.inc |
|
%.dis: %.elf |
$(Q)$(OR32_OBJDUMP) -d $< > $@ |
|
%.bin: %.elf |
$(Q)$(OR32_OBJCOPY) -O binary $< $@ |
|
clean: |
$(Q)rm -f *.elf *.bin *.vmem *.flashin *.dis |
|
/tests/cfi_ctrl/board/cfi_ctrl-simple.c
0,0 → 1,72
#include "board.h" |
#include "cpu-utils.h" |
#include "cfi_ctrl.h" |
#include "uart.h" |
#include "printf.h" |
#include "orpsoc-defines.h" |
|
|
int main(void) |
{ |
uart_init(DEFAULT_UART); |
|
printf("cfi_ctrl-simple test"); |
|
/* Reset the flash */ |
cfi_ctrl_reset_flash(); |
|
/* wait for the controller to be done */ |
while (cfi_ctrl_busy()); |
|
#define NUM_PAGES 8 |
#define TEST_LENGTH 64 |
int i,j; |
unsigned int page_base; |
unsigned short check_data[TEST_LENGTH]; |
unsigned short tmp; |
|
/* test for number of blocks... */ |
for(j=0;j<NUM_PAGES;j++) |
{ |
page_base = j*(128*1024); |
|
printf("Status before clear: %02x\n",cfi_ctrl_get_status()&0xff); |
cfi_ctrl_clear_status(); |
printf("Status after clear: %02x\n",cfi_ctrl_get_status()&0xff); |
|
/* Erase block */ |
if (cfi_ctrl_erase_block(page_base)) |
{ |
//exit(0xbaaaaaad); |
printf("Error erasing block at %08x\n",page_base); |
printf("Aborting test\n"); |
exit(1); |
} |
|
cfi_ctrl_clear_status(); |
|
for (i=0;i<TEST_LENGTH;i++) |
{ |
tmp = (unsigned short)rand(); |
//report(tmp&0xffff); |
printf("writing data: %04x\n", tmp&0xffff); |
cfi_ctrl_write_short(tmp,page_base+i*2); |
check_data[i] = tmp; |
|
} |
|
/* Read back the data and check it */ |
cfi_ctrl_enable_data_read(); |
for (i=0;i<TEST_LENGTH;i++) |
{ |
tmp = REG16(CFI_CTRL_BASE + page_base + (i*2)); |
if (tmp != check_data[i]) |
//exit(0xbaaaaaad); |
printf("read data was not written data: %04x != %04x\n", tmp&0xffff, |
check_data[i]); |
} |
} |
|
report(0x8000000d); |
exit(0); |
} |
/tests/cfi_ctrl/sim/cfi_ctrl-readid.c
0,0 → 1,24
#include "board.h" |
#include "cpu-utils.h" |
#include "cfi_ctrl.h" |
#include "printf.h" |
|
#include "orpsoc-defines.h" |
|
|
int main(void) |
{ |
printf("\nReading some CFI ID\n"); |
printf("manufacturer code: %04x\n",cfi_ctrl_read_identifier(0x00)&0xffff); |
printf("Device ID: %04x\n",cfi_ctrl_read_identifier(0x01)&0xffff); |
printf("RCR: %04x\n",cfi_ctrl_read_identifier(0x05)&0xffff); |
|
printf("query info: %04x\n",cfi_ctrl_query_info(0x10)&0xffff); |
printf("query info: %04x\n",cfi_ctrl_query_info(0x11)&0xffff); |
printf("query info: %04x\n",cfi_ctrl_query_info(0x12)&0xffff); |
printf("device timing & voltage info: %04x\n", |
cfi_ctrl_query_info(0x1b)&0xffff); |
|
report(0x8000000d); |
exit(0); |
} |
/tests/cfi_ctrl/sim/Makefile
0,0 → 1,13
SW_ROOT=../../.. |
|
include $(SW_ROOT)/Makefile.inc |
|
%.dis: %.elf |
$(Q)$(OR32_OBJDUMP) -d $< > $@ |
|
%.bin: %.elf |
$(Q)$(OR32_OBJCOPY) -O binary $< $@ |
|
clean: |
$(Q)rm -f *.elf *.bin *.vmem *.flashin *.dis |
|
/tests/cfi_ctrl/sim/cfi_ctrl-simple.c
0,0 → 1,85
#include "board.h" |
#include "cpu-utils.h" |
#include "cfi_ctrl.h" |
|
#include "orpsoc-defines.h" |
|
|
int main(void) |
{ |
/* Reset the flash */ |
cfi_ctrl_reset_flash(); |
|
/* wait for the controller to be done */ |
while (cfi_ctrl_busy()); |
|
#define NUM_PAGES 8 |
#define TEST_LENGTH 64 |
int i,j; |
unsigned int page_base; |
unsigned short check_data[TEST_LENGTH]; |
unsigned short tmp; |
unsigned short* flash_data_short_ptr; |
|
/* test for number of blocks... */ |
for(j=0;j<NUM_PAGES;j++) |
{ |
page_base = j*(128*1024); |
|
cfi_ctrl_clear_status(); |
|
/* Erase block */ |
if (cfi_ctrl_erase_block(page_base)) |
exit(0xbaaaaaad); |
|
cfi_ctrl_clear_status(); |
|
for (i=0;i<TEST_LENGTH;i++) |
{ |
tmp = (unsigned short)rand(); |
report(tmp&0xffff); |
cfi_ctrl_write_short(tmp,page_base+i*2); |
check_data[i] = tmp; |
|
} |
|
/* Read back as shorts and check it */ |
cfi_ctrl_enable_data_read(); |
for (i=0;i<TEST_LENGTH;i++) |
{ |
//tmp = REG16(CFI_CTRL_BASE + page_base + (i*2)); |
flash_data_short_ptr = (short*) (CFI_CTRL_BASE + page_base); |
//if (tmp != check_data[i]) |
if (flash_data_short_ptr[i] != check_data[i]) |
exit(0xbaaaaaad); |
|
} |
|
char * flash_data_char_ptr = (char*) CFI_CTRL_BASE + page_base; |
char * chardata = (char*) check_data; |
/* Read back as bytes and check it */ |
cfi_ctrl_enable_data_read(); |
for (i=0;i<TEST_LENGTH*2;i++) |
{ |
if (flash_data_char_ptr[i] != chardata[i]) |
exit(0xbaaaaaad); |
|
} |
|
long * flash_data_long_ptr = CFI_CTRL_BASE + page_base; |
long * longdata = (long*) check_data; |
/* Read back as longs and check it */ |
cfi_ctrl_enable_data_read(); |
for (i=0;i<TEST_LENGTH/2;i++) |
{ |
if (flash_data_long_ptr[i] != longdata[i]) |
exit(0xbaaaaaad); |
|
} |
|
|
} |
|
report(0x8000000d); |
exit(0); |
} |
/apps/cfi_ctrl_programmer/cfi_ctrl_programmer.c
0,0 → 1,366
// Program that will erase and program a flash via cfi_ctrl module |
|
#include "cpu-utils.h" |
#include "board.h" |
#include "uart.h" |
#include "printf.h" |
#include "cfi_ctrl.h" |
|
// TODO: detect this manually - it is CFI after all! |
#define BLOCK_SIZE_BYTES (128*1024) |
|
//#define VERBOSE_PROGRAMMING |
#define VERBOSE_VERIFY_ERRORS |
//#define VERIFY_WHEN_WRITE |
|
unsigned long programming_file_start; |
unsigned long programming_file_end; |
unsigned long programming_file_length; |
|
extern unsigned long userprogram_data, _userprogram_data; |
extern unsigned long end_userprogram_data, _end_userprogram_data; |
|
// Globals |
int timeout_counter; |
volatile char dump; |
int programming_base_offset; |
|
#define RESET_PC 0xf0000100 |
|
int |
console_get_num(void) |
{ |
char c = 0x30; |
int num_nums = 0; |
int num_nums_total; |
char nums[16]; // up to 16 decimal digits long |
int retval = 0; |
int decimal_multiplier; |
int i; |
|
printf("Enter decimal value: "); |
|
while (c >= 0x30 && c < 0x40) |
{ |
c = uart_getc(DEFAULT_UART); |
|
if (c >= 0x30 && c < 0x40) |
{ |
printf("%d", c-0x30); |
nums[num_nums] = c-0x30; |
num_nums++; |
} |
|
} |
printf("\n"); |
|
num_nums_total = num_nums; |
|
while(num_nums--) |
{ |
decimal_multiplier = 1; |
for(i=1;i<num_nums_total - num_nums;i++) |
decimal_multiplier *= 10; |
//printf("%d * %d\n",decimal_multiplier,nums[num_nums]); |
|
retval += (decimal_multiplier * nums[num_nums]); |
} |
//printf("%d\n",retval); |
return retval; |
} |
|
void |
console_browse_buffer(char* buf) |
{ |
char c = 0; |
int offset = 0; |
const int linesize = 16; |
int i; |
printf("Press space to scroll through buffer, q to return\n"); |
printf("+/- alter address offset\n"); |
cfi_ctrl_enable_data_read(); |
while (1) |
{ |
c = uart_getc(DEFAULT_UART); |
|
if (c == 'q') |
return; |
else if (c == 'r') |
offset=0; |
else if (c == '+') |
{ |
offset+=linesize; |
printf("%04x:\r",offset); |
} |
else if (c == '-') |
{ |
if (offset >=linesize) |
offset-=linesize; |
|
printf("%04x:\r",offset); |
} |
else if (c == 0x20) // space, print al ine |
{ |
printf("%04x:",offset); |
// print another line of the buffer |
for (i=0;i<linesize;i++) |
{ |
printf(" %02x", buf[offset+i]&0xff); |
} |
printf("\n"); |
|
offset += linesize; |
|
} |
} |
|
} |
|
void |
delay(int n) |
{ |
volatile int i=0; |
while(i<n) |
i++; |
} |
|
void |
timeout_reset(void) |
{ |
timeout_counter = 0; |
} |
|
int |
timeout(void) |
{ |
timeout_counter++; |
if (timeout_counter == 20000) |
{ |
printf("timeout\n"); |
cfi_ctrl_reset_flash(); |
|
return 1; |
} |
return 0; |
} |
|
void |
print_cfi_status(void) |
{ |
char flashid[5]; |
int i; |
printf("\tcfi_ctrl flash status:\n"); |
|
printf("Device status byte: 0x%02x\n",cfi_ctrl_get_status()&0xff); |
printf("\n"); |
printf("Programming file from 0x%x-0x%x, %d bytes\n", |
programming_file_start, programming_file_end, |
programming_file_length); |
// printf("Embedded length: %d\n", (unsigned long) userprogram_data); |
printf("Page programming base: %d (set with 'o' command)\n", |
programming_base_offset); |
} |
|
void |
verify_image(int base_offset, char* data, int length_bytes) |
{ |
|
int base_block = base_offset / BLOCK_SIZE_BYTES; |
|
int num_blocks = (length_bytes/BLOCK_SIZE_BYTES) + 1; |
int i; |
|
int verify_error = 0; |
|
printf("\tVerifying %d bytes of image from 0x%08x\n",length_bytes, |
base_offset); |
|
unsigned int waddr; |
short * data_shorts; |
int short_counter; |
data_shorts = (short*) data; |
|
// Read the pages |
cfi_ctrl_enable_data_read(); |
for(waddr=base_offset, short_counter=0; |
waddr<(base_offset + length_bytes); |
waddr +=2, short_counter++) |
{ |
/* Check what we wrote */ |
short verify_data = REG16(CFI_CTRL_BASE+waddr); |
|
if (verify_data != data_shorts[short_counter]) |
{ |
printf("\tERROR: word verify failed at 0x%08x.\n",waddr); |
printf("\tERROR: Read 0x%04x instead of 0x%04x.\n",verify_data, |
data_shorts[short_counter]); |
verify_error ++; |
} |
|
} |
|
if (verify_error) |
printf("\tVerify complete - %d errors were detected\n", |
verify_error); |
else |
printf("\tImage verified. Press esacpe to boot from 0x%08x.\n",RESET_PC); |
} |
|
void |
program_image(int base_offset, char* data, int length_bytes) |
{ |
|
int base_block = base_offset / BLOCK_SIZE_BYTES; |
|
int num_blocks = (length_bytes/BLOCK_SIZE_BYTES) + 1; |
|
int i; |
|
unsigned int waddr; |
|
short * data_shorts; |
int short_counter; |
|
printf("\tErasing blocks (%d - %d)\n",base_block, |
base_block + num_blocks-1); |
|
// Erase the appropriate blocks |
for(i=base_block;i<base_block + num_blocks;i++) |
{ |
printf("\tErasing block %d\n",i); |
cfi_ctrl_unlock_block(i*BLOCK_SIZE_BYTES); |
if (cfi_ctrl_erase_block(i*BLOCK_SIZE_BYTES)) |
{ |
printf("\tErase failed, trying again\n"); |
i--; // Try erasing again |
continue; |
} |
} |
printf("\tErase complete\n"); |
|
printf("\n\tProgramming %d bytes\n", length_bytes); |
|
data_shorts = (short*) data; |
|
// Program the pages |
for(waddr=base_offset, short_counter=0; |
waddr<(base_offset + length_bytes); |
waddr +=2, short_counter++) |
{ |
if (cfi_ctrl_write_short(data_shorts[short_counter],waddr)) |
{ |
printf("\tERROR: word program failed at 0x%08x\n",waddr); |
return; |
} |
else |
{ |
#ifdef VERIFY_WHEN_WRITE |
/* Check what we wrote */ |
cfi_ctrl_enable_data_read(); |
short verify_data = REG16(CFI_CTRL_BASE+waddr); |
if (verify_data != data_shorts[short_counter]) |
{ |
printf("\tERROR: word verify failed at 0x%08x.\n",waddr); |
printf("\tERROR: Read 0x%04x instead of 0x%04x.\n",verify_data, |
data_shorts[short_counter]); |
return; |
} |
#endif |
} |
} |
|
printf("\tProgramming %d bytes complete\n", length_bytes); |
} |
|
#define printhelp() printf("\nUsage: \n \ |
\t[p]rogram\t\terase req. blocks, write image to flash\n \ |
\t[o]ffset\t\tset page offset to write to\n \ |
\t[v]erify\t\tverify written program\n \ |
\t[s]tatus\t\tprint status of CFI flash\n \ |
\t[e]rase\t\t\terase block of CFI flash\n \ |
\t[r]ead\t\t\tread, browse page of CFI flash\n \ |
\t[i]nspect\t\tinspect page of image in RAM\n \ |
\t[R]eset\t\t\treset CFI flash controller\n \ |
\t[ESC]\t\t\treset by jumping to 0x%08x\n \ |
\n",RESET_PC) |
|
int |
main() |
{ |
uart_init(0); // init the UART before we can printf |
|
volatile char c; |
int i,j; |
|
programming_base_offset = 0; |
|
programming_file_start = (unsigned long) &userprogram_data; |
programming_file_end = (unsigned long) &end_userprogram_data; |
programming_file_length = programming_file_end - programming_file_start; |
|
printf("\n\n\tcfi_ctrl flash programming app\n\n"); |
printf("\ttype 'h' for help menu\n\n"); |
|
while(1){ |
printf(" > "); |
c = uart_getc(DEFAULT_UART); |
printf("%c",c); |
printf("\n"); |
|
if (c == 'h') |
printhelp(); |
else if (c == 's') |
print_cfi_status(); |
else if (c == 'c') |
cfi_ctrl_clear_status(); |
else if (c == 'p') |
program_image(programming_base_offset, |
(char *) &userprogram_data, |
programming_file_length); |
else if (c == 'v') |
verify_image(programming_base_offset, |
(char *) &userprogram_data, |
programming_file_length); |
else if (c == 'o') |
{ |
printf("Enter byte offset to program from.\n"); |
programming_base_offset = console_get_num(); |
} |
// Support/debug commands: |
else if (c == 'e') |
{ |
printf("Erase a block.\n"); |
i = console_get_num(); |
// program a specific page |
cfi_ctrl_erase_block_no_wait(i*BLOCK_SIZE_BYTES); |
} |
else if (c == 'r') |
{ |
printf("Inspect memory.\n"); |
i = console_get_num(); |
// read a page |
console_browse_buffer((char*)CFI_CTRL_BASE + i); |
} |
else if (c == 'i') |
{ |
printf("Inspect image to program.\n"); |
console_browse_buffer((char*) &userprogram_data); |
} |
else if (c == 'R') |
{ |
printf("Reset command to controller\n"); |
cfi_ctrl_reset_flash(); |
} |
else if (c == 0x1b) // Esacpe key |
{ |
// Reset |
void (*reset_function) (void) = |
(void *)RESET_PC; |
(*reset_function)(); |
} |
|
} |
|
return 0; |
|
} |
/apps/cfi_ctrl_programmer/Makefile
0,0 → 1,31
# Program to control the cfi_ctrl module to manage contents of flash memory. |
# |
# author: julius.baxter@orsoc.se |
# |
|
SW_ROOT=../.. |
|
#PROGRAMMINGFILE= |
PROGRAMMINGFILE_SWBIN=progfile.swbin # Binary file with sizeword |
PROGRAMMINGFILE_DATA=progfile.o |
|
ELF_DEPENDS +=$(PROGRAMMINGFILE_DATA) |
|
include $(SW_ROOT)/Makefile.inc |
|
OR32_LDFLAGS = -L$(SW_ROOT)/lib -lorpsoc -lgcc -Tcfi_ctrl_programmer.ld -e 256 |
|
$(PROGRAMMINGFILE_DATA): $(PROGRAMMINGFILE) |
$(Q)$(OR32_LD) -r -b binary -o $@ $< |
$(Q)$(OR32_OBJCOPY) --rename-section .data=.userprogram $@ |
|
%.dis: %.elf |
$(Q)$(OR32_OBJDUMP) -d $< > $@ |
|
%.bin: %.elf |
$(Q)$(OR32_OBJCOPY) -O binary $< $@ |
|
clean: |
$(Q)rm -f *.elf *.bin *.vmem *.flashin *.dis $(PROGRAMMINGFILE_SWBIN) $(PROGRAMMINGFILE_DATA) |
|
#distclean: clean |
/apps/cfi_ctrl_programmer/cfi_ctrl_programmer.ld
0,0 → 1,113
/*STARTUP(../support/crt0.o)*/ |
/*ENTRY()*/ |
OUTPUT_ARCH(or32) |
/*GROUP()*/ |
SEARCH_DIR(.) |
__DYNAMIC = 0; |
|
MEMORY |
{ |
vectors : ORIGIN = 0, LENGTH = 0x1000 |
ram : ORIGIN = 0x1000, LENGTH = (8M - 0x1000) |
} |
|
|
/* |
* Allocate the stack to be at the top of memory, since the stack |
* grows down. |
*/ |
_min_stack = 0x2000; /* 8K - minimum stack space to reserve */ |
|
SECTIONS |
{ |
.vectors : |
{ |
*(.vectors) |
} > vectors |
|
.text : { |
stext = .; |
_stext = .; |
*(.text) |
_etext = .; |
__CTOR_LIST__ = .; |
LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) |
*(.ctors) |
LONG(0) |
__CTOR_END__ = .; |
__DTOR_LIST__ = .; |
LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) |
*(.dtors) |
LONG(0) |
__DTOR_END__ = .; |
*(.lit) |
*(.shdata) |
_endtext = .; |
} > ram |
|
.rodata : { |
*(.rodata); |
*(.rodata.*) |
} > ram |
|
/* Section we'll use for storing the program to load into the flash */ |
.shbss : |
{ |
*(.shbss) |
} > ram |
|
.talias : |
{ |
} > ram |
|
.data : { |
sdata = .; |
_sdata = .; |
*(.data) |
edata = .; |
_edata = .; |
} > ram |
|
.bss SIZEOF(.data) + ADDR(.data) : |
{ |
_bss_start = ALIGN(0x8); |
*(.bss) |
*(COMMON) |
_bss_end = .; |
} |
|
|
/* ensure there is enough room for stack */ |
.stack (NOLOAD): { |
. = ALIGN(4); |
sstack = . ; |
_sstack = . ; |
. = . + _min_stack ; |
. = ALIGN(4); |
stack = . ; |
_stack = . ; |
estack = . ; |
_estack = . ; |
} > ram |
|
. = . + 0x2000 ; |
.userprogram : { |
. = ALIGN(4); |
userprogram_data = .; |
_userprogram_data = .; |
*(.userprogram) |
end_userprogram_data = .; |
_end_userprogram_data = .; |
} > ram |
|
|
.stab 0 (NOLOAD) : |
{ |
[ .stab ] |
} |
|
.stabstr 0 (NOLOAD) : |
{ |
[ .stabstr ] |
} |
} |
/Makefile.inc
202,6 → 202,9
%.vmem: %.bin $(UTILS_BIN2VMEM) |
$(Q)$(UTILS_BIN2VMEM) $< > $@ |
|
%.flash16: %.bin $(UTILS_BIN2VMEM) |
$(Q)$(UTILS_BIN2VMEM) $< -bpw=2 > $@ |
|
%.elf: %.c $(VECTORS_OBJ) $(ELF_DEPENDS) $(SUPPORT_LIBS) |
$(Q)$(OR32_CC) $< $(VECTORS_OBJ) $(ELF_DEPENDS) $(OR32_CFLAGS) \ |
$(OR32_LDFLAGS) -o $@ |
/lib/Makefile
20,5 → 20,5
$(USER_ELF_BIN): $(USER_ELF) |
$(Q)$(OR32_OBJCOPY) -O binary $< $@ |
$(USER_ELF_VMEM): $(USER_ELF_BIN) $(UTILS_BIN2VMEM) |
$(Q)$(UTILS_BIN2VMEM) $< > $@ |
$(Q)$(UTILS_BIN2VMEM) $< $(USER_ELF_VMEM_GEN_OPTS) > $@ |
gen-user-elf-vmem: $(USER_ELF_VMEM) |
/drivers/cfi-ctrl/include/cfi_ctrl.h
0,0 → 1,38
/* cfi_ctrl driver header */ |
|
#define CFI_CTRL_UNLOCKBLOCK_OFFSET 0x04000000 |
#define CFI_CTRL_ERASEBLOCK_OFFSET 0x08000000 |
#define CFI_CTRL_REGS_OFFSET 0x0c000000 |
#define CFI_CTRL_DEVICEIDENT_OFFSET 0x0e000000 |
#define CFI_CTRL_CFIQUERY_OFFSET 0x0e010000 |
|
#define CFI_CTRL_SCR_OFFSET (CFI_CTRL_REGS_OFFSET + 0) |
#define CFI_CTRL_FSR_OFFSET (CFI_CTRL_REGS_OFFSET + 4) |
|
#define CFI_CTRL_SCR_CONTROLLER_BUSY (1 << 0) |
#define CFI_CTRL_SCR_CLEAR_FSR (1 << 1) |
#define CFI_CTRL_SCR_RESET_DEVICE (1 << 2) |
|
/* Flash status register (FSR) bit meanings - from CFI standard */ |
#define CFI_FSR_DWS (1<<7) /* Device write status. 0 - busy, 1 - ready */ |
#define CFI_FSR_ERR (1<<6) /* Erase suspend status - N/A here */ |
#define CFI_FSR_ES (1<<5) /* Erase status. 0 - successful, 1 - fail/seq err. */ |
#define CFI_FSR_PS (1<<4) /* Program status. 0 - successful, 1 - fail/seq err*/ |
#define CFI_FSR_VPPS (1<<3) /* VPP status. N/A here */ |
#define CFI_FSR_PSS (1<<2) /* Program suspend status. N/A here */ |
#define CFI_FSR_BLS (1<<1) /* Block-locked status */ |
#define CFI_FSR_BWS (1<<0) /* Buffer-enhanced programming status - N/A here */ |
|
|
/* Driver function prototypes */ |
void cfi_ctrl_reset_flash(void); |
void cfi_ctrl_clear_status(void); |
int cfi_ctrl_busy(void); |
unsigned char cfi_ctrl_get_status(void); |
void cfi_ctrl_unlock_block(unsigned int addr); |
int cfi_ctrl_erase_block(unsigned int addr); |
void cfi_ctrl_erase_block_no_wait(unsigned int addr); |
int cfi_ctrl_write_short(short data, unsigned int addr); |
short cfi_ctrl_read_identifier(unsigned int addr); |
short cfi_ctrl_query_info(unsigned int addr); |
void cfi_ctrl_enable_data_read(void); |
/drivers/cfi-ctrl/cfi_ctrl.c
0,0 → 1,112
/* Driver functions for cfi_ctrl module which is to control |
CFI flash devices. |
*/ |
|
#include "board.h" |
#include "cpu-utils.h" |
#include "cfi_ctrl.h" |
|
void cfi_ctrl_reset_flash(void) |
{ |
//REG32((CFI_CTRL_BASE + CFI_CTRL_SCR_OFFSET)) = CFI_CTRL_SCR_RESET_DEVICE; |
// Put in array read mode, like reset would |
REG16(CFI_CTRL_BASE) = 0x00ff; |
|
} |
|
int cfi_ctrl_busy(void) |
{ |
// return REG32((CFI_CTRL_BASE + CFI_CTRL_SCR_OFFSET)) & |
//CFI_CTRL_SCR_CONTROLLER_BUSY; |
return 0; |
} |
|
void cfi_ctrl_clear_status(void) |
{ |
//REG32((CFI_CTRL_BASE + CFI_CTRL_SCR_OFFSET)) = CFI_CTRL_SCR_CLEAR_FSR; |
REG16(CFI_CTRL_BASE) = 0x0050; |
} |
|
unsigned char cfi_ctrl_get_status(void) |
{ |
//return (unsigned char) (REG32((CFI_CTRL_BASE + CFI_CTRL_FSR_OFFSET)) & 0xff); |
REG16(CFI_CTRL_BASE) = 0x0070; |
return (unsigned char) REG16(CFI_CTRL_BASE); |
} |
|
void cfi_ctrl_unlock_block(unsigned int addr) |
{ |
//REG32((CFI_CTRL_BASE + CFI_CTRL_UNLOCKBLOCK_OFFSET + addr)) = 0; |
REG16(CFI_CTRL_BASE + addr) = 0x0060; |
REG16(CFI_CTRL_BASE + addr) = 0x00d0; |
} |
|
int cfi_ctrl_erase_block(unsigned int addr) |
{ |
cfi_ctrl_clear_status(); |
|
/* Unlock block first */ |
cfi_ctrl_unlock_block(addr); |
|
//REG32((CFI_CTRL_BASE + CFI_CTRL_ERASEBLOCK_OFFSET + addr)) = 0; |
REG16(CFI_CTRL_BASE + addr) = 0x0020; |
REG16(CFI_CTRL_BASE + addr) = 0x00d0; |
|
/* Wait for device to be finished erasing */ |
while(!(cfi_ctrl_get_status() & CFI_FSR_DWS)); |
|
/* Check if programming was successful */ |
return !!(cfi_ctrl_get_status() & CFI_FSR_ES); |
|
} |
|
void cfi_ctrl_erase_block_no_wait(unsigned int addr) |
{ |
cfi_ctrl_clear_status(); |
|
/* Unlock block first */ |
cfi_ctrl_unlock_block(addr); |
|
/* Now erase the block */ |
REG16(CFI_CTRL_BASE + addr) = 0x0020; |
REG16(CFI_CTRL_BASE + addr) = 0x00d0; |
// REG32((CFI_CTRL_BASE + CFI_CTRL_ERASEBLOCK_OFFSET + addr)) = 0; |
|
return; |
|
} |
|
int cfi_ctrl_write_short(short data, unsigned int addr) |
{ |
|
cfi_ctrl_clear_status(); |
|
REG16(CFI_CTRL_BASE + addr) = 0x0040; |
REG16(CFI_CTRL_BASE + addr) = data; |
|
/* Wait for device to write */ |
while(!(cfi_ctrl_get_status() & CFI_FSR_DWS)); |
|
/* Check if programming was successful */ |
return !!(cfi_ctrl_get_status() & CFI_FSR_PS); |
} |
|
void cfi_ctrl_enable_data_read(void) |
{ |
REG16(CFI_CTRL_BASE) = 0x00ff; |
} |
|
short cfi_ctrl_read_identifier(unsigned int addr) |
{ |
//return REG16(CFI_CTRL_BASE + CFI_CTRL_DEVICEIDENT_OFFSET + (addr<<1)); |
REG16(CFI_CTRL_BASE) = 0x0090; |
return REG16(CFI_CTRL_BASE + (addr<<1)); |
} |
|
short cfi_ctrl_query_info(unsigned int addr) |
{ |
REG16(CFI_CTRL_BASE) = 0x0098; |
return REG16(CFI_CTRL_BASE + (addr<<1)); |
} |
|
|
/drivers/cfi-ctrl/Makefile
0,0 → 1,8
SW_ROOT=../.. |
|
COMPILE_SRCS=cfi_ctrl.c |
|
include $(SW_ROOT)/Makefile.inc |
|
clean: |
$(Q)rm -f *.a *.o |