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

Subversion Repositories neo430

[/] [neo430/] [trunk/] [neo430/] [sw/] [example/] [wb_terminal/] [main.c] - Rev 198

Compare with Previous | Blame | View Log

// #################################################################################################
// #  < Wishbone bus explorer >                                                                    #
// # ********************************************************************************************* #
// # Manual access to the registers of modules, which are connected to the Wishbone bus. This tool #
// # uses NONBLOCKING Wishbone transactions.                                                       #
// # ********************************************************************************************* #
// # BSD 3-Clause License                                                                          #
// #                                                                                               #
// # Copyright (c) 2020, Stephan Nolting. All rights reserved.                                     #
// #                                                                                               #
// # Redistribution and use in source and binary forms, with or without modification, are          #
// # permitted provided that the following conditions are met:                                     #
// #                                                                                               #
// # 1. Redistributions of source code must retain the above copyright notice, this list of        #
// #    conditions and the following disclaimer.                                                   #
// #                                                                                               #
// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     #
// #    conditions and the following disclaimer in the documentation and/or other materials        #
// #    provided with the distribution.                                                            #
// #                                                                                               #
// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  #
// #    endorse or promote products derived from this software without specific prior written      #
// #    permission.                                                                                #
// #                                                                                               #
// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   #
// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               #
// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    #
// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    #
// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     #
// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  #
// # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            #
// # ********************************************************************************************* #
// # The NEO430 Processor - https://github.com/stnolting/neo430                                    #
// #################################################################################################
 
 
// Libraries
#include <stdint.h>
#include <string.h>
#include <neo430.h>
 
// Global variables
uint8_t wb_config = 0;
 
// Prototypes
void setup_wb(void);
void read_wb_address(void);
void write_wb_address(void);
void dump_wb(void);
 
// Configuration
#define MAX_CMD_LENGTH 16
#define BAUD_RATE 19200
 
 
/* ------------------------------------------------------------
 * INFO Main function
 * ------------------------------------------------------------ */
int main(void) {
 
  // setup UART
  neo430_uart_setup(BAUD_RATE);
 
  char buffer[MAX_CMD_LENGTH];
  uint16_t length = 0;
  uint16_t selection = 0;
 
  neo430_uart_br_print("\n--------------------------------------\n"
                  "--- Wishbone Bus Explorer Terminal ---\n"
                  "--------------------------------------\n\n");
 
  // check if WB unit was synthesized, exit if no WB is available
  if (!(SYS_FEATURES & (1<<SYS_WB32_EN))) {
    neo430_uart_br_print("Error! No Wishbone adapter synthesized!");
    return 1;
  }
 
  // default config
  wb_config = 4;
  neo430_wishbone_terminate(); // terminate current transfer
 
  neo430_uart_br_print("Configure the actual data transfer size (1, 2 or 4 bytes)\n"
                       "using 'setup'. Addresses are always 32-bit wide.\n"
                       "This tool uses non-blocking Wishbone transactions.\n\n"
                       "Type 'help' to see the help menu.\n\n");
 
  // Main menu
  for (;;) {
    neo430_uart_br_print("WB_EXPLORER:> ");
    length = neo430_uart_scan(buffer, MAX_CMD_LENGTH, 1);
    neo430_uart_br_print("\n");
 
    if (!length) // nothing to be done
     continue;
 
    // decode input
    selection = 0;
    if (!strcmp(buffer, "help"))
      selection = 1;
    if (!strcmp(buffer, "setup"))
      selection = 2;
    if (!strcmp(buffer, "read"))
      selection = 3;
    if (!strcmp(buffer, "write"))
      selection = 4;
    if (!strcmp(buffer, "dump"))
      selection = 5;
    if (!strcmp(buffer, "reset"))
      selection = 6;
    if (!strcmp(buffer, "exit"))
      selection = 7;
 
    // execute command
    switch(selection) {
 
      case 1: // print help menu
        neo430_uart_br_print("Available commands:\n"
                             " help  - show this text\n"
                             " setup - configure WB interface\n"
                             " read  - read from WB address\n"
                             " write - write to WB address\n"
                             " dump  - dump data from WB addresses\n"
                             " reset - perform soft-reset\n"
                             " exit  - exit program and return to bootloader\n");
        break;
 
      case 2: // setup Wishbone adapter
        setup_wb();
        break;
 
      case 3: // read from address
        read_wb_address();
        break;
 
      case 4: // write to address
        write_wb_address();
        break;
 
      case 5: // dump data
        dump_wb();
        break;
 
      case 6: // restart
        while ((UART_CT & (1<<UART_CT_TX_BUSY)) != 0); // wait for current UART transmission
        neo430_soft_reset();
        break;
 
      case 7: // goto bootloader
        if (!(SYS_FEATURES & (1<<SYS_BTLD_EN)))
          neo430_uart_br_print("No bootloader installed!\n");
        else
          asm volatile ("mov #0xF000, r0");
        break;
 
      default: // invalid command
        neo430_uart_br_print("Invalid command. Type 'help' to see all commands.\n");
        break;
    }
  }
 
  return 0;
}
 
 
/* ------------------------------------------------------------
 * INFO Configure Wishbone adapter
 * ------------------------------------------------------------ */
void setup_wb(void) {
 
  char buffer[2];
 
  neo430_uart_br_print("Select transfer size in bytes (1,2,4): ");
  neo430_uart_scan(buffer, 2, 1);
 
  // process input
  if (!strcmp(buffer, "1"))
    wb_config = 1;
  else if (!strcmp(buffer, "2"))
    wb_config = 2;
  else if (!strcmp(buffer, "4"))
    wb_config = 4;
  else {
    neo430_uart_br_print("\nInvalid input. Cancelling setup.\n");
    return;
  }
 
  neo430_uart_br_print("\nSetup done.\n");
}
 
 
/* ------------------------------------------------------------
 * INFO Read data from Wishbone address
 * ------------------------------------------------------------ */
