Beispiel #1
0
/////////////////////////////////////////////////////////////////////////////
//! Starts a new transfer. If this function is called during an ongoing
//! transfer, we wait until it has been finished and setup the new transfer
//! \param[in] transfer type:<BR>
//! <UL>
//!   <LI>IIC_Read: a common Read transfer
//!   <LI>IIC_Write: a common Write transfer
//!   <LI>IIC_Read_AbortIfFirstByteIs0: used to poll MBHP_IIC_MIDI: aborts transfer
//!         if the first received byte is 0
//!   <LI>IIC_Write_WithoutStop: don't send stop condition after transfer to allow
//!         a restart condition (e.g. used to access EEPROMs)
//! \param[in] iic_port the IIC port (0..MIOS32_IIC_NUM-1)
//! \param[in] address of IIC device (bit 0 always cleared)
//! \param[in] *buffer pointer to transmit/receive buffer
//! \param[in] len number of bytes which should be transmitted/received
//! \return 0 no error
//! \return < 0 on errors, if MIOS32_IIC_ERROR_PREV_OFFSET is added, the previous
//!      transfer got an error (the previous task didn't use \ref MIOS32_IIC_TransferWait
//!      to poll the transfer state)
//! \note Note that the semaphore will be released automatically after an error
//! (MIOS32_IIC_TransferBegin() has to be called again)
/////////////////////////////////////////////////////////////////////////////
s32 MIOS32_IIC_Transfer(u8 iic_port, mios32_iic_transfer_t transfer, u8 address, u8 *buffer, u16 len)
{
  iic_rec_t *iicx = &iic_rec[iic_port];// simplify addressing of record
  s32 error;

  if( iic_port >= MIOS32_IIC_NUM )
    return MIOS32_IIC_ERROR_INVALID_PORT;

  // wait until previous transfer finished
  if( (error = MIOS32_IIC_TransferWait(iic_port)) ) { // transmission error during previous transfer
    iicx->iic_semaphore = 0; // release semaphore for easier programming at user level
    return error + MIOS32_IIC_ERROR_PREV_OFFSET;
  }

  // disable interrupts
  MIOS32_IRQ_Disable(); // TODO: disable peripheral

  // clear transfer state and error value
  iicx->transfer_state.ALL = 0;
  iicx->transfer_error = 0;

  // set buffer length and start index
  iicx->buffer_len = len;
  iicx->buffer_ix = 0;

  // branch depending on read/write
  if( transfer == IIC_Read || transfer == IIC_Read_AbortIfFirstByteIs0 ) {
    // take new address/buffer/len
    iicx->iic_address = address | 1; // set bit 0 for read operation
    iicx->tx_buffer_ptr = NULL; // ensure that previous TX buffer won't be accessed
    iicx->rx_buffer_ptr = buffer;
    // special option for optimized MBHP_IIC_MIDI
    iicx->transfer_state.ABORT_IF_FIRST_BYTE_0 = transfer == IIC_Read_AbortIfFirstByteIs0 ? 1 : 0;
  } else if( transfer == IIC_Write || transfer == IIC_Write_WithoutStop ) {
    // take new address/buffer/len
    iicx->iic_address = address & 0xfe; // clear bit 0 for write operation
    iicx->tx_buffer_ptr = buffer;
    iicx->rx_buffer_ptr = NULL; // ensure that nothing will be received
    // option to skip stop-condition generation after successful write
    iicx->transfer_state.WRITE_WITHOUT_STOP = transfer == IIC_Write_WithoutStop ? 1 : 0;
  } else {
    iicx->iic_semaphore = 0; // release semaphore for easier programming at user level
    MIOS32_IRQ_Enable(); // TODO: enable peripheral??
    return (iicx->last_transfer_error=MIOS32_IIC_ERROR_UNSUPPORTED_TRANSFER_TYPE);
  }

  // clear last error status
  iicx->last_transfer_error = 0;

  // notify that transfer has started
  iicx->transfer_state.BUSY = 1;

  MIOS32_IRQ_Enable(); // TODO: enable peripheral

  // send start condition
  iicx->base->I2CONCLR = 0x04; // clear AA (assert acknowledge) bit
  iicx->base->I2CONSET = 0x20; // set STA (start) bit

  return 0; // no error
}
Beispiel #2
0
/////////////////////////////////////////////////////////////////////////////
// Checks the transfer status or waits for status == 0 (no ongoing transfer)
// IN: blocking = 1: waits for the ongoing transfer to finish; 
//                0: returns the current transfer status
// OUT: transfer status (1: ongoing; 0: no transfer; < 0: error during last
//      transfer. clears the transfer-status on errors.
//      (see README for error codes)
/////////////////////////////////////////////////////////////////////////////
s32 FRAM_TransferWaitCheck(u8 blocking){
  s32 res;
  if(transfer_status == 1){
    // ongoing transfer: poll IIC transfer status
    transfer_status = blocking ? 
      MIOS32_IIC_TransferWait(FRAM_IIC_PORT) : 
      MIOS32_IIC_TransferCheck(FRAM_IIC_PORT);
    }
  res = transfer_status;
  // clear error status
  if(transfer_status < 0)
    transfer_status = 0;
  // return last transfer status
  return res;
  }