ADF7030-1 Device Drivers API Reference Manual  Alpha 0.0.1
Device Drivers for ADF7030-1 Transceiver
adf7030-1__cfg.c
1 /*********************************************************************************
2 
3 Copyright(c) 2016 Analog Devices, Inc. All Rights Reserved.
4 
5 This software is proprietary and confidential. By using this software you agree
6 to the terms of the associated Analog Devices License Agreement.
7 
8 *********************************************************************************/
26 #ifndef _ADF7030_1__CFG_C_
27 
28 #define _ADF7030_1__CFG_C_
29 
30 #include <stddef.h>
31 #include <string.h>
32 #include <assert.h>
33 #include "system.h"
34 #include "common.h"
35 
36 #include <drivers/spi/adi_spi.h>
37 //#include <devices/rf/adf703x/adi_adf7030-1.h>
38 //#include <devices/rf/adf703x/adi_adf7030-1_reg.h>
39 #include <devices/rf/adf703x/adf7030-1__spi.h>
40 #include <devices/rf/adf703x/adf7030-1__mem.h>
41 #include <devices/rf/adf703x/adf7030-1__cfg.h>
42 
43 
44 #ifdef __ICCARM__
45 /*
46 * IAR MISRA C 2004 error suppressions.
47 *
48 * Pm140 (rule 11.3): a cast should not be performed between a pointer type and an integral type
49 * The rule makes an exception for memory-mapped register accesses.
50 *
51 * Pm073 (rule 14.7): a function should have a single point of exit.
52 * Pm143 (rule 14.7): a function should have a single point of exit at the end of the function.
53 * Multiple returns are used for error handling.
54 */
55 #pragma diag_suppress=Pm073,Pm143
56 #endif /* __ICCARM__ */
57 
60 /* SPI Configuration transfer buffer */
61 static uint8_t spi_CfgBuffer[ADF7030_1_SPI_BUFFER_SIZE];
62 
63 
81  ADI_SPI_HANDLE hSPIDevice,
82  uint8_t * pCONFIG,
83  uint32_t Size
84 )
85 {
86 
87  uint32_t array_position = 0;
88 
89  do
90  {
91  // Calculate the number of bytes to write
92  uint32_t length = (*(pCONFIG + array_position ) << 16) |
93  (*(pCONFIG + array_position + 1) << 8) |
94  (*(pCONFIG + array_position + 2));
95 
96  if(length > 0xFFFF)
97  {
98  return FAILURE;
99  }
100 
101  // Write the SPI data pointed to location (MEMORY_FILE + array_position) with specified length (length)
102  uint8_t * pSeqData = (pCONFIG + array_position + 3);
103 
104  // Transfer the Configuration sequence
105  if(adf7030_1__XferCfgSeq(hSPIDevice, pSeqData, length - 4) != SUCCESS)
106  {
107  return FAILURE;
108  }
109 
110  // Update the array position to point to the next block
111  array_position += length;
112 
113  }while(array_position < Size); // Continue operation until full data file has been written
114 
115  return SUCCESS;
116 }
117 
118 
137  ADI_SPI_HANDLE hSPIDevice,
138  uint8_t *pData,
139  uint32_t Size
140 )
141 {
142  // Retrieve Size actual size of sequence
143  switch( *pData & 0x78 )
144  {
145  // 32bits Address Block Write Access of the "Configuration Format"
146  case( ADF703x_SPI_MEM_WRITE | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_ADDRESS | ADF703x_SPI_MEM_LONG ) :
147  {
148  // Move cfg sequence pointer by 1 byte
149  pData++;
150 
151  // Get the Xfer byte size
152  uint32_t SeqDataLen = (Size - 4);
153 
154  // Get the PHY Radio where to write sequence + change pointer to start of data sequence
155  uint32_t Addr = __REV(*(uint32_t *)pData);
156 
157  // Currently, the RADIO SPI driver is implemented to provide a one-to-one relationship
158  // between memory bloc representation of the PHY Radio and the HOST. (Provided the underlying endianness is the same)
159  // Byte transfer via the adf7030_1 SPI interface is done in natural fashion (byteaddress increment)
160  // However 32bits word transfers are wordaddress increment. Each word must byte reversed (intrinsic __REV() on ARM Cortex does just that)
161  // Current driver SPIs call are already rev-ing words to comply with SPI word transfer protocol
162 
163  // This version of ADI Radio SPI driver does not fully support the recommended *.cfg file format where
164  // rev-ing is already done as part of the sequence
165 
166  // So for now, we just need to unrev data...
167  uint32_t * pUNREV_BUFF = (uint32_t *)spi_CfgBuffer;
168  uint32_t * pSEQ_BUFF = (uint32_t *)pData;
169 
170  pSEQ_BUFF++;
171 
172  for(uint32_t i = 0; i < (SeqDataLen >> 2); i++)
173  {
174  *pUNREV_BUFF++ = __REV(*pSEQ_BUFF++);
175  }
176 
177  // Transfert data to using the existing RADIO SPI driver
178  if(adf7030_1__SPI_wr_word_b_a(hSPIDevice, Addr, SeqDataLen >> 2, (uint32_t *)spi_CfgBuffer) != SUCCESS)
179  {
180  return FAILURE;
181  }
182  break;
183  }
184 
185  // 32bits Pointer Block Write Access of the "Configuration Format"
186  case( ADF703x_SPI_MEM_WRITE | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_POINTER | ADF703x_SPI_MEM_LONG ) :
187  {
188  // Get the SPI Pointer ID from the Cfg Sequence
190 
191  // Get the Xfer byte size
192  uint32_t SeqDataLen = Size;
193 
194  // So for now, we just need to unrev data...
195  uint32_t * pUNREV_BUFF = (uint32_t *)spi_CfgBuffer;
196  uint32_t * pSEQ_BUFF = (uint32_t *)pData;
197 
198  pSEQ_BUFF++;
199 
200  for(uint32_t i = 0; i < (SeqDataLen >> 2); i++)
201  {
202  *pUNREV_BUFF++ = __REV(*pSEQ_BUFF++);
203  }
204 
205  // Transfert data to using the existing RADIO SPI driver
206  if(adf7030_1__SPI_wr_word_b_p(hSPIDevice, pntrID, SeqDataLen >> 2, (uint32_t *)spi_CfgBuffer) != SUCCESS)
207  {
208  return FAILURE;
209  }
210 
211  break;
212  }
213 
214  // 8bits Block Write Access with Offset of the "Configuration Format"
215  case( ADF703x_SPI_MEM_WRITE | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_ADDRESS | ADF703x_SPI_MEM_SHORT ) :
216  {
217  // Get the SPI Pointer ID from the Cfg Sequence
219 
220  // Get the Address Offset
221  uint8_t Addr = *pData++;
222 
223  // Get the Xfer byte size
224  uint32_t SeqDataLen = (Size - 1);
225 
226  // Transfert data to using the existing RADIO SPI driver
227  if(adf7030_1__SPI_wr_byte_b_a(hSPIDevice, pntrID, (uint32_t)Addr, SeqDataLen, pData) != SUCCESS)
228  {
229  return FAILURE;
230  }
231 
232  break;
233  }
234 
235  // 8bits Block Write Access of the "Configuration Format"
236  case( ADF703x_SPI_MEM_WRITE | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_POINTER | ADF703x_SPI_MEM_SHORT ) :
237  {
238  // Get the SPI Pointer ID from the Cfg Sequence
240 
241  // Get the Xfer byte size
242  uint32_t SeqDataLen = Size;
243 
244  // Transfert data to using the existing RADIO SPI driver
245  if(adf7030_1__SPI_wr_byte_p_a(hSPIDevice, pntrID, SeqDataLen, pData) != SUCCESS)
246  {
247  return FAILURE;
248  }
249  break;
250  }
251 
252  default : return FAILURE;
253  }
254  return SUCCESS;
255 }
256 
257 
258 #endif /* _ADF7030_1__CFG_C_ */
259  /* End of group adf7030-1__cfg PHY Config Interface */ /* End of group adf7030-1 adf7030-1 Driver */
uint32_t adf7030_1__SPI_wr_byte_p_a(ADI_SPI_HANDLE hSPIDevice, ADI_ADF7030_1_RADIO_SPI_PNTR_TYPE pntrID, uint32_t num_xfrs, uint8_t *pDataIn)
Write a number of byte(s) from Host to memory of the adf7030-1 starting at location pointed by "pntr"...
#define ADF7030_1_SPI_BUFFER_SIZE
uint32_t adf7030_1__SendConfiguration(ADI_SPI_HANDLE hSPIDevice, uint8_t *pCONFIG, uint32_t Size)
ADI Radio Configuration transfer function.
uint32_t adf7030_1__XferCfgSeq(ADI_SPI_HANDLE hSPIDevice, uint8_t *pData, uint32_t Size)
ADI Radio SPI sequence configuration transfer.
uint32_t adf7030_1__SPI_wr_word_b_p(ADI_SPI_HANDLE hSPIDevice, ADI_ADF7030_1_RADIO_SPI_PNTR_TYPE pntrID, uint32_t num_xfrs, uint32_t *pDataIn)
Write a number of word(s) from Host to memory of the adf7030-1 starting at location pointed by "pntr"...
ADI_ADF7030_1_RADIO_SPI_PNTR_TYPE
uint32_t adf7030_1__SPI_wr_word_b_a(ADI_SPI_HANDLE hSPIDevice, uint32_t AddrIn, uint32_t num_xfrs, uint32_t *pDataIn)
Write a number of word(s) from Host to memory of the adf7030-1 Generic 32bits bloc address write to m...
uint32_t adf7030_1__SPI_wr_byte_b_a(ADI_SPI_HANDLE hSPIDevice, ADI_ADF7030_1_RADIO_SPI_PNTR_TYPE pntrID, uint32_t AddrIn, uint32_t num_xfrs, uint8_t *pDataIn)
Write a number of byte(s) from Host to memory of the adf7030-1 starting at location pointed by "pntr"...