Пример #1
0
/** \brief  This function will download a frame to the radio transceiver's frame
 *          buffer.
 *
 *  \param  write_buffer    Pointer to data that is to be written to frame buffer.
 *  \param  length          Length of data. The maximum length is 127 bytes.
 */
void
hal_frame_write( uint8_t *write_buffer, uint8_t length )
{
	uint8_t tmp;
	ENTER_CRITICAL_REGION();

	/* Start SPI transaction by pulling SEL low */
	hal_set_ss_low();
	/* Download to the Frame Buffer.
	* When the FCS is autogenerated there is no need to transfer the last two bytes
	* since they will be overwritten.
	*/
	#if !RF231_CONF_CHECKSUM
		length -= 2;
	#endif
	/* Send the command byte */
	spi_readwrite(RF_SPI,HAL_TRX_CMD_FW);
	/* Length */
	spi_readwrite(RF_SPI,length);
	do {
		tmp = *write_buffer++;
		spi_readwrite(RF_SPI, tmp);
		--length;
	} while (length > 0);
	/* Stop the SPI transaction by setting SEL high. */
	hal_set_ss_high();
	LEAVE_CRITICAL_REGION();
}
Пример #2
0
/** \brief  This function will upload a frame from the radio transceiver's frame
 *          buffer.
 *
 *          If the frame currently available in the radio transceiver's frame buffer
 *          is out of the defined bounds. Then the frame length, lqi value and crc
 *          be set to zero. This is done to indicate an error.
 *          This version is optimized for use with contiki RF230BB driver.
 *          The callback routine and CRC are left out for speed in reading the rx buffer.
 *          Any delays here can lead to overwrites by the next packet!
 *
 *  \param  rx_frame    Pointer to the data structure where the frame is stored.
 *  \param  rx_callback Pointer to callback function for receiving one byte at a time.
 */
