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 63 to Rev 64
- ↔ Reverse comparison
Rev 63 → Rev 64
/neorv32_cfs.c
55,7 → 55,7
**************************************************************************/ |
int neorv32_cfs_available(void) { |
|
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_CFS)) { |
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_CFS)) { |
return 1; |
} |
else { |
/neorv32_cpu.c
151,7 → 151,7
uint32_t uint32[sizeof(uint64_t)/2]; |
} cycles; |
|
uint32_t tmp1, tmp2, tmp3; |
register uint32_t tmp1, tmp2, tmp3; |
while(1) { |
tmp1 = neorv32_cpu_csr_read(CSR_CYCLEH); |
tmp2 = neorv32_cpu_csr_read(CSR_CYCLE); |
202,7 → 202,7
uint32_t uint32[sizeof(uint64_t)/2]; |
} cycles; |
|
uint32_t tmp1, tmp2, tmp3; |
register uint32_t tmp1, tmp2, tmp3; |
while(1) { |
tmp1 = neorv32_cpu_csr_read(CSR_INSTRETH); |
tmp2 = neorv32_cpu_csr_read(CSR_INSTRET); |
253,7 → 253,7
uint32_t uint32[sizeof(uint64_t)/2]; |
} cycles; |
|
uint32_t tmp1, tmp2, tmp3; |
register uint32_t tmp1, tmp2, tmp3; |
while(1) { |
tmp1 = neorv32_cpu_csr_read(CSR_TIMEH); |
tmp2 = neorv32_cpu_csr_read(CSR_TIME); |
271,36 → 271,51
|
|
/**********************************************************************//** |
* Simple delay function using busy wait (simple loop). |
* Delay function using busy wait. |
* |
* @warning This function is not really precise (especially if there is no M extension available)! Use a timer-based approach (using cycle or time CSRs) for precise timings. |
* @note This function uses the time CSRs (from int./ext. MTIME). A simple ASM loop |
* is used as fall back if system timer is not advancing (no MTIME available). |
* |
* @param[in] time_ms Time in ms to wait (max 32767ms). |
* @warning Delay time might be less precise if M extensions is not available |
* (especially if MTIME unit is not available). |
* |
* @param[in] time_ms Time in ms to wait (unsigned 32-bit). |
**************************************************************************/ |
void neorv32_cpu_delay_ms(int16_t time_ms) { |
void neorv32_cpu_delay_ms(uint32_t time_ms) { |
|
const uint32_t loop_cycles_c = 16; // clock cycles per iteration of the ASM loop |
uint32_t clock = NEORV32_SYSINFO.CLK; // clock ticks per second |
clock = clock / 1000; // clock ticks per ms |
|
// check input |
if (time_ms < 0) { |
time_ms = -time_ms; |
uint64_t wait_cycles = ((uint64_t)clock) * ((uint64_t)time_ms); |
|
register uint64_t tmp = neorv32_cpu_get_systime(); |
if (neorv32_cpu_get_systime() > tmp) { // system time advancing (MTIME available and running)? |
|
// use MTIME machine timer |
tmp += wait_cycles; |
while(1) { |
if (neorv32_cpu_get_systime() >= tmp) { |
break; |
} |
} |
} |
else { |
// use ASM loop |
// warning! not really precise (especially if M extensions is not available)! |
|
uint32_t clock = SYSINFO_CLK; // clock ticks per second |
clock = clock / 1000; // clock ticks per ms |
const uint32_t loop_cycles_c = 16; // clock cycles per iteration of the ASM loop |
uint32_t iterations = (uint32_t)(wait_cycles / loop_cycles_c); |
|
uint64_t wait_cycles = ((uint64_t)clock) * ((uint64_t)time_ms); |
uint32_t ticks = (uint32_t)(wait_cycles / loop_cycles_c); |
|
asm volatile (" .balign 4 \n" // make sure this is 32-bit aligned |
" __neorv32_cpu_delay_ms_start: \n" |
" beq %[cnt_r], zero, __neorv32_cpu_delay_ms_end \n" // 3 cycles (not taken) |
" beq %[cnt_r], zero, __neorv32_cpu_delay_ms_end \n" // 3 cycles (never taken) |
" addi %[cnt_w], %[cnt_r], -1 \n" // 2 cycles |
" nop \n" // 2 cycles |
" j __neorv32_cpu_delay_ms_start \n" // 6 cycles |
" __neorv32_cpu_delay_ms_end: " |
: [cnt_w] "=r" (ticks) : [cnt_r] "r" (ticks)); |
asm volatile (" .balign 4 \n" // make sure this is 32-bit aligned |
" __neorv32_cpu_delay_ms_start: \n" |
" beq %[cnt_r], zero, __neorv32_cpu_delay_ms_end \n" // 3 cycles (not taken) |
" beq %[cnt_r], zero, __neorv32_cpu_delay_ms_end \n" // 3 cycles (never taken) |
" addi %[cnt_w], %[cnt_r], -1 \n" // 2 cycles |
" nop \n" // 2 cycles |
" j __neorv32_cpu_delay_ms_start \n" // 6 cycles |
" __neorv32_cpu_delay_ms_end: " |
: [cnt_w] "=r" (iterations) : [cnt_r] "r" (iterations)); |
} |
} |
|
|
332,7 → 347,7
uint32_t neorv32_cpu_pmp_get_num_regions(void) { |
|
// PMP implemented at all? |
if ((SYSINFO_CPU & (1<<SYSINFO_CPU_PMP)) == 0) { |
if ((NEORV32_SYSINFO.CPU & (1<<SYSINFO_CPU_PMP)) == 0) { |
return 0; |
} |
|
597,7 → 612,7
uint32_t neorv32_cpu_hpm_get_counters(void) { |
|
// HPMs implemented at all? |
if ((SYSINFO_CPU & (1<<SYSINFO_CPU_HPM)) == 0) { |
if ((NEORV32_SYSINFO.CPU & (1<<SYSINFO_CPU_HPM)) == 0) { |
return 0; |
} |
|
680,7 → 695,7
uint32_t neorv32_cpu_hpm_get_size(void) { |
|
// HPMs implemented at all? |
if ((SYSINFO_CPU & (1<<SYSINFO_CPU_HPM)) == 0) { |
if ((NEORV32_SYSINFO.CPU & (1<<SYSINFO_CPU_HPM)) == 0) { |
return 0; |
} |
|
/neorv32_gpio.c
52,7 → 52,7
**************************************************************************/ |
int neorv32_gpio_available(void) { |
|
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_GPIO)) { |
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_GPIO)) { |
return 1; |
} |
else { |
71,10 → 71,10
uint32_t mask = (uint32_t)(1 << (pin & 0x1f)); |
|
if (pin < 32) { |
GPIO_OUTPUT_LO |= mask; |
NEORV32_GPIO.OUTPUT_LO |= mask; |
} |
else { |
GPIO_OUTPUT_HI |= mask; |
NEORV32_GPIO.OUTPUT_HI |= mask; |
} |
} |
|
89,10 → 89,10
uint32_t mask = (uint32_t)(1 << (pin & 0x1f)); |
|
if (pin < 32) { |
GPIO_OUTPUT_LO &= ~mask; |
NEORV32_GPIO.OUTPUT_LO &= ~mask; |
} |
else { |
GPIO_OUTPUT_HI &= ~mask; |
NEORV32_GPIO.OUTPUT_HI &= ~mask; |
} |
} |
|
107,10 → 107,10
uint32_t mask = (uint32_t)(1 << (pin & 0x1f)); |
|
if (pin < 32) { |
GPIO_OUTPUT_LO ^= mask; |
NEORV32_GPIO.OUTPUT_LO ^= mask; |
} |
else { |
GPIO_OUTPUT_HI ^= mask; |
NEORV32_GPIO.OUTPUT_HI ^= mask; |
} |
} |
|
126,10 → 126,10
uint32_t mask = (uint32_t)(1 << (pin & 0x1f)); |
|
if (pin < 32) { |
return GPIO_INPUT_LO & mask; |
return NEORV32_GPIO.INPUT_LO & mask; |
} |
else { |
return GPIO_INPUT_HI & mask; |
return NEORV32_GPIO.INPUT_HI & mask; |
} |
} |
|
141,7 → 141,14
**************************************************************************/ |
void neorv32_gpio_port_set(uint64_t port_data) { |
|
GPIO_OUTPUT = port_data; |
union { |
uint64_t uint64; |
uint32_t uint32[sizeof(uint64_t)/2]; |
} data; |
|
data.uint64 = port_data; |
NEORV32_GPIO.OUTPUT_LO = data.uint32[0]; |
NEORV32_GPIO.OUTPUT_HI = data.uint32[1]; |
} |
|
|
152,6 → 159,14
**************************************************************************/ |
uint64_t neorv32_gpio_port_get(void) { |
|
return GPIO_INPUT; |
union { |
uint64_t uint64; |
uint32_t uint32[sizeof(uint64_t)/2]; |
} data; |
|
data.uint32[0] = NEORV32_GPIO.OUTPUT_LO; |
data.uint32[1] = NEORV32_GPIO.OUTPUT_HI; |
|
return data.uint64; |
} |
|
/neorv32_mtime.c
52,7 → 52,7
**************************************************************************/ |
int neorv32_mtime_available(void) { |
|
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_MTIME)) { |
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_MTIME)) { |
return 1; |
} |
else { |
77,9 → 77,9
|
cycles.uint64 = time; |
|
MTIME_LO = 0; |
MTIME_HI = cycles.uint32[1]; |
MTIME_LO = cycles.uint32[0]; |
NEORV32_MTIME.TIME_LO = 0; |
NEORV32_MTIME.TIME_HI = cycles.uint32[1]; |
NEORV32_MTIME.TIME_LO = cycles.uint32[0]; |
|
} |
|
100,9 → 100,9
|
uint32_t tmp1, tmp2, tmp3; |
while(1) { |
tmp1 = MTIME_HI; |
tmp2 = MTIME_LO; |
tmp3 = MTIME_HI; |
tmp1 = NEORV32_MTIME.TIME_HI; |
tmp2 = NEORV32_MTIME.TIME_LO; |
tmp3 = NEORV32_MTIME.TIME_HI; |
if (tmp1 == tmp3) { |
break; |
} |
132,9 → 132,9
|
cycles.uint64 = timecmp; |
|
MTIMECMP_LO = -1; // prevent MTIMECMP from temporarily becoming smaller than the lesser of the old and new values |
MTIMECMP_HI = cycles.uint32[1]; |
MTIMECMP_LO = cycles.uint32[0]; |
NEORV32_MTIME.TIMECMP_LO = -1; // prevent MTIMECMP from temporarily becoming smaller than the lesser of the old and new values |
NEORV32_MTIME.TIMECMP_HI = cycles.uint32[1]; |
NEORV32_MTIME.TIMECMP_LO = cycles.uint32[0]; |
} |
|
|
145,5 → 145,13
**************************************************************************/ |
uint64_t neorv32_mtime_get_timecmp(void) { |
|
return MTIMECMP; |
union { |
uint64_t uint64; |
uint32_t uint32[sizeof(uint64_t)/2]; |
} cycles; |
|
cycles.uint32[0] = NEORV32_MTIME.TIMECMP_LO; |
cycles.uint32[1] = NEORV32_MTIME.TIMECMP_HI; |
|
return cycles.uint64; |
} |
/neorv32_neoled.c
52,7 → 52,7
**************************************************************************/ |
int neorv32_neoled_available(void) { |
|
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_NEOLED)) { |
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_NEOLED)) { |
return 1; |
} |
else { |
62,7 → 62,7
|
|
/**********************************************************************//** |
* Enable and configure NEOLED controller. The NEOLED control register bits are listed in #NEORV32_NEOLED_CT_enum. |
* Enable and configure NEOLED controller. The NEOLED control register bits are listed in #NEORV32_NEOLED_CTRL_enum. |
* This function performs a "raw" configuration (just configuraing the according control register bit). |
* |
* @param[in] prsc Clock prescaler select (0..7). See #NEORV32_CLOCK_PRSC_enum. |
72,25 → 72,25
**************************************************************************/ |
void neorv32_neoled_setup(uint32_t prsc, uint32_t t_total, uint32_t t_high_zero, uint32_t t_high_one) { |
|
NEOLED_CT = 0; // reset |
NEORV32_NEOLED.CTRL = 0; // reset |
|
// module enable |
uint32_t ct_enable = 1 << NEOLED_CT_EN; |
uint32_t ct_enable = 1 << NEOLED_CTRL_EN; |
|
// clock pre-scaler |
uint32_t ct_prsc = (prsc & 0x7) << NEOLED_CT_PRSC0; |
uint32_t ct_prsc = (prsc & 0x7) << NEOLED_CTRL_PRSC0; |
|
// serial data output: total period length for one bit |
uint32_t ct_t_total = (t_total & 0x1f) << NEOLED_CT_T_TOT_0; |
uint32_t ct_t_total = (t_total & 0x1f) << NEOLED_CTRL_T_TOT_0; |
|
// serial data output: high-time for sending a '0' |
uint32_t ct_t_zero = (t_high_zero & 0x1f) << NEOLED_CT_T_ZERO_H_0; |
uint32_t ct_t_zero = (t_high_zero & 0x1f) << NEOLED_CTRL_T_ZERO_H_0; |
|
// serial data output: high-time for sending a '1' |
uint32_t ct_t_one = (t_high_one & 0x1f) << NEOLED_CT_T_ONE_H_0; |
uint32_t ct_t_one = (t_high_one & 0x1f) << NEOLED_CTRL_T_ONE_H_0; |
|
// set new configuration |
NEOLED_CT = ct_enable | ct_prsc | ct_t_total | ct_t_zero | ct_t_one; |
NEORV32_NEOLED.CTRL = ct_enable | ct_prsc | ct_t_total | ct_t_zero | ct_t_one; |
} |
|
|
112,7 → 112,7
const uint32_t CLK_PRSC_FACTOR_LUT[8] = {2, 4, 8, 64, 128, 1024, 2048, 4096}; |
|
// get base clock period in multiples of 0.5ns |
uint32_t t_clock_x500ps = (2 * 1000 * 1000 * 1000) / SYSINFO_CLK; |
uint32_t t_clock_x500ps = (2 * 1000 * 1000 * 1000) / NEORV32_SYSINFO.CLK; |
|
// compute LED interface timing parameters |
uint32_t t_base = 0; |
162,10 → 162,10
**************************************************************************/ |
void neorv32_neoled_set_mode(uint32_t mode) { |
|
uint32_t ctrl = NEOLED_CT; |
ctrl &= ~(0b1 << NEOLED_CT_MODE); // clear current mode |
ctrl |= ((mode & 1) << NEOLED_CT_MODE); // set new mode |
NEOLED_CT = ctrl; |
uint32_t ctrl = NEORV32_NEOLED.CTRL; |
ctrl &= ~(0b1 << NEOLED_CTRL_MODE); // clear current mode |
ctrl |= ((mode & 1) << NEOLED_CTRL_MODE); // set new mode |
NEORV32_NEOLED.CTRL = ctrl; |
} |
|
|
175,7 → 175,7
void neorv32_neoled_strobe_blocking(void) { |
|
while(1) { // wait for FIFO full flag to clear |
if ((NEOLED_CT & (1 << NEOLED_CT_TX_FULL)) == 0) { |
if ((NEORV32_NEOLED.CTRL & (1 << NEOLED_CTRL_TX_FULL)) == 0) { |
break; |
} |
} |
189,12 → 189,12
**************************************************************************/ |
void neorv32_neoled_strobe_nonblocking(void) { |
|
const uint32_t mask = 1 << NEOLED_CT_STROBE; // strobe bit |
uint32_t ctrl = NEOLED_CT; |
const uint32_t mask = 1 << NEOLED_CTRL_STROBE; // strobe bit |
uint32_t ctrl = NEORV32_NEOLED.CTRL; |
|
NEOLED_CT = ctrl | mask; // set strobe bit |
NEOLED_DATA = 0; // send any data to trigger strobe command |
NEOLED_CT = ctrl & (~mask); // clear strobe bit |
NEORV32_NEOLED.CTRL = ctrl | mask; // set strobe bit |
NEORV32_NEOLED.DATA = 0; // send any data to trigger strobe command |
NEORV32_NEOLED.CTRL = ctrl & (~mask); // clear strobe bit |
} |
|
|
203,7 → 203,7
**************************************************************************/ |
void neorv32_neoled_enable(void) { |
|
NEOLED_CT |= ((uint32_t)(1 << NEOLED_CT_EN)); |
NEORV32_NEOLED.CTRL |= ((uint32_t)(1 << NEOLED_CTRL_EN)); |
} |
|
|
212,7 → 212,7
**************************************************************************/ |
void neorv32_neoled_disable(void) { |
|
NEOLED_CT &= ~((uint32_t)(1 << NEOLED_CT_EN)); |
NEORV32_NEOLED.CTRL &= ~((uint32_t)(1 << NEOLED_CTRL_EN)); |
} |
|
|
226,7 → 226,7
void neorv32_neoled_write_blocking(uint32_t data) { |
|
while(1) { // wait for FIFO full flag to clear |
if ((NEOLED_CT & (1 << NEOLED_CT_TX_FULL)) == 0) { |
if ((NEORV32_NEOLED.CTRL & (1 << NEOLED_CTRL_TX_FULL)) == 0) { |
break; |
} |
} |
242,8 → 242,8
**************************************************************************/ |
uint32_t neorv32_neoled_get_buffer_size(void) { |
|
uint32_t tmp = NEOLED_CT; |
tmp = tmp >> NEOLED_CT_BUFS_0; |
uint32_t tmp = NEORV32_NEOLED.CTRL; |
tmp = tmp >> NEOLED_CTRL_BUFS_0; |
tmp = tmp & 0xf; // isolate buffer size bits |
|
return (1 << tmp); // num entries = pow(2, buffer size flags) |
/neorv32_pwm.c
52,7 → 52,7
**************************************************************************/ |
int neorv32_pwm_available(void) { |
|
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_PWM)) { |
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_PWM)) { |
return 1; |
} |
else { |
62,21 → 62,21
|
|
/**********************************************************************//** |
* Enable and configure pulse width modulation controller. The PWM control register bits are listed in #NEORV32_PWM_CT_enum. |
* Enable and configure pulse width modulation controller. The PWM control register bits are listed in #NEORV32_PWM_CTRL_enum. |
* |
* @param[in] prsc Clock prescaler select (0..7). See #NEORV32_CLOCK_PRSC_enum. |
**************************************************************************/ |
void neorv32_pwm_setup(uint8_t prsc) { |
|
PWM_CT = 0; // reset |
NEORV32_PWM.CTRL = 0; // reset |
|
uint32_t ct_enable = 1; |
ct_enable = ct_enable << PWM_CT_EN; |
ct_enable = ct_enable << PWM_CTRL_EN; |
|
uint32_t ct_prsc = (uint32_t)(prsc & 0x07); |
ct_prsc = ct_prsc << PWM_CT_PRSC0; |
ct_prsc = ct_prsc << PWM_CTRL_PRSC0; |
|
PWM_CT = ct_enable | ct_prsc; |
NEORV32_PWM.CTRL = ct_enable | ct_prsc; |
} |
|
|
85,7 → 85,7
**************************************************************************/ |
void neorv32_pwm_disable(void) { |
|
PWM_CT &= ~((uint32_t)(1 << PWM_CT_EN)); |
NEORV32_PWM.CTRL &= ~((uint32_t)(1 << PWM_CTRL_EN)); |
} |
|
|
94,7 → 94,7
**************************************************************************/ |
void neorv32_pwm_enable(void) { |
|
PWM_CT |= ((uint32_t)(1 << PWM_CT_EN)); |
NEORV32_PWM.CTRL |= ((uint32_t)(1 << PWM_CTRL_EN)); |
} |
|
|
132,23 → 132,19
return; // out-of-range |
} |
|
// compute duty-cycle offset |
uint32_t reg_offset = (uint32_t)(channel / 4); |
uint8_t byte_offset = channel % 4; |
|
// read-modify-write |
uint32_t duty_mask = 0xff; |
uint32_t duty_new = (uint32_t)duty; |
|
duty_mask = duty_mask << (byte_offset * 8); |
duty_new = duty_new << (byte_offset * 8); |
duty_mask = duty_mask << ((channel % 4) * 8); |
duty_new = duty_new << ((channel % 4) * 8); |
|
uint32_t duty_cycle = (*(IO_REG32 (&PWM_DUTY0 + reg_offset))); |
uint32_t duty_cycle = NEORV32_PWM.DUTY[channel/4]; |
|
duty_cycle &= ~duty_mask; // clear previous duty cycle |
duty_cycle |= duty_new; // set new duty cycle |
|
(*(IO_REG32 (&PWM_DUTY0 + reg_offset))) = duty_cycle; |
NEORV32_PWM.DUTY[channel/4] = duty_cycle; |
} |
|
|
164,13 → 160,7
return 0; // out-of-range |
} |
|
// compute duty-cycle offset |
uint32_t reg_offset = (uint32_t)(channel / 4); |
uint8_t byte_offset = channel % 4; |
uint32_t reg_data = NEORV32_PWM.DUTY[channel/4] >> (((channel % 4) * 8)); |
|
// read |
uint32_t tmp = (*(IO_REG32 (&PWM_DUTY0 + reg_offset))); |
tmp = tmp >> ((byte_offset * 8)); |
|
return (uint8_t)tmp; |
return (uint8_t)reg_data; |
} |
/neorv32_rte.c
48,9 → 48,9
static uint32_t __neorv32_rte_vector_lut[NEORV32_RTE_NUM_TRAPS] __attribute__((unused)); // trap handler vector table |
|
// private functions |
static void __attribute__((__interrupt__)) __neorv32_rte_core(void) __attribute__((aligned(16))) __attribute__((unused)); |
static void __neorv32_rte_debug_exc_handler(void) __attribute__((unused)); |
static void __neorv32_rte_print_true_false(int state) __attribute__((unused)); |
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_hex_word(uint32_t num); |
|
|
162,7 → 162,6
case TRAP_CODE_S_ACCESS: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_S_ACCESS]; break; |
case TRAP_CODE_UENV_CALL: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_UENV_CALL]; break; |
case TRAP_CODE_MENV_CALL: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MENV_CALL]; break; |
case TRAP_CODE_NMI: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_NMI]; break; |
case TRAP_CODE_MSI: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MSI]; break; |
case TRAP_CODE_MTI: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MTI]; break; |
case TRAP_CODE_MEI: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MEI]; break; |
277,16 → 276,16
|
// Processor - general stuff |
neorv32_uart0_printf("\n=== << General >> ===\n" |
"Clock speed: %u Hz\n", SYSINFO_CLK); |
neorv32_uart0_printf("Full HW reset: "); __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_HW_RESET)); |
"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 (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_BOOTLOADER)) { |
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_BOOTLOADER)) { |
neorv32_uart0_printf("via Bootloader\n"); |
} |
else { |
neorv32_uart0_printf("from memory (@ 0x%x)\n", SYSINFO_ISPACE_BASE); |
neorv32_uart0_printf("from memory (@ 0x%x)\n", NEORV32_SYSINFO.ISPACE_BASE); |
} |
neorv32_uart0_printf("On-chip debug: "); __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_OCD)); |
neorv32_uart0_printf("On-chip debug: "); __neorv32_rte_print_true_false(NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_OCD)); |
|
|
// CPU configuration |
330,7 → 329,7
} |
|
// Z* CPU extensions |
tmp = SYSINFO_CPU; |
tmp = NEORV32_SYSINFO.CPU; |
if (tmp & (1<<SYSINFO_CPU_ZICSR)) { |
neorv32_uart0_printf("Zicsr "); |
} |
381,12 → 380,12
// Memory configuration |
neorv32_uart0_printf("\n=== << Memory Configuration >> ===\n"); |
|
neorv32_uart0_printf("Instr. base address: 0x%x\n", SYSINFO_ISPACE_BASE); |
neorv32_uart0_printf("Instr. base address: 0x%x\n", NEORV32_SYSINFO.ISPACE_BASE); |
|
// IMEM |
neorv32_uart0_printf("Internal IMEM: "); |
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM)) { |
neorv32_uart0_printf("yes, %u bytes\n", SYSINFO_IMEM_SIZE); |
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_MEM_INT_IMEM)) { |
neorv32_uart0_printf("yes, %u bytes\n", NEORV32_SYSINFO.IMEM_SIZE); |
} |
else { |
neorv32_uart0_printf("no\n"); |
393,18 → 392,18
} |
|
// DMEM |
neorv32_uart0_printf("Data base address: 0x%x\n", SYSINFO_DSPACE_BASE); |
neorv32_uart0_printf("Data base address: 0x%x\n", NEORV32_SYSINFO.DSPACE_BASE); |
neorv32_uart0_printf("Internal DMEM: "); |
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_DMEM)) { neorv32_uart0_printf("yes, %u bytes\n", SYSINFO_DMEM_SIZE); } |
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(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_ICACHE)); |
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_ICACHE)) { |
__neorv32_rte_print_true_false(NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_ICACHE)); |
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_ICACHE)) { |
neorv32_uart0_printf("- "); |
|
uint32_t ic_block_size = (SYSINFO_CACHE >> SYSINFO_CACHE_IC_BLOCK_SIZE_0) & 0x0F; |
uint32_t ic_block_size = (NEORV32_SYSINFO.CACHE >> SYSINFO_CACHE_IC_BLOCK_SIZE_0) & 0x0F; |
if (ic_block_size) { |
ic_block_size = 1 << ic_block_size; |
} |
412,7 → 411,7
ic_block_size = 0; |
} |
|
uint32_t ic_num_blocks = (SYSINFO_CACHE >> SYSINFO_CACHE_IC_NUM_BLOCKS_0) & 0x0F; |
uint32_t ic_num_blocks = (NEORV32_SYSINFO.CACHE >> SYSINFO_CACHE_IC_NUM_BLOCKS_0) & 0x0F; |
if (ic_num_blocks) { |
ic_num_blocks = 1 << ic_num_blocks; |
} |
420,7 → 419,7
ic_num_blocks = 0; |
} |
|
uint32_t ic_associativity = (SYSINFO_CACHE >> SYSINFO_CACHE_IC_ASSOCIATIVITY_0) & 0x0F; |
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); |
427,7 → 426,7
if (ic_associativity == 1) { |
neorv32_uart0_printf(" (direct-mapped)\n"); |
} |
else if (((SYSINFO_CACHE >> SYSINFO_CACHE_IC_REPLACEMENT_0) & 0x0F) == 1) { |
else if (((NEORV32_SYSINFO.CACHE >> SYSINFO_CACHE_IC_REPLACEMENT_0) & 0x0F) == 1) { |
neorv32_uart0_printf(" (LRU replacement policy)\n"); |
} |
else { |
436,9 → 435,9
} |
|
neorv32_uart0_printf("Ext. bus interface: "); |
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT)); |
__neorv32_rte_print_true_false(NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_MEM_EXT)); |
neorv32_uart0_printf("Ext. bus Endianness: "); |
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT_ENDIAN)) { |
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_MEM_EXT_ENDIAN)) { |
neorv32_uart0_printf("big\n"); |
} |
else { |
448,20 → 447,20
// peripherals |
neorv32_uart0_printf("\n=== << Peripherals >> ===\n"); |
|
tmp = SYSINFO_FEATURES; |
neorv32_uart0_printf("GPIO - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_GPIO)); |
neorv32_uart0_printf("MTIME - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_MTIME)); |
neorv32_uart0_printf("UART0 - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_UART0)); |
neorv32_uart0_printf("UART1 - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_UART1)); |
neorv32_uart0_printf("SPI - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_SPI)); |
neorv32_uart0_printf("TWI - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TWI)); |
neorv32_uart0_printf("PWM - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_PWM)); |
neorv32_uart0_printf("WDT - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_WDT)); |
neorv32_uart0_printf("TRNG - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TRNG)); |
neorv32_uart0_printf("CFS - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_CFS)); |
neorv32_uart0_printf("SLINK - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_SLINK)); |
neorv32_uart0_printf("NEOLED - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_NEOLED)); |
neorv32_uart0_printf("XIRQ - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_XIRQ)); |
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)); |
} |
|
|
546,7 → 545,7
} |
|
neorv32_uart0_print("The NEORV32 RISC-V Processor\n" |
"(c) Stephan Nolting\n" |
"(c) 2021, Stephan Nolting\n" |
"BSD 3-Clause License\n" |
"https://github.com/stnolting/neorv32\n\n"); |
} |
/neorv32_slink.c
50,7 → 50,7
**************************************************************************/ |
int neorv32_slink_available(void) { |
|
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_SLINK)) { |
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_SLINK)) { |
return 1; |
} |
else { |
64,7 → 64,7
**************************************************************************/ |
void neorv32_slink_enable(void) { |
|
SLINK_CT |= (uint32_t)(1 << SLINK_CT_EN); |
NEORV32_SLINK.CTRL |= (uint32_t)(1 << SLINK_CTRL_EN); |
} |
|
|
75,7 → 75,7
**************************************************************************/ |
void neorv32_slink_disable(void) { |
|
SLINK_CT &= ~(uint32_t)(1 << SLINK_CT_EN); |
NEORV32_SLINK.CTRL &= ~(uint32_t)(1 << SLINK_CTRL_EN); |
} |
|
|
87,7 → 87,7
int neorv32_slink_get_rx_num(void) { |
|
if (neorv32_slink_available()) { |
return (int)((SLINK_CT >> SLINK_CT_RX_NUM0) & 0xf); |
return (int)((NEORV32_SLINK.CTRL >> SLINK_CTRL_RX_NUM0) & 0xf); |
} |
else { |
return 0; |
103,7 → 103,7
int neorv32_slink_get_tx_num(void) { |
|
if (neorv32_slink_available()) { |
return (int)((SLINK_CT >> SLINK_CT_TX_NUM0) & 0xf); |
return (int)((NEORV32_SLINK.CTRL >> SLINK_CTRL_TX_NUM0) & 0xf); |
} |
else { |
return 0; |
119,7 → 119,7
int neorv32_slink_get_rx_depth(void) { |
|
if (neorv32_slink_available()) { |
uint32_t tmp = (SLINK_CT >> SLINK_CT_RX_FIFO_S0) & 0x0f; |
uint32_t tmp = (NEORV32_SLINK.CTRL >> SLINK_CTRL_RX_FIFO_S0) & 0x0f; |
return (int)(1 << tmp); |
} |
else { |
136,7 → 136,7
int neorv32_slink_get_tx_depth(void) { |
|
if (neorv32_slink_available()) { |
uint32_t tmp = (SLINK_CT >> SLINK_CT_TX_FIFO_S0) & 0x0f; |
uint32_t tmp = (NEORV32_SLINK.CTRL >> SLINK_CTRL_TX_FIFO_S0) & 0x0f; |
return (int)(1 << tmp); |
} |
else { |
155,7 → 155,7
|
const uint32_t mask = 1 << SLINK_STATUS_RX0_HALF; |
|
if (SLINK_STATUS & (mask << (link_id & 0x7))) { |
if (NEORV32_SLINK.STATUS & (mask << (link_id & 0x7))) { |
return 1; |
} |
else { |
174,7 → 174,7
|
const uint32_t mask = 1 << SLINK_STATUS_TX0_HALF; |
|
if (SLINK_STATUS & (mask << (link_id & 0x7))) { |
if (NEORV32_SLINK.STATUS & (mask << (link_id & 0x7))) { |
return 1; |
} |
else { |
191,8 → 191,8
**************************************************************************/ |
int neorv32_slink_tx0_nonblocking(uint32_t tx_data) { |
|
if (SLINK_STATUS & (1 << SLINK_STATUS_TX0_FREE)) { |
SLINK_CH0 = tx_data; |
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX0_FREE)) { |
NEORV32_SLINK.DATA[0] = tx_data; |
return 0; |
} |
return 1; |
207,8 → 207,8
**************************************************************************/ |
int neorv32_slink_tx1_nonblocking(uint32_t tx_data) { |
|
if (SLINK_STATUS & (1 << SLINK_STATUS_TX1_FREE)) { |
SLINK_CH1 = tx_data; |
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX1_FREE)) { |
NEORV32_SLINK.DATA[1] = tx_data; |
return 0; |
} |
return 1; |
223,8 → 223,8
**************************************************************************/ |
int neorv32_slink_tx2_nonblocking(uint32_t tx_data) { |
|
if (SLINK_STATUS & (1 << SLINK_STATUS_TX2_FREE)) { |
SLINK_CH2 = tx_data; |
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX2_FREE)) { |
NEORV32_SLINK.DATA[2] = tx_data; |
return 0; |
} |
return 1; |
239,8 → 239,8
**************************************************************************/ |
int neorv32_slink_tx3_nonblocking(uint32_t tx_data) { |
|
if (SLINK_STATUS & (1 << SLINK_STATUS_TX3_FREE)) { |
SLINK_CH3 = tx_data; |
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX3_FREE)) { |
NEORV32_SLINK.DATA[3] = tx_data; |
return 0; |
} |
return 1; |
255,8 → 255,8
**************************************************************************/ |
int neorv32_slink_tx4_nonblocking(uint32_t tx_data) { |
|
if (SLINK_STATUS & (1 << SLINK_STATUS_TX4_FREE)) { |
SLINK_CH4 = tx_data; |
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX4_FREE)) { |
NEORV32_SLINK.DATA[4] = tx_data; |
return 0; |
} |
return 1; |
271,8 → 271,8
**************************************************************************/ |
int neorv32_slink_tx5_nonblocking(uint32_t tx_data) { |
|
if (SLINK_STATUS & (1 << SLINK_STATUS_TX5_FREE)) { |
SLINK_CH5 = tx_data; |
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX5_FREE)) { |
NEORV32_SLINK.DATA[5] = tx_data; |
return 0; |
} |
return 1; |
287,8 → 287,8
**************************************************************************/ |
int neorv32_slink_tx6_nonblocking(uint32_t tx_data) { |
|
if (SLINK_STATUS & (1 << SLINK_STATUS_TX6_FREE)) { |
SLINK_CH6 = tx_data; |
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX6_FREE)) { |
NEORV32_SLINK.DATA[6] = tx_data; |
return 0; |
} |
return 1; |
303,8 → 303,8
**************************************************************************/ |
int neorv32_slink_tx7_nonblocking(uint32_t tx_data) { |
|
if (SLINK_STATUS & (1 << SLINK_STATUS_TX7_FREE)) { |
SLINK_CH7 = tx_data; |
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX7_FREE)) { |
NEORV32_SLINK.DATA[7] = tx_data; |
return 0; |
} |
return 1; |
319,8 → 319,8
**************************************************************************/ |
int neorv32_slink_rx0_nonblocking(uint32_t *rx_data) { |
|
if (SLINK_STATUS & (1 << SLINK_STATUS_RX0_AVAIL)) { |
*rx_data = SLINK_CH0; |
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX0_AVAIL)) { |
*rx_data = NEORV32_SLINK.DATA[0]; |
return 0; |
} |
return 1; |
335,8 → 335,8
**************************************************************************/ |
int neorv32_slink_rx1_nonblocking(uint32_t *rx_data) { |
|
if (SLINK_STATUS & (1 << SLINK_STATUS_RX1_AVAIL)) { |
*rx_data = SLINK_CH1; |
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX1_AVAIL)) { |
*rx_data = NEORV32_SLINK.DATA[1]; |
return 0; |
} |
return 1; |
351,8 → 351,8
**************************************************************************/ |
int neorv32_slink_rx2_nonblocking(uint32_t *rx_data) { |
|
if (SLINK_STATUS & (1 << SLINK_STATUS_RX2_AVAIL)) { |
*rx_data = SLINK_CH2; |
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX2_AVAIL)) { |
*rx_data = NEORV32_SLINK.DATA[2]; |
return 0; |
} |
return 1; |
367,8 → 367,8
**************************************************************************/ |
int neorv32_slink_rx3_nonblocking(uint32_t *rx_data) { |
|
if (SLINK_STATUS & (1 << SLINK_STATUS_RX3_AVAIL)) { |
*rx_data = SLINK_CH3; |
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX3_AVAIL)) { |
*rx_data = NEORV32_SLINK.DATA[3]; |
return 0; |
} |
return 1; |
383,8 → 383,8
**************************************************************************/ |
int neorv32_slink_rx4_nonblocking(uint32_t *rx_data) { |
|
if (SLINK_STATUS & (1 << SLINK_STATUS_RX4_AVAIL)) { |
*rx_data = SLINK_CH4; |
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX4_AVAIL)) { |
*rx_data = NEORV32_SLINK.DATA[4]; |
return 0; |
} |
return 1; |
399,8 → 399,8
**************************************************************************/ |
int neorv32_slink_rx5_nonblocking(uint32_t *rx_data) { |
|
if (SLINK_STATUS & (1 << SLINK_STATUS_RX5_AVAIL)) { |
*rx_data = SLINK_CH5; |
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX5_AVAIL)) { |
*rx_data = NEORV32_SLINK.DATA[5]; |
return 0; |
} |
return 1; |
415,8 → 415,8
**************************************************************************/ |
int neorv32_slink_rx6_nonblocking(uint32_t *rx_data) { |
|
if (SLINK_STATUS & (1 << SLINK_STATUS_RX6_AVAIL)) { |
*rx_data = SLINK_CH6; |
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX6_AVAIL)) { |
*rx_data = NEORV32_SLINK.DATA[6]; |
return 0; |
} |
return 1; |
431,8 → 431,8
**************************************************************************/ |
int neorv32_slink_rx7_nonblocking(uint32_t *rx_data) { |
|
if (SLINK_STATUS & (1 << SLINK_STATUS_RX7_AVAIL)) { |
*rx_data = SLINK_CH7; |
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX7_AVAIL)) { |
*rx_data = NEORV32_SLINK.DATA[7]; |
return 0; |
} |
return 1; |
/neorv32_spi.c
52,7 → 52,7
**************************************************************************/ |
int neorv32_spi_available(void) { |
|
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_SPI)) { |
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_SPI)) { |
return 1; |
} |
else { |
62,7 → 62,7
|
|
/**********************************************************************//** |
* Enable and configure SPI controller. The SPI control register bits are listed in #NEORV32_SPI_CT_enum. |
* 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). |
70,21 → 70,21
**************************************************************************/ |
void neorv32_spi_setup(uint8_t prsc, uint8_t clk_polarity, uint8_t data_size) { |
|
SPI_CT = 0; // reset |
NEORV32_SPI.CTRL = 0; // reset |
|
uint32_t ct_enable = 1; |
ct_enable = ct_enable << SPI_CT_EN; |
ct_enable = ct_enable << SPI_CTRL_EN; |
|
uint32_t ct_prsc = (uint32_t)(prsc & 0x07); |
ct_prsc = ct_prsc << SPI_CT_PRSC0; |
ct_prsc = ct_prsc << SPI_CTRL_PRSC0; |
|
uint32_t ct_polarity = (uint32_t)(clk_polarity & 0x01); |
ct_polarity = ct_polarity << SPI_CT_CPHA; |
ct_polarity = ct_polarity << SPI_CTRL_CPHA; |
|
uint32_t ct_size = (uint32_t)(data_size & 0x03); |
ct_size = ct_size << SPI_CT_SIZE0; |
ct_size = ct_size << SPI_CTRL_SIZE0; |
|
SPI_CT = ct_enable | ct_prsc | ct_polarity | ct_size; |
NEORV32_SPI.CTRL = ct_enable | ct_prsc | ct_polarity | ct_size; |
} |
|
|
93,7 → 93,7
**************************************************************************/ |
void neorv32_spi_disable(void) { |
|
SPI_CT &= ~((uint32_t)(1 << SPI_CT_EN)); |
NEORV32_SPI.CTRL &= ~((uint32_t)(1 << SPI_CTRL_EN)); |
} |
|
|
102,7 → 102,7
**************************************************************************/ |
void neorv32_spi_enable(void) { |
|
SPI_CT |= ((uint32_t)(1 << SPI_CT_EN)); |
NEORV32_SPI.CTRL |= ((uint32_t)(1 << SPI_CTRL_EN)); |
} |
|
|
116,8 → 116,8
void neorv32_spi_cs_en(uint8_t cs) { |
|
uint32_t cs_mask = (uint32_t)(1 << (cs & 0x07)); |
cs_mask = cs_mask << SPI_CT_CS0; |
SPI_CT |= cs_mask; |
cs_mask = cs_mask << SPI_CTRL_CS0; |
NEORV32_SPI.CTRL |= cs_mask; |
} |
|
|
131,8 → 131,8
void neorv32_spi_cs_dis(uint8_t cs) { |
|
uint32_t cs_mask = (uint32_t)(1 << (cs & 0x07)); |
cs_mask = cs_mask << SPI_CT_CS0; |
SPI_CT &= ~cs_mask; |
cs_mask = cs_mask << SPI_CTRL_CS0; |
NEORV32_SPI.CTRL &= ~cs_mask; |
} |
|
|
148,10 → 148,10
**************************************************************************/ |
uint32_t neorv32_spi_trans(uint32_t tx_data) { |
|
SPI_DATA = tx_data; // trigger transfer |
while((SPI_CT & (1<<SPI_CT_BUSY)) != 0); // wait for current transfer to finish |
NEORV32_SPI.DATA = tx_data; // trigger transfer |
while((NEORV32_SPI.CTRL & (1<<SPI_CTRL_BUSY)) != 0); // wait for current transfer to finish |
|
return SPI_DATA; |
return NEORV32_SPI.DATA; |
} |
|
|
164,7 → 164,7
**************************************************************************/ |
int neorv32_spi_busy(void) { |
|
if ((SPI_CT & (1<<SPI_CT_BUSY)) != 0) { |
if ((NEORV32_SPI.CTRL & (1<<SPI_CTRL_BUSY)) != 0) { |
return 1; |
} |
return 0; |
/neorv32_trng.c
52,7 → 52,7
**************************************************************************/ |
int neorv32_trng_available(void) { |
|
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_TRNG)) { |
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_TRNG)) { |
return 1; |
} |
else { |
62,19 → 62,19
|
|
/**********************************************************************//** |
* Enable true random number generator. The TRNG control register bits are listed in #NEORV32_TRNG_CT_enum. |
* Enable true random number generator. The TRNG control register bits are listed in #NEORV32_TRNG_CTRL_enum. |
**************************************************************************/ |
void neorv32_trng_enable(void) { |
|
int i; |
|
TRNG_CT = 0; // reset |
NEORV32_TRNG.CTRL = 0; // reset |
|
for (i=0; i<256; i++) { |
asm volatile ("nop"); |
} |
|
TRNG_CT = 1 << TRNG_CT_EN; // activate |
NEORV32_TRNG.CTRL = 1 << TRNG_CTRL_EN; // activate |
|
for (i=0; i<256; i++) { |
asm volatile ("nop"); |
87,7 → 87,7
**************************************************************************/ |
void neorv32_trng_disable(void) { |
|
TRNG_CT = 0; |
NEORV32_TRNG.CTRL = 0; |
} |
|
|
104,13 → 104,13
uint32_t ct_reg; |
|
for (i=0; i<retries; i++) { |
ct_reg = TRNG_CT; |
ct_reg = NEORV32_TRNG.CTRL; |
|
if ((ct_reg & (1<<TRNG_CT_VALID)) == 0) { // output data valid? |
if ((ct_reg & (1<<TRNG_CTRL_VALID)) == 0) { // output data valid? |
continue; |
} |
|
*data = (uint8_t)(ct_reg >> TRNG_CT_DATA_LSB); |
*data = (uint8_t)(ct_reg >> TRNG_CTRL_DATA_LSB); |
return 0; // valid data |
} |
|
/neorv32_twi.c
52,7 → 52,7
**************************************************************************/ |
int neorv32_twi_available(void) { |
|
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_TWI)) { |
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_TWI)) { |
return 1; |
} |
else { |
62,7 → 62,7
|
|
/**********************************************************************//** |
* Enable and configure TWI controller. The TWI control register bits are listed in #NEORV32_TWI_CT_enum. |
* Enable and configure TWI controller. The TWI control register bits are listed in #NEORV32_TWI_CTRL_enum. |
* |
* @param[in] prsc Clock prescaler select (0..7). See #NEORV32_CLOCK_PRSC_enum. |
* @param[in] ckst_en Enable clock-stretching by peripherals when 1. |
69,18 → 69,18
**************************************************************************/ |
void neorv32_twi_setup(uint8_t prsc, uint8_t ckst_en) { |
|
TWI_CT = 0; // reset |
NEORV32_TWI.CTRL = 0; // reset |
|
uint32_t ct_enable = 1; |
ct_enable = ct_enable << TWI_CT_EN; |
ct_enable = ct_enable << TWI_CTRL_EN; |
|
uint32_t ct_prsc = (uint32_t)(prsc & 0x07); |
ct_prsc = ct_prsc << TWI_CT_PRSC0; |
ct_prsc = ct_prsc << TWI_CTRL_PRSC0; |
|
uint32_t ct_cksten = (uint32_t)(ckst_en & 0x01); |
ct_cksten = ct_cksten << TWI_CT_CKSTEN; |
ct_cksten = ct_cksten << TWI_CTRL_CKSTEN; |
|
TWI_CT = ct_enable | ct_prsc | ct_cksten; |
NEORV32_TWI.CTRL = ct_enable | ct_prsc | ct_cksten; |
} |
|
|
89,7 → 89,7
**************************************************************************/ |
void neorv32_twi_disable(void) { |
|
TWI_CT &= ~((uint32_t)(1 << TWI_CT_EN)); |
NEORV32_TWI.CTRL &= ~((uint32_t)(1 << TWI_CTRL_EN)); |
} |
|
|
98,7 → 98,7
**************************************************************************/ |
void neorv32_twi_enable(void) { |
|
TWI_CT |= (uint32_t)(1 << TWI_CT_EN); |
NEORV32_TWI.CTRL |= (uint32_t)(1 << TWI_CTRL_EN); |
} |
|
|
107,7 → 107,7
**************************************************************************/ |
void neorv32_twi_mack_enable(void) { |
|
TWI_CT |= ((uint32_t)(1 << TWI_CT_MACK)); |
NEORV32_TWI.CTRL |= ((uint32_t)(1 << TWI_CTRL_MACK)); |
} |
|
|
116,7 → 116,7
**************************************************************************/ |
void neorv32_twi_mack_disable(void) { |
|
TWI_CT &= ~((uint32_t)(1 << TWI_CT_MACK)); |
NEORV32_TWI.CTRL &= ~((uint32_t)(1 << TWI_CTRL_MACK)); |
} |
|
|
129,7 → 129,7
**************************************************************************/ |
int neorv32_twi_busy(void) { |
|
if (TWI_CT & (1 << TWI_CT_BUSY)) { |
if (NEORV32_TWI.CTRL & (1 << TWI_CTRL_BUSY)) { |
return 1; |
} |
return 0; |
148,11 → 148,11
|
neorv32_twi_generate_start(); // generate START condition |
|
TWI_DATA = (uint32_t)a; // send address |
while(TWI_CT & (1 << TWI_CT_BUSY)); // wait until idle again |
NEORV32_TWI.DATA = (uint32_t)a; // send address |
while(NEORV32_TWI.CTRL & (1 << TWI_CTRL_BUSY)); // wait until idle again |
|
// check for ACK/NACK |
if (TWI_CT & (1 << TWI_CT_ACK)) |
if (NEORV32_TWI.CTRL & (1 << TWI_CTRL_ACK)) |
return 0; // ACK received |
else |
return 1; // NACK received |
169,11 → 169,11
**************************************************************************/ |
int neorv32_twi_trans(uint8_t d) { |
|
TWI_DATA = (uint32_t)d; // send data |
while(TWI_CT & (1 << TWI_CT_BUSY)); // wait until idle again |
NEORV32_TWI.DATA = (uint32_t)d; // send data |
while(NEORV32_TWI.CTRL & (1 << TWI_CTRL_BUSY)); // wait until idle again |
|
// check for ACK/NACK |
if (TWI_CT & (1 << TWI_CT_ACK)) |
if (NEORV32_TWI.CTRL & (1 << TWI_CTRL_ACK)) |
return 0; // ACK received |
else |
return 1; // NACK received |
187,7 → 187,7
**************************************************************************/ |
uint8_t neorv32_twi_get_data(void) { |
|
return (uint8_t)TWI_DATA; // get RX data from previous transmission |
return (uint8_t)NEORV32_TWI.DATA; // get RX data from previous transmission |
} |
|
|
198,8 → 198,8
**************************************************************************/ |
void neorv32_twi_generate_stop(void) { |
|
TWI_CT |= (uint32_t)(1 << TWI_CT_STOP); // generate STOP condition |
while(TWI_CT & (1 << TWI_CT_BUSY)); // wait until idle again |
NEORV32_TWI.CTRL |= (uint32_t)(1 << TWI_CTRL_STOP); // generate STOP condition |
while(NEORV32_TWI.CTRL & (1 << TWI_CTRL_BUSY)); // wait until idle again |
} |
|
|
210,6 → 210,6
**************************************************************************/ |
void neorv32_twi_generate_start(void) { |
|
TWI_CT |= (1 << TWI_CT_START); // generate START condition |
while(TWI_CT & (1 << TWI_CT_BUSY)); // wait until idle again |
NEORV32_TWI.CTRL |= (1 << TWI_CTRL_START); // generate START condition |
while(NEORV32_TWI.CTRL & (1 << TWI_CTRL_BUSY)); // wait until idle again |
} |
/neorv32_uart.c
226,7 → 226,7
**************************************************************************/ |
int neorv32_uart0_available(void) { |
|
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_UART0)) { |
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_UART0)) { |
return 1; |
} |
else { |
249,9 → 249,9
**************************************************************************/ |
void neorv32_uart0_setup(uint32_t baudrate, uint8_t parity, uint8_t flow_con) { |
|
UART0_CT = 0; // reset |
NEORV32_UART0.CTRL = 0; // reset |
|
uint32_t clock = SYSINFO_CLK; |
uint32_t clock = NEORV32_SYSINFO.CLK; |
uint16_t i = 0; // BAUD rate divisor |
uint8_t p = 0; // initial prsc = CLK/2 |
|
277,20 → 277,20
} |
|
uint32_t clk_prsc = (uint32_t)p; |
clk_prsc = clk_prsc << UART_CT_PRSC0; |
clk_prsc = clk_prsc << UART_CTRL_PRSC0; |
|
uint32_t baud_prsc = (uint32_t)i; |
baud_prsc = baud_prsc - 1; |
baud_prsc = baud_prsc << UART_CT_BAUD00; |
baud_prsc = baud_prsc << UART_CTRL_BAUD00; |
|
uint32_t uart_en = 1; |
uart_en = uart_en << UART_CT_EN; |
uart_en = uart_en << UART_CTRL_EN; |
|
uint32_t parity_config = (uint32_t)(parity & 3); |
parity_config = parity_config << UART_CT_PMODE0; |
parity_config = parity_config << UART_CTRL_PMODE0; |
|
uint32_t flow_control = (uint32_t)(flow_con & 3); |
flow_control = flow_control << UART_CT_RTS_EN; |
flow_control = flow_control << UART_CTRL_RTS_EN; |
|
/* Enable UART0 for SIM mode. */ |
/* USE THIS ONLY FOR SIMULATION! */ |
299,12 → 299,12
#endif |
#if defined UART0_SIM_MODE || defined UART_SIM_MODE |
#warning UART0_SIM_MODE (primary UART) enabled! Sending all UART0.TX data to text.io simulation output instead of real UART0 transmitter. Use this for simulations only! |
uint32_t sim_mode = 1 << UART_CT_SIM_MODE; |
uint32_t sim_mode = 1 << UART_CTRL_SIM_MODE; |
#else |
uint32_t sim_mode = 0; |
#endif |
|
UART0_CT = clk_prsc | baud_prsc | uart_en | parity_config | sim_mode | flow_control; |
NEORV32_UART0.CTRL = clk_prsc | baud_prsc | uart_en | parity_config | sim_mode | flow_control; |
} |
|
|
313,7 → 313,7
**************************************************************************/ |
void neorv32_uart0_disable(void) { |
|
UART0_CT &= ~((uint32_t)(1 << UART_CT_EN)); |
NEORV32_UART0.CTRL &= ~((uint32_t)(1 << UART_CTRL_EN)); |
} |
|
|
322,7 → 322,7
**************************************************************************/ |
void neorv32_uart0_enable(void) { |
|
UART0_CT = ((uint32_t)(1 << UART_CT_EN)); |
NEORV32_UART0.CTRL = ((uint32_t)(1 << UART_CTRL_EN)); |
} |
|
|
336,8 → 336,8
void neorv32_uart0_putc(char c) { |
|
// wait for previous transfer to finish |
while ((UART0_CT & (1<<UART_CT_TX_BUSY)) != 0); |
UART0_DATA = ((uint32_t)c) << UART_DATA_LSB; |
while ((NEORV32_UART0.CTRL & (1<<UART_CTRL_TX_BUSY)) != 0); |
NEORV32_UART0.DATA = ((uint32_t)c) << UART_DATA_LSB; |
} |
|
|
350,7 → 350,7
**************************************************************************/ |
int neorv32_uart0_tx_busy(void) { |
|
if ((UART0_CT & (1<<UART_CT_TX_BUSY)) != 0) { |
if ((NEORV32_UART0.CTRL & (1<<UART_CTRL_TX_BUSY)) != 0) { |
return 1; |
} |
return 0; |
368,7 → 368,7
|
uint32_t d = 0; |
while (1) { |
d = UART0_DATA; |
d = NEORV32_UART0.DATA; |
if ((d & (1<<UART_DATA_AVAIL)) != 0) { // char received? |
return (char)d; |
} |
386,7 → 386,7
**************************************************************************/ |
int neorv32_uart0_getc_safe(char *data) { |
|
uint32_t uart_rx = UART0_DATA; |
uint32_t uart_rx = NEORV32_UART0.DATA; |
if (uart_rx & (1<<UART_DATA_AVAIL)) { // char available at all? |
|
int status = 0; |
426,7 → 426,7
**************************************************************************/ |
int neorv32_uart0_char_received(void) { |
|
if ((UART0_DATA & (1<<UART_DATA_AVAIL)) != 0) { |
if ((NEORV32_UART0.DATA & (1<<UART_DATA_AVAIL)) != 0) { |
return 1; |
} |
else { |
445,7 → 445,7
**************************************************************************/ |
char neorv32_uart0_char_received_get(void) { |
|
return (char)UART0_DATA; |
return (char)NEORV32_UART0.DATA; |
} |
|
|
589,7 → 589,7
**************************************************************************/ |
int neorv32_uart1_available(void) { |
|
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_UART1)) { |
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_UART1)) { |
return 1; |
} |
else { |
612,9 → 612,9
**************************************************************************/ |
void neorv32_uart1_setup(uint32_t baudrate, uint8_t parity, uint8_t flow_con) { |
|
UART1_CT = 0; // reset |
NEORV32_UART1.CTRL = 0; // reset |
|
uint32_t clock = SYSINFO_CLK; |
uint32_t clock = NEORV32_SYSINFO.CLK; |
uint16_t i = 0; // BAUD rate divisor |
uint8_t p = 0; // initial prsc = CLK/2 |
|
640,31 → 640,31
} |
|
uint32_t clk_prsc = (uint32_t)p; |
clk_prsc = clk_prsc << UART_CT_PRSC0; |
clk_prsc = clk_prsc << UART_CTRL_PRSC0; |
|
uint32_t baud_prsc = (uint32_t)i; |
baud_prsc = baud_prsc - 1; |
baud_prsc = baud_prsc << UART_CT_BAUD00; |
baud_prsc = baud_prsc << UART_CTRL_BAUD00; |
|
uint32_t uart_en = 1; |
uart_en = uart_en << UART_CT_EN; |
uart_en = uart_en << UART_CTRL_EN; |
|
uint32_t parity_config = (uint32_t)(parity & 3); |
parity_config = parity_config << UART_CT_PMODE0; |
parity_config = parity_config << UART_CTRL_PMODE0; |
|
uint32_t flow_control = (uint32_t)(flow_con & 3); |
flow_control = flow_control << UART_CT_RTS_EN; |
flow_control = flow_control << UART_CTRL_RTS_EN; |
|
/* Enable UART1 for SIM mode. */ |
/* USE THIS ONLY FOR SIMULATION! */ |
#ifdef UART1_SIM_MODE |
#warning UART1_SIM_MODE (secondary UART) enabled! Sending all UART1.TX data to text.io simulation output instead of real UART1 transmitter. Use this for simulations only! |
uint32_t sim_mode = 1 << UART_CT_SIM_MODE; |
uint32_t sim_mode = 1 << UART_CTRL_SIM_MODE; |
#else |
uint32_t sim_mode = 0; |
#endif |
|
UART1_CT = clk_prsc | baud_prsc | uart_en | parity_config | sim_mode | flow_control; |
NEORV32_UART1.CTRL = clk_prsc | baud_prsc | uart_en | parity_config | sim_mode | flow_control; |
} |
|
|
673,7 → 673,7
**************************************************************************/ |
void neorv32_uart1_disable(void) { |
|
UART1_CT &= ~((uint32_t)(1 << UART_CT_EN)); |
NEORV32_UART1.CTRL &= ~((uint32_t)(1 << UART_CTRL_EN)); |
} |
|
|
682,7 → 682,7
**************************************************************************/ |
void neorv32_uart1_enable(void) { |
|
UART1_CT |= ((uint32_t)(1 << UART_CT_EN)); |
NEORV32_UART1.CTRL |= ((uint32_t)(1 << UART_CTRL_EN)); |
} |
|
|
696,8 → 696,8
void neorv32_uart1_putc(char c) { |
|
// wait for previous transfer to finish |
while ((UART1_CT & (1<<UART_CT_TX_BUSY)) != 0); |
UART1_DATA = ((uint32_t)c) << UART_DATA_LSB; |
while ((NEORV32_UART1.CTRL & (1<<UART_CTRL_TX_BUSY)) != 0); |
NEORV32_UART1.DATA = ((uint32_t)c) << UART_DATA_LSB; |
} |
|
|
710,7 → 710,7
**************************************************************************/ |
int neorv32_uart1_tx_busy(void) { |
|
if ((UART1_CT & (1<<UART_CT_TX_BUSY)) != 0) { |
if ((NEORV32_UART1.CTRL & (1<<UART_CTRL_TX_BUSY)) != 0) { |
return 1; |
} |
return 0; |
728,7 → 728,7
|
uint32_t d = 0; |
while (1) { |
d = UART1_DATA; |
d = NEORV32_UART1.DATA; |
if ((d & (1<<UART_DATA_AVAIL)) != 0) { // char received? |
return (char)d; |
} |
746,7 → 746,7
**************************************************************************/ |
int neorv32_uart1_getc_safe(char *data) { |
|
uint32_t uart_rx = UART1_DATA; |
uint32_t uart_rx = NEORV32_UART1.DATA; |
if (uart_rx & (1<<UART_DATA_AVAIL)) { // char available at all? |
|
int status = 0; |
786,7 → 786,7
**************************************************************************/ |
int neorv32_uart1_char_received(void) { |
|
if ((UART1_DATA & (1<<UART_DATA_AVAIL)) != 0) { |
if ((NEORV32_UART1.DATA & (1<<UART_DATA_AVAIL)) != 0) { |
return 1; |
} |
else { |
805,7 → 805,7
**************************************************************************/ |
char neorv32_uart1_char_received_get(void) { |
|
return (char)UART1_DATA; |
return (char)NEORV32_UART1.DATA; |
} |
|
|
/neorv32_wdt.c
52,7 → 52,7
**************************************************************************/ |
int neorv32_wdt_available(void) { |
|
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_WDT)) { |
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_WDT)) { |
return 1; |
} |
else { |
62,7 → 62,7
|
|
/**********************************************************************//** |
* Configure and enable watchdog timer. The WDT control register bits are listed in #NEORV32_WDT_CT_enum. |
* Configure and enable watchdog timer. The WDT control register bits are listed in #NEORV32_WDT_CTRL_enum. |
* |
* @param[in] prsc Clock prescaler to select timeout interval. See #NEORV32_CLOCK_PRSC_enum. |
* @param[in] mode Trigger system reset on timeout when 1, trigger interrupt on timeout when 0. |
70,21 → 70,21
**************************************************************************/ |
void neorv32_wdt_setup(uint8_t prsc, uint8_t mode, uint8_t lock) { |
|
WDT_CT = (1 << WDT_CT_RESET); // reset WDT counter |
NEORV32_WDT.CTRL = (1 << WDT_CTRL_RESET); // reset WDT counter |
|
uint32_t prsc_int = (uint32_t)(prsc & 0x07); |
prsc_int = prsc_int << WDT_CT_CLK_SEL0; |
prsc_int = prsc_int << WDT_CTRL_CLK_SEL0; |
|
uint32_t mode_int = (uint32_t)(mode & 0x01); |
mode_int = mode_int << WDT_CT_MODE; |
mode_int = mode_int << WDT_CTRL_MODE; |
|
uint32_t lock_int = (uint32_t)(lock & 0x01); |
lock_int = lock_int << WDT_CT_LOCK; |
lock_int = lock_int << WDT_CTRL_LOCK; |
|
const uint32_t enable = (uint32_t)(1 << WDT_CT_EN); |
const uint32_t enable = (uint32_t)(1 << WDT_CTRL_EN); |
|
// update WDT control register |
WDT_CT = enable | mode_int | prsc_int | lock_int; |
NEORV32_WDT.CTRL = enable | mode_int | prsc_int | lock_int; |
} |
|
|
95,10 → 95,10
**************************************************************************/ |
int neorv32_wdt_disable(void) { |
|
WDT_CT = 0; |
NEORV32_WDT.CTRL = 0; |
|
// check if wdt is really off |
if (WDT_CT & (1 << WDT_CT_EN)) { |
if (NEORV32_WDT.CTRL & (1 << WDT_CTRL_EN)) { |
return -1; // WDT still active |
} |
else { |
112,7 → 112,7
**************************************************************************/ |
void neorv32_wdt_reset(void) { |
|
WDT_CT = WDT_CT | (1 << WDT_CT_RESET); |
NEORV32_WDT.CTRL = NEORV32_WDT.CTRL | (1 << WDT_CTRL_RESET); |
} |
|
|
123,7 → 123,7
**************************************************************************/ |
int neorv32_wdt_get_cause(void) { |
|
if (WDT_CT & (1 << WDT_CT_RCAUSE)) { // reset caused by watchdog |
if (NEORV32_WDT.CTRL & (1 << WDT_CTRL_RCAUSE)) { // reset caused by watchdog |
return 1; |
} |
else { // external reset |
137,5 → 137,5
**************************************************************************/ |
void neorv32_wdt_force(void) { |
|
WDT_CT = WDT_CT | (1 << WDT_CT_FORCE); |
NEORV32_WDT.CTRL = NEORV32_WDT.CTRL | (1 << WDT_CTRL_FORCE); |
} |
/neorv32_xirq.c
49,8 → 49,8
static uint32_t __neorv32_xirq_vector_lut[32] __attribute__((unused)); // trap handler vector table |
|
// private functions |
static void __attribute__((aligned(16))) __attribute__((unused)) __neorv32_xirq_core(void); |
static void __attribute__((unused)) __neorv32_xirq_dummy_handler(void); |
static void __attribute__((aligned(16))) __neorv32_xirq_core(void); |
static void __neorv32_xirq_dummy_handler(void); |
|
|
/**********************************************************************//** |
60,7 → 60,7
**************************************************************************/ |
int neorv32_xirq_available(void) { |
|
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_XIRQ)) { |
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_XIRQ)) { |
return 1; |
} |
else { |
78,8 → 78,8
**************************************************************************/ |
int neorv32_xirq_setup(void) { |
|
XIRQ_IER = 0; // disable all input channels |
XIRQ_IPR = 0xffffffff; // clear/ack all pending IRQs |
NEORV32_XIRQ.IER = 0; // disable all input channels |
NEORV32_XIRQ.IPR = 0; // clear all pending IRQs |
|
int i; |
for (i=0; i<32; i++) { |
86,7 → 86,7
__neorv32_xirq_vector_lut[i] = (uint32_t)(&__neorv32_xirq_dummy_handler); |
} |
|
// register XIRQ handler in RTE |
// register XIRQ handler in NEORV32 RTE |
return neorv32_rte_exception_install(XIRQ_RTE_ID, __neorv32_xirq_core); |
} |
|
124,8 → 124,8
if (neorv32_xirq_available()) { |
|
neorv32_cpu_irq_disable(XIRQ_FIRQ_ENABLE); // make sure XIRQ cannot fire |
XIRQ_IER = 0xffffffff; // try to set all enable flags |
enable = XIRQ_IER; // read back actually set flags |
NEORV32_XIRQ.IER = 0xffffffff; // try to set all enable flags |
enable = NEORV32_XIRQ.IER; // read back actually set flags |
|
// count set bits in enable |
cnt = 0; |
144,6 → 144,45
|
|
/**********************************************************************//** |
* Clear pending interrupt. |
* |
* @param[in] ch XIRQ interrupt channel (0..31). |
**************************************************************************/ |
void neorv32_xirq_clear_pending(uint8_t ch) { |
|
if (ch < 32) { // channel valid? |
NEORV32_XIRQ.IPR = ~(1 << ch); |
} |
} |
|
|
/**********************************************************************//** |
* Enable IRQ channel. |
* |
* @param[in] ch XIRQ interrupt channel (0..31). |
**************************************************************************/ |
void neorv32_xirq_channel_enable(uint8_t ch) { |
|
if (ch < 32) { // channel valid? |
NEORV32_XIRQ.IER |= 1 << ch; |
} |
} |
|
|
/**********************************************************************//** |
* Disable IRQ channel. |
* |
* @param[in] ch XIRQ interrupt channel (0..31). |
**************************************************************************/ |
void neorv32_xirq_channel_disable(uint8_t ch) { |
|
if (ch < 32) { // channel valid? |
NEORV32_XIRQ.IER &= ~(1 << ch); |
} |
} |
|
|
/**********************************************************************//** |
* Install exception handler function for XIRQ channel. |
* |
* @note This will also activate the according XIRQ channel and clear a pending IRQ at this channel. |
158,8 → 197,8
if (ch < 32) { |
__neorv32_xirq_vector_lut[ch] = (uint32_t)handler; // install handler |
uint32_t mask = 1 << ch; |
XIRQ_IPR = mask; // clear if pending |
XIRQ_IER |= mask; // enable channel |
NEORV32_XIRQ.IPR = ~mask; // clear if pending |
NEORV32_XIRQ.IER |= mask; // enable channel |
return 0; |
} |
return 1; |
180,8 → 219,8
if (ch < 32) { |
__neorv32_xirq_vector_lut[ch] = (uint32_t)(&__neorv32_xirq_dummy_handler); // override using dummy handler |
uint32_t mask = 1 << ch; |
XIRQ_IER &= ~mask; // disable channel |
XIRQ_IPR = mask; // clear if pending |
NEORV32_XIRQ.IER &= ~mask; // disable channel |
NEORV32_XIRQ.IPR = ~mask; // clear if pending |
return 0; |
} |
return 1; |
189,17 → 228,16
|
|
/**********************************************************************//** |
* This is the actual second-level IRQ handler for the XIRQ. It will call the previously installed handler |
* if an XIRQ fires. |
* |
* @note This function must no be used by the user. |
* This is the actual second-level (F)IRQ handler for the XIRQ. It will |
* call the previously installed handler if an XIRQ fires. |
**************************************************************************/ |
static void __attribute__((aligned(16))) __attribute__((unused)) __neorv32_xirq_core(void) { |
static void __attribute__((aligned(16))) __neorv32_xirq_core(void) { |
|
register uint32_t src = XIRQ_SCR; // get IRQ source (with highest priority) |
src &= 0x1f; |
register uint32_t src = NEORV32_XIRQ.SCR; // get IRQ source (with highest priority) |
|
XIRQ_IPR = (uint32_t)(1 << src); // acknowledge pending interrupt |
uint32_t mask = 1 << src; |
NEORV32_XIRQ.IPR = ~mask; // clear current pending interrupt |
NEORV32_XIRQ.SCR = 0; // acknowledge current interrupt (CPU FIRQ) |
|
// execute handler |
register uint32_t xirq_handler = __neorv32_xirq_vector_lut[src]; |
212,7 → 250,7
/**********************************************************************//** |
* XIRQ dummy handler. |
**************************************************************************/ |
static void __attribute__((unused)) __neorv32_xirq_dummy_handler(void) { |
static void __neorv32_xirq_dummy_handler(void) { |
|
asm volatile ("nop"); |
} |