OpenCores
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/lib/source
    from Rev 64 to Rev 65
    Reverse comparison

Rev 64 → Rev 65

/neorv32_cpu.c
354,9 → 354,9
uint32_t i = 0;
 
// try setting R bit in all PMPCFG CSRs
const uint32_t tmp = 0x01010101;
const uint32_t mask = 0x01010101;
for (i=0; i<16; i++) {
__neorv32_cpu_pmp_cfg_write(i, tmp);
__neorv32_cpu_pmp_cfg_write(i, mask);
}
 
// sum up all written ones (only available PMPCFG* CSRs/entries will return =! 0)
367,7 → 367,7
 
cnt.uint32 = 0;
for (i=0; i<16; i++) {
cnt.uint32 += __neorv32_cpu_pmp_cfg_read(i);
cnt.uint32 += __neorv32_cpu_pmp_cfg_read(i) & mask;
}
 
// sum up bytes
/neorv32_rte.c
51,6 → 51,7
static void __attribute__((__interrupt__)) __neorv32_rte_core(void) __attribute__((aligned(16)));
static void __neorv32_rte_debug_exc_handler(void);
static void __neorv32_rte_print_true_false(int state);
static void __neorv32_rte_print_checkbox(int state);
static void __neorv32_rte_print_hex_word(uint32_t num);
 
 
204,7 → 205,7
char tmp;
 
// intro
neorv32_uart_print("<RTE> ");
neorv32_uart0_print("<RTE> ");
 
// cause
register uint32_t trap_cause = neorv32_cpu_csr_read(CSR_MCAUSE);
216,19 → 217,19
tmp = '0' + tmp;
}
switch (trap_cause) {
case TRAP_CODE_I_MISALIGNED: neorv32_uart_print("Instruction address misaligned"); break;
case TRAP_CODE_I_ACCESS: neorv32_uart_print("Instruction access fault"); break;
case TRAP_CODE_I_ILLEGAL: neorv32_uart_print("Illegal instruction"); break;
case TRAP_CODE_BREAKPOINT: neorv32_uart_print("Breakpoint"); break;
case TRAP_CODE_L_MISALIGNED: neorv32_uart_print("Load address misaligned"); break;
case TRAP_CODE_L_ACCESS: neorv32_uart_print("Load access fault"); break;
case TRAP_CODE_S_MISALIGNED: neorv32_uart_print("Store address misaligned"); break;
case TRAP_CODE_S_ACCESS: neorv32_uart_print("Store access fault"); break;
case TRAP_CODE_UENV_CALL: neorv32_uart_print("Environment call from U-mode"); break;
case TRAP_CODE_MENV_CALL: neorv32_uart_print("Environment call from M-mode"); break;
case TRAP_CODE_MSI: neorv32_uart_print("Machine software interrupt"); break;
case TRAP_CODE_MTI: neorv32_uart_print("Machine timer interrupt"); break;
case TRAP_CODE_MEI: neorv32_uart_print("Machine external interrupt"); break;
case TRAP_CODE_I_MISALIGNED: neorv32_uart0_print("Instruction address misaligned"); break;
case TRAP_CODE_I_ACCESS: neorv32_uart0_print("Instruction access fault"); break;
case TRAP_CODE_I_ILLEGAL: neorv32_uart0_print("Illegal instruction"); break;
case TRAP_CODE_BREAKPOINT: neorv32_uart0_print("Breakpoint"); break;
case TRAP_CODE_L_MISALIGNED: neorv32_uart0_print("Load address misaligned"); break;
case TRAP_CODE_L_ACCESS: neorv32_uart0_print("Load access fault"); break;
case TRAP_CODE_S_MISALIGNED: neorv32_uart0_print("Store address misaligned"); break;
case TRAP_CODE_S_ACCESS: neorv32_uart0_print("Store access fault"); break;
case TRAP_CODE_UENV_CALL: neorv32_uart0_print("Environment call from U-mode"); break;
case TRAP_CODE_MENV_CALL: neorv32_uart0_print("Environment call from M-mode"); break;
case TRAP_CODE_MSI: neorv32_uart0_print("Machine software interrupt"); break;
case TRAP_CODE_MTI: neorv32_uart0_print("Machine timer interrupt"); break;
case TRAP_CODE_MEI: neorv32_uart0_print("Machine external interrupt"); break;
case TRAP_CODE_FIRQ_0:
case TRAP_CODE_FIRQ_1:
case TRAP_CODE_FIRQ_2:
244,18 → 245,18
case TRAP_CODE_FIRQ_12:
case TRAP_CODE_FIRQ_13:
case TRAP_CODE_FIRQ_14:
case TRAP_CODE_FIRQ_15: neorv32_uart_print("Fast interrupt "); neorv32_uart_putc(tmp); break;
default: neorv32_uart_print("Unknown trap cause: "); __neorv32_rte_print_hex_word(trap_cause); break;
case TRAP_CODE_FIRQ_15: neorv32_uart0_print("Fast interrupt "); neorv32_uart0_putc(tmp); break;
default: neorv32_uart0_print("Unknown trap cause: "); __neorv32_rte_print_hex_word(trap_cause); break;
}
 