void
hal_frame_read( hal_rx_frame_t *rx_frame)
{
	uint8_t dummy_rx_data;

	uint8_t phy_status;
	uint8_t frame_length;
	uint8_t *rx_data;

    ENTER_CRITICAL_REGION();
    /* Start SPI transaction by pulling SEL low */
    hal_set_ss_low();
    /* Send the command byte */
    phy_status  = spi_readwrite(RF_SPI,HAL_TRX_CMD_FR);
    frame_length = spi_readwrite(RF_SPI,0);
     /*Check for correct frame length.*/
     if ((frame_length >= HAL_MIN_FRAME_LENGTH) &&
         (frame_length <= HAL_MAX_FRAME_LENGTH)){
       rx_data = rx_frame->data;
       rx_frame->length = frame_length;
       do {
         *rx_data++  = spi_readwrite(RF_SPI,0);
       } while (--frame_length > 0);
       rx_frame->lqi = spi_readwrite(RF_SPI,0);
       rx_frame->crc = 1;
     } else {
		rx_frame->length = 0;
		rx_frame->lqi    = 0;
		rx_frame->crc    = 0;
     }
    /* Stop the SPI transaction by setting SEL high. */
    hal_set_ss_high();
    LEAVE_CRITICAL_REGION();
}
Пример #3
0
rt_size_t fm25_read(rt_device_t dev, rt_off_t offset, void * buf, rt_size_t size)
{
    uint32_t index;

	uint8_t *buffer = (uint8_t*) buf;

    fram_lock();
    //spi_config();
	//rt_kprintf("READ: %d, size=%d\n", offset, size);

    CS_LOW();
	spi_readwrite( FM25_READ);
	spi_readwrite( (offset >> 8)&0xFF );
	spi_readwrite( offset & 0xFF  );
    for(index=0; index<size; index++)
    {
		*buffer++ = spi_readwrite(0xFF);

		if( spi_timeout_cnt > 0 )
		{
			fram_unlock();
			spi_timeout_cnt = 0;
			rt_kprintf("Read time out\n");
			return -1;
		}

		offset++;
    }
    CS_HIGH();

    fram_unlock();

    return size;
}
Пример #4
0
/*********************************************************************************************************
** Function name:           mcp2515_setRegister
** Descriptions:            set register
*********************************************************************************************************/
void MCP_CAN::mcp2515_setRegister(const INT8U address, const INT8U value)
{
	MCP2515_SELECT();
	spi_readwrite(MCP_WRITE);
	spi_readwrite(address);
	spi_readwrite(value);
	MCP2515_UNSELECT();
}
Пример #5
0
/*********************************************************************************************************
** Function name:           mcp2515_modifyRegister
** Descriptions:            set bit of one register
*********************************************************************************************************/
void MCP_CAN::mcp2515_modifyRegister(const INT8U address, const INT8U mask, const INT8U data)
{
	MCP2515_SELECT();
	spi_readwrite(MCP_BITMOD);
	spi_readwrite(address);
	spi_readwrite(mask);
	spi_readwrite(data);
	MCP2515_UNSELECT();
}
Пример #6
0
static uint8_t sst25vfxx_read_status(void)
{
    uint8_t tmp;

    //CS_LOW();
    spi_readwrite( CMD_RDSR );
    tmp=spi_readwrite(0XFF);
    //CS_HIGH();
    return tmp;
}
Пример #7
0
static uint8_t fm25_read_status(void)
{
    uint8_t tmp;

    CS_LOW();
    spi_readwrite( FM25_RDSR );
    tmp=spi_readwrite(0xFF);
    CS_HIGH();
    return tmp;
}
Пример #8
0
void hal_aci_tl_poll_rdy_line(void)
{
  uint8_t byte_cnt;
  uint8_t byte_sent_cnt;
  uint8_t max_bytes;
  bool is_transmit_finished = false;
  
  if ( 1 == digitalRead(rdy) )
  {
    return;
  }
  

  digitalWrite(reqn, LOW);

  
  // Send length, receive header
  byte_sent_cnt = 0;
  received_data.status_byte = spi_readwrite(data_to_send.buffer[byte_sent_cnt++]);
  // Send first byte, receive length from slave
  received_data.buffer[0] = spi_readwrite(data_to_send.buffer[byte_sent_cnt++]);
  if (0 == data_to_send.buffer[0])
  {
    max_bytes = received_data.buffer[0];
  }
  else
  {
    // Set the maximum to the biggest size. One command byte is already sent
    max_bytes = (received_data.buffer[0] > (data_to_send.buffer[0] - 1)) 
      ? received_data.buffer[0] : (data_to_send.buffer[0] - 1);
  }

  if (max_bytes > HAL_ACI_MAX_LENGTH)
  {
    max_bytes = HAL_ACI_MAX_LENGTH;
  }

  // Transmit/receive the rest of the packet 
  for (byte_cnt = 0; byte_cnt < max_bytes; byte_cnt++)
  {
    received_data.buffer[byte_cnt+1] =  spi_readwrite(data_to_send.buffer[byte_sent_cnt++]);
  }
  /* Release REQN */
  digitalWrite(reqn, HIGH);

//  ASSERT(ERROR_CODE_HAL_ACI_TL_STATUS_BYTE,(0 != received_data.status_byte));
  if (spi_transmit_requested)
  {
    data_to_send.buffer[0] = 0;
    spi_transmit_requested = false;
  }
  
  /* valid Rx available or transmit finished*/
  hal_aci_tl_msg_rcv_hook(&received_data);
}
Пример #9
0
/*********************************************************************************************************
** Function name:           mcp2515_readRegister
** Descriptions:            read register
*********************************************************************************************************/
INT8U MCP_CAN::mcp2515_readRegister(const INT8U address)
{
	INT8U ret;

	MCP2515_SELECT();
	spi_readwrite(MCP_READ);
	spi_readwrite(address);
	ret = spi_read();
	MCP2515_UNSELECT();

	return ret;
}
Пример #10
0
/*********************************************************************************************************
** Function name:           mcp2515_setRegisterS
** Descriptions:            set registerS
*********************************************************************************************************/
void MCP_CAN::mcp2515_setRegisterS(const INT8U address, const INT8U values[], const INT8U n)
{
	INT8U i;
	MCP2515_SELECT();
	spi_readwrite(MCP_WRITE);
	spi_readwrite(address);

	for (i = 0; i < n; i++)
	{
		spi_readwrite(values[i]);
	}
	MCP2515_UNSELECT();
}
Пример #11
0
/*********************************************************************************************************
** Function name:           mcp2515_readRegisterS
** Descriptions:            read registerS
*********************************************************************************************************/
void MCP_CAN::mcp2515_readRegisterS(const INT8U address, INT8U values[], const INT8U n)
{
	INT8U i;
	MCP2515_SELECT();
	spi_readwrite(MCP_READ);
	spi_readwrite(address);
	// mcp2515 has auto-increment of address-pointer
	for (i = 0; i < n; i++)
	{
		values[i] = spi_read();
	}
	MCP2515_UNSELECT();
}
Пример #12
0
/*********************************************************************************************************
** Function name:           mcp2515_reset
** Descriptions:            reset the device
*********************************************************************************************************/
void MCP_CAN::mcp2515_reset(void)
{
	MCP2515_SELECT();
	spi_readwrite(MCP_RESET);
	MCP2515_UNSELECT();
	delay(10);
}
Пример #13
0
static rt_err_t fm25_open(rt_device_t dev, rt_uint16_t oflag)
{
	char i;
	SPI_Cmd(FM25_SPI, ENABLE);

	if( oflag != RT_DEVICE_FLAG_RDONLY )
	{
		CS_LOW();
		spi_readwrite( FM25_WRSR );
		spi_readwrite( FM25_WPEN );
		CS_HIGH();
		//rt_kprintf("RDSR=0x%X\n", fm25_read_status());

	}
	return RT_EOK;
}
Пример #14
0
void fm25_hw_init()
{
	int i = 0xFFFFF;
	fm25_spi_cfg();

	while(i--);
	//spi_config();
	CS_LOW();
    spi_readwrite( FM25_WRDI );
    CS_HIGH();

	spi_flash_device.type    = RT_Device_Class_Block;
    spi_flash_device.init    = fm25_init;
    spi_flash_device.open    = fm25_open;
    spi_flash_device.close   = fm25_close;
    spi_flash_device.read 	 = fm25_read;
    spi_flash_device.write   = fm25_write;
    spi_flash_device.control = fm25_control;
    /* no private */
    spi_flash_device.user_data = RT_NULL;

    rt_device_register(&spi_flash_device, "fram0",
                       RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);

}
Пример #15
0
/** \brief  This function reads data from one of the radio transceiver's registers.
 *  \param  address Register address to read from. See datasheet for register map.
 *  \see Look at the at86rf231_registermap.h file for register address definitions.
 *  \returns The actual value of the read register.
 */
