mbed library sources

Fork of mbed-src by mbed official

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?

UserRevisionLine numberNew 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