Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:22:48

0001 /**
0002  * @file
0003  *
0004  * @ingroup arm_beagle
0005  *
0006  * @brief Support for the BeagleBone Black.
0007  */
0008 
0009 /**
0010  * Copyright (c) 2015 Ketul Shah <ketulshah1993 at gmail.com>
0011  *
0012  * The license and distribution terms for this file may be
0013  * found in the file LICENSE in this distribution or at
0014  * http://www.rtems.org/license/LICENSE.
0015  */
0016 
0017 /* BSP specific function definitions for BeagleBone Black.
0018  * It is totally beased on Generic GPIO API definition. 
0019  * For more details related to GPIO API please have a 
0020  * look at libbbsp/shared/include/gpio.h
0021  */
0022 
0023 #include <bsp/beagleboneblack.h>
0024 #include <bsp/irq-generic.h>
0025 #include <bsp/gpio.h>
0026 #include <bsp/bbb-gpio.h>
0027 #include <libcpu/am335x.h>
0028 
0029 #include <assert.h>
0030 #include <stdlib.h>
0031 
0032 /* Currently these definitions are for BeagleBone Black board only
0033  * Later on Beagle-xM board support can be added in this code.
0034  * After support gets added if condition should be removed
0035  */
0036 #if IS_AM335X
0037 
0038 static const uint32_t gpio_bank_addrs[] = 
0039   { AM335X_GPIO0_BASE,
0040     AM335X_GPIO1_BASE, 
0041     AM335X_GPIO2_BASE, 
0042     AM335X_GPIO3_BASE };
0043 
0044 static const rtems_vector_number gpio_bank_vector[] =
0045   { AM335X_INT_GPIOINT0A,
0046     AM335X_INT_GPIOINT1A,
0047     AM335X_INT_GPIOINT2A,
0048     AM335X_INT_GPIOINT3A };
0049 
0050 /* Get the value of Base Register + Offset */
0051 uint32_t static inline bbb_reg(uint32_t bank, uint32_t reg)
0052 {
0053   return (gpio_bank_addrs[bank] + reg);
0054 }
0055 
0056 static rtems_status_code bbb_select_pin_function(
0057   uint32_t bank,
0058   uint32_t pin,
0059   uint32_t type
0060 ) {
0061 
0062   if ( type == BBB_DIGITAL_IN ) {
0063     mmio_set(bbb_reg(bank, AM335X_GPIO_OE), BIT(pin));
0064   } else {
0065     mmio_clear(bbb_reg(bank, AM335X_GPIO_OE), BIT(pin));
0066   }
0067 
0068   return RTEMS_SUCCESSFUL;
0069 }
0070 
0071 rtems_status_code rtems_gpio_bsp_multi_set(uint32_t bank, uint32_t bitmask)
0072 {
0073   mmio_set(bbb_reg(bank, AM335X_GPIO_SETDATAOUT), bitmask);
0074 
0075   return RTEMS_SUCCESSFUL;
0076 }
0077 
0078 rtems_status_code rtems_gpio_bsp_multi_clear(uint32_t bank, uint32_t bitmask)
0079 {
0080   mmio_set(bbb_reg(bank, AM335X_GPIO_CLEARDATAOUT), bitmask);
0081 
0082   return RTEMS_SUCCESSFUL;
0083 }
0084 
0085 uint32_t rtems_gpio_bsp_multi_read(uint32_t bank, uint32_t bitmask)
0086 {
0087   return (bbb_reg(bank, AM335X_GPIO_DATAIN) & bitmask);
0088 }
0089 
0090 rtems_status_code rtems_gpio_bsp_set(uint32_t bank, uint32_t pin)
0091 {
0092   mmio_set(bbb_reg(bank, AM335X_GPIO_SETDATAOUT), BIT(pin));
0093 
0094   return RTEMS_SUCCESSFUL;
0095 }
0096 
0097 rtems_status_code rtems_gpio_bsp_clear(uint32_t bank, uint32_t pin)
0098 {
0099   mmio_set(bbb_reg(bank, AM335X_GPIO_CLEARDATAOUT), BIT(pin));
0100 
0101   return RTEMS_SUCCESSFUL;
0102 }
0103 
0104 uint32_t rtems_gpio_bsp_get_value(uint32_t bank, uint32_t pin)
0105 {
0106   return (mmio_read(bbb_reg(bank, AM335X_GPIO_DATAIN)) & BIT(pin));
0107 }
0108 
0109 rtems_status_code rtems_gpio_bsp_select_input(
0110   uint32_t bank,
0111   uint32_t pin,
0112   void *bsp_specific
0113 ) {
0114   return bbb_select_pin_function(bank, pin, BBB_DIGITAL_IN);
0115 }
0116 
0117 rtems_status_code rtems_gpio_bsp_select_output(
0118   uint32_t bank,
0119   uint32_t pin,
0120   void *bsp_specific
0121 ) {
0122   return bbb_select_pin_function(bank, pin, BBB_DIGITAL_OUT);
0123 }
0124 
0125 rtems_status_code rtems_gpio_bsp_select_specific_io(
0126   uint32_t bank,
0127   uint32_t pin,
0128   uint32_t function,
0129   void *pin_data
0130 ) {
0131   return RTEMS_NOT_DEFINED;
0132 }
0133 
0134 rtems_status_code rtems_gpio_bsp_set_resistor_mode(
0135   uint32_t bank,
0136   uint32_t pin,
0137   rtems_gpio_pull_mode mode
0138 ) {
0139   /* TODO: Add support for setting up resistor mode */
0140   return RTEMS_NOT_DEFINED;
0141 }
0142 
0143 rtems_vector_number rtems_gpio_bsp_get_vector(uint32_t bank)
0144 {
0145   return gpio_bank_vector[bank];
0146 }
0147 
0148 uint32_t rtems_gpio_bsp_interrupt_line(rtems_vector_number vector)
0149 {
0150   uint32_t event_status;
0151   uint8_t bank_nr = 0;
0152 
0153   /* Following loop will get the bank number from vector number */
0154   while (bank_nr < GPIO_BANK_COUNT && vector != gpio_bank_vector[bank_nr])
0155   {
0156     bank_nr++;
0157   }
0158 
0159   /* Retrieve the interrupt event status. */
0160   event_status = mmio_read(bbb_reg(bank_nr, AM335X_GPIO_IRQSTATUS_0));
0161 
0162   /* Clear the interrupt line. */
0163   mmio_write(
0164     (bbb_reg(bank_nr, AM335X_GPIO_IRQSTATUS_0)), event_status);
0165   
0166   return event_status;
0167 }
0168 
0169 rtems_status_code rtems_gpio_bsp_enable_interrupt(
0170   uint32_t bank,
0171   uint32_t pin,
0172   rtems_gpio_interrupt interrupt
0173 ) {
0174   
0175   /* Enable IRQ generation for the specific pin */
0176   mmio_set(bbb_reg(bank, AM335X_GPIO_IRQSTATUS_SET_0), BIT(pin));
0177   
0178   switch ( interrupt ) {
0179     case FALLING_EDGE:
0180       /* Enables asynchronous falling edge detection. */
0181       mmio_set(bbb_reg(bank, AM335X_GPIO_FALLINGDETECT), BIT(pin));
0182       break;
0183     case RISING_EDGE:
0184       /* Enables asynchronous rising edge detection. */
0185       mmio_set(bbb_reg(bank, AM335X_GPIO_RISINGDETECT), BIT(pin));
0186       break;
0187     case BOTH_EDGES:
0188       /* Enables asynchronous falling edge detection. */
0189       mmio_set(bbb_reg(bank, AM335X_GPIO_FALLINGDETECT), BIT(pin));
0190 
0191       /* Enables asynchronous rising edge detection. */
0192       mmio_set(bbb_reg(bank, AM335X_GPIO_RISINGDETECT), BIT(pin));
0193       break;
0194     case LOW_LEVEL:
0195       /* Enables pin low level detection. */
0196       mmio_set(bbb_reg(bank, AM335X_GPIO_LEVELDETECT0), BIT(pin));
0197       break;
0198     case HIGH_LEVEL:
0199        /* Enables pin high level detection. */
0200       mmio_set(bbb_reg(bank, AM335X_GPIO_LEVELDETECT1), BIT(pin));
0201       break;
0202     case BOTH_LEVELS:
0203       /* Enables pin low level detection. */
0204       mmio_set(bbb_reg(bank, AM335X_GPIO_LEVELDETECT0), BIT(pin));
0205 
0206       /* Enables pin high level detection. */
0207       mmio_set(bbb_reg(bank, AM335X_GPIO_LEVELDETECT1), BIT(pin));
0208       break;
0209     case NONE:
0210     default:
0211       return RTEMS_UNSATISFIED;
0212   }
0213 
0214   /* The detection starts after 5 clock cycles as per AM335X TRM
0215    * This period is required to clean the synchronization edge/
0216    * level detection pipeline
0217    */
0218   asm volatile("nop"); asm volatile("nop"); asm volatile("nop");
0219   asm volatile("nop"); asm volatile("nop");
0220   
0221   return RTEMS_SUCCESSFUL;
0222 }
0223 
0224 rtems_status_code rtems_gpio_bsp_disable_interrupt(
0225   uint32_t bank,
0226   uint32_t pin,
0227   rtems_gpio_interrupt interrupt
0228 ) {
0229   /* Clear IRQ generation for the specific pin */
0230   mmio_write(bbb_reg(bank, AM335X_GPIO_IRQSTATUS_CLR_0), BIT(pin));
0231 
0232   switch ( interrupt ) {
0233     case FALLING_EDGE:
0234       /* Disables asynchronous falling edge detection. */
0235       mmio_clear(bbb_reg(bank, AM335X_GPIO_FALLINGDETECT), BIT(pin));
0236       break;
0237     case RISING_EDGE:
0238       /* Disables asynchronous rising edge detection. */
0239       mmio_clear(bbb_reg(bank, AM335X_GPIO_RISINGDETECT), BIT(pin));
0240       break;
0241     case BOTH_EDGES:
0242       /* Disables asynchronous falling edge detection. */
0243       mmio_clear(bbb_reg(bank, AM335X_GPIO_FALLINGDETECT), BIT(pin));
0244 
0245       /* Disables asynchronous rising edge detection. */
0246       mmio_clear(bbb_reg(bank, AM335X_GPIO_RISINGDETECT), BIT(pin));
0247       break;
0248     case LOW_LEVEL:
0249       /* Disables pin low level detection. */
0250       mmio_clear(bbb_reg(bank, AM335X_GPIO_LEVELDETECT0), BIT(pin));
0251       break;
0252     case HIGH_LEVEL:
0253       /* Disables pin high level detection. */
0254        mmio_clear(bbb_reg(bank, AM335X_GPIO_LEVELDETECT1), BIT(pin));
0255       break;
0256     case BOTH_LEVELS:
0257       /* Disables pin low level detection. */
0258       mmio_clear(bbb_reg(bank, AM335X_GPIO_LEVELDETECT0), BIT(pin));
0259 
0260       /* Disables pin high level detection. */
0261       mmio_clear(bbb_reg(bank, AM335X_GPIO_LEVELDETECT1), BIT(pin));
0262       break;
0263     case NONE:
0264     default:
0265       return RTEMS_UNSATISFIED;
0266   }
0267 
0268   /* The detection starts after 5 clock cycles as per AM335X TRM
0269    * This period is required to clean the synchronization edge/
0270    * level detection pipeline
0271    */
0272   asm volatile("nop"); asm volatile("nop"); asm volatile("nop");
0273   asm volatile("nop"); asm volatile("nop");
0274 
0275   return RTEMS_SUCCESSFUL;
0276 }
0277 
0278 rtems_status_code rtems_gpio_bsp_multi_select(
0279   rtems_gpio_multiple_pin_select *pins,
0280   uint32_t pin_count,
0281   uint32_t select_bank
0282 ) {
0283   uint32_t register_address;
0284   uint32_t select_register;
0285   uint8_t i;
0286 
0287   register_address = gpio_bank_addrs[select_bank] + AM335X_GPIO_OE;
0288 
0289   select_register = REG(register_address);
0290 
0291   for ( i = 0; i < pin_count; ++i ) {
0292     if ( pins[i].function == DIGITAL_INPUT ) {
0293       select_register |= BIT(pins[i].pin_number);
0294     } else if ( pins[i].function == DIGITAL_OUTPUT ) {
0295       select_register &= ~BIT(pins[i].pin_number);
0296     } else { /* BSP_SPECIFIC function. */
0297       return RTEMS_NOT_DEFINED;
0298     }
0299   }
0300 
0301   REG(register_address) = select_register;
0302 
0303   return RTEMS_SUCCESSFUL;
0304 }
0305 
0306 rtems_status_code rtems_gpio_bsp_specific_group_operation(
0307   uint32_t bank,
0308   uint32_t *pins,
0309   uint32_t pin_count,
0310   void *arg
0311 ) {
0312   return RTEMS_NOT_DEFINED;
0313 }
0314 
0315 #endif /* IS_AM335X */
0316 
0317 /* For support of BeagleboardxM */
0318 #if IS_DM3730
0319 
0320 /* Currently this section is just to satisfy
0321  * GPIO API and to make the build successful.
0322  * Later on support can be added here.
0323  */
0324 
0325 rtems_status_code rtems_gpio_bsp_multi_set(uint32_t bank, uint32_t bitmask)
0326 {
0327   return RTEMS_NOT_DEFINED;
0328 }
0329 
0330 rtems_status_code rtems_gpio_bsp_multi_clear(uint32_t bank, uint32_t bitmask)
0331 {
0332   return RTEMS_NOT_DEFINED;
0333 }
0334 
0335 uint32_t rtems_gpio_bsp_multi_read(uint32_t bank, uint32_t bitmask)
0336 {
0337   return -1;
0338 }
0339 
0340 rtems_status_code rtems_gpio_bsp_set(uint32_t bank, uint32_t pin)
0341 {
0342   return RTEMS_NOT_DEFINED;
0343 }
0344 
0345 rtems_status_code rtems_gpio_bsp_clear(uint32_t bank, uint32_t pin)
0346 {
0347   return RTEMS_NOT_DEFINED;
0348 }
0349 
0350 uint32_t rtems_gpio_bsp_get_value(uint32_t bank, uint32_t pin)
0351 {
0352   return -1;
0353 }
0354 
0355 rtems_status_code rtems_gpio_bsp_select_input(
0356   uint32_t bank,
0357   uint32_t pin,
0358   void *bsp_specific
0359 ) {
0360   return RTEMS_NOT_DEFINED;
0361 }
0362 
0363 rtems_status_code rtems_gpio_bsp_select_output(
0364   uint32_t bank,
0365   uint32_t pin,
0366   void *bsp_specific
0367 ) {
0368   return RTEMS_NOT_DEFINED;
0369 }
0370 
0371 rtems_status_code rtems_gpio_bsp_select_specific_io(
0372   uint32_t bank,
0373   uint32_t pin,
0374   uint32_t function,
0375   void *pin_data
0376 ) {
0377   return RTEMS_NOT_DEFINED;
0378 }
0379 
0380 rtems_status_code rtems_gpio_bsp_set_resistor_mode(
0381   uint32_t bank,
0382   uint32_t pin,
0383   rtems_gpio_pull_mode mode
0384 ) {
0385   return RTEMS_NOT_DEFINED;
0386 }
0387 
0388 rtems_vector_number rtems_gpio_bsp_get_vector(uint32_t bank)
0389 {
0390   return -1;
0391 }
0392 
0393 uint32_t rtems_gpio_bsp_interrupt_line(rtems_vector_number vector)
0394 {
0395   return -1;
0396 }
0397 
0398 rtems_status_code rtems_gpio_bsp_enable_interrupt(
0399   uint32_t bank,
0400   uint32_t pin,
0401   rtems_gpio_interrupt interrupt
0402 ) {
0403   return RTEMS_NOT_DEFINED;
0404 }
0405 
0406 rtems_status_code rtems_gpio_bsp_disable_interrupt(
0407   uint32_t bank,
0408   uint32_t pin,
0409   rtems_gpio_interrupt interrupt
0410 ) {
0411   return RTEMS_NOT_DEFINED;
0412 }
0413 
0414 rtems_status_code rtems_gpio_bsp_multi_select(
0415   rtems_gpio_multiple_pin_select *pins,
0416   uint32_t pin_count,
0417   uint32_t select_bank
0418 ) {
0419   return RTEMS_NOT_DEFINED;
0420 }
0421 
0422 rtems_status_code rtems_gpio_bsp_specific_group_operation(
0423   uint32_t bank,
0424   uint32_t *pins,
0425   uint32_t pin_count,
0426   void *arg
0427 ) {
0428   return RTEMS_NOT_DEFINED;
0429 }
0430 
0431 #endif /* IS_DM3730 */