URL
https://opencores.org/ocsvn/neorv32/neorv32/trunk
Subversion Repositories neorv32
Compare Revisions
- This comparison shows the changes necessary to convert path
/neorv32/trunk/sw/example/demo_spi
- from Rev 68 to Rev 69
- ↔ Reverse comparison
Rev 68 → Rev 69
/main.c
60,11 → 60,24
void spi_cs(uint32_t type); |
void spi_trans(void); |
void spi_setup(void); |
void flash_write(void); |
void flash_read(void); |
uint32_t hexstr_to_uint(char *buffer, uint8_t length); |
void aux_print_hex_byte(uint8_t byte); |
|
|
/**********************************************************************//** |
* SPI flash commands |
**************************************************************************/ |
enum SPI_FLASH_CMD { |
SPI_FLASH_CMD_WRITE = 0x02, /**< Write data */ |
SPI_FLASH_CMD_READ = 0x03, /**< Read data */ |
SPI_FLASH_CMD_READ_SR = 0x05, /**< Get status register */ |
SPI_FLASH_CMD_WREN = 0x06 /**< Enable write access */ |
}; |
|
|
/**********************************************************************//** |
* This program provides an interactive console to communicate with SPI devices. |
* |
* @note This program requires the UART and the SPI to be synthesized. |
73,7 → 86,7
**************************************************************************/ |
int main() { |
|
char buffer[8]; |
char buffer[16]; |
int length = 0; |
|
|
99,7 → 112,6
return 1; |
} |
|
|
// info |
neorv32_uart0_printf("This program allows to create SPI transfers by hand.\n" |
"Type 'help' to see the help menu.\n\n"); |
113,7 → 125,7
// Main menu |
for (;;) { |
neorv32_uart0_printf("SPI_EXPLORER:> "); |
length = neorv32_uart0_scan(buffer, 8, 1); |
length = neorv32_uart0_scan(buffer, 15, 1); |
neorv32_uart0_printf("\n"); |
|
if (!length) // nothing to be done |
122,14 → 134,20
// decode input and execute command |
if (!strcmp(buffer, "help")) { |
neorv32_uart0_printf("Available commands:\n" |
" help - show this text\n" |
" setup - configure SPI module\n" |
" cs-en - enable CS line (set low)\n" |
" cs-dis - disable CS line (set high)\n" |
" trans - execute a transmission (write & read to/from SPI)\n" |
" help - show this text\n" |
" setup - configure SPI module (clock speed and mode, data size)\n" |
" cs-en - enable CS line (set low)\n" |
" cs-dis - disable CS line (set high)\n" |
" trans - execute a transmission (write & read to/from SPI)\n" |
"\n" |
" flash-wr - write binary file to SPI flash\n" |
" flash-rd - dump SPI flash\n" |
"\n" |
"Configure the SPI module using 'setup'. Enable a certain module using 'cs-en',\n" |
"then transfer data using 'trans' and disable the module again using 'cs-dis'.\n\n"); |
"then transfer data using 'trans' and disable the module again using 'cs-dis'.\n" |
"\n" |
"Standard SPI flash and EEPROM memories can be programmed/read\n" |
"via 'flash-wr' and 'flash-rd'.\n\n"); |
} |
else if (!strcmp(buffer, "setup")) { |
spi_setup(); |
143,6 → 161,12
else if (!strcmp(buffer, "trans")) { |
spi_trans(); |
} |
else if (!strcmp(buffer, "flash-wr")) { |
flash_write(); |
} |
else if (!strcmp(buffer, "flash-rd")) { |
flash_read(); |
} |
else { |
neorv32_uart0_printf("Invalid command. Type 'help' to see all commands.\n"); |
} |
203,7 → 227,7
return; |
} |
|
neorv32_uart0_printf("Enter TX data (%u hex chars): 0x", spi_size); |
neorv32_uart0_printf("Enter TX data (%u hex chars): 0x", spi_size*2); |
neorv32_uart0_scan(terminal_buffer, spi_size*2+1, 1); |
uint32_t tx_data = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer)); |
|
322,6 → 346,214
|
|
/**********************************************************************//** |
* Read (dump) flash |
**************************************************************************/ |
void flash_read(void) { |
|
char terminal_buffer[9]; |
uint32_t tmp, addr, channel, num_addr_bytes; |
|
if (spi_configured == 0) { |
neorv32_uart0_printf("SPI module not configured yet! Use 'setup' to configure SPI module.\n"); |
return; |
} |
|
// configure 8-bit SPI mode |
tmp = NEORV32_SPI.CTRL; |
tmp &= ~(0x03 << SPI_CTRL_SIZE0); |
NEORV32_SPI.CTRL = tmp; |
neorv32_uart0_printf("Warning! SPI size configuration has been overridden!\n"); |
|
// how many address bytes? |
while (1) { |
neorv32_uart0_printf("Enter number of address bytes (2,3): "); |
neorv32_uart0_scan(terminal_buffer, 2, 1); // 1 hex char plus '\0' |
num_addr_bytes = hexstr_to_uint(terminal_buffer, strlen(terminal_buffer)); |
if ((num_addr_bytes < 2) || (num_addr_bytes > 3)) { |
neorv32_uart0_printf("\nInvalid channel selection!\n"); |
continue; |
} |
else { |
break; |
} |
} |
|
// chip-select |
while (1) { |
neorv32_uart0_printf("\nSelect flash chip-select line [0..7]: "); |
neorv32_uart0_scan(terminal_buffer, 2, 1); // 1 hex char plus '\0' |
channel = hexstr_to_uint(terminal_buffer, strlen(terminal_buffer)); |
if (channel > 7) { |
neorv32_uart0_printf("\nInvalid channel selection!\n"); |
continue; |
} |
else { |
break; |
} |
} |
|
// base address |
neorv32_uart0_printf("\nEnter base address (8 hex chars): 0x"); |
neorv32_uart0_scan(terminal_buffer, 9, 1); |
addr = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer)); |
|
neorv32_uart0_printf("\nPress any key to start. Press any key to stop reading.\n"); |
while(neorv32_uart0_char_received() == 0); |
|
while(1) { |
if (neorv32_uart0_char_received()) { // abort when key pressed |
break; |
} |
|
if ((addr & 0x1f) == 0) { |
neorv32_uart0_printf("\n%x: ", addr); |
} |
|
// read byte |
neorv32_spi_cs_en((uint8_t)channel); |
neorv32_spi_trans(SPI_FLASH_CMD_READ); |
if (num_addr_bytes == 3) { |
neorv32_spi_trans(addr >> 16); |
} |
neorv32_spi_trans(addr >> 8); |
neorv32_spi_trans(addr >> 0); |
tmp = neorv32_spi_trans(0); |
neorv32_spi_cs_dis((uint8_t)channel); |
|
aux_print_hex_byte((uint8_t)tmp); |
neorv32_uart0_putc(' '); |
|
addr++; |
} |
|
neorv32_uart0_printf("\n"); |
spi_configured = 0; |
} |
|
|
/**********************************************************************//** |
* Write flash |
**************************************************************************/ |
void flash_write(void) { |
|
neorv32_uart0_printf("work-in-progress\n"); |
return; |
|
char terminal_buffer[9], rx_data; |
uint32_t tmp, addr, channel, num_data_bytes, num_addr_bytes; |
int res; |
|
if (spi_configured == 0) { |
neorv32_uart0_printf("SPI module not configured yet! Use 'setup' to configure SPI module.\n"); |
return; |
} |
|
// configure 8-bit SPI mode |
tmp = NEORV32_SPI.CTRL; |
tmp &= ~(0x03 << SPI_CTRL_SIZE0); |
NEORV32_SPI.CTRL = tmp; |
neorv32_uart0_printf("Warning! SPI size configuration has been overridden!\n"); |
|
// how many address bytes? |
while (1) { |
neorv32_uart0_printf("Enter number of address bytes (2,3): "); |
neorv32_uart0_scan(terminal_buffer, 2, 1); // 1 hex char plus '\0' |
num_addr_bytes = hexstr_to_uint(terminal_buffer, strlen(terminal_buffer)); |
if ((num_addr_bytes < 2) || (num_addr_bytes > 3)) { |
neorv32_uart0_printf("\nInvalid channel selection!\n"); |
continue; |
} |
else { |
break; |
} |
} |
|
// how many bytes? |
neorv32_uart0_printf("\nEnter total number of bytes to write (%u hex chars): ", num_addr_bytes*2); |
neorv32_uart0_scan(terminal_buffer, num_addr_bytes*2+1, 1); // 1 hex char plus '\0' |
num_data_bytes = hexstr_to_uint(terminal_buffer, strlen(terminal_buffer)); |
|
// chip-select |
while (1) { |
neorv32_uart0_printf("\nSelect flash chip-select line [0..7]: "); |
neorv32_uart0_scan(terminal_buffer, 2, 1); // 1 hex char plus '\0' |
channel = hexstr_to_uint(terminal_buffer, strlen(terminal_buffer)); |
if (channel > 7) { |
neorv32_uart0_printf("\nInvalid channel selection!\n"); |
continue; |
} |
else { |
break; |
} |
} |
|
// base address |
neorv32_uart0_printf("\nEnter base address (8 hex chars): 0x"); |
neorv32_uart0_scan(terminal_buffer, 9, 1); |
addr = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer)); |
|
// start! |
neorv32_uart0_printf("\nSend raw data via UART (%u bytes)...\n", num_data_bytes); |
while (neorv32_uart0_tx_busy()); |
|
// clear UART0 FIFOs |
neorv32_uart0_disable(); |
neorv32_uart0_enable(); |
|
while (num_data_bytes) { |
|
// write enable |
neorv32_spi_cs_en((uint8_t)channel); |
neorv32_spi_trans(SPI_FLASH_CMD_WREN); |
neorv32_spi_cs_dis((uint8_t)channel); |
|
// get new UART data |
while(1) { |
res = neorv32_uart0_getc_safe(&rx_data); |
if (res == -1) { |
continue; |
} |
if (res == 0) { |
break; |
} |
else { |
neorv32_uart0_printf("UART transmission error (%i)!\n", res); |
return; |
} |
} |
|
// write byte |
neorv32_spi_cs_en((uint8_t)channel); |
neorv32_spi_trans(SPI_FLASH_CMD_WRITE); |
if (num_addr_bytes == 3) { |
neorv32_spi_trans(addr >> 16); |
} |
neorv32_spi_trans(addr >> 8); |
neorv32_spi_trans(addr >> 0); |
neorv32_spi_trans((uint32_t)rx_data); |
neorv32_spi_cs_dis((uint8_t)channel); |
|
// check status register |
while (1) { |
neorv32_spi_cs_en((uint8_t)channel); |
neorv32_spi_trans(SPI_FLASH_CMD_READ_SR); |
tmp = neorv32_spi_trans(0); |
neorv32_spi_cs_dis((uint8_t)channel); |
if ((tmp & 0x01) == 0) { // write-in-progress flag cleared? |
break; |
} |
} |
|
addr++; |
num_data_bytes--; |
} |
|
neorv32_uart0_printf("\n"); |
spi_configured = 0; |
} |
|
|
/**********************************************************************//** |
* Helper function to convert N hex chars string into uint32_T |
* |
* @param[in,out] buffer Pointer to array of chars to convert into number. |