uint8_t
hal_register_read( uint8_t address ) {
	// derived frompal_trx_access
	uint8_t register_value;
	ENTER_CRITICAL_REGION();
	// Prepare the command byte
	address |= HAL_TRX_CMD_RR;
	// Start SPI transaction by pulling SEL low
	hal_set_ss_low();
	// Send the write command byte
	spi_readwrite(RF_SPI,address);
	register_value = spi_readwrite(RF_SPI,0x0);
	// Stop the SPI transaction by setting SEL high
	hal_set_ss_high();

	LEAVE_CRITICAL_REGION();
	return (register_value);
}
Пример #16
0
static rt_err_t fm25_close(rt_device_t dev)
{
	CS_LOW();
    spi_readwrite( FM25_WRDI );
    CS_HIGH();
	SPI_Cmd(FM25_SPI, DISABLE);

	return RT_EOK;
}
Пример #17
0
/*********************************************************************************************************
** Function name:           mcp2515_readStatus
** Descriptions:            read mcp2515's Status
*********************************************************************************************************/
INT8U MCP_CAN::mcp2515_readStatus(void)
{
	INT8U i;
	MCP2515_SELECT();
	spi_readwrite(MCP_READ_STATUS);
	i = spi_read();
	MCP2515_UNSELECT();

	return i;
}
static bool m_aci_spi_transfer(hal_aci_data_t * data_to_send, hal_aci_data_t * received_data)
{
  uint8_t byte_cnt;
  uint8_t byte_sent_cnt;
  uint8_t max_bytes;

  m_aci_reqn_enable();

  // Send length, receive header
  byte_sent_cnt = 0;
  received_data->status_byte = spi_readwrite(data_to_send->buffer[byte_sent_cnt++]);
  // Send first byte, receive length from slave
  received_data->buffer[0] = spi_readwrite(data_to_send->buffer[byte_sent_cnt++]);
  if (0 == data_to_send->buffer[0])
  {
    max_bytes = received_data->buffer[0];
  }
  else
  {
    // Set the maximum to the biggest size. One command byte is already sent
    max_bytes = (received_data->buffer[0] > (data_to_send->buffer[0] - 1))
                                          ? received_data->buffer[0]
                                          : (data_to_send->buffer[0] - 1);
  }

  if (max_bytes > HAL_ACI_MAX_LENGTH)
  {
    max_bytes = HAL_ACI_MAX_LENGTH;
  }

  // Transmit/receive the rest of the packet
  for (byte_cnt = 0; byte_cnt < max_bytes; byte_cnt++)
  {
    received_data->buffer[byte_cnt+1] =  spi_readwrite(data_to_send->buffer[byte_sent_cnt++]);
  }

  // RDYN should follow the REQN line in approx 100ns
  m_aci_reqn_disable();

  return (max_bytes > 0);
}
Пример #19
0
/** \brief read [size] byte from [offset] to [buffer]
 *
 * \param offset uint32_t unit : byte
 * \param buffer uint8_t*
 * \param size uint32_t   unit : byte
 * \return uint32_t byte for read
 *
 */