// instruction address
neorv32_uart_print(" @ PC=");
neorv32_uart0_print(" @ PC=");
__neorv32_rte_print_hex_word(neorv32_cpu_csr_read(CSR_MSCRATCH)); // rte core stores actual mepc to mscratch
 
// additional info
neorv32_uart_print(", MTVAL=");
neorv32_uart0_print(", MTVAL=");
__neorv32_rte_print_hex_word(neorv32_cpu_csr_read(CSR_MTVAL));
neorv32_uart_print(" </RTE>");
neorv32_uart0_print(" </RTE>");
}
 
 
272,25 → 273,15
int i;
char c;
 
neorv32_uart_printf("\n\n<<< Processor Configuration Overview >>>\n");
neorv32_uart0_printf("\n\n<<< Processor Configuration Overview >>>\n");
 
// Processor - general stuff
neorv32_uart0_printf("\n=== << General >> ===\n"
"Clock speed: %u Hz\n", NEORV32_SYSINFO.CLK);
neorv32_uart0_printf("Full HW reset: "); __neorv32_rte_print_true_false(NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_HW_RESET));
neorv32_uart0_printf("Boot Config.: Boot ");
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_BOOTLOADER)) {
neorv32_uart0_printf("via Bootloader\n");
}
else {
neorv32_uart0_printf("from memory (@ 0x%x)\n", NEORV32_SYSINFO.ISPACE_BASE);
}
neorv32_uart0_printf("On-chip debug: "); __neorv32_rte_print_true_false(NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_OCD));
 
 
// CPU configuration
neorv32_uart0_printf("\n=== << CPU >> ===\n");
 
// general
neorv32_uart0_printf("Clock speed: %u Hz\n", NEORV32_SYSINFO.CLK);
neorv32_uart0_printf("Full HW reset: "); __neorv32_rte_print_true_false(NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_HW_RESET));
neorv32_uart0_printf("On-chip debugger: "); __neorv32_rte_print_true_false(NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_OCD));
// ID
neorv32_uart0_printf("Hart ID: 0x%x\n"
"Vendor ID: 0x%x\n", neorv32_cpu_csr_read(CSR_MHARTID), neorv32_cpu_csr_read(CSR_MVENDORID));
378,8 → 369,16
 
 
// Memory configuration
neorv32_uart0_printf("\n=== << Memory Configuration >> ===\n");
neorv32_uart0_printf("\n=== << Memory System >> ===\n");
 
neorv32_uart0_printf("Boot Config.: Boot ");
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_BOOTLOADER)) {
neorv32_uart0_printf("via Bootloader\n");
}
else {
neorv32_uart0_printf("from memory (@ 0x%x)\n", NEORV32_SYSINFO.ISPACE_BASE);
}
 
neorv32_uart0_printf("Instr. base address: 0x%x\n", NEORV32_SYSINFO.ISPACE_BASE);
 
// IMEM
394,14 → 393,17
// DMEM
neorv32_uart0_printf("Data base address: 0x%x\n", NEORV32_SYSINFO.DSPACE_BASE);
neorv32_uart0_printf("Internal DMEM: ");
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_MEM_INT_DMEM)) { neorv32_uart0_printf("yes, %u bytes\n", NEORV32_SYSINFO.DMEM_SIZE); }
else { neorv32_uart0_printf("no\n"); }
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_MEM_INT_DMEM)) {
neorv32_uart0_printf("yes, %u bytes\n", NEORV32_SYSINFO.DMEM_SIZE);
}
else {
neorv32_uart0_printf("no\n");
}
 
