text: /*******************************************************************************
   MRF24WG register access
  
    Summary: Functions to access registers on MRF24WG
  
    Description: Same as summary
  *******************************************************************************/
  
  /* MRF24WG0M Universal Driver
  *
  * Copyright (c) 2012-2013, Microchip <www.microchip.com>
  * Contact Microchip for the latest version.
  *
  * This program is free software; distributed under the terms of BSD
  * license:
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *
  * 1.    Redistributions of source code must retain the above copyright notice, this
  *        list of conditions and the following disclaimer.
  * 2.    Redistributions in binary form must reproduce the above copyright notice,
  *        this list of conditions and the following disclaimer in the documentation
  *        and/or other materials provided with the distribution.
  * 3.    Neither the name(s) of the above-listed copyright holder(s) nor the names
  *        of its contributors may be used to endorse or promote products derived
  *        from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  */
  /*
   * Modified for port to ARC processor
   * by Huaqi Fang huaqi.fang@synopsys.com, Synopsys, Inc.
   */
  
  //==============================================================================
  //                                  INCLUDES
  //==============================================================================
  #include <stdlib.h>
  #include "wf_dev_hal.h"
  
  #include "./inc/shared/wf_universal_driver.h"
  #include "./inc/internal/wf_global_includes.h"
  
  //==============================================================================
  //                                  LOCAL GLOBALS
  //==============================================================================
  // using global buffers because the register functions are called from the
  // external interrupt routine, and for parts that use overlay memory using local
  // buffers fails.
  static uint8_t g_txBuf[3];
  static uint8_t g_rxBuf[3];
  
  static DEV_SPI_TRANSFER wf_spi_tsf_cmd;
  
  #define WFSPI_CHECK_EXP_NORTN(EXPR)     CHECK_EXP_NOERCD(EXPR, error_exit)
  
  /*****************************************************************************
   * FUNCTION: Read8BitWFRegister
   *
   * RETURNS: register value
   *
   * PARAMS:
   *      regId -- ID of 8-bit register being read
   *
   *  NOTES: Reads WF 8-bit register
   *****************************************************************************/
  uint8_t Read8BitWFRegister(uint8_t regId)
  {
      WF_OPS *p_wf_ops = get_wf_ops();
  
      WFSPI_CHECK_EXP_NORTN(p_wf_ops);
  
      g_txBuf[0] = regId | WF_READ_REGISTER_MASK;
  
      p_wf_ops->spi_ops->spi_cs(WF_CHIP_SELECTED);
  
      DEV_SPI_XFER_SET_TXBUF(&wf_spi_tsf_cmd, g_txBuf, 0, 1);
      DEV_SPI_XFER_SET_RXBUF(&wf_spi_tsf_cmd, g_rxBuf, 1, 1);
      DEV_SPI_XFER_SET_NEXT(&wf_spi_tsf_cmd, NULL);
  
      p_wf_ops->spi_ops->spi_transfer(&wf_spi_tsf_cmd);
  
      p_wf_ops->spi_ops->spi_cs(WF_CHIP_DESELECTED);
  
  error_exit:
      return g_rxBuf[0];   /* register value returned in the second byte clocking */
  }
  
  /*****************************************************************************
   * FUNCTION: Write8BitWFRegister
   *
   * RETURNS: None
   *
   * PARAMS:
   *      regId -- ID of 8-bit register being written to
   *      value -- value to write
   *
   *  NOTES: Writes WF 8-bit register
   *****************************************************************************/
  void Write8BitWFRegister(uint8_t regId, uint8_t value)
  {
      WF_OPS *p_wf_ops = get_wf_ops();
  
      WFSPI_CHECK_EXP_NORTN(p_wf_ops);
  
      g_txBuf[0] = regId | WF_WRITE_REGISTER_MASK;
      g_txBuf[1] = value;
  
      p_wf_ops->spi_ops->spi_cs(WF_CHIP_SELECTED);
  
      DEV_SPI_XFER_SET_TXBUF(&wf_spi_tsf_cmd, g_txBuf, 0, 2);
      DEV_SPI_XFER_SET_RXBUF(&wf_spi_tsf_cmd, g_rxBuf, 2, 0);
      DEV_SPI_XFER_SET_NEXT(&wf_spi_tsf_cmd, NULL);
  
      p_wf_ops->spi_ops->spi_transfer(&wf_spi_tsf_cmd);
  
      p_wf_ops->spi_ops->spi_cs(WF_CHIP_DESELECTED);
  
  error_exit:
      return;
  }
  
  /*****************************************************************************
   * FUNCTION: Write16BitWFRegister
   *
   * RETURNS: None
   *
   * PARAMS:
   *      regId -- ID of 16-bit register being written to
   *      value -- value to write
   *
   *  NOTES: Writes WF 16-bit register
   *****************************************************************************/
  void Write16BitWFRegister(uint8_t regId, uint16_t value)
  {
      WF_OPS *p_wf_ops = get_wf_ops();
  
      WFSPI_CHECK_EXP_NORTN(p_wf_ops);
  
      g_txBuf[0] = regId | WF_WRITE_REGISTER_MASK;
      g_txBuf[1] = (uint8_t)(value >> 8);       /* MS byte being written     */
      g_txBuf[2] = (uint8_t)(value & 0x00ff);   /* LS byte being written     */
  
      p_wf_ops->spi_ops->spi_cs(WF_CHIP_SELECTED);
  
      DEV_SPI_XFER_SET_TXBUF(&wf_spi_tsf_cmd, g_txBuf, 0, 3);
      DEV_SPI_XFER_SET_RXBUF(&wf_spi_tsf_cmd, g_rxBuf, 3, 0);
      DEV_SPI_XFER_SET_NEXT(&wf_spi_tsf_cmd, NULL);
  
      p_wf_ops->spi_ops->spi_transfer(&wf_spi_tsf_cmd);
  
      p_wf_ops->spi_ops->spi_cs(WF_CHIP_DESELECTED);
  
  error_exit:
      return;
  }
  
  /*****************************************************************************
   * FUNCTION: Read16BitWFRegister
   *
   * RETURNS: register value
   *
   * PARAMS:
   *      regId -- ID of 16-bit register being read
   *
   *  NOTES: Reads WF 16-bit register
   *****************************************************************************/
  uint16_t Read16BitWFRegister(uint8_t regId)
  {
      WF_OPS *p_wf_ops = get_wf_ops();
  
      WFSPI_CHECK_EXP_NORTN(p_wf_ops);
  
      g_txBuf[0] = regId | WF_READ_REGISTER_MASK;
  
      p_wf_ops->spi_ops->spi_cs(WF_CHIP_SELECTED);
  
      DEV_SPI_XFER_SET_TXBUF(&wf_spi_tsf_cmd, g_txBuf, 0, 1);
      DEV_SPI_XFER_SET_RXBUF(&wf_spi_tsf_cmd, g_rxBuf, 1, 2);
      DEV_SPI_XFER_SET_NEXT(&wf_spi_tsf_cmd, NULL);
  
      p_wf_ops->spi_ops->spi_transfer(&wf_spi_tsf_cmd);
  
      p_wf_ops->spi_ops->spi_cs(WF_CHIP_DESELECTED);
  
  error_exit:
      return (((uint16_t)g_rxBuf[0]) << 8) | ((uint16_t)(g_rxBuf[1]));
  }
  
  /*****************************************************************************
   * FUNCTION: WriteWFArray
   *
   * RETURNS: None
   *
   * PARAMS:
   *      regId  -- Raw register being written to
   *      pBuf   -- pointer to array of bytes being written
   *      length -- number of bytes in pBuf
   *
   *  NOTES: Writes a data block to specified raw register
   *****************************************************************************/
  void WriteWFArray(uint8_t regId, const uint8_t *p_Buf, uint16_t length)
  {
      uint8_t *data_buf;
      uint16_t i;
      WF_OPS *p_wf_ops = get_wf_ops();
  
      WFSPI_CHECK_EXP_NORTN(p_wf_ops);
  
      data_buf = malloc(length + 1);
  
      if (data_buf == NULL) {
          return;
      }
  
      data_buf[0] = regId;
      for (i = 1; i <= length ; i++) {
          data_buf[i] = *p_Buf;
          p_Buf++;
      }
  
      p_wf_ops->spi_ops->spi_cs(WF_CHIP_SELECTED);
  
      DEV_SPI_XFER_SET_TXBUF(&wf_spi_tsf_cmd, data_buf, 0, length + 1);
      DEV_SPI_XFER_SET_RXBUF(&wf_spi_tsf_cmd, g_rxBuf, 1, 0);
      DEV_SPI_XFER_SET_NEXT(&wf_spi_tsf_cmd, NULL);
  
     // DEV_SPI_XFER_SET_TXBUF(&wf_spi_tsf_data, p_Buf, 0, length);
     // DEV_SPI_XFER_SET_RXBUF(&wf_spi_tsf_data, g_rxBuf, length, 0);
     // DEV_SPI_XFER_SET_NEXT(&wf_spi_tsf_data, NULL);
  
      p_wf_ops->spi_ops->spi_transfer(&wf_spi_tsf_cmd);
  
      p_wf_ops->spi_ops->spi_cs(WF_CHIP_DESELECTED);
  
      free(data_buf);
  
  error_exit:
      return;
  }
  
  /*****************************************************************************
   * FUNCTION: ReadWFArray
   *
   * RETURNS: None
   *
   * PARAMS:
   *      regId  -- Raw register being read from
   *      pBuf   -- pointer where to write out bytes
   *      length -- number of bytes to read
   *
   *  NOTES: Reads a block of data from a raw register
   *****************************************************************************/
  void ReadWFArray(uint8_t  regId, uint8_t *p_Buf, uint16_t length)
  {
      WF_OPS *p_wf_ops = get_wf_ops();
  
      WFSPI_CHECK_EXP_NORTN(p_wf_ops);
  
      /* output command byte */
      g_txBuf[0] = regId | WF_READ_REGISTER_MASK;
  
      p_wf_ops->spi_ops->spi_cs(WF_CHIP_SELECTED);
  
      DEV_SPI_XFER_SET_TXBUF(&wf_spi_tsf_cmd, g_txBuf, 0, 1);
      DEV_SPI_XFER_SET_RXBUF(&wf_spi_tsf_cmd, p_Buf, 1, length);
      DEV_SPI_XFER_SET_NEXT(&wf_spi_tsf_cmd, NULL);
  
      // DEV_SPI_XFER_SET_TXBUF(&wf_spi_tsf_data, p_Buf, 0, 0);
      // DEV_SPI_XFER_SET_RXBUF(&wf_spi_tsf_data, p_Buf, 0, length);
      // DEV_SPI_XFER_SET_NEXT(&wf_spi_tsf_data, NULL);
  
      p_wf_ops->spi_ops->spi_transfer(&wf_spi_tsf_cmd);
  
      p_wf_ops->spi_ops->spi_cs(WF_CHIP_DESELECTED);
  
  error_exit:
      return;
  }
  
  
  