Пример #1
0
/**
\brief Test case: TC_CoreFunc_PRIMASK
\details
- Check if __get_PRIMASK and __set_PRIMASK intrinsic can be used to manipulate PRIMASK.
- Check if __enable_irq and __disable_irq are reflected in PRIMASK.
*/
void TC_CoreFunc_PRIMASK (void) {
  uint32_t orig = __get_PRIMASK();

  // toggle primask
  uint32_t primask = (orig & ~0x01U) | (~orig & 0x01U);

  __set_PRIMASK(primask);
  uint32_t result = __get_PRIMASK();

  ASSERT_TRUE(result == primask);

  __disable_irq();
  result = __get_PRIMASK();
  ASSERT_TRUE((result & 0x01U) == 1U);

  __enable_irq();
  result = __get_PRIMASK();
  ASSERT_TRUE((result & 0x01U) == 0U);

  __disable_irq();
  result = __get_PRIMASK();
  ASSERT_TRUE((result & 0x01U) == 1U);

  __set_PRIMASK(orig);
}
Пример #2
0
/***************************************************************************//**
 * @brief
 *   Unlock the given SPI bus.
 *
 * @param[in] id
 *   The unique ID used for SPI bus locking.
 ******************************************************************************/
void TD_SPI_UnLock(uint8_t id)
{
	TD_SPI_LockedCallback temp;
	uint32_t msk;
	uint8_t bus;

	EFM_ASSERT(id <= CONFIG_MAX_SPI_ID);
	bus = TD_SPI_Conf[id].bus;
	EFM_ASSERT(bus < MAX_SPI_BUS);
	EFM_ASSERT(SPI[bus].lock && SPI[bus].lock_id == id);
	DEBUG_PRINTF("UnL%d\r\n", id);
	DEBUG_PRINTF_INFO("Cnt%d\r\n", SPI[bus].lock);
	msk = __get_PRIMASK();
	__set_PRIMASK(1);
	if (SPI[bus].lock && (SPI[bus].lock_id == id || SPI[bus].lock_id == TD_SPI_Conf[id].friend_id)) {

		// Bus not locked, and no flushing of queue in callstack
		if ((--SPI[bus].lock) == 0 && !SPI[bus].flush_in_progress) {

			// Now, we are flushing queue
			SPI[bus].flush_in_progress = true;

			// Process all callback to flush in queue
			while (SPI[bus].top != SPI[bus].bottom) {

				// There is callback to call, get it
				temp = SPI[bus].cb[SPI[bus].bottom];

				// Remove it
				SPI[bus].bottom++;
				if (SPI[bus].bottom >= MAX_LOCKED_CALLBACK) {
					SPI[bus].bottom = 0;
				}
				__set_PRIMASK(msk);

				// Call it, IRQ available if needed
				DEBUG_PRINTF("Lock feed 0x%08X\r\n", temp);
				(*temp)();
				msk = __get_PRIMASK();
				__set_PRIMASK(1);
			}
			SPI[bus].flush_in_progress = false;
		}
	} else {
		TD_Trap(TRAP_SPI_INVALID_UNLOCK, (bus << 8) | id);
	}
	__set_PRIMASK(msk);
}
Пример #3
0
/// Decrement Semaphore tokens.
/// \param[in]  semaphore       semaphore object.
/// \return 1 - success, 0 - failure.
static uint32_t SemaphoreTokenDecrement (os_semaphore_t *semaphore) {
#if (__EXCLUSIVE_ACCESS == 0U)
  uint32_t primask = __get_PRIMASK();
#endif
  uint32_t ret;

#if (__EXCLUSIVE_ACCESS == 0U)
  __disable_irq();

  if (semaphore->tokens != 0U) {
    semaphore->tokens--;
    ret = 1U;
  } else {
    ret = 0U;
  }

  if (primask == 0U) {
    __enable_irq();
  }
#else
  if (atomic_dec16_nz(&semaphore->tokens) != 0U) {
    ret = 1U;
  } else {
    ret = 0U;
  }
#endif

  return ret;
}
Пример #4
0
void Timer_delete(uint32_t id) {
	if (id == INVALID_HANDLE)
		return;
	timerNode_p node = s_timersListHead;
	timerNode_p prev = NULL;
	uint32_t primask = __get_PRIMASK();
	__disable_irq();
	while (node) {
		if (node->id == id)
			break;
		prev = node;
		node = node->next;
	}
	if (prev) {
		prev = node->next;
		if (node == s_timersListTail)
			s_timersListTail = prev;
		MEMMAN_free(node);
	} else {
		MEMMAN_free(s_timersListHead);
		s_timersListHead = s_timersListTail = NULL;
	}
	if (!primask) {
		__enable_irq();
	}
}
Пример #5
0
uint32_t ulSetInterruptMaskFromISR( void )
{
        uint32 primask = __get_PRIMASK();
        __set_PRIMASK(1);
        DBG_CONFIGURE_HIGH(CMN_TIMING_DEBUG, CMNDBG_CRITICAL_SECTION);
        return primask;
}
Пример #6
0
uint32_t Timer_newArmed(uint32_t tout, _Bool isPeriodic, onTimerFire_t cb, void *cbData) {
	uint32_t handle = INVALID_HANDLE;
	if (!cb || !tout)
		return INVALID_HANDLE;
	do {
		handle = getNewHandle();
	} while (!isTimerHandleUnique(handle));
	timerNode_p last = s_timersListTail;
	uint32_t primask = __get_PRIMASK();
	__disable_irq();
	if (!last && (last = MEMMAN_malloc(sizeof(timerNode_t)))) {
		last->id = handle;
		last->cnt = last->timeout = tout;
		last->isPeriodic = isPeriodic;
		last->isActive = true;
		last->cb = cb;
		last->cbData = cbData;
		last->next = NULL;
		s_timersListTail = s_timersListHead = last;
	}
	if (!primask) {
		__enable_irq();
	}

	return handle;
}
Пример #7
0
uint32_t DisableInterrupt()
{
	uint32_t primask = __get_PRIMASK();
	__disable_irq();

	return primask;
}
Пример #8
0
size_t Uart::write(const uint8_t data)
{
  if (sercom->isDataRegisterEmptyUART() && txBuffer.available() == 0) {
    sercom->writeDataUART(data);
  } else {
    // spin lock until a spot opens up in the buffer
    while(txBuffer.isFull()) {
      uint8_t interruptsEnabled = ((__get_PRIMASK() & 0x1) == 0);

      if (interruptsEnabled) {
        uint32_t exceptionNumber = (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk);

        if (exceptionNumber == 0 ||
              NVIC_GetPriority((IRQn_Type)(exceptionNumber - 16)) > SERCOM_NVIC_PRIORITY) {
          // no exception or called from an ISR with lower priority,
          // wait for free buffer spot via IRQ
          continue;
        }
      }

      // interrupts are disabled or called from ISR with higher or equal priority than the SERCOM IRQ
      // manually call the UART IRQ handler when the data register is empty
      if (sercom->isDataRegisterEmptyUART()) {
        IrqHandler();
      }
    }

    txBuffer.store_char(data);

    sercom->enableDataRegisterEmptyInterruptUART();
  }

  return 1;
}
Пример #9
0
/// Increment Semaphore tokens.
/// \param[in]  semaphore       semaphore object.
/// \return 1 - success, 0 - failure.
static uint32_t SemaphoreTokenIncrement (os_semaphore_t *semaphore) {
#if (__EXCLUSIVE_ACCESS == 0U)
  uint32_t primask = __get_PRIMASK();
#endif
  uint32_t ret;

#if (__EXCLUSIVE_ACCESS == 0U)
  __disable_irq();

  if (semaphore->tokens < semaphore->max_tokens) {
    semaphore->tokens++;
    ret = 1U;
  } else {
    ret = 0U;
  }

  if (primask == 0U) {
    __enable_irq();
  }
#else
  if (atomic_inc16_lt(&semaphore->tokens, semaphore->max_tokens) < semaphore->max_tokens) {
    ret = 1U;
  } else {
    ret = 0U;
  }
#endif

  return ret;
}
Пример #10
0
uint32_t gzll_interupts_save(void)
{
  uint32_t flag;
  flag = __get_PRIMASK();
  __disable_irq();
  return flag;
}
Пример #11
0
void BoardSupportPackage::pushEvent(Event_p pEvent) {
	uint32_t primask = __get_PRIMASK();
	__disable_irq();
	eventQueue = Queue_pushEvent(eventQueue, pEvent);
	if (!primask) {
		__enable_irq();
	}
}
Пример #12
0
unsigned int disableIRQ(void)
{
    // FIXME PRIMASK is the old CPSR (FAULTMASK ??? BASEPRI ???)
    //PRIMASK lesen
    unsigned int uiPriMask = __get_PRIMASK();
    __disable_irq();
    return uiPriMask;
}
Пример #13
0
bool core_util_are_interrupts_enabled(void)
{
#if defined(__CORTEX_A9)
    return ((__get_CPSR() & 0x80) == 0);
#else
    return ((__get_PRIMASK() & 0x1) == 0);
#endif
}
Пример #14
0
/*
  This optional function does a "fast" critical region protection and returns
  the previous protection level. This function is only called during very short
  critical regions. An embedded system which supports ISR-based drivers might
  want to implement this function by disabling interrupts. Task-based systems
  might want to implement this by using a mutex or disabling tasking. This
  function should support recursive calls from the same task or interrupt. In
  other words, sys_arch_protect() could be called while already protected. In
  that case the return value indicates that it is already protected.

  sys_arch_protect() is only required if your port is supporting an operating
  system.
*/
sys_prot_t sys_arch_protect(void) {
    sys_prot_t res = 0;
    
    res = __get_PRIMASK();
    __disable_irq();
    
    return res;
}
Пример #15
0
int
os_arch_in_critical(void)
{
    uint32_t isr_ctx;

    isr_ctx = __get_PRIMASK();
    return (isr_ctx & 1);
}
Пример #16
0
/***************************************************************************//**
 * @brief
 *   Try to lock the given SPI bus.
 *
 * @param[in] id
 *   The unique ID used for SPI bus locking.
 *
 * @param[in] callback
 *   Pointer to the call-back function that will be called when the bus is unlocked.
 *
 * @return
 * 	 true if bus was successfully locked, false otherwise
 ******************************************************************************/
