Ejemplo n.º 1
0
static ssize_t i2schar_write(FAR struct file *filep, FAR const char *buffer,
                             size_t buflen)
{
  FAR struct inode *inode = filep->f_inode;
  FAR struct i2schar_dev_s *priv;
  FAR struct ap_buffer_s *apb;
  size_t nbytes;
  int ret;

  i2svdbg("buffer=%p buflen=%d\n", buffer, (int)buflen);

  /* Get our private data structure */

  DEBUGASSERT(filep && buffer);

  inode = filep->f_inode;
  DEBUGASSERT(inode);

  priv = (FAR struct i2schar_dev_s *)inode->i_private;
  DEBUGASSERT(priv);

  /* Verify that the buffer refers to one, correctly sized audio buffer */

  DEBUGASSERT(buflen >= sizeof(struct ap_buffer_s));

  apb    = (FAR struct ap_buffer_s *)buffer;
  nbytes = apb->nmaxbytes;
  DEBUGASSERT(buflen >= (sizeof(struct ap_buffer_s) + nbytes));

  /* Add a reference to the audio buffer */

  apb_reference(apb);

  /* Get exclusive access to i2c character driver */

  ret = sem_wait(&priv->exclsem);
  if (ret < 0)
    {
      ret = -errno;
      DEBUGASSERT(ret < 0);
      i2sdbg("ERROR: sem_wait returned: %d\n", ret);
      goto errout_with_reference;
    }

  /* Give the audio buffer to the I2S driver */

  ret = I2S_SEND(priv->i2s, apb, i2schar_txcallback, priv,
                 CONFIG_AUDIO_I2SCHAR_TXTIMEOUT);
  if (ret < 0)
    {
      i2sdbg("ERROR: I2S_SEND returned: %d\n", ret);
      goto errout_with_reference;
    }

  /* Lie to the caller and tell them that all of the bytes have been
   * sent.
   */

  sem_post(&priv->exclsem);
  return sizeof(struct ap_buffer_s) + nbytes;

errout_with_reference:
  apb_free(apb);
  sem_post(&priv->exclsem);
  return ret;
}
Ejemplo n.º 2
0
static ssize_t i2schar_read(FAR struct file *filep, FAR char *buffer,
                            size_t buflen)
{
  FAR struct inode *inode;
  FAR struct i2schar_dev_s *priv;
  FAR struct ap_buffer_s *apb;
  size_t nbytes;
  int ret;

  i2sinfo("buffer=%p buflen=%d\n", buffer, (int)buflen);

  /* Get our private data structure */

  DEBUGASSERT(filep != NULL && buffer != NULL);

  inode = filep->f_inode;
  DEBUGASSERT(inode != NULL);

  priv = (FAR struct i2schar_dev_s *)inode->i_private;
  DEBUGASSERT(priv != NULL);

  /* Verify that the buffer refers to one, correctly sized audio buffer */

  DEBUGASSERT(buflen >= sizeof(struct ap_buffer_s));

  apb    = (FAR struct ap_buffer_s *)buffer;
  nbytes = apb->nmaxbytes;
  DEBUGASSERT(buflen >= (sizeof(struct ap_buffer_s) + nbytes));

  /* Add a reference to the audio buffer */

  apb_reference(apb);

  /* Get exclusive access to i2c character driver */

  ret = nxsem_wait(&priv->exclsem);
  if (ret < 0)
    {
      i2serr("ERROR: nxsem_wait returned: %d\n", ret);
      goto errout_with_reference;
    }

  /* Give the buffer to the I2S driver */

  ret = I2S_RECEIVE(priv->i2s, apb, i2schar_rxcallback, priv,
                    CONFIG_AUDIO_I2SCHAR_RXTIMEOUT);
  if (ret < 0)
    {
      i2serr("ERROR: I2S_RECEIVE returned: %d\n", ret);
      goto errout_with_reference;
    }

  /* Lie to the caller and tell them that all of the bytes have been
   * received
   */

  nxsem_post(&priv->exclsem);
  return sizeof(struct ap_buffer_s) + nbytes;

errout_with_reference:
  apb_free(apb);
  nxsem_post(&priv->exclsem);
  return ret;
}