File indexing completed on 2025-05-11 08:23:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <bsp.h>
0018 #include <bsp/raspberrypi.h>
0019 #include <bsp/irq-generic.h>
0020 #include <bsp/gpio.h>
0021 #include <bsp/rpi-gpio.h>
0022
0023 #include <stdlib.h>
0024
0025 RTEMS_INTERRUPT_LOCK_DEFINE( static, rtems_gpio_bsp_lock, "rtems_gpio_bsp_lock" );
0026
0027
0028 #define SELECT_PIN_FUNCTION(fn, pn) (fn << ((pn % 10) * 3))
0029
0030 rtems_gpio_specific_data alt_func_def[] = {
0031 {.io_function = RPI_ALT_FUNC_0, .pin_data = NULL},
0032 {.io_function = RPI_ALT_FUNC_1, .pin_data = NULL},
0033 {.io_function = RPI_ALT_FUNC_2, .pin_data = NULL},
0034 {.io_function = RPI_ALT_FUNC_3, .pin_data = NULL},
0035 {.io_function = RPI_ALT_FUNC_4, .pin_data = NULL},
0036 {.io_function = RPI_ALT_FUNC_5, .pin_data = NULL}
0037 };
0038
0039
0040 #include "gpio-interfaces-pi1-rev2.c"
0041
0042
0043 static void arm_delay(uint8_t cycles)
0044 {
0045 uint8_t i;
0046
0047 for ( i = 0; i < cycles; ++i ) {
0048 asm volatile("nop");
0049 }
0050 }
0051
0052 static rtems_status_code rpi_select_pin_function(
0053 uint32_t bank,
0054 uint32_t pin,
0055 uint32_t type
0056 ) {
0057
0058 volatile uint32_t *pin_addr = (uint32_t *) BCM2835_GPIO_REGS_BASE +
0059 (pin / 10);
0060 uint32_t reg_old;
0061 uint32_t reg_new;
0062 rtems_interrupt_lock_context lock_context;
0063
0064 rtems_interrupt_lock_acquire(&rtems_gpio_bsp_lock, &lock_context);
0065 reg_new = reg_old = *pin_addr;
0066 reg_new &= ~SELECT_PIN_FUNCTION(RPI_ALT_FUNC_MASK, pin);
0067 reg_new |= SELECT_PIN_FUNCTION(type, pin);
0068 *pin_addr = reg_new;
0069 rtems_interrupt_lock_release(&rtems_gpio_bsp_lock, &lock_context);
0070
0071 return RTEMS_SUCCESSFUL;
0072 }
0073
0074 rtems_status_code rtems_gpio_bsp_multi_set(uint32_t bank, uint32_t bitmask)
0075 {
0076 BCM2835_REG(BCM2835_GPIO_GPSET0) = bitmask;
0077
0078 return RTEMS_SUCCESSFUL;
0079 }
0080
0081 rtems_status_code rtems_gpio_bsp_multi_clear(uint32_t bank, uint32_t bitmask)
0082 {
0083 BCM2835_REG(BCM2835_GPIO_GPCLR0) = bitmask;
0084
0085 return RTEMS_SUCCESSFUL;
0086 }
0087
0088 uint32_t rtems_gpio_bsp_multi_read(uint32_t bank, uint32_t bitmask)
0089 {
0090 return (BCM2835_REG(BCM2835_GPIO_GPLEV0) & bitmask);
0091 }
0092
0093 rtems_status_code rtems_gpio_bsp_set(uint32_t bank, uint32_t pin)
0094 {
0095 BCM2835_REG(BCM2835_GPIO_GPSET0) = (1 << pin);
0096
0097 return RTEMS_SUCCESSFUL;
0098 }
0099
0100 rtems_status_code rtems_gpio_bsp_clear(uint32_t bank, uint32_t pin)
0101 {
0102 BCM2835_REG(BCM2835_GPIO_GPCLR0) = (1 << pin);
0103
0104 return RTEMS_SUCCESSFUL;
0105 }
0106
0107 uint32_t rtems_gpio_bsp_get_value(uint32_t bank, uint32_t pin)
0108 {
0109 return (BCM2835_REG(BCM2835_GPIO_GPLEV0) & (1 << pin));
0110 }
0111
0112 rtems_status_code rtems_gpio_bsp_select_input(
0113 uint32_t bank,
0114 uint32_t pin,
0115 void *bsp_specific
0116 ) {
0117 return rpi_select_pin_function(bank, pin, RPI_DIGITAL_IN);
0118 }
0119
0120 rtems_status_code rtems_gpio_bsp_select_output(
0121 uint32_t bank,
0122 uint32_t pin,
0123 void *bsp_specific
0124 ) {
0125 return rpi_select_pin_function(bank, pin, RPI_DIGITAL_OUT);
0126 }
0127
0128 rtems_status_code rtems_gpio_bsp_select_specific_io(
0129 uint32_t bank,
0130 uint32_t pin,
0131 uint32_t function,
0132 void *pin_data
0133 ) {
0134 return rpi_select_pin_function(bank, pin, function);
0135 }
0136
0137 rtems_status_code rtems_gpio_bsp_set_resistor_mode(
0138 uint32_t bank,
0139 uint32_t pin,
0140 rtems_gpio_pull_mode mode
0141 ) {
0142
0143 switch ( mode ) {
0144 case PULL_UP:
0145 BCM2835_REG(BCM2835_GPIO_GPPUD) = (1 << 1);
0146 break;
0147 case PULL_DOWN:
0148 BCM2835_REG(BCM2835_GPIO_GPPUD) = (1 << 0);
0149 break;
0150 case NO_PULL_RESISTOR:
0151 BCM2835_REG(BCM2835_GPIO_GPPUD) = 0;
0152 break;
0153 default:
0154 return RTEMS_UNSATISFIED;
0155 }
0156
0157
0158 arm_delay(150);
0159
0160
0161 BCM2835_REG(BCM2835_GPIO_GPPUDCLK0) = (1 << pin);
0162
0163 arm_delay(150);
0164
0165
0166 BCM2835_REG(BCM2835_GPIO_GPPUD) = 0;
0167
0168
0169 BCM2835_REG(BCM2835_GPIO_GPPUDCLK0) = 0;
0170
0171 return RTEMS_SUCCESSFUL;
0172 }
0173
0174 rtems_vector_number rtems_gpio_bsp_get_vector(uint32_t bank)
0175 {
0176 return BCM2835_IRQ_ID_GPIO_0;
0177 }
0178
0179 uint32_t rtems_gpio_bsp_interrupt_line(rtems_vector_number vector)
0180 {
0181 uint32_t event_status;
0182
0183
0184 event_status = BCM2835_REG(BCM2835_GPIO_GPEDS0);
0185
0186
0187 BCM2835_REG(BCM2835_GPIO_GPEDS0) = event_status;
0188
0189 return event_status;
0190 }
0191
0192 rtems_status_code rtems_gpio_bsp_enable_interrupt(
0193 uint32_t bank,
0194 uint32_t pin,
0195 rtems_gpio_interrupt interrupt
0196 ) {
0197 switch ( interrupt ) {
0198 case FALLING_EDGE:
0199
0200 BCM2835_REG(BCM2835_GPIO_GPAFEN0) |= (1 << pin);
0201 break;
0202 case RISING_EDGE:
0203
0204 BCM2835_REG(BCM2835_GPIO_GPAREN0) |= (1 << pin);
0205 break;
0206 case BOTH_EDGES:
0207
0208 BCM2835_REG(BCM2835_GPIO_GPAFEN0) |= (1 << pin);
0209
0210
0211 BCM2835_REG(BCM2835_GPIO_GPAREN0) |= (1 << pin);
0212 break;
0213 case LOW_LEVEL:
0214
0215 BCM2835_REG(BCM2835_GPIO_GPLEN0) |= (1 << pin);
0216 break;
0217 case HIGH_LEVEL:
0218
0219 BCM2835_REG(BCM2835_GPIO_GPHEN0) |= (1 << pin);
0220 break;
0221 case BOTH_LEVELS:
0222
0223 BCM2835_REG(BCM2835_GPIO_GPLEN0) |= (1 << pin);
0224
0225
0226 BCM2835_REG(BCM2835_GPIO_GPHEN0) |= (1 << pin);
0227 break;
0228 case NONE:
0229 default:
0230 return RTEMS_UNSATISFIED;
0231 }
0232
0233 return RTEMS_SUCCESSFUL;
0234 }
0235
0236 rtems_status_code rtems_gpio_bsp_disable_interrupt(
0237 uint32_t bank,
0238 uint32_t pin,
0239 rtems_gpio_interrupt interrupt
0240 ) {
0241 switch ( interrupt ) {
0242 case FALLING_EDGE:
0243
0244 BCM2835_REG(BCM2835_GPIO_GPAFEN0) &= ~(1 << pin);
0245 break;
0246 case RISING_EDGE:
0247
0248 BCM2835_REG(BCM2835_GPIO_GPAREN0) &= ~(1 << pin);
0249 break;
0250 case BOTH_EDGES:
0251
0252 BCM2835_REG(BCM2835_GPIO_GPAFEN0) &= ~(1 << pin);
0253
0254
0255 BCM2835_REG(BCM2835_GPIO_GPAREN0) &= ~(1 << pin);
0256 break;
0257 case LOW_LEVEL:
0258
0259 BCM2835_REG(BCM2835_GPIO_GPLEN0) &= ~(1 << pin);
0260 break;
0261 case HIGH_LEVEL:
0262
0263 BCM2835_REG(BCM2835_GPIO_GPHEN0) &= ~(1 << pin);
0264 break;
0265 case BOTH_LEVELS:
0266
0267 BCM2835_REG(BCM2835_GPIO_GPLEN0) &= ~(1 << pin);
0268
0269
0270 BCM2835_REG(BCM2835_GPIO_GPHEN0) &= ~(1 << pin);
0271 break;
0272 case NONE:
0273 default:
0274 return RTEMS_UNSATISFIED;
0275 }
0276
0277 return RTEMS_SUCCESSFUL;
0278 }
0279
0280 rtems_status_code rpi_gpio_select_jtag(void)
0281 {
0282 return rtems_gpio_multi_select(jtag_config, JTAG_PIN_COUNT);
0283 }
0284
0285 rtems_status_code rpi_gpio_select_spi(void)
0286 {
0287 return rtems_gpio_multi_select(spi_config, SPI_PIN_COUNT);
0288 }
0289
0290 rtems_status_code rpi_gpio_select_i2c(void)
0291 {
0292 return rtems_gpio_multi_select(i2c_config, I2C_PIN_COUNT);
0293 }
0294
0295 rtems_status_code rtems_gpio_bsp_multi_select(
0296 rtems_gpio_multiple_pin_select *pins,
0297 uint32_t pin_count,
0298 uint32_t select_bank
0299 ) {
0300 uint32_t register_address;
0301 uint32_t select_register;
0302 uint8_t i;
0303
0304 register_address = BCM2835_GPIO_REGS_BASE + (select_bank * 0x04);
0305
0306 select_register = BCM2835_REG(register_address);
0307
0308 for ( i = 0; i < pin_count; ++i ) {
0309 if ( pins[i].function == DIGITAL_INPUT ) {
0310 select_register &=
0311 ~SELECT_PIN_FUNCTION(RPI_DIGITAL_IN, pins[i].pin_number);
0312 }
0313 else if ( pins[i].function == DIGITAL_OUTPUT ) {
0314 select_register |=
0315 SELECT_PIN_FUNCTION(RPI_DIGITAL_OUT, pins[i].pin_number);
0316 }
0317 else {
0318 select_register |=
0319 SELECT_PIN_FUNCTION(pins[i].io_function, pins[i].pin_number);
0320 }
0321 }
0322
0323 BCM2835_REG(register_address) = select_register;
0324
0325 return RTEMS_SUCCESSFUL;
0326 }
0327
0328 rtems_status_code rtems_gpio_bsp_specific_group_operation(
0329 uint32_t bank,
0330 uint32_t *pins,
0331 uint32_t pin_count,
0332 void *arg
0333 ) {
0334 return RTEMS_NOT_DEFINED;
0335 }