bool TD_SPI_Lock(uint8_t id, TD_SPI_LockedCallback callback)
{
	uint8_t msk, ret, top, bus;

	DEBUG_PRINTF("Lck%d\r\n", id);
	EFM_ASSERT(id <= CONFIG_MAX_SPI_ID);
	bus = TD_SPI_Conf[id].bus;
	EFM_ASSERT(bus < MAX_SPI_BUS);
	EFM_ASSERT(SPI[bus].lock != 0xFF);
	msk = __get_PRIMASK();
	if (!msk) {
		__set_PRIMASK(1);
	}

	// We have already locked this bus for this usage, just increment lock count
	if (SPI[bus].lock && (SPI[bus].lock_id == id || SPI[bus].lock_id == TD_SPI_Conf[id].friend_id)) {
		SPI[bus].lock++;
		ret = true;

		// Bus is not actually locked, lock it
	} else if (!SPI[bus].lock) {
		SPI[bus].lock_id = id;
		SPI[bus].lock = 1;
		TD_SPI_UpdateConf(id);
		ret = true;
	} else {

		// Bus is locked, but for another usage
		if (callback) {

			// We should append callback to queue
			top = SPI[bus].top + 1;
			if (top >= MAX_LOCKED_CALLBACK) {
				top = 0;
			}

			// Enough room
			if (top != SPI[bus].bottom) {
				SPI[bus].cb[SPI[bus].top] = callback;

#ifdef SPI_DEBUG_STAMP
				SPI[bus].lock_stamp[SPI[bus].top] = RTC->CNT;
#endif

				SPI[bus].top = top;
			} else {
				TD_Trap(TRAP_SPI_MAX_LOCK, (bus << 8) | id);
			}
			DEBUG_PRINTF("Lock add 0x%08X, lbyid:%d cnt:%d\r\n", callback, SPI[bus].lock_id, SPI[bus].lock);
		}
		ret = false;
	}
	DEBUG_PRINTF_INFO("Cnt%d\r\n", SPI[bus].lock);
	if (!msk) {
		__set_PRIMASK(0);
	}
	return ret;
}
Пример #17
0
os_sr_t
os_arch_save_sr(void)
{
    uint32_t isr_ctx;

    isr_ctx = __get_PRIMASK();
    __disable_irq();
    return (isr_ctx & 1);
}
Пример #18
0
void BoardSupportPackage::pendEvent(Event_p pEvent) {
	while (!eventQueue);
	uint32_t primask = __get_PRIMASK();
	__disable_irq();
	eventQueue = Queue_getEvent(eventQueue, pEvent);
	if (!primask) {
		__enable_irq();
	}
}
Пример #19
0
int __atomic_fetch_sub_4(int *d, int val, int mem)
{
	uint32_t primask = __get_PRIMASK();
	__disable_irq();
	*d -= val;
	__set_PRIMASK(primask);

	return *d;
}
Пример #20
0
void DisplayResults(uint8_t line)
{
	uint8_t			irqEnabled = __get_PRIMASK() == 0;
	__disable_irq();
	DETECTORSTATUS	st = g_statuses[line];
	if(irqEnabled) __enable_irq();

	uint32_t freq = ((uint32_t)((uint64_t)48000000*64 / st.lastMeasured));
	I2cLcd_SetCursor(&g_lcd, 0, line);
	I2cLcd_PrintUint(&g_lcd, freq, 0);
}
Пример #21
0
    uint64_t micros(void)
    {
        uint64_t micro;
        if((SysTick->CTRL & (1 << 16)) && (__get_PRIMASK())) //如果此时屏蔽了所有中断且发生了systick溢出,需要对millis_secend进行补偿
        {
            millis_seconds++;
        }
        no_interrupts();
//        micro = (millis_seconds * 1000 + (1000 - (SysTick->VAL)/(cpu.clock.core/1000000)));
        micro = (millis_seconds * 1000 + (1000 - (SysTick->VAL)/(micro_para)));
        interrupts();
        return  micro;
    }