// i-cache
neorv32_uart0_printf("Internal i-cache: ");
__neorv32_rte_print_true_false(NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_ICACHE));
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_ICACHE)) {
neorv32_uart0_printf("- ");
neorv32_uart0_printf("yes, ");
 
uint32_t ic_block_size = (NEORV32_SYSINFO.CACHE >> SYSINFO_CACHE_IC_BLOCK_SIZE_0) & 0x0F;
if (ic_block_size) {
422,7 → 424,7
uint32_t ic_associativity = (NEORV32_SYSINFO.CACHE >> SYSINFO_CACHE_IC_ASSOCIATIVITY_0) & 0x0F;
ic_associativity = 1 << ic_associativity;
 
neorv32_uart0_printf("%u bytes: %u set(s), %u block(s) per set, %u bytes per block", ic_associativity*ic_num_blocks*ic_block_size, ic_associativity, ic_num_blocks, ic_block_size);
neorv32_uart0_printf("%u bytes, %u set(s), %u block(s) per set, %u bytes per block", ic_associativity*ic_num_blocks*ic_block_size, ic_associativity, ic_num_blocks, ic_block_size);
if (ic_associativity == 1) {
neorv32_uart0_printf(" (direct-mapped)\n");
}
433,6 → 435,9
neorv32_uart0_printf("\n");
}
}
else {
neorv32_uart0_printf("no\n");
}
 
neorv32_uart0_printf("Ext. bus interface: ");
__neorv32_rte_print_true_false(NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_MEM_EXT));
448,19 → 453,19
neorv32_uart0_printf("\n=== << Peripherals >> ===\n");
 