void read_wb_address(void) {
 
  char buffer[9];
 
  neo430_uart_br_print("Enter hexadecimal target address: 0x");
  neo430_uart_scan(buffer, 9, 1); // 8 hex chars for address plus '\0'
  uint32_t address = neo430_hexstr_to_uint(buffer, strlen(buffer));
 
  neo430_uart_br_print("\nReading from [0x");
  neo430_uart_print_hex_dword(address);
  neo430_uart_br_print("]... ");
 
  // print result
  neo430_uart_br_print("Read data: 0x");
 
  if (wb_config == 1)
    neo430_wishbone32_read8_start(address);
  else if (wb_config == 2)
    neo430_wishbone32_read16_start(address);
  else if (wb_config == 4)
    neo430_wishbone32_read32_start(address);
 
  // wait for transfer to finish
  uint16_t timeout = 0;
  while(1){
    if (!neo430_wishbone_busy())
      break;
    if (timeout++ == 100) {
      neo430_uart_br_print("\nError! Device not responding! Press key to proceed.\n");
      neo430_wishbone_terminate(); // terminate current transfer
      while(!neo430_uart_char_received());
      return;
    }
  }
 
  // read data
  if (wb_config == 1)
    neo430_uart_print_hex_byte(neo430_wishbone32_get_data8(address));
  else if (wb_config == 2)
    neo430_uart_print_hex_word(neo430_wishbone32_get_data16(address));
  else if (wb_config == 4)
    neo430_uart_print_hex_dword(neo430_wishbone32_get_data32());
 
  neo430_uart_br_print("\n");
}
 
 
/* ------------------------------------------------------------
 * INFO Write data to Wishbone address
 * ------------------------------------------------------------ */
void write_wb_address(void) {
 
  char buffer[9];
 
  neo430_uart_br_print("Enter hexadecimal target address: 0x");
  neo430_uart_scan(buffer, 9, 1); // 8 hex chars for address plus '\0'
  uint32_t address = neo430_hexstr_to_uint(buffer, strlen(buffer));
 
  neo430_uart_br_print("\nEnter hexadecimal write data: 0x");
  neo430_uart_scan(buffer, wb_config*2+1, 1); // get right number of hex chars for data plus '\0'
  uint32_t data = neo430_hexstr_to_uint(buffer, strlen(buffer));
 
  neo430_uart_br_print("\nWriting '0x");
  neo430_uart_print_hex_dword(data);
  neo430_uart_br_print("' to [0x");
  neo430_uart_print_hex_dword(address);
  neo430_uart_br_print("]... ");
 
  // perform access
  if (wb_config == 1)
    neo430_wishbone32_write8_start(address, (uint8_t)data);
  else if (wb_config == 2)
    neo430_wishbone32_write16_start(address, (uint16_t)data);
  else if (wb_config == 4)
    neo430_wishbone32_write32_start(address, data);
 
  // wait for transfer to finish
  uint16_t timeout = 0;
  while(1){
    if (!neo430_wishbone_busy())
      break;
    if (timeout++ == 100) {
      neo430_uart_br_print("\nError! Device not responding! Press key to proceed.\n");
      neo430_wishbone_terminate(); // terminate current transfer
      while(!neo430_uart_char_received());
      return;
    }
  }
 
  neo430_uart_br_print("Done.\n"); 
}
 
 
/* ------------------------------------------------------------
 * INFO Dump data from Wishbone address
 * ------------------------------------------------------------ */
void dump_wb(void) {
 
  char buffer[9];
  uint16_t i = 0;
 
  neo430_uart_br_print("Enter hexadecimal start address: 0x");
  neo430_uart_scan(buffer, 9, 1); // 8 hex chars for address plus '\0'
  uint32_t address = neo430_hexstr_to_uint(buffer, strlen(buffer));
 
  neo430_uart_br_print("\nPress any key to start.\n"
                       "You can abort dumping by pressing any key.\n");
  while(!neo430_uart_char_received());
 
  while(1) {
    neo430_uart_br_print("0x");
    neo430_uart_print_hex_dword(address);
    neo430_uart_br_print(":  ");
 
    uint16_t border = 16 / wb_config;
    for (i=0; i<border; i++) {
 
      // trigger access
      if (wb_config == 1)
        neo430_wishbone32_read8_start(address);
      else if (wb_config == 2)
        neo430_wishbone32_read16_start(address);
      else if (wb_config == 4)
        neo430_wishbone32_read32_start(address);
 
      // wait for transfer to finish
      uint16_t timeout = 0;
      while(1){
        if (!neo430_wishbone_busy())
          break;
        if (timeout++ == 100) {
          neo430_uart_br_print("\nError! Device not responding! Press key to proceed.\n");
          neo430_wishbone_terminate(); // terminate current transfer
          while(!neo430_uart_char_received());
          return;
        }
      }
 
      // read data
      if (wb_config == 1) {
        neo430_uart_print_hex_byte(neo430_wishbone32_get_data8(address));
        address += 1;
      }
      else if (wb_config == 2) {
        neo430_uart_print_hex_word(neo430_wishbone32_get_data16(address));
        address += 2;
      }
      else if (wb_config == 4) {
        neo430_uart_print_hex_dword(neo430_wishbone32_get_data32());
        address += 4;
      }
 
      neo430_uart_putc(' ');
    }
 
    neo430_uart_br_print("\n");
    if (neo430_uart_char_received()) // abort
      return;
  }
}
 
 

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.