File indexing completed on 2025-05-11 08:24:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <rtems/score/atomic.h>
0018 #include <rtems/chain.h>
0019 #include <bsp/irq-generic.h>
0020 #include <bsp/gpio.h>
0021 #include <assert.h>
0022 #include <stdlib.h>
0023
0024
0025
0026
0027 #define MUTEX_ATTRIBUTES ( \
0028 RTEMS_LOCAL \
0029 | RTEMS_PRIORITY \
0030 | RTEMS_BINARY_SEMAPHORE \
0031 | RTEMS_INHERIT_PRIORITY \
0032 | RTEMS_NO_PRIORITY_CEILING \
0033 )
0034
0035 #define CREATE_LOCK(name, lock_id) rtems_semaphore_create( \
0036 name, \
0037 1, \
0038 MUTEX_ATTRIBUTES, \
0039 0, \
0040 lock_id \
0041 )
0042
0043 #define ACQUIRE_LOCK(m) assert ( rtems_semaphore_obtain(m, \
0044 RTEMS_WAIT, \
0045 RTEMS_NO_TIMEOUT \
0046 ) == RTEMS_SUCCESSFUL )
0047
0048 #define RELEASE_LOCK(m) assert ( rtems_semaphore_release(m) == RTEMS_SUCCESSFUL )
0049
0050
0051
0052
0053
0054
0055 struct rtems_gpio_group
0056 {
0057 rtems_chain_node node;
0058
0059 uint32_t *digital_inputs;
0060 uint32_t digital_input_bank;
0061 uint32_t input_count;
0062
0063 uint32_t *digital_outputs;
0064 uint32_t digital_output_bank;
0065 uint32_t output_count;
0066
0067 uint32_t *bsp_speficifc_pins;
0068 uint32_t bsp_specific_bank;
0069 uint32_t bsp_specific_pin_count;
0070
0071 rtems_id group_lock;
0072 };
0073
0074
0075
0076
0077
0078
0079
0080 typedef struct
0081 {
0082 rtems_chain_node node;
0083
0084
0085 rtems_gpio_irq_state (*handler) (void *arg);
0086
0087
0088 void *arg;
0089 } gpio_handler_node;
0090
0091
0092
0093
0094
0095
0096
0097 typedef struct
0098 {
0099
0100 rtems_gpio_interrupt active_interrupt;
0101
0102
0103 rtems_gpio_handler_flag handler_flag;
0104
0105
0106 rtems_chain_control handler_chain;
0107
0108
0109 uint32_t debouncing_tick_count;
0110 rtems_interval last_isr_tick;
0111 } gpio_pin_interrupt_state;
0112
0113
0114
0115
0116
0117
0118 typedef struct
0119 {
0120 rtems_gpio_function pin_function;
0121
0122
0123 rtems_gpio_pull_mode resistor_mode;
0124
0125
0126 bool logic_invert;
0127
0128
0129 bool on_group;
0130
0131
0132
0133 gpio_pin_interrupt_state *interrupt_state;
0134 } gpio_pin;
0135
0136
0137
0138
0139
0140
0141 typedef struct
0142 {
0143 uint32_t bank_number;
0144 uint32_t interrupt_counter;
0145 rtems_id lock;
0146
0147
0148
0149
0150 bool threaded_interrupts;
0151 } gpio_bank;
0152
0153 static gpio_pin gpio_pin_state[BSP_GPIO_PIN_COUNT];
0154 static Atomic_Flag init_flag = ATOMIC_INITIALIZER_FLAG;
0155 static gpio_bank gpio_bank_state[GPIO_BANK_COUNT];
0156 static Atomic_Uint threaded_interrupt_counter = ATOMIC_INITIALIZER_UINT(0);
0157 static rtems_chain_control gpio_group;
0158
0159 #define BANK_NUMBER(pin_number) pin_number / BSP_GPIO_PINS_PER_BANK
0160 #define PIN_NUMBER(pin_number) pin_number % BSP_GPIO_PINS_PER_BANK
0161
0162 static int debounce_switch(gpio_pin_interrupt_state *interrupt_state)
0163 {
0164 rtems_interval time;
0165
0166 time = rtems_clock_get_ticks_since_boot();
0167
0168
0169 if (
0170 (time - interrupt_state->last_isr_tick) <
0171 interrupt_state->debouncing_tick_count
0172 ) {
0173 return -1;
0174 }
0175
0176 interrupt_state->last_isr_tick = time;
0177
0178 return 0;
0179 }
0180
0181
0182 static uint32_t get_bank_pin_count(uint32_t bank)
0183 {
0184
0185 if ( bank == GPIO_BANK_COUNT - 1 ) {
0186 return GPIO_LAST_BANK_PINS;
0187 }
0188
0189 return BSP_GPIO_PINS_PER_BANK;
0190 }
0191
0192
0193
0194
0195 static void generic_bank_isr(void *arg)
0196 {
0197 gpio_pin_interrupt_state *interrupt_state;
0198 rtems_chain_control *handler_list;
0199 rtems_chain_node *node;
0200 rtems_chain_node *next_node;
0201 gpio_handler_node *isr_node;
0202 rtems_vector_number vector;
0203 uint32_t event_status;
0204 uint32_t bank_number;
0205 uint32_t bank_start_pin;
0206 uint8_t handled_count;
0207 uint8_t rv;
0208 uint8_t i;
0209
0210 bank_number = *((uint32_t*) arg);
0211
0212 assert ( bank_number >= 0 && bank_number < GPIO_BANK_COUNT );
0213
0214
0215 bank_start_pin = bank_number * BSP_GPIO_PINS_PER_BANK;
0216
0217 vector = rtems_gpio_bsp_get_vector(bank_number);
0218
0219
0220
0221 if ( gpio_bank_state[bank_number].threaded_interrupts == false ) {
0222
0223 bsp_interrupt_vector_disable(vector);
0224 }
0225
0226
0227
0228 event_status = rtems_gpio_bsp_interrupt_line(vector);
0229
0230
0231
0232 for ( i = 0; i < get_bank_pin_count(bank_number); ++i ) {
0233
0234 if ( event_status & (1 << i) ) {
0235 interrupt_state = gpio_pin_state[bank_start_pin + i].interrupt_state;
0236
0237 assert ( interrupt_state != NULL );
0238
0239 handled_count = 0;
0240
0241 if ( gpio_bank_state[bank_number].threaded_interrupts ) {
0242 ACQUIRE_LOCK(gpio_bank_state[bank_number].lock);
0243 }
0244
0245
0246 if ( interrupt_state->debouncing_tick_count > 0 ) {
0247 rv = debounce_switch(interrupt_state);
0248
0249
0250
0251 if ( rv < 0 ) {
0252 if ( gpio_bank_state[bank_number].threaded_interrupts ) {
0253 RELEASE_LOCK(gpio_bank_state[bank_number].lock);
0254 }
0255
0256 continue;
0257 }
0258 }
0259
0260 handler_list = &interrupt_state->handler_chain;
0261
0262 node = rtems_chain_first(handler_list);
0263
0264
0265 while ( !rtems_chain_is_tail(handler_list, node) ) {
0266 isr_node = (gpio_handler_node *) node;
0267
0268 next_node = node->next;
0269
0270 if ( (isr_node->handler)(isr_node->arg) == IRQ_HANDLED ) {
0271 ++handled_count;
0272 }
0273
0274 node = next_node;
0275 }
0276
0277
0278
0279 if ( handled_count == 0 ) {
0280 bsp_interrupt_handler_default(rtems_gpio_bsp_get_vector(bank_number));
0281 }
0282
0283 if ( gpio_bank_state[bank_number].threaded_interrupts ) {
0284 RELEASE_LOCK(gpio_bank_state[bank_number].lock);
0285 }
0286 }
0287 }
0288
0289 if ( gpio_bank_state[bank_number].threaded_interrupts == false ) {
0290 bsp_interrupt_vector_enable(vector);
0291 }
0292 }
0293
0294
0295
0296 static rtems_status_code get_pin_bitmask(
0297 uint32_t *pins,
0298 uint32_t pin_count,
0299 uint32_t *bank_number,
0300 uint32_t *bitmask,
0301 rtems_gpio_function function
0302 ) {
0303 uint32_t pin_number;
0304 uint32_t bank;
0305 uint8_t i;
0306
0307 if ( pin_count < 1 ) {
0308 return RTEMS_UNSATISFIED;
0309 }
0310
0311 *bitmask = 0;
0312
0313 for ( i = 0; i < pin_count; ++i ) {
0314 pin_number = pins[i];
0315
0316 if ( pin_number < 0 || pin_number >= BSP_GPIO_PIN_COUNT ) {
0317 return RTEMS_INVALID_ID;
0318 }
0319
0320 bank = BANK_NUMBER(pin_number);
0321
0322 if ( i == 0 ) {
0323 *bank_number = bank;
0324
0325 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
0326 }
0327 else if ( bank != *bank_number ) {
0328 RELEASE_LOCK(gpio_bank_state[*bank_number].lock);
0329
0330 return RTEMS_UNSATISFIED;
0331 }
0332
0333 if (
0334 gpio_pin_state[pin_number].pin_function != function ||
0335 gpio_pin_state[pin_number].on_group
0336 ) {
0337 RELEASE_LOCK(gpio_bank_state[bank].lock);
0338
0339 return RTEMS_NOT_CONFIGURED;
0340 }
0341
0342 *bitmask |= (1 << PIN_NUMBER(pin_number));
0343 }
0344
0345 RELEASE_LOCK(gpio_bank_state[bank].lock);
0346
0347 return RTEMS_SUCCESSFUL;
0348 }
0349
0350 static rtems_status_code check_same_bank_and_availability(
0351 const rtems_gpio_pin_conf *pin_confs,
0352 uint32_t pin_count,
0353 uint32_t *bank_number,
0354 uint32_t *pins
0355 ) {
0356 uint32_t pin_number;
0357 uint32_t bank;
0358 uint8_t i;
0359
0360 for ( i = 0; i < pin_count; ++i ) {
0361 pin_number = pin_confs[i].pin_number;
0362
0363 bank = BANK_NUMBER(pin_number);
0364
0365 if ( i == 0 ) {
0366 *bank_number = bank;
0367
0368 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
0369 }
0370 else if ( bank != *bank_number ) {
0371 RELEASE_LOCK(gpio_bank_state[*bank_number].lock);
0372
0373 return RTEMS_UNSATISFIED;
0374 }
0375
0376 if ( gpio_pin_state[pin_number].pin_function != NOT_USED ) {
0377 RELEASE_LOCK(gpio_bank_state[bank].lock);
0378
0379 return RTEMS_RESOURCE_IN_USE;
0380 }
0381
0382 pins[i] = PIN_NUMBER(pin_number);
0383 }
0384
0385 RELEASE_LOCK(gpio_bank_state[*bank_number].lock);
0386
0387 return RTEMS_SUCCESSFUL;
0388 }
0389
0390 static rtems_status_code setup_resistor_and_interrupt_configuration(
0391 uint32_t pin_number,
0392 rtems_gpio_pull_mode pull_mode,
0393 rtems_gpio_interrupt_configuration *interrupt_conf
0394 ) {
0395 gpio_pin_interrupt_state *interrupt_state;
0396 rtems_status_code sc;
0397 uint32_t bank;
0398
0399 sc = rtems_gpio_resistor_mode(pin_number, pull_mode);
0400
0401 if ( sc != RTEMS_SUCCESSFUL ) {
0402 #if defined(DEBUG)
0403 printk("rtems_gpio_resistor_mode failed with status code %d\n", sc);
0404 #endif
0405
0406 return RTEMS_UNSATISFIED;
0407 }
0408
0409 if ( interrupt_conf != NULL ) {
0410 bank = BANK_NUMBER(pin_number);
0411
0412 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
0413
0414 sc = rtems_gpio_enable_interrupt(
0415 pin_number,
0416 interrupt_conf->active_interrupt,
0417 interrupt_conf->handler_flag,
0418 interrupt_conf->threaded_interrupts,
0419 interrupt_conf->handler,
0420 interrupt_conf->arg
0421 );
0422
0423 if ( sc != RTEMS_SUCCESSFUL ) {
0424 RELEASE_LOCK(gpio_bank_state[bank].lock);
0425
0426 #if defined(DEBUG)
0427 printk(
0428 "rtems_gpio_enable_interrupt failed with status code %d\n",
0429 sc
0430 );
0431 #endif
0432
0433 return RTEMS_UNSATISFIED;
0434 }
0435
0436 interrupt_state = gpio_pin_state[pin_number].interrupt_state;
0437
0438 interrupt_state->debouncing_tick_count =
0439 interrupt_conf->debounce_clock_tick_interval;
0440
0441 interrupt_state->last_isr_tick = 0;
0442
0443 RELEASE_LOCK(gpio_bank_state[bank].lock);
0444 }
0445
0446 return RTEMS_SUCCESSFUL;
0447 }
0448
0449 static rtems_status_code gpio_multi_select(
0450 const rtems_gpio_pin_conf *pins,
0451 uint8_t pin_count,
0452 bool on_group
0453 ) {
0454 rtems_status_code sc;
0455 uint32_t pin_number;
0456 uint32_t bank;
0457 uint8_t i;
0458
0459
0460 #ifdef BSP_GPIO_PINS_PER_SELECT_BANK
0461 rtems_gpio_multiple_pin_select
0462 pin_data[GPIO_SELECT_BANK_COUNT][BSP_GPIO_PINS_PER_SELECT_BANK];
0463 rtems_gpio_specific_data *bsp_data;
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473 uint32_t select_bank;
0474 uint32_t bank_number;
0475 uint32_t select_bank_counter[GPIO_SELECT_BANK_COUNT];
0476 uint32_t select_count;
0477 uint32_t pin;
0478
0479 if ( pin_count == 0 ) {
0480 return RTEMS_SUCCESSFUL;
0481 }
0482
0483 for ( i = 0; i < GPIO_SELECT_BANK_COUNT; ++i ) {
0484 select_bank_counter[i] = 0;
0485 }
0486
0487 for ( i = 0; i < pin_count; ++i ) {
0488 pin_number = pins[i].pin_number;
0489
0490 if ( pin_number < 0 || pin_number >= BSP_GPIO_PIN_COUNT ) {
0491 return RTEMS_INVALID_ID;
0492 }
0493
0494 bank = BANK_NUMBER(pin_number);
0495 pin = PIN_NUMBER(pin_number);
0496
0497 if ( i == 0 ) {
0498 bank_number = bank;
0499
0500 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
0501 }
0502 else if ( bank != bank_number ) {
0503 RELEASE_LOCK(gpio_bank_state[bank_number].lock);
0504
0505 return RTEMS_UNSATISFIED;
0506 }
0507
0508
0509 if ( gpio_pin_state[pin_number].pin_function != NOT_USED ) {
0510 RELEASE_LOCK(gpio_bank_state[bank_number].lock);
0511
0512 return RTEMS_RESOURCE_IN_USE;
0513 }
0514
0515 select_bank = (pin_number / BSP_GPIO_PINS_PER_SELECT_BANK) -
0516 (bank * GPIO_SELECT_BANK_COUNT);
0517
0518 select_count = select_bank_counter[select_bank];
0519
0520 pin_data[select_bank][select_count].pin_number = pin_number;
0521 pin_data[select_bank][select_count].function = pins[i].function;
0522
0523 if ( pins[i].function == BSP_SPECIFIC ) {
0524 bsp_data = (rtems_gpio_specific_data *) pins[i].bsp_specific;
0525
0526 if ( bsp_data == NULL ) {
0527 RELEASE_LOCK(gpio_bank_state[bank_number].lock);
0528
0529 return RTEMS_UNSATISFIED;
0530 }
0531
0532 pin_data[select_bank][select_count].io_function = bsp_data->io_function;
0533 pin_data[select_bank][select_count].bsp_specific = bsp_data->pin_data;
0534 }
0535 else {
0536
0537 pin_data[select_bank][select_count].io_function = 0;
0538 pin_data[select_bank][select_count].bsp_specific = pins[i].bsp_specific;
0539 }
0540
0541 ++select_bank_counter[select_bank];
0542 }
0543
0544 for ( i = 0; i < GPIO_SELECT_BANK_COUNT; ++i ) {
0545 if ( select_bank_counter[i] == 0 ) {
0546 continue;
0547 }
0548
0549 sc = rtems_gpio_bsp_multi_select(
0550 pin_data[i], select_bank_counter[i], i +
0551 (bank_number * GPIO_SELECT_BANK_COUNT)
0552 );
0553
0554 if ( sc != RTEMS_SUCCESSFUL ) {
0555 RELEASE_LOCK(gpio_bank_state[bank_number].lock);
0556
0557 return sc;
0558 }
0559 }
0560
0561 for ( i = 0; i < pin_count; ++i ) {
0562 pin_number = pins[i].pin_number;
0563
0564
0565 gpio_pin_state[pin_number].pin_function = pins[i].function;
0566 gpio_pin_state[pin_number].logic_invert = pins[i].logic_invert;
0567 gpio_pin_state[pin_number].on_group = on_group;
0568
0569 sc = setup_resistor_and_interrupt_configuration(
0570 pin_number,
0571 pins[i].pull_mode,
0572 pins[i].interrupt
0573 );
0574
0575 if ( sc != RTEMS_SUCCESSFUL ) {
0576 RELEASE_LOCK(gpio_bank_state[bank_number].lock);
0577
0578 return sc;
0579 }
0580
0581 bank = BANK_NUMBER(pin_number);
0582 pin = PIN_NUMBER(pin_number);
0583
0584 if ( pins[i].function == DIGITAL_OUTPUT ) {
0585 if ( pins[i].output_enabled == true ) {
0586 sc = rtems_gpio_bsp_set(bank, pin);
0587 }
0588 else {
0589 sc = rtems_gpio_bsp_clear(bank, pin);
0590 }
0591
0592 if ( sc != RTEMS_SUCCESSFUL ) {
0593 RELEASE_LOCK(gpio_bank_state[bank_number].lock);
0594
0595 return sc;
0596 }
0597 }
0598 }
0599
0600 RELEASE_LOCK(gpio_bank_state[bank_number].lock);
0601
0602 return sc;
0603
0604
0605
0606 #else
0607 for ( i = 0; i < pin_count; ++i ) {
0608 pin_number = pins[i].pin_number;
0609
0610 if ( pin_number < 0 || pin_number >= BSP_GPIO_PIN_COUNT ) {
0611 return RTEMS_INVALID_ID;
0612 }
0613
0614 bank = BANK_NUMBER(pin_number);
0615
0616 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
0617
0618
0619 if ( gpio_pin_state[pin_number].pin_function != NOT_USED ) {
0620 RELEASE_LOCK(gpio_bank_state[bank].lock);
0621
0622 return RTEMS_RESOURCE_IN_USE;
0623 }
0624 }
0625
0626 for ( i = 0; i < pin_count; ++i ) {
0627 sc = rtems_gpio_request_configuration(&pins[i]);
0628
0629 if ( sc != RTEMS_SUCCESSFUL ) {
0630 return sc;
0631 }
0632
0633 gpio_pin_state[pins[i].pin_number].on_group = on_group;
0634 }
0635
0636 return RTEMS_SUCCESSFUL;
0637 #endif
0638 }
0639
0640 rtems_status_code rtems_gpio_initialize(void)
0641 {
0642 rtems_status_code sc;
0643 uint32_t i;
0644
0645 if ( _Atomic_Flag_test_and_set(&init_flag, ATOMIC_ORDER_RELAXED) == true ) {
0646 return RTEMS_SUCCESSFUL;
0647 }
0648
0649 for ( i = 0; i < GPIO_BANK_COUNT; ++i ) {
0650 sc = CREATE_LOCK(
0651 rtems_build_name('G', 'I', 'N', 'T'),
0652 &gpio_bank_state[i].lock
0653 );
0654
0655 if ( sc != RTEMS_SUCCESSFUL ) {
0656 return sc;
0657 }
0658
0659 gpio_bank_state[i].bank_number = i;
0660 gpio_bank_state[i].interrupt_counter = 0;
0661
0662
0663
0664 }
0665
0666 for ( i = 0; i < BSP_GPIO_PIN_COUNT; ++i ) {
0667 gpio_pin_state[i].pin_function = NOT_USED;
0668 gpio_pin_state[i].resistor_mode = NO_PULL_RESISTOR;
0669 gpio_pin_state[i].logic_invert = false;
0670 gpio_pin_state[i].on_group = false;
0671 gpio_pin_state[i].interrupt_state = NULL;
0672 }
0673
0674
0675 rtems_chain_initialize_empty(&gpio_group);
0676
0677 return RTEMS_SUCCESSFUL;
0678 }
0679
0680 rtems_gpio_group *rtems_gpio_create_pin_group(void)
0681 {
0682 struct rtems_gpio_group *group;
0683
0684 group = (struct rtems_gpio_group *) malloc(sizeof(struct rtems_gpio_group));
0685
0686 return group;
0687 }
0688
0689 rtems_status_code rtems_gpio_define_pin_group(
0690 const rtems_gpio_group_definition *group_definition,
0691 rtems_gpio_group *group
0692 ) {
0693 rtems_status_code sc;
0694
0695 if ( group_definition == NULL || group == NULL ) {
0696 return RTEMS_UNSATISFIED;
0697 }
0698
0699 if (
0700 group_definition->input_count == 0 &&
0701 group_definition->output_count == 0 &&
0702 group_definition->bsp_specific_pin_count == 0
0703 ) {
0704 return RTEMS_UNSATISFIED;
0705 }
0706
0707 group->input_count = group_definition->input_count;
0708
0709 if ( group->input_count > 0 ) {
0710 group->digital_inputs =
0711 (uint32_t *) malloc(group->input_count * sizeof(uint32_t));
0712
0713
0714
0715
0716 sc = check_same_bank_and_availability(
0717 group_definition->digital_inputs,
0718 group->input_count,
0719 &group->digital_input_bank,
0720 group->digital_inputs
0721 );
0722
0723 if ( sc != RTEMS_SUCCESSFUL ) {
0724 return sc;
0725 }
0726 }
0727 else {
0728 group->digital_inputs = NULL;
0729 }
0730
0731 group->output_count = group_definition->output_count;
0732
0733 if ( group->output_count > 0 ) {
0734 group->digital_outputs =
0735 (uint32_t *) malloc(group->output_count * sizeof(uint32_t));
0736
0737 sc = check_same_bank_and_availability(
0738 group_definition->digital_outputs,
0739 group->output_count,
0740 &group->digital_output_bank,
0741 group->digital_outputs
0742 );
0743
0744 if ( sc != RTEMS_SUCCESSFUL ) {
0745 return sc;
0746 }
0747 }
0748 else {
0749 group->digital_outputs = NULL;
0750 }
0751
0752 group->bsp_specific_pin_count = group_definition->bsp_specific_pin_count;
0753
0754 if ( group->bsp_specific_pin_count > 0 ) {
0755 group->bsp_speficifc_pins =
0756 (uint32_t *) malloc(
0757 group->bsp_specific_pin_count *
0758 sizeof(uint32_t)
0759 );
0760
0761 sc = check_same_bank_and_availability(
0762 group_definition->bsp_specifics,
0763 group->bsp_specific_pin_count,
0764 &group->bsp_specific_bank,
0765 group->bsp_speficifc_pins
0766 );
0767
0768 if ( sc != RTEMS_SUCCESSFUL ) {
0769 return sc;
0770 }
0771 }
0772 else {
0773 group->bsp_speficifc_pins = NULL;
0774 }
0775
0776
0777 sc = gpio_multi_select(
0778 group_definition->digital_inputs,
0779 group_definition->input_count,
0780 true
0781 );
0782
0783 if ( sc != RTEMS_SUCCESSFUL ) {
0784 return RTEMS_UNSATISFIED;
0785 }
0786
0787 sc = gpio_multi_select(
0788 group_definition->digital_outputs,
0789 group_definition->output_count,
0790 true
0791 );
0792
0793 if ( sc != RTEMS_SUCCESSFUL ) {
0794 sc = rtems_gpio_release_multiple_pins(
0795 group_definition->digital_inputs,
0796 group_definition->input_count
0797 );
0798
0799 assert ( sc == RTEMS_SUCCESSFUL );
0800
0801 return RTEMS_UNSATISFIED;
0802 }
0803
0804 sc = gpio_multi_select(
0805 group_definition->bsp_specifics,
0806 group_definition->bsp_specific_pin_count,
0807 true
0808 );
0809
0810 if ( sc != RTEMS_SUCCESSFUL ) {
0811 sc = rtems_gpio_release_multiple_pins(
0812 group_definition->digital_inputs,
0813 group_definition->input_count
0814 );
0815
0816 assert ( sc == RTEMS_SUCCESSFUL );
0817
0818 sc = rtems_gpio_release_multiple_pins(
0819 group_definition->digital_outputs,
0820 group_definition->output_count
0821 );
0822
0823 assert ( sc == RTEMS_SUCCESSFUL );
0824
0825 return RTEMS_UNSATISFIED;
0826 }
0827
0828
0829 sc = CREATE_LOCK(rtems_build_name('G', 'R', 'P', 'L'), &group->group_lock);
0830
0831 if ( sc != RTEMS_SUCCESSFUL ) {
0832 return sc;
0833 }
0834
0835 rtems_chain_append(&gpio_group, &group->node);
0836
0837 return RTEMS_SUCCESSFUL;
0838 }
0839
0840 rtems_status_code rtems_gpio_write_group(uint32_t data, rtems_gpio_group *group)
0841 {
0842 rtems_status_code sc = RTEMS_SUCCESSFUL;
0843 uint32_t set_bitmask;
0844 uint32_t clear_bitmask;
0845 uint32_t bank;
0846 uint32_t pin;
0847 uint8_t i;
0848
0849 if ( group->output_count == 0 ) {
0850 return RTEMS_NOT_DEFINED;
0851 }
0852
0853 bank = group->digital_output_bank;
0854
0855
0856 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
0857
0858
0859 ACQUIRE_LOCK(group->group_lock);
0860
0861 set_bitmask = 0;
0862 clear_bitmask = 0;
0863
0864 for ( i = 0; i < group->output_count; ++i ) {
0865 pin = group->digital_outputs[i];
0866
0867 if ( (data & (1 << i)) == 0 ) {
0868 clear_bitmask |= (1 << pin);
0869 }
0870 else {
0871 set_bitmask |= (1 << pin);
0872 }
0873 }
0874
0875
0876 if ( set_bitmask > 0 ) {
0877 sc = rtems_gpio_bsp_multi_set(bank, set_bitmask);
0878
0879 if ( sc != RTEMS_SUCCESSFUL ) {
0880 RELEASE_LOCK(group->group_lock);
0881 RELEASE_LOCK(gpio_bank_state[bank].lock);
0882
0883 return sc;
0884 }
0885 }
0886
0887
0888 if ( clear_bitmask > 0 ) {
0889 sc = rtems_gpio_bsp_multi_clear(bank, clear_bitmask);
0890
0891 if ( sc != RTEMS_SUCCESSFUL ) {
0892 RELEASE_LOCK(group->group_lock);
0893 RELEASE_LOCK(gpio_bank_state[bank].lock);
0894
0895 return sc;
0896 }
0897 }
0898
0899 RELEASE_LOCK(group->group_lock);
0900 RELEASE_LOCK(gpio_bank_state[bank].lock);
0901
0902 return RTEMS_SUCCESSFUL;
0903 }
0904
0905 uint32_t rtems_gpio_read_group(rtems_gpio_group *group)
0906 {
0907 uint32_t read_bitmask;
0908 uint32_t bank;
0909 uint32_t pin;
0910 uint32_t rv;
0911 uint8_t i;
0912
0913 if ( group->input_count == 0 ) {
0914 return GPIO_INPUT_ERROR;
0915 }
0916
0917 bank = group->digital_input_bank;
0918
0919
0920 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
0921
0922
0923 ACQUIRE_LOCK(group->group_lock);
0924
0925 read_bitmask = 0;
0926
0927 for ( i = 0; i < group->input_count; ++i ) {
0928 pin = group->digital_inputs[i];
0929
0930 read_bitmask |= (1 << pin);
0931 }
0932
0933 rv = rtems_gpio_bsp_multi_read(bank, read_bitmask);
0934
0935 RELEASE_LOCK(gpio_bank_state[bank].lock);
0936 RELEASE_LOCK(group->group_lock);
0937
0938 return rv;
0939 }
0940
0941 rtems_status_code rtems_gpio_group_bsp_specific_operation(
0942 rtems_gpio_group *group,
0943 void *arg
0944 ) {
0945 rtems_status_code sc;
0946 uint32_t bank;
0947
0948 if ( group->bsp_specific_pin_count == 0 ) {
0949 return RTEMS_NOT_DEFINED;
0950 }
0951
0952 bank = group->bsp_specific_bank;
0953
0954
0955 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
0956
0957
0958 ACQUIRE_LOCK(group->group_lock);
0959
0960 sc = rtems_gpio_bsp_specific_group_operation(
0961 bank,
0962 group->bsp_speficifc_pins,
0963 group->bsp_specific_pin_count,
0964 arg
0965 );
0966
0967 RELEASE_LOCK(gpio_bank_state[bank].lock);
0968 RELEASE_LOCK(group->group_lock);
0969
0970 return sc;
0971 }
0972
0973 rtems_status_code rtems_gpio_multi_select(
0974 const rtems_gpio_pin_conf *pins,
0975 uint8_t pin_count
0976 ) {
0977 return gpio_multi_select(pins, pin_count, false);
0978 }
0979
0980 rtems_status_code rtems_gpio_request_configuration(
0981 const rtems_gpio_pin_conf *conf
0982 ) {
0983 rtems_status_code sc;
0984
0985 sc = rtems_gpio_request_pin(
0986 conf->pin_number,
0987 conf->function,
0988 conf->output_enabled,
0989 conf->logic_invert,
0990 conf->bsp_specific
0991 );
0992
0993 if ( sc != RTEMS_SUCCESSFUL ) {
0994 #if defined(DEBUG)
0995 printk("rtems_gpio_request_pin failed with status code %d\n",sc);
0996 #endif
0997
0998 return RTEMS_UNSATISFIED;
0999 }
1000
1001 return setup_resistor_and_interrupt_configuration(
1002 conf->pin_number,
1003 conf->pull_mode,
1004 conf->interrupt
1005 );
1006 }
1007
1008 rtems_status_code rtems_gpio_update_configuration(
1009 const rtems_gpio_pin_conf *conf
1010 ) {
1011 rtems_gpio_interrupt_configuration *interrupt_conf;
1012 gpio_pin_interrupt_state *interrupt_state;
1013 rtems_status_code sc;
1014 uint32_t bank;
1015
1016 if ( conf->pin_number < 0 || conf->pin_number >= BSP_GPIO_PIN_COUNT ) {
1017 return RTEMS_INVALID_ID;
1018 }
1019
1020 bank = BANK_NUMBER(conf->pin_number);
1021
1022 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
1023
1024
1025 if ( gpio_pin_state[conf->pin_number].pin_function == NOT_USED ) {
1026 RELEASE_LOCK(gpio_bank_state[bank].lock);
1027
1028 return RTEMS_NOT_CONFIGURED;
1029 }
1030
1031 sc = rtems_gpio_resistor_mode(conf->pin_number, conf->pull_mode);
1032
1033 if ( sc != RTEMS_SUCCESSFUL ) {
1034 #if defined(DEBUG)
1035 printk("rtems_gpio_resistor_mode failed with status code %d\n", sc);
1036 #endif
1037
1038 return RTEMS_UNSATISFIED;
1039 }
1040
1041 interrupt_conf = (rtems_gpio_interrupt_configuration *) conf->interrupt;
1042
1043 interrupt_state = gpio_pin_state[conf->pin_number].interrupt_state;
1044
1045 if ( interrupt_state != NULL ) {
1046 sc = rtems_gpio_disable_interrupt(conf->pin_number);
1047
1048 if ( sc != RTEMS_SUCCESSFUL ) {
1049 RELEASE_LOCK(gpio_bank_state[bank].lock);
1050
1051 #if defined(DEBUG)
1052 printk(
1053 "rtems_gpio_disable_interrupt failed with status code %d\n",
1054 sc
1055 );
1056 #endif
1057
1058 return RTEMS_UNSATISFIED;
1059 }
1060 }
1061
1062 if ( interrupt_conf != NULL ) {
1063 sc = rtems_gpio_enable_interrupt(
1064 conf->pin_number,
1065 interrupt_conf->active_interrupt,
1066 interrupt_conf->handler_flag,
1067 interrupt_conf->threaded_interrupts,
1068 interrupt_conf->handler,
1069 interrupt_conf->arg
1070 );
1071
1072 if ( sc != RTEMS_SUCCESSFUL ) {
1073 RELEASE_LOCK(gpio_bank_state[bank].lock);
1074
1075 #if defined(DEBUG)
1076 printk(
1077 "rtems_gpio_enable_interrupt failed with status code %d\n",
1078 sc
1079 );
1080 #endif
1081
1082 return RTEMS_UNSATISFIED;
1083 }
1084 }
1085
1086 if ( interrupt_conf != NULL && interrupt_state != NULL ) {
1087 if (
1088 interrupt_conf->debounce_clock_tick_interval !=
1089 interrupt_state->debouncing_tick_count
1090 ) {
1091 interrupt_state->debouncing_tick_count =
1092 interrupt_conf->debounce_clock_tick_interval;
1093
1094 interrupt_state->last_isr_tick = 0;
1095 }
1096 }
1097
1098 RELEASE_LOCK(gpio_bank_state[bank].lock);
1099
1100 return RTEMS_SUCCESSFUL;
1101 }
1102
1103 rtems_status_code rtems_gpio_multi_set(
1104 uint32_t *pin_numbers,
1105 uint32_t pin_count
1106 ) {
1107 rtems_status_code sc;
1108 uint32_t bitmask;
1109 uint32_t bank;
1110
1111 sc = get_pin_bitmask(pin_numbers, pin_count, &bank, &bitmask, DIGITAL_OUTPUT);
1112
1113 if ( sc != RTEMS_SUCCESSFUL ) {
1114 return sc;
1115 }
1116
1117 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
1118
1119 sc = rtems_gpio_bsp_multi_set(bank, bitmask);
1120
1121 RELEASE_LOCK(gpio_bank_state[bank].lock);
1122
1123 return sc;
1124 }
1125
1126 rtems_status_code rtems_gpio_multi_clear(
1127 uint32_t *pin_numbers,
1128 uint32_t pin_count
1129 ) {
1130 rtems_status_code sc;
1131 uint32_t bitmask;
1132 uint32_t bank;
1133
1134 sc = get_pin_bitmask(pin_numbers, pin_count, &bank, &bitmask, DIGITAL_OUTPUT);
1135
1136 if ( sc != RTEMS_SUCCESSFUL ) {
1137 return sc;
1138 }
1139
1140 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
1141
1142 sc = rtems_gpio_bsp_multi_clear(bank, bitmask);
1143
1144 RELEASE_LOCK(gpio_bank_state[bank].lock);
1145
1146 return sc;
1147 }
1148
1149 uint32_t rtems_gpio_multi_read(
1150 uint32_t *pin_numbers,
1151 uint32_t pin_count
1152 ) {
1153 rtems_status_code sc;
1154 uint32_t bitmask;
1155 uint32_t bank;
1156 uint32_t rv;
1157
1158 sc = get_pin_bitmask(pin_numbers, pin_count, &bank, &bitmask, DIGITAL_INPUT);
1159
1160 if ( sc != RTEMS_SUCCESSFUL ) {
1161 return GPIO_INPUT_ERROR;
1162 }
1163
1164 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
1165
1166 rv = rtems_gpio_bsp_multi_read(bank, bitmask);
1167
1168 RELEASE_LOCK(gpio_bank_state[bank].lock);
1169
1170 return rv;
1171 }
1172
1173 rtems_status_code rtems_gpio_set(uint32_t pin_number)
1174 {
1175 rtems_status_code sc;
1176 uint32_t bank;
1177 uint32_t pin;
1178
1179 if ( pin_number < 0 || pin_number >= BSP_GPIO_PIN_COUNT ) {
1180 return RTEMS_INVALID_ID;
1181 }
1182
1183 bank = BANK_NUMBER(pin_number);
1184 pin = PIN_NUMBER(pin_number);
1185
1186 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
1187
1188 if (
1189 gpio_pin_state[pin_number].pin_function != DIGITAL_OUTPUT ||
1190 gpio_pin_state[pin_number].on_group
1191 ) {
1192 RELEASE_LOCK(gpio_bank_state[bank].lock);
1193
1194 #if defined(DEBUG)
1195 printk("Can only set digital output pins\n");
1196 #endif
1197
1198 return RTEMS_NOT_CONFIGURED;
1199 }
1200
1201 if ( gpio_pin_state[pin_number].logic_invert ) {
1202 sc = rtems_gpio_bsp_clear(bank, pin);
1203 }
1204 else {
1205 sc = rtems_gpio_bsp_set(bank, pin);
1206 }
1207
1208 RELEASE_LOCK(gpio_bank_state[bank].lock);
1209
1210 return sc;
1211 }
1212
1213 rtems_status_code rtems_gpio_clear(uint32_t pin_number)
1214 {
1215 rtems_status_code sc;
1216 uint32_t bank;
1217 uint32_t pin;
1218
1219 if ( pin_number < 0 || pin_number >= BSP_GPIO_PIN_COUNT ) {
1220 return RTEMS_INVALID_ID;
1221 }
1222
1223 bank = BANK_NUMBER(pin_number);
1224 pin = PIN_NUMBER(pin_number);
1225
1226 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
1227
1228 if (
1229 gpio_pin_state[pin_number].pin_function != DIGITAL_OUTPUT ||
1230 gpio_pin_state[pin_number].on_group
1231 ) {
1232 RELEASE_LOCK(gpio_bank_state[bank].lock);
1233
1234 #if defined(DEBUG)
1235 printk("Can only clear digital output pins\n");
1236 #endif
1237
1238 return RTEMS_NOT_CONFIGURED;
1239 }
1240
1241 if ( gpio_pin_state[pin_number].logic_invert ) {
1242 sc = rtems_gpio_bsp_set(bank, pin);
1243 }
1244 else {
1245 sc = rtems_gpio_bsp_clear(bank, pin);
1246 }
1247
1248 RELEASE_LOCK(gpio_bank_state[bank].lock);
1249
1250 return sc;
1251 }
1252
1253 int rtems_gpio_get_value(uint32_t pin_number)
1254 {
1255 uint32_t bank;
1256 uint32_t pin;
1257 uint32_t rv;
1258
1259 if ( pin_number < 0 || pin_number >= BSP_GPIO_PIN_COUNT ) {
1260 return -1;
1261 }
1262
1263 bank = BANK_NUMBER(pin_number);
1264 pin = PIN_NUMBER(pin_number);
1265
1266 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
1267
1268 if (
1269 gpio_pin_state[pin_number].pin_function != DIGITAL_INPUT ||
1270 gpio_pin_state[pin_number].on_group
1271 ) {
1272 RELEASE_LOCK(gpio_bank_state[bank].lock);
1273
1274 #if defined(DEBUG)
1275 printk("Can only read digital input pins\n");
1276 #endif
1277
1278 return -1;
1279 }
1280
1281 rv = rtems_gpio_bsp_get_value(bank, pin);
1282
1283 if ( rv == GPIO_INPUT_ERROR ) {
1284 RELEASE_LOCK(gpio_bank_state[bank].lock);
1285
1286 return -1;
1287 }
1288
1289 if ( gpio_pin_state[pin_number].logic_invert ) {
1290 RELEASE_LOCK(gpio_bank_state[bank].lock);
1291
1292 return !rv;
1293 }
1294
1295 RELEASE_LOCK(gpio_bank_state[bank].lock);
1296
1297 return rv > 0;
1298 }
1299
1300 rtems_status_code rtems_gpio_request_pin(
1301 uint32_t pin_number,
1302 rtems_gpio_function function,
1303 bool output_enabled,
1304 bool logic_invert,
1305 void *bsp_specific
1306 ) {
1307 rtems_gpio_specific_data *bsp_data;
1308 rtems_status_code sc = RTEMS_SUCCESSFUL;
1309 uint32_t bank;
1310 uint32_t pin;
1311
1312 if ( pin_number < 0 || pin_number >= BSP_GPIO_PIN_COUNT ) {
1313 return RTEMS_INVALID_ID;
1314 }
1315
1316 bank = BANK_NUMBER(pin_number);
1317 pin = PIN_NUMBER(pin_number);
1318
1319 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
1320
1321
1322 if ( gpio_pin_state[pin_number].pin_function != NOT_USED ) {
1323 RELEASE_LOCK(gpio_bank_state[bank].lock);
1324
1325 return RTEMS_RESOURCE_IN_USE;
1326 }
1327
1328 switch ( function ) {
1329 case DIGITAL_INPUT:
1330 sc = rtems_gpio_bsp_select_input(bank, pin, bsp_specific);
1331 break;
1332 case DIGITAL_OUTPUT:
1333 sc = rtems_gpio_bsp_select_output(bank, pin, bsp_specific);
1334 break;
1335 case BSP_SPECIFIC:
1336 bsp_data = (rtems_gpio_specific_data *) bsp_specific;
1337
1338 if ( bsp_data == NULL ) {
1339 RELEASE_LOCK(gpio_bank_state[bank].lock);
1340
1341 return RTEMS_UNSATISFIED;
1342 }
1343
1344 sc = rtems_gpio_bsp_select_specific_io(
1345 bank,
1346 pin,
1347 bsp_data->io_function,
1348 bsp_data->pin_data
1349 );
1350 break;
1351 case NOT_USED:
1352 default:
1353 RELEASE_LOCK(gpio_bank_state[bank].lock);
1354
1355 return RTEMS_NOT_DEFINED;
1356 }
1357
1358 if ( sc != RTEMS_SUCCESSFUL ) {
1359 RELEASE_LOCK(gpio_bank_state[bank].lock);
1360
1361 return sc;
1362 }
1363
1364
1365
1366 gpio_pin_state[pin_number].pin_function = function;
1367 gpio_pin_state[pin_number].logic_invert = logic_invert;
1368
1369 if ( function == DIGITAL_OUTPUT ) {
1370 if ( output_enabled == true ) {
1371 sc = rtems_gpio_bsp_set(bank, pin);
1372 }
1373 else {
1374 sc = rtems_gpio_bsp_clear(bank, pin);
1375 }
1376 }
1377
1378 RELEASE_LOCK(gpio_bank_state[bank].lock);
1379
1380 return sc;
1381 }
1382
1383 rtems_status_code rtems_gpio_resistor_mode(
1384 uint32_t pin_number,
1385 rtems_gpio_pull_mode mode
1386 ) {
1387 rtems_status_code sc;
1388 uint32_t bank;
1389 uint32_t pin;
1390
1391 if ( pin_number < 0 || pin_number >= BSP_GPIO_PIN_COUNT ) {
1392 return RTEMS_INVALID_ID;
1393 }
1394
1395 bank = BANK_NUMBER(pin_number);
1396 pin = PIN_NUMBER(pin_number);
1397
1398 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
1399
1400
1401
1402
1403
1404 if (
1405 gpio_pin_state[pin_number].resistor_mode == mode &&
1406 mode != NO_PULL_RESISTOR
1407 ) {
1408 RELEASE_LOCK(gpio_bank_state[bank].lock);
1409
1410 return RTEMS_SUCCESSFUL;
1411 }
1412
1413 sc = rtems_gpio_bsp_set_resistor_mode(bank, pin, mode);
1414
1415 if ( sc != RTEMS_SUCCESSFUL ) {
1416 RELEASE_LOCK(gpio_bank_state[bank].lock);
1417
1418 return sc;
1419 }
1420
1421 gpio_pin_state[pin_number].resistor_mode = mode;
1422
1423 RELEASE_LOCK(gpio_bank_state[bank].lock);
1424
1425 return RTEMS_SUCCESSFUL;
1426 }
1427
1428 rtems_status_code rtems_gpio_release_pin(uint32_t pin_number)
1429 {
1430 gpio_pin_interrupt_state *interrupt_state;
1431 rtems_status_code sc;
1432 uint32_t bank;
1433
1434 if ( pin_number < 0 || pin_number >= BSP_GPIO_PIN_COUNT ) {
1435 return RTEMS_INVALID_ID;
1436 }
1437
1438 bank = BANK_NUMBER(pin_number);
1439
1440 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
1441
1442 interrupt_state = gpio_pin_state[pin_number].interrupt_state;
1443
1444
1445
1446 if ( interrupt_state != NULL ) {
1447 sc = rtems_gpio_disable_interrupt(pin_number);
1448
1449 if ( sc != RTEMS_SUCCESSFUL ) {
1450 RELEASE_LOCK(gpio_bank_state[bank].lock);
1451
1452 return sc;
1453 }
1454 }
1455
1456 gpio_pin_state[pin_number].pin_function = NOT_USED;
1457 gpio_pin_state[pin_number].resistor_mode = NO_PULL_RESISTOR;
1458 gpio_pin_state[pin_number].logic_invert = false;
1459 gpio_pin_state[pin_number].on_group = false;
1460
1461 RELEASE_LOCK(gpio_bank_state[bank].lock);
1462
1463 return RTEMS_SUCCESSFUL;
1464 }
1465
1466 rtems_status_code rtems_gpio_release_configuration(
1467 const rtems_gpio_pin_conf *conf
1468 ) {
1469 if ( conf == NULL ) {
1470 return RTEMS_UNSATISFIED;
1471 }
1472
1473 return rtems_gpio_release_pin(conf->pin_number);
1474 }
1475
1476 rtems_status_code rtems_gpio_release_multiple_pins(
1477 const rtems_gpio_pin_conf *pins,
1478 uint32_t pin_count
1479 ) {
1480 rtems_status_code sc;
1481 uint32_t i;
1482
1483 if ( pins == NULL ) {
1484 return RTEMS_UNSATISFIED;
1485 }
1486
1487 for ( i = 0; i < pin_count; ++i ) {
1488 sc = rtems_gpio_release_pin(pins[i].pin_number);
1489
1490 if ( sc != RTEMS_SUCCESSFUL ) {
1491 return sc;
1492 }
1493 }
1494
1495 return RTEMS_SUCCESSFUL;
1496 }
1497
1498 rtems_status_code rtems_gpio_release_pin_group(
1499 rtems_gpio_group *group
1500 ) {
1501 rtems_status_code sc;
1502 uint8_t i;
1503
1504 ACQUIRE_LOCK(group->group_lock);
1505
1506 sc = rtems_semaphore_flush(group->group_lock);
1507
1508 if ( sc != RTEMS_SUCCESSFUL ) {
1509 RELEASE_LOCK(group->group_lock);
1510
1511 return sc;
1512 }
1513
1514 RELEASE_LOCK(group->group_lock);
1515
1516
1517 sc = rtems_semaphore_delete(group->group_lock);
1518
1519 if ( sc != RTEMS_SUCCESSFUL ) {
1520 return sc;
1521 }
1522
1523
1524 for ( i = 0; i < group->input_count; ++i ) {
1525 sc = rtems_gpio_release_pin(group->digital_inputs[i]);
1526
1527 if ( sc != RTEMS_SUCCESSFUL ) {
1528 return sc;
1529 }
1530 }
1531
1532 if ( group->input_count > 0 ) {
1533 free(group->digital_inputs);
1534 }
1535
1536 for ( i = 0; i < group->output_count; ++i ) {
1537 sc = rtems_gpio_release_pin(group->digital_outputs[i]);
1538
1539 if ( sc != RTEMS_SUCCESSFUL ) {
1540 return sc;
1541 }
1542 }
1543
1544 if ( group->output_count > 0 ) {
1545 free(group->digital_outputs);
1546 }
1547
1548 for ( i = 0; i < group->bsp_specific_pin_count; ++i ) {
1549 sc = rtems_gpio_release_pin(group->bsp_speficifc_pins[i]);
1550
1551 if ( sc != RTEMS_SUCCESSFUL ) {
1552 return sc;
1553 }
1554 }
1555
1556 if ( group->bsp_specific_pin_count > 0 ) {
1557 free(group->bsp_speficifc_pins);
1558 }
1559
1560 rtems_chain_extract(&group->node);
1561
1562 free(group);
1563
1564 return RTEMS_SUCCESSFUL;
1565 }
1566
1567 rtems_status_code rtems_gpio_debounce_switch(uint32_t pin_number, int ticks)
1568 {
1569 gpio_pin_interrupt_state *interrupt_state;
1570 uint32_t bank;
1571
1572 if ( pin_number < 0 || pin_number >= BSP_GPIO_PIN_COUNT ) {
1573 return RTEMS_INVALID_ID;
1574 }
1575
1576 bank = BANK_NUMBER(pin_number);
1577
1578 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
1579
1580 interrupt_state = gpio_pin_state[pin_number].interrupt_state;
1581
1582
1583
1584 if (
1585 interrupt_state == NULL ||
1586 gpio_pin_state[pin_number].pin_function != DIGITAL_INPUT ||
1587 gpio_pin_state[pin_number].on_group
1588 ) {
1589 RELEASE_LOCK(gpio_bank_state[bank].lock);
1590
1591 return RTEMS_NOT_CONFIGURED;
1592 }
1593
1594 interrupt_state->debouncing_tick_count = ticks;
1595 interrupt_state->last_isr_tick = 0;
1596
1597 RELEASE_LOCK(gpio_bank_state[bank].lock);
1598
1599 return RTEMS_SUCCESSFUL;
1600 }
1601
1602 rtems_status_code rtems_gpio_interrupt_handler_install(
1603 uint32_t pin_number,
1604 rtems_gpio_irq_state (*handler) (void *arg),
1605 void *arg
1606 ) {
1607 gpio_pin_interrupt_state *interrupt_state;
1608 gpio_handler_node *isr_node;
1609 uint32_t bank;
1610
1611 if ( pin_number < 0 || pin_number >= BSP_GPIO_PIN_COUNT ) {
1612 return RTEMS_INVALID_ID;
1613 }
1614
1615 bank = BANK_NUMBER(pin_number);
1616
1617 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
1618
1619 interrupt_state = gpio_pin_state[pin_number].interrupt_state;
1620
1621
1622 if ( interrupt_state == NULL ) {
1623 RELEASE_LOCK(gpio_bank_state[bank].lock);
1624
1625 return RTEMS_NOT_CONFIGURED;
1626 }
1627
1628
1629
1630 if ( interrupt_state->active_interrupt == NONE ) {
1631 RELEASE_LOCK(gpio_bank_state[bank].lock);
1632
1633 return RTEMS_NOT_CONFIGURED;
1634 }
1635
1636
1637 else if (
1638 interrupt_state->handler_flag == UNIQUE_HANDLER &&
1639 !rtems_chain_is_empty(&interrupt_state->handler_chain)
1640 ) {
1641 RELEASE_LOCK(gpio_bank_state[bank].lock);
1642
1643 return RTEMS_TOO_MANY;
1644 }
1645
1646
1647 isr_node = (gpio_handler_node *) malloc(sizeof(gpio_handler_node));
1648
1649 if ( isr_node == NULL ) {
1650 RELEASE_LOCK(gpio_bank_state[bank].lock);
1651
1652 return RTEMS_NO_MEMORY;
1653 }
1654
1655 isr_node->handler = handler;
1656 isr_node->arg = arg;
1657
1658 rtems_chain_append(&interrupt_state->handler_chain, &isr_node->node);
1659
1660 RELEASE_LOCK(gpio_bank_state[bank].lock);
1661
1662 return RTEMS_SUCCESSFUL;
1663 }
1664
1665 rtems_status_code rtems_gpio_enable_interrupt(
1666 uint32_t pin_number,
1667 rtems_gpio_interrupt interrupt,
1668 rtems_gpio_handler_flag flag,
1669 bool threaded_handling,
1670 rtems_gpio_irq_state (*handler) (void *arg),
1671 void *arg
1672 ) {
1673 gpio_pin_interrupt_state *interrupt_state;
1674 rtems_vector_number vector;
1675 rtems_status_code sc;
1676 uint32_t bank;
1677 uint32_t pin;
1678
1679 if ( pin_number < 0 || pin_number >= BSP_GPIO_PIN_COUNT ) {
1680 return RTEMS_INVALID_ID;
1681 }
1682
1683 bank = BANK_NUMBER(pin_number);
1684 pin = PIN_NUMBER(pin_number);
1685
1686 vector = rtems_gpio_bsp_get_vector(bank);
1687
1688 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
1689
1690 if (
1691 gpio_pin_state[pin_number].pin_function != DIGITAL_INPUT ||
1692 gpio_pin_state[pin_number].on_group
1693 ) {
1694 RELEASE_LOCK(gpio_bank_state[bank].lock);
1695
1696 return RTEMS_NOT_CONFIGURED;
1697 }
1698
1699
1700
1701
1702 if (
1703 gpio_bank_state[bank].interrupt_counter > 0 &&
1704 gpio_bank_state[bank].threaded_interrupts != threaded_handling
1705 ) {
1706 RELEASE_LOCK(gpio_bank_state[bank].lock);
1707
1708 return RTEMS_RESOURCE_IN_USE;
1709 }
1710
1711
1712 if ( gpio_pin_state[pin_number].interrupt_state != NULL ) {
1713 RELEASE_LOCK(gpio_bank_state[bank].lock);
1714
1715 return RTEMS_RESOURCE_IN_USE;
1716 }
1717
1718 gpio_pin_state[pin_number].interrupt_state =
1719 (gpio_pin_interrupt_state *) malloc(sizeof(gpio_pin_interrupt_state));
1720
1721 if ( gpio_pin_state[pin_number].interrupt_state == NULL ) {
1722 return RTEMS_NO_MEMORY;
1723 }
1724
1725 interrupt_state = gpio_pin_state[pin_number].interrupt_state;
1726 interrupt_state->active_interrupt = NONE;
1727 interrupt_state->debouncing_tick_count = 0;
1728 interrupt_state->last_isr_tick = 0;
1729
1730 rtems_chain_initialize_empty( &interrupt_state->handler_chain );
1731
1732 interrupt_state->active_interrupt = interrupt;
1733 interrupt_state->handler_flag = flag;
1734
1735
1736
1737 sc = rtems_gpio_interrupt_handler_install(pin_number, handler, arg);
1738
1739 if ( sc != RTEMS_SUCCESSFUL ) {
1740 free(interrupt_state);
1741 gpio_pin_state[pin_number].interrupt_state = NULL;
1742 RELEASE_LOCK(gpio_bank_state[bank].lock);
1743
1744 return RTEMS_UNSATISFIED;
1745 }
1746
1747 if ( threaded_handling ) {
1748 if (
1749 _Atomic_Load_uint(&threaded_interrupt_counter, ATOMIC_ORDER_RELAXED) == 0
1750 ) {
1751 sc = rtems_interrupt_server_initialize(
1752 INTERRUPT_SERVER_PRIORITY,
1753 INTERRUPT_SERVER_STACK_SIZE,
1754 INTERRUPT_SERVER_MODES,
1755 INTERRUPT_SERVER_ATTRIBUTES,
1756 NULL
1757 );
1758
1759 if ( sc != RTEMS_SUCCESSFUL ) {
1760 RELEASE_LOCK(gpio_bank_state[bank].lock);
1761
1762 return RTEMS_UNSATISFIED;
1763 }
1764 }
1765
1766 if ( gpio_bank_state[bank].interrupt_counter == 0 ) {
1767 sc = rtems_interrupt_server_handler_install(
1768 RTEMS_ID_NONE,
1769 vector,
1770 "GPIO_HANDLER",
1771 RTEMS_INTERRUPT_UNIQUE,
1772 (rtems_interrupt_handler) generic_bank_isr,
1773 &gpio_bank_state[bank].bank_number
1774 );
1775
1776 if ( sc != RTEMS_SUCCESSFUL ) {
1777 RELEASE_LOCK(gpio_bank_state[bank].lock);
1778
1779 return RTEMS_UNSATISFIED;
1780 }
1781
1782 _Atomic_Fetch_add_uint(
1783 &threaded_interrupt_counter,
1784 1,
1785 ATOMIC_ORDER_RELAXED
1786 );
1787 }
1788 }
1789 else if ( gpio_bank_state[bank].interrupt_counter == 0 ) {
1790 sc = rtems_interrupt_handler_install(
1791 vector,
1792 "GPIO_HANDLER",
1793 RTEMS_INTERRUPT_UNIQUE,
1794 (rtems_interrupt_handler) generic_bank_isr,
1795 &gpio_bank_state[bank].bank_number
1796 );
1797
1798 if ( sc != RTEMS_SUCCESSFUL ) {
1799 RELEASE_LOCK(gpio_bank_state[bank].lock);
1800
1801 return RTEMS_UNSATISFIED;
1802 }
1803 }
1804
1805 sc = rtems_gpio_bsp_enable_interrupt(bank, pin, interrupt);
1806
1807 if ( sc != RTEMS_SUCCESSFUL ) {
1808 RELEASE_LOCK(gpio_bank_state[bank].lock);
1809
1810 return RTEMS_UNSATISFIED;
1811 }
1812
1813
1814
1815 if ( gpio_bank_state[bank].interrupt_counter == 0 ) {
1816 gpio_bank_state[bank].threaded_interrupts = threaded_handling;
1817 }
1818
1819 ++gpio_bank_state[bank].interrupt_counter;
1820
1821 RELEASE_LOCK(gpio_bank_state[bank].lock);
1822
1823 return RTEMS_SUCCESSFUL;
1824 }
1825
1826 rtems_status_code rtems_gpio_interrupt_handler_remove(
1827 uint32_t pin_number,
1828 rtems_gpio_irq_state (*handler) (void *arg),
1829 void *arg
1830 ) {
1831 gpio_pin_interrupt_state *interrupt_state;
1832 rtems_chain_control *handler_list;
1833 rtems_chain_node *node;
1834 rtems_chain_node *next_node;
1835 gpio_handler_node *isr_node;
1836 uint32_t bank;
1837
1838 if ( pin_number < 0 || pin_number >= BSP_GPIO_PIN_COUNT ) {
1839 return RTEMS_INVALID_ID;
1840 }
1841
1842 bank = BANK_NUMBER(pin_number);
1843
1844 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
1845
1846 interrupt_state = gpio_pin_state[pin_number].interrupt_state;
1847
1848
1849 if ( interrupt_state == NULL ) {
1850 RELEASE_LOCK(gpio_bank_state[bank].lock);
1851
1852 return RTEMS_NOT_CONFIGURED;
1853 }
1854
1855 handler_list = &interrupt_state->handler_chain;
1856
1857 node = rtems_chain_first(handler_list);
1858
1859
1860
1861
1862 if ( rtems_chain_is_last(node) ) {
1863 RELEASE_LOCK(gpio_bank_state[bank].lock);
1864
1865 return rtems_gpio_disable_interrupt(pin_number);
1866 }
1867
1868
1869 while ( !rtems_chain_is_tail(handler_list, node) ) {
1870 isr_node = (gpio_handler_node *) node;
1871
1872 next_node = node->next;
1873
1874 if ( isr_node->handler == handler && isr_node->arg == arg ) {
1875 rtems_chain_extract(node);
1876
1877 break;
1878 }
1879
1880 node = next_node;
1881 }
1882
1883 RELEASE_LOCK(gpio_bank_state[bank].lock);
1884
1885 return RTEMS_SUCCESSFUL;
1886 }
1887
1888 rtems_status_code rtems_gpio_disable_interrupt(uint32_t pin_number)
1889 {
1890 gpio_pin_interrupt_state *interrupt_state;
1891 rtems_chain_control *handler_list;
1892 rtems_chain_node *node;
1893 rtems_chain_node *next_node;
1894 rtems_vector_number vector;
1895 rtems_status_code sc;
1896 uint32_t bank;
1897 uint32_t pin;
1898
1899 if ( pin_number < 0 || pin_number >= BSP_GPIO_PIN_COUNT ) {
1900 return RTEMS_INVALID_ID;
1901 }
1902
1903 bank = BANK_NUMBER(pin_number);
1904 pin = PIN_NUMBER(pin_number);
1905
1906 vector = rtems_gpio_bsp_get_vector(bank);
1907
1908 ACQUIRE_LOCK(gpio_bank_state[bank].lock);
1909
1910 interrupt_state = gpio_pin_state[pin_number].interrupt_state;
1911
1912
1913 if ( interrupt_state == NULL ) {
1914 RELEASE_LOCK(gpio_bank_state[bank].lock);
1915
1916 return RTEMS_NOT_CONFIGURED;
1917 }
1918
1919 sc = rtems_gpio_bsp_disable_interrupt(bank, pin, interrupt_state->active_interrupt);
1920
1921 if ( sc != RTEMS_SUCCESSFUL ) {
1922 RELEASE_LOCK(gpio_bank_state[bank].lock);
1923
1924 return RTEMS_UNSATISFIED;
1925 }
1926
1927 interrupt_state->active_interrupt = NONE;
1928
1929 handler_list = &interrupt_state->handler_chain;
1930
1931 node = rtems_chain_first(handler_list);
1932
1933
1934 while ( !rtems_chain_is_tail(handler_list, node) ) {
1935 next_node = node->next;
1936
1937 rtems_chain_extract(node);
1938
1939 node = next_node;
1940 }
1941
1942
1943
1944 if ( gpio_bank_state[bank].interrupt_counter == 1 ) {
1945 if ( gpio_bank_state[bank].threaded_interrupts ) {
1946 sc = rtems_interrupt_server_handler_remove(
1947 RTEMS_ID_NONE,
1948 vector,
1949 (rtems_interrupt_handler) generic_bank_isr,
1950 &gpio_bank_state[bank].bank_number
1951 );
1952 }
1953 else {
1954 sc = rtems_interrupt_handler_remove(
1955 vector,
1956 (rtems_interrupt_handler) generic_bank_isr,
1957 &gpio_bank_state[bank].bank_number
1958 );
1959 }
1960
1961 if ( sc != RTEMS_SUCCESSFUL ) {
1962 RELEASE_LOCK(gpio_bank_state[bank].lock);
1963
1964 return RTEMS_UNSATISFIED;
1965 }
1966 }
1967
1968
1969 free(interrupt_state);
1970
1971 --gpio_bank_state[bank].interrupt_counter;
1972
1973 if ( gpio_bank_state[bank].threaded_interrupts ) {
1974 _Atomic_Fetch_sub_uint(&threaded_interrupt_counter, 1, ATOMIC_ORDER_RELAXED);
1975 }
1976
1977 RELEASE_LOCK(gpio_bank_state[bank].lock);
1978
1979 return RTEMS_SUCCESSFUL;
1980 }