tmp = NEORV32_SYSINFO.SOC;
neorv32_uart0_printf("GPIO - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_GPIO));
neorv32_uart0_printf("MTIME - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_MTIME));
neorv32_uart0_printf("UART0 - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_UART0));
neorv32_uart0_printf("UART1 - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_UART1));
neorv32_uart0_printf("SPI - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_SPI));
neorv32_uart0_printf("TWI - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_TWI));
neorv32_uart0_printf("PWM - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_PWM));
neorv32_uart0_printf("WDT - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_WDT));
neorv32_uart0_printf("TRNG - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_TRNG));
neorv32_uart0_printf("CFS - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_CFS));
neorv32_uart0_printf("SLINK - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_SLINK));
neorv32_uart0_printf("NEOLED - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_NEOLED));
neorv32_uart0_printf("XIRQ - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_XIRQ));
__neorv32_rte_print_checkbox(tmp & (1 << SYSINFO_SOC_IO_GPIO)); neorv32_uart0_printf(" GPIO\n");
__neorv32_rte_print_checkbox(tmp & (1 << SYSINFO_SOC_IO_MTIME)); neorv32_uart0_printf(" MTIME\n");
__neorv32_rte_print_checkbox(tmp & (1 << SYSINFO_SOC_IO_UART0)); neorv32_uart0_printf(" UART0\n");
__neorv32_rte_print_checkbox(tmp & (1 << SYSINFO_SOC_IO_UART1)); neorv32_uart0_printf(" UART1\n");
__neorv32_rte_print_checkbox(tmp & (1 << SYSINFO_SOC_IO_SPI)); neorv32_uart0_printf(" SPI\n");
__neorv32_rte_print_checkbox(tmp & (1 << SYSINFO_SOC_IO_TWI)); neorv32_uart0_printf(" TWI\n");
__neorv32_rte_print_checkbox(tmp & (1 << SYSINFO_SOC_IO_PWM)); neorv32_uart0_printf(" PWM\n");
__neorv32_rte_print_checkbox(tmp & (1 << SYSINFO_SOC_IO_WDT)); neorv32_uart0_printf(" WDT\n");
__neorv32_rte_print_checkbox(tmp & (1 << SYSINFO_SOC_IO_TRNG)); neorv32_uart0_printf(" TRNG\n");
__neorv32_rte_print_checkbox(tmp & (1 << SYSINFO_SOC_IO_CFS)); neorv32_uart0_printf(" CFS\n");
__neorv32_rte_print_checkbox(tmp & (1 << SYSINFO_SOC_IO_SLINK)); neorv32_uart0_printf(" SLINK\n");
__neorv32_rte_print_checkbox(tmp & (1 << SYSINFO_SOC_IO_NEOLED)); neorv32_uart0_printf(" NEOLED\n");
__neorv32_rte_print_checkbox(tmp & (1 << SYSINFO_SOC_IO_XIRQ)); neorv32_uart0_printf(" XIRQ\n");
}
 
 
468,7 → 473,7
* NEORV32 runtime environment: Private function to print yes or no.
* @note This function is used by neorv32_rte_print_hw_config(void) only.
*
* @param[in] state Print 'yes' when !=0, print '0' when 0
* @param[in] state Print 'yes' when !=0, print 'no' when 0
**************************************************************************/
static void __neorv32_rte_print_true_false(int state) {
 
482,6 → 487,25
 
 
/**********************************************************************//**
* NEORV32 runtime environment: Private function to print [x] or [ ].
* @note This function is used by neorv32_rte_print_hw_config(void) only.
*
* @param[in] state Print '[x]' when !=0, print '[ ]' when 0
**************************************************************************/
static void __neorv32_rte_print_checkbox(int state) {
 
neorv32_uart0_putc('[');
if (state) {
neorv32_uart0_putc('x');
}
else {
neorv32_uart0_putc(' ');
}
neorv32_uart0_putc(']');
}
 
 
/**********************************************************************//**
* NEORV32 runtime environment: Private function to print 32-bit number
* as 8-digit hexadecimal value (with "0x" suffix).
*
606,7 → 630,7
return; // cannot output anything if UART0 is not implemented
}
 
neorv32_uart_print(
neorv32_uart0_print(
"\n"
"BSD 3-Clause License\n"
"\n"
712,7 → 736,7
}
else {
if ((silent == 0) || (neorv32_uart0_available() == 0)) {
neorv32_uart_printf("\nWARNING! SW_ISA (features required) vs HW_ISA (features available) mismatch!\n"
neorv32_uart0_printf("\nWARNING! SW_ISA (features required) vs HW_ISA (features available) mismatch!\n"
"SW_ISA = 0x%x (compiler flags)\n"
"HW_ISA = 0x%x (misa csr)\n\n", misa_sw, misa_hw);
}
/neorv32_slink.c
80,6 → 80,72
 
 
/**********************************************************************//**
* Configure SLINK RX interrupt.
*
* @param[in] link_id Link id (0..7).
* @param[in] irq_en Link's IRQ enable (#NEORV32_SLINK_IRQ_EN_enum)
* @param[in] irq_type Link's IRQ type (#NEORV32_SLINK_IRQ_RX_TYPE_enum)
**************************************************************************/
void neorv32_slink_rx_irq_config(int link_id, int irq_en, int irq_type) {
 
link_id = link_id & 7;
 
uint32_t slink_irq_conf = NEORV32_SLINK.IRQ;
 
// enable IRQ
if (irq_en) {
slink_irq_conf |= (1 << (SLINK_IRQ_RX_EN_LSB + link_id));
}
else {
slink_irq_conf &= ~(1 << (SLINK_IRQ_RX_EN_LSB + link_id));
}
 
// configure type
if (irq_type) {
slink_irq_conf |= (1 << (SLINK_IRQ_RX_MODE_LSB + link_id));
}
else {
slink_irq_conf &= ~(1 << (SLINK_IRQ_RX_MODE_LSB + link_id));
}
 
NEORV32_SLINK.IRQ = slink_irq_conf;
}
 
 
/**********************************************************************//**
* Configure SLINK TX interrupt.
*
* @param[in] link_id Link id (0..7).
* @param[in] irq_en Link's IRQ enable (#NEORV32_SLINK_IRQ_EN_enum)
* @param[in] irq_type Link's IRQ type (#NEORV32_SLINK_IRQ_TX_TYPE_enum)
**************************************************************************/
void neorv32_slink_tx_irq_config(int link_id, int irq_en, int irq_type) {
 
link_id = link_id & 7;
 
uint32_t slink_irq_conf = NEORV32_SLINK.IRQ;
 
// enable IRQ
if (irq_en) {
slink_irq_conf |= (1 << (SLINK_IRQ_TX_EN_LSB + link_id));
}
else {
slink_irq_conf &= ~(1 << (SLINK_IRQ_TX_EN_LSB + link_id));
}
 
// configure type
if (irq_type) {
slink_irq_conf |= (1 << (SLINK_IRQ_TX_MODE_LSB + link_id));
}
else {
slink_irq_conf &= ~(1 << (SLINK_IRQ_TX_MODE_LSB + link_id));
}
 
NEORV32_SLINK.IRQ = slink_irq_conf;
}
 
 
/**********************************************************************//**
* Get number of implemented RX links
*
* @return Number of implemented RX link (0..8).
/neorv32_spi.c
65,10 → 65,11
* Enable and configure SPI controller. The SPI control register bits are listed in #NEORV32_SPI_CTRL_enum.
*
* @param[in] prsc Clock prescaler select (0..7). See #NEORV32_CLOCK_PRSC_enum.
* @param[in] clk_polarity Idle clock polarity (0, 1).
* @param[in] clk_phase Clock phase (0=sample on rising edge, 1=sample on falling edge).
* @param[in] clk_polarity Clock polarity (when idle).
* @param[in] data_size Data transfer size (0: 8-bit, 1: 16-bit, 2: 24-bit, 3: 32-bit).
**************************************************************************/
void neorv32_spi_setup(uint8_t prsc, uint8_t clk_polarity, uint8_t data_size) {
void neorv32_spi_setup(uint8_t prsc, uint8_t clk_phase, uint8_t clk_polarity, uint8_t data_size) {
 
NEORV32_SPI.CTRL = 0; // reset
 
78,13 → 79,16
uint32_t ct_prsc = (uint32_t)(prsc & 0x07);
ct_prsc = ct_prsc << SPI_CTRL_PRSC0;
 
uint32_t ct_phase = (uint32_t)(clk_phase & 0x01);
ct_phase = ct_phase << SPI_CTRL_CPHA;
 
uint32_t ct_polarity = (uint32_t)(clk_polarity & 0x01);
ct_polarity = ct_polarity << SPI_CTRL_CPHA;
ct_polarity = ct_polarity << SPI_CTRL_CPOL;
 
uint32_t ct_size = (uint32_t)(data_size & 0x03);
ct_size = ct_size << SPI_CTRL_SIZE0;
 
NEORV32_SPI.CTRL = ct_enable | ct_prsc | ct_polarity | ct_size;
NEORV32_SPI.CTRL = ct_enable | ct_prsc | ct_phase | ct_polarity | ct_size;
}
 
 
158,8 → 162,6
/**********************************************************************//**
* Check if SPI transceiver is busy.
*
* @note This function is blocking.
*
* @return 0 if idle, 1 if busy
**************************************************************************/
int neorv32_spi_busy(void) {
167,5 → 169,7
if ((NEORV32_SPI.CTRL & (1<<SPI_CTRL_BUSY)) != 0) {
return 1;
}
return 0;
else {
return 0;
}
}
/neorv32_uart.c
50,8 → 50,8
 
/// \cond
// Private functions
static void __neorv32_uart_itoa(uint32_t x, char *res) __attribute__((unused)); // GCC: do not ouput a warning when this variable is unused
static void __neorv32_uart_tohex(uint32_t x, char *res) __attribute__((unused)); // GCC: do not ouput a warning when this variable is unused
static void __neorv32_uart_itoa(uint32_t x, char *res) __attribute__((unused)); // GCC: do not output a warning when this variable is unused
static void __neorv32_uart_tohex(uint32_t x, char *res) __attribute__((unused)); // GCC: do not output a warning when this variable is unused
/// \endcond
 
 
336,13 → 336,13
void neorv32_uart0_putc(char c) {
 
// wait for previous transfer to finish
while ((NEORV32_UART0.CTRL & (1<<UART_CTRL_TX_BUSY)) != 0);
while ((NEORV32_UART0.CTRL & (1<<UART_CTRL_TX_FULL)) != 0); // wait for space in TX FIFO
NEORV32_UART0.DATA = ((uint32_t)c) << UART_DATA_LSB;
}
 
 
/**********************************************************************//**
* Check if UART0 TX is busy.
* Check if UART0 TX is busy (transmitter busy or data left in TX buffer).
*
* @note This function is blocking.
*
350,7 → 350,10
**************************************************************************/
int neorv32_uart0_tx_busy(void) {
 
if ((NEORV32_UART0.CTRL & (1<<UART_CTRL_TX_BUSY)) != 0) {
uint32_t ctrl = NEORV32_UART0.CTRL;
 
if (((ctrl & (1<<UART_CTRL_TX_BUSY)) != 0) || // TX engine busy
((ctrl & (1<<UART_CTRL_TX_EMPTY)) == 0)) { // TX buffer not empty
return 1;
}
return 0;
382,37 → 385,41
* @note This function is non-blocking and checks for frame and parity errors.
*
* @param[in,out] data Received char.
* @return Status code (0=nothing received, 1: char received without errors; -1: char received with frame error; -2: char received with parity error; -3 char received with frame & parity error).
* @return Status code:
* 0 = char received without errors
* -1 = nothing received
* -2 = char received with frame error
* -3 = char received with parity error
* -4 = char received with overrun error.
**************************************************************************/
int neorv32_uart0_getc_safe(char *data) {
 
uint32_t uart_rx = NEORV32_UART0.DATA;
if (uart_rx & (1<<UART_DATA_AVAIL)) { // char available at all?
 
int status = 0;
// get received byte (if there is any)
*data = (char)uart_rx;
 
// check for frame error
if (uart_rx & (1<<UART_DATA_FERR)) {
status -= 1;
}
// check if no data available at all
if ((uart_rx & (1<<UART_DATA_AVAIL)) == 0) {
return -1;
}
 
// check for parity error
if (uart_rx & (1<<UART_DATA_PERR)) {
status -= 2;
}
// check for frame error
if (uart_rx & (1<<UART_DATA_FERR)) {
return -2;
}
 
if (status == 0) {
status = 1;
}
// check for parity error
if (uart_rx & (1<<UART_DATA_PERR)) {
return -3;
}
 
// get received byte
*data = (char)uart_rx;
// check for overrun error
if (uart_rx & (1<<UART_DATA_OVERR)) {
return -4;
}
 
return status;
}
else {
return 0;
}
return 0; // all fine
}
 
 
696,13 → 703,13
void neorv32_uart1_putc(char c) {
 
// wait for previous transfer to finish
while ((NEORV32_UART1.CTRL & (1<<UART_CTRL_TX_BUSY)) != 0);
while ((NEORV32_UART1.CTRL & (1<<UART_CTRL_TX_FULL)) != 0); // wait for space in TX FIFO
NEORV32_UART1.DATA = ((uint32_t)c) << UART_DATA_LSB;
}
 
 
/**********************************************************************//**
* Check if UART1 TX is busy.
* Check if UART1 TX is busy (transmitter busy or data left in TX buffer).
*
* @note This function is blocking.
*
710,7 → 717,10
**************************************************************************/
int neorv32_uart1_tx_busy(void) {
 
if ((NEORV32_UART1.CTRL & (1<<UART_CTRL_TX_BUSY)) != 0) {
uint32_t ctrl = NEORV32_UART1.CTRL;
 
if (((ctrl & (1<<UART_CTRL_TX_BUSY)) != 0) || // TX engine busy
((ctrl & (1<<UART_CTRL_TX_EMPTY)) == 0)) { // TX buffer not empty
return 1;
}
return 0;
742,37 → 752,41
* @note This function is non-blocking and checks for frame and parity errors.
*
* @param[in,out] data Received char.
* @return Status code (0=nothing received, 1: char received without errors; -1: char received with frame error; -2: char received with parity error; -3 char received with frame & parity error).
* @return Status code:
* 0 = char received without errors
* -1 = nothing received
* -2 = char received with frame error
* -3 = char received with parity error
* -4 = char received with overrun error.
**************************************************************************/
int neorv32_uart1_getc_safe(char *data) {
 
uint32_t uart_rx = NEORV32_UART1.DATA;
if (uart_rx & (1<<UART_DATA_AVAIL)) { // char available at all?
 
int status = 0;
// get received byte (if there is any)
*data = (char)uart_rx;
 
// check for frame error
if (uart_rx & (1<<UART_DATA_FERR)) {
status -= 1;
}
// check if no data available at all
if ((uart_rx & (1<<UART_DATA_AVAIL)) == 0) {
return -1;
}
 
// check for parity error
if (uart_rx & (1<<UART_DATA_PERR)) {
status -= 2;
}
// check for frame error
if (uart_rx & (1<<UART_DATA_FERR)) {
return -2;
}
 
if (status == 0) {
status = 1;
}
// check for parity error
if (uart_rx & (1<<UART_DATA_PERR)) {
return -3;
}
 
// get received byte
*data = (char)uart_rx;
// check for overrun error
if (uart_rx & (1<<UART_DATA_OVERR)) {
return -4;
}
 
return status;
}
else {
return 0;
}
return 0; // all fine
}
 
 

powered by: WebSVN 2.1.0

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