extern size_t ciaaLibs_circBufWriteTo(ciaaLibs_CircBufType * cbuf, int32_t filDes, size_t nbytes)
{
   size_t rawCount;

   /* the tail of the circular buffer my be changed, therefore it has to be
    * read only once */
   size_t tail = cbuf->tail;

   /* if the users tries to read to much data, only available data will be
    * provided */
   if (nbytes > ciaaLibs_circBufCount(cbuf, tail))
   {
      nbytes = ciaaLibs_circBufCount(cbuf, tail);
   }

   /* check if data to be read */
   if (nbytes > 0)
   {
      rawCount = ciaaLibs_circBufRawCount(cbuf, tail);

      /* check if all data can be read without wrapping */
      if (nbytes <= rawCount)
      {
         ciaaPOSIX_write(filDes, ciaaLibs_circBufReadPos(cbuf), nbytes);
      }
      else
      {
         ciaaPOSIX_write(filDes, ciaaLibs_circBufReadPos(cbuf), rawCount);
         ciaaPOSIX_write(filDes, (void*)(&cbuf->buf[0]), nbytes-rawCount);
      }

   }

   return nbytes;
} /* end ciaaLibs_circBufWriteTo */
extern void ciaaSerialDevices_txConfirmation(ciaaDevices_deviceType const * const device, uint32_t const nbyte)
{
   /* get serial device */
   ciaaSerialDevices_deviceType * serialDevice =
      (ciaaSerialDevices_deviceType*) device->layer;
   uint32_t write = 0;
   ciaaLibs_CircBufType * cbuf = &serialDevice->txBuf;
   uint32_t tail = cbuf->tail;
   uint32_t rawCount = ciaaLibs_circBufRawCount(cbuf, tail);
   uint32_t count = ciaaLibs_circBufCount(cbuf, tail);
   TaskType taskID = serialDevice->blocked.taskID;

   /* if some data have to be transmitted */
   if (count > 0)
   {
      /* write data to the driver */
      write = serialDevice->device->write(device->loLayer, ciaaLibs_circBufReadPos(cbuf), rawCount);

      /* update buffer */
      ciaaLibs_circBufUpdateHead(cbuf, write);

      /* if all bytes were written and more data is available */
      if ( (write == rawCount) && (count > rawCount ) )
      {
         /* re calculate rawCount */
         rawCount = ciaaLibs_circBufRawCount(cbuf, tail);

         /* write more bytes */
         write = serialDevice->device->write(device->loLayer,
               ciaaLibs_circBufReadPos(cbuf), rawCount);

         if (write > 0)
         {
            /* update buffer */
            ciaaLibs_circBufUpdateHead(cbuf, write);
         }
      }
      /* if task is blocked and waiting for reception of this device */
      if ( (255 != taskID) &&
            (serialDevice->blocked.fct ==
             (void*) ciaaSerialDevices_write) )
      {
         /* invalidate task id */
         serialDevice->blocked.taskID = 255; /* TODO add a macro */

         /* reset function */
         serialDevice->blocked.fct = NULL;

         /* set task event */
#ifdef POSIXE
         SetEvent(taskID, POSIXE);
#endif
      }
   }
}
Example #3
0
extern size_t ciaaLibs_circBufGet(ciaaLibs_CircBufType * cbuf, void * data, size_t nbytes)
{
   size_t rawCount;

   /* the tail of the circular buffer my be changed, therefore it has to be
    * read only once */
   size_t tail = cbuf->tail;

   /* if the users tries to read to much data, only available data will be
    * provided */
   if (nbytes > ciaaLibs_circBufCount(cbuf, tail))
   {
      nbytes = ciaaLibs_circBufCount(cbuf, tail);
   }

   /* check if data to be read */
   if (nbytes > 0)
   {
      rawCount = ciaaLibs_circBufRawCount(cbuf, tail);

      /* check if all data can be read without wrapping */
      if (nbytes <= rawCount)
      {
         ciaaPOSIX_memcpy(data, ciaaLibs_circBufReadPos(cbuf), nbytes);
      }
      else
      {
         ciaaPOSIX_memcpy(data, ciaaLibs_circBufReadPos(cbuf), rawCount);
         ciaaPOSIX_memcpy((void*)((intptr_t)data + rawCount), (void*)(&cbuf->buf[0]), nbytes-rawCount);
      }

      /* calculates new head position */
      ciaaLibs_circBufUpdateHead(cbuf, nbytes);
   }

   return nbytes;
} /* end ciaaLibs_circBufGet */