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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [example/] [demo_spi/] [main.c] - Diff between revs 68 and 69

Show entire file | Details | Blame | View Log

Rev 68 Rev 69
Line 58... Line 58...
 
 
// Prototypes
// Prototypes
void spi_cs(uint32_t type);
void spi_cs(uint32_t type);
void spi_trans(void);
void spi_trans(void);
void spi_setup(void);
void spi_setup(void);
 
void flash_write(void);
 
void flash_read(void);
uint32_t hexstr_to_uint(char *buffer, uint8_t length);
uint32_t hexstr_to_uint(char *buffer, uint8_t length);
void aux_print_hex_byte(uint8_t byte);
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.
 * This program provides an interactive console to communicate with SPI devices.
 *
 *
 * @note This program requires the UART and the SPI to be synthesized.
 * @note This program requires the UART and the SPI to be synthesized.
 *
 *
 * @return Irrelevant.
 * @return Irrelevant.
 **************************************************************************/
 **************************************************************************/
int main() {
int main() {
 
 
  char buffer[8];
  char buffer[16];
  int length = 0;
  int length = 0;
 
 
 
 
  // capture all exceptions and give debug info via UART
  // capture all exceptions and give debug info via UART
  // this is not required, but keeps us safe
  // this is not required, but keeps us safe
Line 97... Line 110...
  if (neorv32_spi_available() == 0) {
  if (neorv32_spi_available() == 0) {
    neorv32_uart0_printf("No SPI unit implemented.");
    neorv32_uart0_printf("No SPI unit implemented.");
    return 1;
    return 1;
  }
  }
 
 
 
 
  // info
  // info
  neorv32_uart0_printf("This program allows to create SPI transfers by hand.\n"
  neorv32_uart0_printf("This program allows to create SPI transfers by hand.\n"
                      "Type 'help' to see the help menu.\n\n");
                      "Type 'help' to see the help menu.\n\n");
 
 
  // disable and reset SPI module
  // disable and reset SPI module
Line 111... Line 123...
 
 
 
 
  // Main menu
  // Main menu
  for (;;) {
  for (;;) {
    neorv32_uart0_printf("SPI_EXPLORER:> ");
    neorv32_uart0_printf("SPI_EXPLORER:> ");
    length = neorv32_uart0_scan(buffer, 8, 1);
    length = neorv32_uart0_scan(buffer, 15, 1);
    neorv32_uart0_printf("\n");
    neorv32_uart0_printf("\n");
 
 
    if (!length) // nothing to be done
    if (!length) // nothing to be done
     continue;
     continue;
 
 
    // decode input and execute command
    // decode input and execute command
    if (!strcmp(buffer, "help")) {
    if (!strcmp(buffer, "help")) {
      neorv32_uart0_printf("Available commands:\n"
      neorv32_uart0_printf("Available commands:\n"
                          " help   - show this text\n"
                          " help   - show this text\n"
                          " setup  - configure SPI module\n"
                          " setup    - configure SPI module (clock speed and mode, data size)\n"
                          " cs-en  - enable CS line (set low)\n"
                          " cs-en  - enable CS line (set low)\n"
                          " cs-dis - disable CS line (set high)\n"
                          " cs-dis - disable CS line (set high)\n"
                          " trans  - execute a transmission (write & read to/from SPI)\n"
                          " trans  - execute a transmission (write & read to/from SPI)\n"
                          "\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"
                          "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")) {
    else if (!strcmp(buffer, "setup")) {
      spi_setup();
      spi_setup();
    }
    }
    else if (!strcmp(buffer, "cs-en")) {
    else if (!strcmp(buffer, "cs-en")) {
Line 141... Line 159...
      spi_cs(0);
      spi_cs(0);
    }
    }
    else if (!strcmp(buffer, "trans")) {
    else if (!strcmp(buffer, "trans")) {
      spi_trans();
      spi_trans();
    }
    }
 
    else if (!strcmp(buffer, "flash-wr")) {
 
      flash_write();
 
    }
 
    else if (!strcmp(buffer, "flash-rd")) {
 
      flash_read();
 
    }
    else {
    else {
      neorv32_uart0_printf("Invalid command. Type 'help' to see all commands.\n");
      neorv32_uart0_printf("Invalid command. Type 'help' to see all commands.\n");
    }
    }
  }
  }
 
 
Line 201... Line 225...
  if (spi_configured == 0) {
  if (spi_configured == 0) {
    neorv32_uart0_printf("SPI module not configured yet! Use 'setup' to configure SPI module.\n");
    neorv32_uart0_printf("SPI module not configured yet! Use 'setup' to configure SPI module.\n");
    return;
    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);
  neorv32_uart0_scan(terminal_buffer, spi_size*2+1, 1);
  uint32_t tx_data = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
  uint32_t tx_data = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
 
 
  uint32_t rx_data = neorv32_spi_trans(tx_data);
  uint32_t rx_data = neorv32_spi_trans(tx_data);
 
 
Line 320... Line 344...
  spi_size = tmp;
  spi_size = tmp;
}
}
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 
 * 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
 * Helper function to convert N hex chars string into uint32_T
 *
 *
 * @param[in,out] buffer Pointer to array of chars to convert into number.
 * @param[in,out] buffer Pointer to array of chars to convert into number.
 * @param[in,out] length Length of the conversion string.
 * @param[in,out] length Length of the conversion string.
 * @return Converted number.
 * @return Converted number.

powered by: WebSVN 2.1.0

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