uint32_t sst25vfxx_read(uint32_t offset,uint8_t * buffer,uint32_t size)
{
    uint32_t index;

    spi_lock();
    spi_config();

    //CS_LOW();
    spi_readwrite( CMD_WRDI );
    //CS_HIGH();

    //CS_LOW();
    spi_readwrite( CMD_READ);
    spi_readwrite(  offset>>16 );
    spi_readwrite(  offset>>8 );
    spi_readwrite(  offset );
#if SPI_FLASH_USE_DMA
    for(index=0; index<size/DMA_BUFFER_SIZE; index++)
    {
        DMA_RxConfiguration((rt_uint32_t)_spi_flash_buffer, DMA_BUFFER_SIZE);
        SPI_I2S_ClearFlag(SPI1, SPI_I2S_FLAG_RXNE);
        SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, ENABLE);
        while (DMA_GetFlagStatus(DMA1_FLAG_TC2) == RESET);
        SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, DISABLE);
        rt_memcpy(buffer,_spi_flash_buffer,DMA_BUFFER_SIZE);
        buffer += DMA_BUFFER_SIZE;
    }
#else
    for(index=0; index<size; index++)
    {
        *buffer++ = spi_readwrite(0xFF);
    }
#endif
    //CS_HIGH();

    spi_unlock();

    return size;
}
Пример #20
0
/** \brief  This function writes a new value to one of the radio transceiver's
 *          registers.
 *  \see Look at the at86rf231_registermap.h file for register address definitions.
 *  \param  address Address of register to write.
 *  \param  value   Value to write.
 */
void
hal_register_write( uint8_t address, uint8_t value ) {

	ENTER_CRITICAL_REGION();

    // Prepare the command byte
    address |= HAL_TRX_CMD_RW;

    // Start SPI transaction by pulling SEL low
    hal_set_ss_low();

    // Send the Read command byte
    spi_readwrite(RF_SPI,address);

    // Write the byte in the transceiver data register
    spi_readwrite(RF_SPI,value);

    // Stop the SPI transaction by setting SEL high
    hal_set_ss_high();

    LEAVE_CRITICAL_REGION();
}
Пример #21
0
rt_size_t fm25_write(rt_device_t dev, rt_off_t offset, const void * buf, rt_size_t size)
{
    uint32_t index = size;

	uint8_t *buffer = (uint8_t*) buf;
    fram_lock();
    //spi_config();
	//rt_kprintf("WRITE: %d, size=%d\n", offset, size);
	CS_LOW();
    spi_readwrite( FM25_WREN );
	CS_HIGH();
	CS_LOW();
    spi_readwrite( FM25_WRITE);
	spi_readwrite( (offset >> 8)&0xFF );
	spi_readwrite( offset & 0xFF  );
	while( index > 0 )
	{
		spi_readwrite( *buffer++ );

		if( spi_timeout_cnt > 0 )
		{
			fram_unlock();
			rt_kprintf("Write time out\n");
			spi_timeout_cnt = 0;
			return -1;
		}
		index--;
		offset++;	
	}
    CS_HIGH();
	//rt_thread_delay(100);

    fram_unlock();

    return size;
}
Пример #22
0
hal_aci_data_t * hal_aci_tl_poll_get(void)
{
  uint8_t byte_cnt;
  uint8_t byte_sent_cnt;
  uint8_t max_bytes;
  hal_aci_data_t data_to_send;


  //SPI.begin();
    
  HAL_IO_SET_STATE(HAL_IO_RADIO_REQN, 0);
  
  // Receive from queue
  if (m_aci_q_dequeue(&aci_tx_q, &data_to_send) == false)
  {
    /* queue was empty, nothing to send */
    data_to_send.status_byte = 0;
    data_to_send.buffer[0] = 0;
  }
  
  //Change this if your mcu has DMA for the master SPI
  
  // Send length, receive header
  byte_sent_cnt = 0;
  received_data.status_byte = spi_readwrite(data_to_send.buffer[byte_sent_cnt++]);
  // Send first byte, receive length from slave
  received_data.buffer[0] = spi_readwrite(data_to_send.buffer[byte_sent_cnt++]);
  if (0 == data_to_send.buffer[0])
  {
    max_bytes = received_data.buffer[0];
  }
  else
  {
    // Set the maximum to the biggest size. One command byte is already sent
    max_bytes = (received_data.buffer[0] > (data_to_send.buffer[0] - 1)) 
      ? received_data.buffer[0] : (data_to_send.buffer[0] - 1);
  }

  if (max_bytes > HAL_ACI_MAX_LENGTH)
  {
    max_bytes = HAL_ACI_MAX_LENGTH;
  }

  // Transmit/receive the rest of the packet 
  for (byte_cnt = 0; byte_cnt < max_bytes; byte_cnt++)
  {
    received_data.buffer[byte_cnt+1] =  spi_readwrite(data_to_send.buffer[byte_sent_cnt++]);
  }

  HAL_IO_SET_STATE(HAL_IO_RADIO_REQN, 1);
  //SPI.end();
  //RDYN should follow the REQN line in approx 100ns
  
  sleep_enable();
  attachInterrupt(HAL_IO_RADIO_IRQ, m_rdy_line_handle, LOW);  


  
  if (false == m_aci_q_is_empty(&aci_tx_q))
  {
    //Lower the REQN line to start a new ACI transaction         
    HAL_IO_SET_STATE(HAL_IO_RADIO_REQN, 0); 
  }
  
  /* valid Rx available or transmit finished*/
  return (&received_data);
}
Пример #23
0
/** \brief write N page on [page]
 *
 * \param page uint32_t unit : byte (4096 * N,1 page = 4096byte)
 * \param buffer const uint8_t*
 * \param size uint32_t unit : byte ( 4096*N )
 * \return uint32_t
 *
 */
