rtems_status_code rtems_gpio_bsp_multi_select( rtems_gpio_multiple_pin_select *pins, uint32_t pin_count, uint32_t select_bank ) { uint32_t register_address; uint32_t select_register; uint8_t i; register_address = BCM2835_GPIO_REGS_BASE + (select_bank * 0x04); select_register = BCM2835_REG(register_address); for ( i = 0; i < pin_count; ++i ) { if ( pins[i].function == DIGITAL_INPUT ) { select_register &= ~SELECT_PIN_FUNCTION(RPI_DIGITAL_IN, pins[i].pin_number); } else if ( pins[i].function == DIGITAL_OUTPUT ) { select_register |= SELECT_PIN_FUNCTION(RPI_DIGITAL_OUT, pins[i].pin_number); } else { /* BSP_SPECIFIC function. */ select_register |= SELECT_PIN_FUNCTION(pins[i].io_function, pins[i].pin_number); } } BCM2835_REG(register_address) = select_register; return RTEMS_SUCCESSFUL; }
rtems_status_code bsp_interrupt_facility_initialize(void) { BCM2835_REG(BCM2835_IRQ_DISABLE1) = 0xffffffff; BCM2835_REG(BCM2835_IRQ_DISABLE2) = 0xffffffff; BCM2835_REG(BCM2835_IRQ_DISABLE_BASIC) = 0xffffffff; BCM2835_REG(BCM2835_IRQ_FIQ_CTRL) = 0; return RTEMS_SUCCESSFUL; }
static void usart_write_polled(int minor, char c) { while (1) { if ((BCM2835_REG(BCM2835_UART0_FR) & BCM2835_UART0_FR_TXFF) == 0) break; } BCM2835_REG(BCM2835_UART0_DR) = c; }
benchmark_timer_t benchmark_timer_read( void ) { uint32_t delta = BCM2835_REG( BCM2835_GPU_TIMER_CLO ) - benchmark_timer_base; if ( benchmark_timer_find_average_overhead ) { return delta; } else { return BCM2835_REG( BCM2835_GPU_TIMER_CLO ); } }
uint32_t rtems_gpio_bsp_interrupt_line(rtems_vector_number vector) { uint32_t event_status; /* Retrieve the interrupt event status. */ event_status = BCM2835_REG(BCM2835_GPIO_GPEDS0); /* Clear the interrupt line. */ BCM2835_REG(BCM2835_GPIO_GPEDS0) = event_status; return event_status; }
static int usart_read_polled(int minor) { if (minor == 0) { if (((BCM2835_REG(BCM2835_UART0_FR)) & BCM2835_UART0_FR_RXFE) == 0) { return((BCM2835_REG(BCM2835_UART0_DR)) & 0xFF ); } else { return -1; } } else { printk("Unknown console minor number: %d\n", minor); return -1; } }
void rpi_ipi_initialize(void) { uint32_t cpu_index_self = _SMP_Get_current_processor(); /* * Includes support only for mailbox 3 interrupt. * Further interrupt support has to be added. This will have to be integrated * with existing interrupt support for Raspberry Pi */ /* reset mailbox 3 contents to zero */ BCM2835_REG(BCM2836_MAILBOX_3_READ_CLEAR_BASE + 0x10 * cpu_index_self) = 0xffffffff; BCM2835_REG(BCM2836_MAILBOX_IRQ_CTRL(cpu_index_self)) = BCM2836_MAILBOX_IRQ_CTRL_MBOX3_IRQ; }
rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) { if ( vector > BSP_INTERRUPT_VECTOR_MAX ) return RTEMS_INVALID_ID; BCM2835_REG(bsp_vector_to_reg(vector)->disable_reg_addr) = bsp_vector_to_mask(vector); return RTEMS_SUCCESSFUL; }
/* * Determine the source of the interrupt and dispatch the correct handler. */ void bsp_interrupt_dispatch(void) { unsigned int pend; unsigned int pend_bit; rtems_vector_number vector = 255; #ifdef RTEMS_SMP uint32_t cpu_index_self = _SMP_Get_current_processor(); uint32_t local_source = BCM2835_REG(BCM2836_IRQ_SOURCE_REG(cpu_index_self)); if ( local_source & BCM2836_IRQ_SOURCE_MBOX3 ) { /* reset mailbox 3 contents to zero */ BCM2835_REG(BCM2836_MAILBOX_3_READ_CLEAR_BASE + 0x10 * cpu_index_self) = 0xffffffff; _SMP_Inter_processor_interrupt_handler(); } if ( cpu_index_self != 0 ) return; #endif /* RTEMS_SMP */ pend = BCM2835_REG(BCM2835_IRQ_BASIC); if ( pend & BCM2835_IRQ_BASIC_SPEEDUP_USED_BITS ) { pend_bit = ffs(pend) - 1; vector = bcm2835_irq_speedup_table[pend_bit]; } else { pend = BCM2835_REG(BCM2835_IRQ_PENDING1); if ( pend != 0 ) { pend_bit = ffs(pend) - 1; vector = pend_bit; } else { pend = BCM2835_REG(BCM2835_IRQ_PENDING2); if ( pend != 0 ) { pend_bit = ffs(pend) - 1; vector = pend_bit + 32; } } } if ( vector < 255 ) { bsp_interrupt_handler_dispatch(vector); } }
static void raspberrypi_clock_initialize(void) { BCM2835_REG(BCM2835_TIMER_CTL) = 0x003E0000; BCM2835_REG(BCM2835_TIMER_LOD) = 10000 - 1; BCM2835_REG(BCM2835_TIMER_RLD) = 10000 - 1; BCM2835_REG(BCM2835_TIMER_DIV) = BCM2835_TIMER_PRESCALE; BCM2835_REG(BCM2835_TIMER_CLI) = 0; BCM2835_REG(BCM2835_TIMER_CTL) = 0x003E00A2; }
rtems_status_code rtems_bsp_disable_interrupt( uint32_t bank, uint32_t pin, rtems_gpio_interrupt interrupt ) { switch ( interrupt ) { case FALLING_EDGE: /* Disables asynchronous falling edge detection. */ BCM2835_REG(BCM2835_GPIO_GPAFEN0) &= ~(1 << pin); break; case RISING_EDGE: /* Disables asynchronous rising edge detection. */ BCM2835_REG(BCM2835_GPIO_GPAREN0) &= ~(1 << pin); break; case BOTH_EDGES: /* Disables asynchronous falling edge detection. */ BCM2835_REG(BCM2835_GPIO_GPAFEN0) &= ~(1 << pin); /* Disables asynchronous rising edge detection. */ BCM2835_REG(BCM2835_GPIO_GPAREN0) &= ~(1 << pin); break; case LOW_LEVEL: /* Disables pin low level detection. */ BCM2835_REG(BCM2835_GPIO_GPLEN0) &= ~(1 << pin); break; case HIGH_LEVEL: /* Disables pin high level detection. */ BCM2835_REG(BCM2835_GPIO_GPHEN0) &= ~(1 << pin); break; case BOTH_LEVELS: /* Disables pin low level detection. */ BCM2835_REG(BCM2835_GPIO_GPLEN0) &= ~(1 << pin); /* Disables pin high level detection. */ BCM2835_REG(BCM2835_GPIO_GPHEN0) &= ~(1 << pin); break; case NONE: default: return RTEMS_UNSATISFIED; } return RTEMS_SUCCESSFUL; }
bool _CPU_SMP_Start_processor( uint32_t cpu_index ) { bool started; uint32_t cpu_index_self = _SMP_Get_current_processor(); if (cpu_index != cpu_index_self) { BCM2835_REG(BCM2836_MAILBOX_3_WRITE_SET_BASE + 0x10 * cpu_index) = (uint32_t)_start; /* * Wait for secondary processor to complete its basic initialization so * that we can enable the unified L2 cache. */ started = _Per_CPU_State_wait_for_non_initial_state(cpu_index, 0); } else { started = false; } return started; }
rtems_status_code rtems_gpio_bsp_set_resistor_mode( uint32_t bank, uint32_t pin, rtems_gpio_pull_mode mode ) { /* Set control signal. */ switch ( mode ) { case PULL_UP: BCM2835_REG(BCM2835_GPIO_GPPUD) = (1 << 1); break; case PULL_DOWN: BCM2835_REG(BCM2835_GPIO_GPPUD) = (1 << 0); break; case NO_PULL_RESISTOR: BCM2835_REG(BCM2835_GPIO_GPPUD) = 0; break; default: return RTEMS_UNSATISFIED; } /* Wait 150 cyles, as per BCM2835 documentation. */ arm_delay(150); /* Setup clock for the control signal. */ BCM2835_REG(BCM2835_GPIO_GPPUDCLK0) = (1 << pin); arm_delay(150); /* Remove the control signal. */ BCM2835_REG(BCM2835_GPIO_GPPUD) = 0; /* Remove the clock. */ BCM2835_REG(BCM2835_GPIO_GPPUDCLK0) = 0; return RTEMS_SUCCESSFUL; }
rtems_status_code rtems_gpio_bsp_clear(uint32_t bank, uint32_t pin) { BCM2835_REG(BCM2835_GPIO_GPCLR0) = (1 << pin); return RTEMS_SUCCESSFUL; }
static void raspberrypi_clock_at_tick(void) { BCM2835_REG(BCM2835_TIMER_CLI) = 0; }
void _CPU_SMP_Send_interrupt( uint32_t target_cpu_index ) { /* Generates IPI */ BCM2835_REG(BCM2836_MAILBOX_3_WRITE_SET_BASE + 0x10 * target_cpu_index) = 0x1; }
void benchmark_timer_initialize(void) { benchmark_timer_base = BCM2835_REG(BCM2835_GPU_TIMER_CLO); }
uint32_t rtems_gpio_bsp_get_value(uint32_t bank, uint32_t pin) { return (BCM2835_REG(BCM2835_GPIO_GPLEV0) & (1 << pin)); }
static void usart_initialize(int minor) { unsigned int gpio_reg; /* ** Program GPIO pins for UART 0 */ gpio_reg = BCM2835_REG(BCM2835_GPIO_GPFSEL1); gpio_reg &= ~(7<<12); /* gpio14 */ gpio_reg |= (4<<12); /* alt0 */ gpio_reg &= ~(7<<15); /* gpio15 */ gpio_reg |= (4<<15); /* alt0 */ BCM2835_REG(BCM2835_GPIO_GPFSEL1) = gpio_reg; BCM2835_REG(BCM2835_GPIO_GPPUD) = 0; usart_delay(150); BCM2835_REG(BCM2835_GPIO_GPPUDCLK0) = (1<<14)|(1<<15); usart_delay(150); BCM2835_REG(BCM2835_GPIO_GPPUDCLK0) = 0; /* ** Init the PL011 UART */ BCM2835_REG(BCM2835_UART0_CR) = 0; BCM2835_REG(BCM2835_UART0_ICR) = 0x7FF; BCM2835_REG(BCM2835_UART0_IMSC) = 0; BCM2835_REG(BCM2835_UART0_IBRD) = 1; BCM2835_REG(BCM2835_UART0_FBRD) = 40; BCM2835_REG(BCM2835_UART0_LCRH) = 0x70; BCM2835_REG(BCM2835_UART0_RSRECR) = 0; BCM2835_REG(BCM2835_UART0_CR) = 0x301; BCM2835_REG(BCM2835_UART0_IMSC) = BCM2835_UART0_IMSC_RX; usart_set_baud(minor, 115000); }
rtems_status_code rtems_gpio_bsp_multi_clear(uint32_t bank, uint32_t bitmask) { BCM2835_REG(BCM2835_GPIO_GPCLR0) = bitmask; return RTEMS_SUCCESSFUL; }
uint32_t rtems_gpio_bsp_multi_read(uint32_t bank, uint32_t bitmask) { return (BCM2835_REG(BCM2835_GPIO_GPLEV0) & bitmask); }