mbed library sources
Fork of mbed-src by
targets/hal/TARGET_Atmel/TARGET_SAM21/drivers/system/interrupt/system_interrupt.c@592:a274ee790e56, 2015-07-17 (annotated)
- Committer:
- mbed_official
- Date:
- Fri Jul 17 09:15:10 2015 +0100
- Revision:
- 592:a274ee790e56
- Parent:
- 579:53297373a894
Synchronized with git revision e7144f83a8d75df80c4877936b6ffe552b0be9e6
Full URL: https://github.com/mbedmicro/mbed/commit/e7144f83a8d75df80c4877936b6ffe552b0be9e6/
More API implementation for SAMR21
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mbed_official | 579:53297373a894 | 1 | #include "system_interrupt.h" |
mbed_official | 579:53297373a894 | 2 | |
mbed_official | 579:53297373a894 | 3 | /** |
mbed_official | 579:53297373a894 | 4 | * \brief Check if a interrupt line is pending. |
mbed_official | 579:53297373a894 | 5 | * |
mbed_official | 579:53297373a894 | 6 | * Checks if the requested interrupt vector is pending. |
mbed_official | 579:53297373a894 | 7 | * |
mbed_official | 579:53297373a894 | 8 | * \param[in] vector Interrupt vector number to check |
mbed_official | 579:53297373a894 | 9 | * |
mbed_official | 579:53297373a894 | 10 | * \returns A boolean identifying if the requested interrupt vector is pending. |
mbed_official | 579:53297373a894 | 11 | * |
mbed_official | 579:53297373a894 | 12 | * \retval true Specified interrupt vector is pending |
mbed_official | 579:53297373a894 | 13 | * \retval false Specified interrupt vector is not pending |
mbed_official | 579:53297373a894 | 14 | * |
mbed_official | 579:53297373a894 | 15 | */ |
mbed_official | 579:53297373a894 | 16 | bool system_interrupt_is_pending( |
mbed_official | 579:53297373a894 | 17 | const enum system_interrupt_vector vector) |
mbed_official | 579:53297373a894 | 18 | { |
mbed_official | 579:53297373a894 | 19 | bool result; |
mbed_official | 579:53297373a894 | 20 | |
mbed_official | 579:53297373a894 | 21 | if (vector >= _SYSTEM_INTERRUPT_EXTERNAL_VECTOR_START) { |
mbed_official | 579:53297373a894 | 22 | result = ((NVIC->ISPR[0] & (1 << vector)) != 0); |
mbed_official | 579:53297373a894 | 23 | } else if (vector == SYSTEM_INTERRUPT_SYSTICK) { |
mbed_official | 579:53297373a894 | 24 | result = ((SCB->ICSR & SCB_ICSR_PENDSTSET_Msk) != 0); |
mbed_official | 579:53297373a894 | 25 | } else { |
mbed_official | 579:53297373a894 | 26 | Assert(false); |
mbed_official | 579:53297373a894 | 27 | result = false; |
mbed_official | 579:53297373a894 | 28 | } |
mbed_official | 579:53297373a894 | 29 | |
mbed_official | 579:53297373a894 | 30 | return result; |
mbed_official | 579:53297373a894 | 31 | } |
mbed_official | 579:53297373a894 | 32 | |
mbed_official | 579:53297373a894 | 33 | /** |
mbed_official | 579:53297373a894 | 34 | * \brief Set a interrupt vector as pending. |
mbed_official | 579:53297373a894 | 35 | * |
mbed_official | 579:53297373a894 | 36 | * Set the requested interrupt vector as pending (i.e issues a software |
mbed_official | 579:53297373a894 | 37 | * interrupt request for the specified vector). The software handler will be |
mbed_official | 579:53297373a894 | 38 | * handled (if enabled) in a priority order based on vector number and |
mbed_official | 579:53297373a894 | 39 | * configured priority settings. |
mbed_official | 579:53297373a894 | 40 | * |
mbed_official | 579:53297373a894 | 41 | * \param[in] vector Interrupt vector number which is set as pending |
mbed_official | 579:53297373a894 | 42 | * |
mbed_official | 579:53297373a894 | 43 | * \returns Status code identifying if the vector was successfully set as |
mbed_official | 579:53297373a894 | 44 | * pending. |
mbed_official | 579:53297373a894 | 45 | * |
mbed_official | 579:53297373a894 | 46 | * \retval STATUS_OK If no error was detected |
mbed_official | 579:53297373a894 | 47 | * \retval STATUS_INVALID_ARG If an unsupported interrupt vector number was given |
mbed_official | 579:53297373a894 | 48 | */ |
mbed_official | 579:53297373a894 | 49 | enum status_code system_interrupt_set_pending( |
mbed_official | 579:53297373a894 | 50 | const enum system_interrupt_vector vector) |
mbed_official | 579:53297373a894 | 51 | { |
mbed_official | 579:53297373a894 | 52 | enum status_code status = STATUS_OK; |
mbed_official | 579:53297373a894 | 53 | |
mbed_official | 579:53297373a894 | 54 | if (vector >= _SYSTEM_INTERRUPT_EXTERNAL_VECTOR_START) { |
mbed_official | 579:53297373a894 | 55 | NVIC->ISPR[0] = (1 << vector); |
mbed_official | 579:53297373a894 | 56 | } else if (vector == SYSTEM_INTERRUPT_NON_MASKABLE) { |
mbed_official | 579:53297373a894 | 57 | /* Note: Because NMI has highest priority it will be executed |
mbed_official | 579:53297373a894 | 58 | * immediately after it has been set pending */ |
mbed_official | 579:53297373a894 | 59 | SCB->ICSR = SCB_ICSR_NMIPENDSET_Msk; |
mbed_official | 579:53297373a894 | 60 | } else if (vector == SYSTEM_INTERRUPT_SYSTICK) { |
mbed_official | 579:53297373a894 | 61 | SCB->ICSR = SCB_ICSR_PENDSTSET_Msk; |
mbed_official | 579:53297373a894 | 62 | } else { |
mbed_official | 579:53297373a894 | 63 | /* The user want to set something unsupported as pending */ |
mbed_official | 579:53297373a894 | 64 | Assert(false); |
mbed_official | 579:53297373a894 | 65 | status = STATUS_ERR_INVALID_ARG; |
mbed_official | 579:53297373a894 | 66 | } |
mbed_official | 579:53297373a894 | 67 | |
mbed_official | 579:53297373a894 | 68 | return status; |
mbed_official | 579:53297373a894 | 69 | } |
mbed_official | 579:53297373a894 | 70 | |
mbed_official | 579:53297373a894 | 71 | /** |
mbed_official | 579:53297373a894 | 72 | * \brief Clear pending interrupt vector. |
mbed_official | 579:53297373a894 | 73 | * |
mbed_official | 579:53297373a894 | 74 | * Clear a pending interrupt vector, so the software handler is not executed. |
mbed_official | 579:53297373a894 | 75 | * |
mbed_official | 579:53297373a894 | 76 | * \param[in] vector Interrupt vector number to clear |
mbed_official | 579:53297373a894 | 77 | * |
mbed_official | 579:53297373a894 | 78 | * \returns A status code identifying if the interrupt pending state was |
mbed_official | 579:53297373a894 | 79 | * successfully cleared. |
mbed_official | 579:53297373a894 | 80 | * |
mbed_official | 579:53297373a894 | 81 | * \retval STATUS_OK If no error was detected |
mbed_official | 579:53297373a894 | 82 | * \retval STATUS_INVALID_ARG If an unsupported interrupt vector number was given |
mbed_official | 579:53297373a894 | 83 | */ |
mbed_official | 579:53297373a894 | 84 | enum status_code system_interrupt_clear_pending( |
mbed_official | 579:53297373a894 | 85 | const enum system_interrupt_vector vector) |
mbed_official | 579:53297373a894 | 86 | { |
mbed_official | 579:53297373a894 | 87 | enum status_code status = STATUS_OK; |
mbed_official | 579:53297373a894 | 88 | |
mbed_official | 579:53297373a894 | 89 | if (vector >= _SYSTEM_INTERRUPT_EXTERNAL_VECTOR_START) { |
mbed_official | 579:53297373a894 | 90 | NVIC->ICPR[0] = (1 << vector); |
mbed_official | 579:53297373a894 | 91 | } else if (vector == SYSTEM_INTERRUPT_NON_MASKABLE) { |
mbed_official | 579:53297373a894 | 92 | /* Note: Clearing of NMI pending interrupts does not make sense and is |
mbed_official | 579:53297373a894 | 93 | * not supported by the device, as it has the highest priority and will |
mbed_official | 579:53297373a894 | 94 | * always be executed at the moment it is set */ |
mbed_official | 579:53297373a894 | 95 | return STATUS_ERR_INVALID_ARG; |
mbed_official | 579:53297373a894 | 96 | } else if (vector == SYSTEM_INTERRUPT_SYSTICK) { |
mbed_official | 579:53297373a894 | 97 | SCB->ICSR = SCB_ICSR_PENDSTCLR_Msk; |
mbed_official | 579:53297373a894 | 98 | } else { |
mbed_official | 579:53297373a894 | 99 | Assert(false); |
mbed_official | 579:53297373a894 | 100 | status = STATUS_ERR_INVALID_ARG; |
mbed_official | 579:53297373a894 | 101 | } |
mbed_official | 579:53297373a894 | 102 | |
mbed_official | 579:53297373a894 | 103 | return status; |
mbed_official | 579:53297373a894 | 104 | } |
mbed_official | 579:53297373a894 | 105 | |
mbed_official | 579:53297373a894 | 106 | /** |
mbed_official | 579:53297373a894 | 107 | * \brief Set interrupt vector priority level. |
mbed_official | 579:53297373a894 | 108 | * |
mbed_official | 579:53297373a894 | 109 | * Set the priority level of an external interrupt or exception. |
mbed_official | 579:53297373a894 | 110 | * |
mbed_official | 579:53297373a894 | 111 | * \param[in] vector Interrupt vector to change |
mbed_official | 579:53297373a894 | 112 | * \param[in] priority_level New vector priority level to set |
mbed_official | 579:53297373a894 | 113 | * |
mbed_official | 579:53297373a894 | 114 | * \returns Status code indicating if the priority level of the interrupt was |
mbed_official | 579:53297373a894 | 115 | * successfully set. |
mbed_official | 579:53297373a894 | 116 | * |
mbed_official | 579:53297373a894 | 117 | * \retval STATUS_OK If no error was detected |
mbed_official | 579:53297373a894 | 118 | * \retval STATUS_INVALID_ARG If an unsupported interrupt vector number was given |
mbed_official | 579:53297373a894 | 119 | */ |
mbed_official | 579:53297373a894 | 120 | enum status_code system_interrupt_set_priority( |
mbed_official | 579:53297373a894 | 121 | const enum system_interrupt_vector vector, |
mbed_official | 579:53297373a894 | 122 | const enum system_interrupt_priority_level priority_level) |
mbed_official | 579:53297373a894 | 123 | { |
mbed_official | 579:53297373a894 | 124 | enum status_code status = STATUS_OK; |
mbed_official | 579:53297373a894 | 125 | |
mbed_official | 579:53297373a894 | 126 | if (vector >= _SYSTEM_INTERRUPT_EXTERNAL_VECTOR_START) { |
mbed_official | 579:53297373a894 | 127 | uint8_t register_num = vector / 4; |
mbed_official | 579:53297373a894 | 128 | uint8_t priority_pos = ((vector % 4) * 8) + (8 - __NVIC_PRIO_BITS); |
mbed_official | 579:53297373a894 | 129 | |
mbed_official | 579:53297373a894 | 130 | NVIC->IP[register_num] = |
mbed_official | 579:53297373a894 | 131 | (NVIC->IP[register_num] & ~(0x3 << priority_pos)) | |
mbed_official | 579:53297373a894 | 132 | (priority_level << priority_pos); |
mbed_official | 579:53297373a894 | 133 | |
mbed_official | 579:53297373a894 | 134 | } else if (vector == SYSTEM_INTERRUPT_SYSTICK) { |
mbed_official | 579:53297373a894 | 135 | SCB->SHP[1] = (priority_level << _SYSTEM_INTERRUPT_SYSTICK_PRI_POS); |
mbed_official | 579:53297373a894 | 136 | } else { |
mbed_official | 579:53297373a894 | 137 | Assert(false); |
mbed_official | 579:53297373a894 | 138 | status = STATUS_ERR_INVALID_ARG; |
mbed_official | 579:53297373a894 | 139 | } |
mbed_official | 579:53297373a894 | 140 | |
mbed_official | 579:53297373a894 | 141 | return status; |
mbed_official | 579:53297373a894 | 142 | } |
mbed_official | 579:53297373a894 | 143 | |
mbed_official | 579:53297373a894 | 144 | /** |
mbed_official | 579:53297373a894 | 145 | * \brief Get interrupt vector priority level. |
mbed_official | 579:53297373a894 | 146 | * |
mbed_official | 579:53297373a894 | 147 | * Retrieves the priority level of the requested external interrupt or exception. |
mbed_official | 579:53297373a894 | 148 | * |
mbed_official | 579:53297373a894 | 149 | * \param[in] vector Interrupt vector of which the priority level will be read |
mbed_official | 579:53297373a894 | 150 | * |
mbed_official | 579:53297373a894 | 151 | * \return Currently configured interrupt priority level of the given interrupt |
mbed_official | 579:53297373a894 | 152 | * vector. |
mbed_official | 579:53297373a894 | 153 | */ |
mbed_official | 579:53297373a894 | 154 | enum system_interrupt_priority_level system_interrupt_get_priority( |
mbed_official | 579:53297373a894 | 155 | const enum system_interrupt_vector vector) |
mbed_official | 579:53297373a894 | 156 | { |
mbed_official | 579:53297373a894 | 157 | uint8_t register_num = vector / 4; |
mbed_official | 579:53297373a894 | 158 | uint8_t priority_pos = ((vector % 4) * 8) + (8 - __NVIC_PRIO_BITS); |
mbed_official | 579:53297373a894 | 159 | |
mbed_official | 579:53297373a894 | 160 | enum system_interrupt_priority_level priority = SYSTEM_INTERRUPT_PRIORITY_LEVEL_0; |
mbed_official | 579:53297373a894 | 161 | |
mbed_official | 579:53297373a894 | 162 | if (vector >= 0) { |
mbed_official | 579:53297373a894 | 163 | priority = (enum system_interrupt_priority_level) |
mbed_official | 579:53297373a894 | 164 | ((NVIC->IP[register_num] >> priority_pos) & _SYSTEM_INTERRUPT_PRIORITY_MASK); |
mbed_official | 579:53297373a894 | 165 | } else if (vector == SYSTEM_INTERRUPT_SYSTICK) { |
mbed_official | 579:53297373a894 | 166 | priority = (enum system_interrupt_priority_level) |
mbed_official | 579:53297373a894 | 167 | ((SCB->SHP[1] >> _SYSTEM_INTERRUPT_SYSTICK_PRI_POS) & _SYSTEM_INTERRUPT_PRIORITY_MASK); |
mbed_official | 579:53297373a894 | 168 | } |
mbed_official | 579:53297373a894 | 169 | |
mbed_official | 579:53297373a894 | 170 | return priority; |
mbed_official | 579:53297373a894 | 171 | } |
mbed_official | 579:53297373a894 | 172 |