Esempio n. 1
0
//----------------------------------------------------------------
fifocell * fifoget (fifo * ff) 
{
	fifocell * volatile head;
	fifocell * next;
	short done = 0;
	
	do {
		LWARX (&ff->head);
        head = ff->head;				/* read the head cell */
		next = head->link;				/* read the next cell */
		/*
		  WARNING: the next pointer still needs to be checked before reading its value 
		*/
		if (head == ff->tail) {			/* is queue empty or tail falling behind? */
			if (head->link == fifo_end(ff) && STWCX (&ff->head, (void *)head, (void *)head)) /* is queue really empty? */
				return 0;				/* queue is empty; return NULL */
			/* tail is pointing to head in a non empty queue, */
			/* try to set tail to the next cell               */
			CASLNE (&ff->tail, (void *)head, fifo_end(ff));
		}
		else if (next != fifo_end(ff)) { /* if we are not competing on the dummy cell */
			/* and we try to set head to the next cell */
			done = STWCX (&ff->head, (void *)head, next);
		}
	} while (!done);
	msAtomicDec (&ff->count);
	if (head == &ff->dummy) {
		fifoput(ff,head);
		head = fifoget(ff);
	}
	return (fifocell *)head;
}
Esempio n. 2
0
//----------------------------------------------------------------
fifocell *  fifoget(fifo * ff)
{
    fifocell * volatile head;
    fifocell * next;
    unsigned long ic, oc;
    short done = 0;

    do {
        oc = ff->oc;					/* read the head modification count */
        ic = ff->ic;					/* read the tail modification count */
        head = ff->head;				/* read the head cell */
        next = head->link;				/* read the next cell */
        if (oc == ff->oc) {				/* ensures that next is a valid pointer */
            /* to avoid failure when reading next value */
            if (head == ff->tail) {			/* is queue empty or tail falling behind? */
                if (next == fifo_end(ff))	/* is queue empty?             */
                    return 0;				/* queue is empty; return NULL */
                /* tail is pointing to head in a non empty queue, */
                /* try to set tail to the next cell               */
                CAS2 (&ff->tail, head, ic, next, ic+1);
            }
            else if (next != fifo_end(ff)) { /* if we are not competing on the dummy cell */
                /* and we try to set head to the next cell */
                done = CAS2 (&ff->head, head, oc, next, oc+1);
            }
        }
    } while (!done);
    msAtomicDec (&ff->count);
    if (head == &ff->dummy) {
        fifoput(ff,head);
        head = fifoget(ff);
    }
    return (fifocell *)head;
}
Esempio n. 3
0
static void nrf24l01_worker(FAR void *arg)
{
  FAR struct nrf24l01_dev_s *dev = (FAR struct nrf24l01_dev_s *) arg;
  uint8_t status;
  uint8_t fifo_status;

  nrf24l01_lock(dev->spi);

  status = nrf24l01_readregbyte(dev, NRF24L01_STATUS);

  if (status & NRF24L01_RX_DR)
    {
      /* put CE low */

      bool ce = nrf24l01_chipenable(dev, false);

      wdbg("RX_DR is set!\n");

      /* Read and store all received payloads */

      do
        {
          uint8_t pipeno;
          uint8_t pktlen;
          uint8_t buf[NRF24L01_MAX_PAYLOAD_LEN];

          /* For each packet:
           *   - Get pipe #
           *   - Get payload length  (either static or dynamic)
           *   - Read payload content
           */

          pipeno = (status & NRF24L01_RX_P_NO_MASK) >> NRF24L01_RX_P_NO_SHIFT;

          pktlen = dev->pipedatalen[pipeno];
          if (NRF24L01_DYN_LENGTH == pktlen)
            {
              /* If dynamic length payload need to use R_RX_PL_WID command to get actual length */

              nrf24l01_access(dev, MODE_READ, NRF24L01_R_RX_PL_WID, &pktlen, 1);
            }

          /* Get payload content */

          nrf24l01_access(dev, MODE_READ, NRF24L01_R_RX_PAYLOAD, buf, pktlen);

          fifoput(dev, pipeno, buf, pktlen);
          sem_post(&dev->sem_rx);  /* Wake-up any thread waiting in recv */

          status = nrf24l01_readreg(dev, NRF24L01_FIFO_STATUS, &fifo_status, 1);

          wdbg("FIFO_STATUS=%02x\n", fifo_status);
          wdbg("STATUS=%02x\n", status);
        }
      while (!(fifo_status | NRF24L01_RX_EMPTY));

      /* Clear interrupt sources */

      nrf24l01_writeregbyte(dev, NRF24L01_STATUS, NRF24L01_RX_DR);

      /* Restore CE */

      nrf24l01_chipenable(dev, ce);

#ifndef CONFIG_DISABLE_POLL
      if (dev->pfd)
        {
          dev->pfd->revents |= POLLIN;  /* Data available for input */

          wvdbg("Wake up polled fd");
          sem_post(dev->pfd->sem);
        }
#endif
    }