uint32_t sst25vfxx_page_write(uint32_t page,const uint8_t * buffer,uint32_t size)
{
    uint32_t index;

    page &= ~0xFFF; // page size = 4096byte

    spi_lock();
    spi_config();

    //CS_LOW();
    spi_readwrite( CMD_WREN );//write en
    //CS_HIGH();

    //CS_LOW();
    spi_readwrite( CMD_ERASE_4K );
    spi_readwrite( page >> 16 );
    spi_readwrite( page >> 8 );
    spi_readwrite( page  );
    //CS_HIGH();

    sst25vfxx_wait_busy(); // wait erase done.

    //CS_LOW();
    spi_readwrite( CMD_WREN );//write en
    //CS_HIGH();

    //CS_LOW();
    spi_readwrite( CMD_AAIP );
    spi_readwrite(  page>>16 );
    spi_readwrite(  page>>8 );
    spi_readwrite(  page );

    spi_readwrite( *buffer++ );
    spi_readwrite( *buffer++ );
    size -= 2;
    //CS_HIGH();

    sst25vfxx_wait_busy();

    for(index=0; index < size/2; index++)
    {
        //CS_LOW();
        spi_readwrite( CMD_AAIP );
        spi_readwrite( *buffer++ );
        spi_readwrite( *buffer++ );
        //CS_HIGH();
        sst25vfxx_wait_busy();
    }
    //CS_HIGH();

    //CS_LOW();
    spi_readwrite( CMD_WRDI );
    //CS_HIGH();

    spi_unlock();
    return size;
}
Пример #24
0
byte sonar::spi_read(void)
{
	return spi_readwrite(TRANSFER_DATA);
}
Пример #25
0
/** \brief sst25vfxx SPI flash init
 *
 * \param void
 * \return void
 *
 */