Пример #22
0
void send_keyboard(report_keyboard_t *report)
{
    uint32_t irqflags;

#ifdef NKRO_ENABLE
    if (!keymap_config.nkro)
    {
#endif //NKRO_ENABLE
        while (udi_hid_kbd_b_report_trans_ongoing) { main_subtasks(); } //Run other tasks while waiting for USB to be free

        irqflags = __get_PRIMASK();
        __disable_irq();
        __DMB();

        memcpy(udi_hid_kbd_report, report->raw, UDI_HID_KBD_REPORT_SIZE);
        udi_hid_kbd_b_report_valid = 1;
        udi_hid_kbd_send_report();

        __DMB();
        __set_PRIMASK(irqflags);
#ifdef NKRO_ENABLE
    }
    else
    {
        while (udi_hid_nkro_b_report_trans_ongoing) { main_subtasks(); } //Run other tasks while waiting for USB to be free

        irqflags = __get_PRIMASK();
        __disable_irq();
        __DMB();

        memcpy(udi_hid_nkro_report, report->raw, UDI_HID_NKRO_REPORT_SIZE);
        udi_hid_nkro_b_report_valid = 1;
        udi_hid_nkro_send_report();

        __DMB();
        __set_PRIMASK(irqflags);
    }
#endif //NKRO_ENABLE
}
Пример #23
0
void Timer_rearm(uint32_t id) {
	if (id == INVALID_HANDLE)
		return;
	uint32_t primask = __get_PRIMASK();
	__disable_irq();
	timerNode_p node = findTimerById(id);
	if (node) {
		node->isActive = true;
		node->cnt = node->timeout;
	}
	if (!primask) {
		__enable_irq();
	}
}
Пример #24
0
/// Get a Message from Queue with Highest Priority.
/// \param[in]  mq              message queue object.
/// \return message object or NULL.
static os_message_t *MessageQueueGet (os_message_queue_t *mq) {
#if (__EXCLUSIVE_ACCESS == 0U)
  uint32_t      primask = __get_PRIMASK();
#endif
  os_message_t *msg;
  uint32_t      count;
  uint8_t       flags;

#if (__EXCLUSIVE_ACCESS == 0U)
  __disable_irq();

  count = mq->msg_count;
  if (count != 0U) {
    mq->msg_count--;
  }

  if (primask == 0U) {
    __enable_irq();
  }
#else
  count = atomic_dec32_nz(&mq->msg_count);
#endif

  if (count == 0U) {
    return NULL;
  }

  msg = mq->msg_first;

  while (msg != NULL) {
#if (__EXCLUSIVE_ACCESS == 0U)
    __disable_irq();

    flags = msg->flags;
    msg->flags = 1U;

    if (primask == 0U) {
      __enable_irq();
    }
#else
    flags = atomic_wr8(&msg->flags, 1U);
#endif
    if (flags == 0U) {
      break;
    }
    msg = msg->next;
  }

  return msg;
}
Пример #25
0
//*****************************************************************************
//
//!  set_socket_active_status
//!
//!  @param Sd
//!	 @param Status
//!  @return         none
//!
//!  @brief          Check if the socket ID and status are valid and set 
//!                  accordingly  the global socket status
//
//*****************************************************************************
void set_socket_active_status(long Sd, long Status)
{
        DEBUG("Sd=%d, Status %s",Sd, Status == SOCKET_STATUS_ACTIVE ?  "SOCKET_STATUS_ACTIVE" : "SOCKET_STATUS_IACTIVE");
	if(M_IS_VALID_SD(Sd) && M_IS_VALID_STATUS(Status))
	{
	        uint32_t is = __get_PRIMASK();
              __disable_irq();
		socket_active_status &= ~(1 << Sd);      /* clean socket's mask */
		socket_active_status |= (Status << Sd); /* set new socket's mask */
              if ((is & 1) == 0) {
                  __enable_irq();
	}
}
}
Пример #26
0
long
get_socket_active_status(long Sd)
{
        long rv = SOCKET_STATUS_INACTIVE;
	if(M_IS_VALID_SD(Sd))
	{
            uint32_t is = __get_PRIMASK();
            __disable_irq();
            rv = (socket_active_status & (1 << Sd)) ? SOCKET_STATUS_INACTIVE : SOCKET_STATUS_ACTIVE;
            if ((is & 1) == 0) {
                __enable_irq();
            }
	}
	return rv;
}
Пример #27
0
uint16_t FillTxBuffer(const uint8_t *buffer, uint16_t count)
{
	uint8_t				irqEnabled = __get_PRIMASK() == 0;
	HAL_StatusTypeDef	st;
	uint16_t   			free, freestart, tocopy, copied = 0;

	UNUSED(st);

	__disable_irq();
	freestart = g_txStart + g_txCount;
	free = g_size - g_txCount;
	EnableIrq(irqEnabled);

	freestart -= (freestart >= g_size) ? g_size : 0;
	if(count > free) count = free;
	tocopy = freestart + count > g_size ? g_size - freestart : count;

	memcpy(g_buffer + freestart, buffer, tocopy);

	__disable_irq();
	if(!g_txCount) {
		EnableIrq(irqEnabled);
		g_chunkSize = tocopy;
		st = HAL_UART_Transmit_IT(g_huart, g_buffer + freestart, tocopy);
	}
	copied = tocopy;
	count -= tocopy;
	__disable_irq();
	g_txCount += tocopy;
	EnableIrq(irqEnabled);

	if(!count)
		return copied;

	buffer += tocopy;
	memcpy(g_buffer, buffer, count);

	uint8_t schedule;
	__disable_irq();
	schedule = !g_txCount;
	g_txCount += count;
	EnableIrq(irqEnabled);

	if(schedule)	//	unlikely corner case
		st = HAL_UART_Transmit_IT(g_huart, g_buffer, count);

	return copied + count;
}
InterruptMask disableInterruptMasking()
{
#if CONFIG_ARCHITECTURE_ARMV7_M_KERNEL_BASEPRI != 0

	const auto interruptMask = __get_BASEPRI();
	__set_BASEPRI(0);
	return interruptMask;

#else	// CONFIG_ARCHITECTURE_ARMV7_M_KERNEL_BASEPRI == 0

	const auto interruptMask = __get_PRIMASK();
	__enable_irq();
	return interruptMask;

#endif	// CONFIG_ARCHITECTURE_ARMV7_M_KERNEL_BASEPRI == 0
}
Пример #29
0
void Timer_disarm(uint32_t id) {
	if (id == INVALID_HANDLE)
		return;
	uint32_t primask = __get_PRIMASK();
	__disable_irq();
	timerNode_p node = s_timersListHead;
	while (node) {
		if (node->id == id) {
			node->isActive = false;
			break;
		}
		node = node->next;
	}
	if (!primask) {
		__enable_irq();
	}
}
Пример #30
0
void send_mouse(report_mouse_t *report)
{
#ifdef MOUSEKEY_ENABLE
    uint32_t irqflags;

    irqflags = __get_PRIMASK();
    __disable_irq();
    __DMB();

    memcpy(udi_hid_mou_report, report, UDI_HID_MOU_REPORT_SIZE);
    udi_hid_mou_b_report_valid = 1;
    udi_hid_mou_send_report();

    __DMB();
    __set_PRIMASK(irqflags);
#endif //MOUSEKEY_ENABLE
}