rt_err_t rt_hw_sst25vfxx_init(const char * spi_device_name)
{
    port_init();
	
		if (rt_sem_init(&spi2_lock, "spi2lock", 1, RT_IPC_FLAG_FIFO) != RT_EOK)
		{
				rt_kprintf("init spi2 lock semaphore failed\n");
		}
		
		
		rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
		if(rt_spi_device == RT_NULL)
		{
				FLASH_TRACE("spi device %s not found!\r\n", spi_device_name);
				return -RT_ENOSYS;
		}
		
		
/* config spi */
{
		struct rt_spi_configuration cfg;
		cfg.data_width = 8;
		cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0 and Mode 3 */
		cfg.max_hz = 9 * 1000 * 1000; /* 10M */
		rt_spi_configure(rt_spi_device, &cfg);
}
		
    spi_lock();
    spi_config();
    //CS_LOW();
    spi_readwrite( CMD_WRDI );
    //CS_HIGH();

    //CS_LOW();
    spi_readwrite( CMD_JEDEC_ID );
    device_id  = spi_readwrite(0xFF);
    device_id |= spi_readwrite(0xFF)<<8;
    device_id |= spi_readwrite(0xFF)<<16;
    //CS_HIGH();

		
    if(device_id == SST25VF016)
    {
        FLASH_TRACE("FLASH TYPE : SST25VF016\r\n");
				rt_kprintf("SPI Flash device_id is : 0x%X !\n",device_id);
        //CS_LOW();
        spi_readwrite( CMD_DBSY );
        //CS_HIGH();

        //CS_LOW();
        spi_readwrite( CMD_EWSR );
        //CS_HIGH();

        //CS_LOW();
        spi_readwrite( CMD_WRSR );
        spi_readwrite( 0 );
        //CS_HIGH();
    }
rt_kprintf("SPI Flash device_id is : 0x%X !\n",device_id);
    spi_unlock();

    spi_flash_device.type    = RT_Device_Class_Block;
    spi_flash_device.init    = sst25vfxx_flash_init;
    spi_flash_device.open    = sst25vfxx_flash_open;
    spi_flash_device.close   = sst25vfxx_flash_close;
    spi_flash_device.read 	 = sst25vfxx_flash_read;
    spi_flash_device.write   = sst25vfxx_flash_write;
    spi_flash_device.control = sst25vfxx_flash_control;
    /* no private */
    spi_flash_device.user_data = RT_NULL;

    rt_device_register(&spi_flash_device, "spi0",
                       RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);			
		return	RT_EOK;
}
Пример #26
0
hal_aci_data_t * hal_aci_tl_poll_get(void)
{
  uint8_t byte_cnt;
  uint8_t byte_sent_cnt;
  uint8_t max_bytes;
  hal_aci_data_t data_to_send;



  digitalWrite(a_pins_local_ptr->reqn_pin, 0);
  
  // Receive from queue
  if (m_aci_q_dequeue(&aci_tx_q, &data_to_send) == false)
  {
    /* queue was empty, nothing to send */
    data_to_send.status_byte = 0;
    data_to_send.buffer[0] = 0;
  }
  
  //Change this if your mcu has DMA for the master SPI
  
  // Send length, receive header
  byte_sent_cnt = 0;
  
  //Byte at index 0 sent, byte from slave is the status byte
  received_data.status_byte = spi_readwrite(data_to_send.buffer[byte_sent_cnt++]);
  // Send first byte, receive length from slave
  received_data.buffer[0] = spi_readwrite(data_to_send.buffer[byte_sent_cnt++]);
  
  
  if (0 == data_to_send.buffer[0])
  {
    max_bytes = received_data.buffer[0];
  }
  else
  {
    // Set the maximum to the biggest size. One command byte is already sent
    max_bytes = (received_data.buffer[0] > (data_to_send.buffer[0] - 1)) 
      ? received_data.buffer[0] : (data_to_send.buffer[0] - 1);
  }

  if (max_bytes > HAL_ACI_MAX_LENGTH)
  {
    max_bytes = HAL_ACI_MAX_LENGTH;
  }

  // Transmit/receive the rest of the packet 
  for (byte_cnt = 0; byte_cnt < max_bytes; byte_cnt++)
  {
    received_data.buffer[byte_cnt+1] =  spi_readwrite(data_to_send.buffer[byte_sent_cnt++]);
  }

  //REQN/SS is set to high
  digitalWrite(a_pins_local_ptr->reqn_pin, 1);
  //RDYN should automatically follow the REQN line in approx 100ns
  
  //sleep_enable();
  if (a_pins_local_ptr->interface_is_interrupt)
  {
	attachInterrupt(a_pins_local_ptr->interrupt_number, m_rdy_line_handle, LOW);	  
  }


  
  if (false == m_aci_q_is_empty(&aci_tx_q))
  {
    //Lower the REQN line to start a new ACI transaction         
    digitalWrite(a_pins_local_ptr->reqn_pin, 0); 
  }
  
  /* valid Rx available or transmit finished*/
  return (&received_data);
}