ADF7030-1 Device Drivers API Reference Manual  Alpha 0.0.1
Device Drivers for ADF7030-1 Transceiver
adf7030-1__spi.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 *********************************************************************************/
27 #ifndef _ADF7030_1__SPI_C_
28 
30 #define _ADF7030_1__SPI_C_
31 
32 #include <stddef.h>
33 #include <string.h>
34 #include <assert.h>
35 #include "system.h"
36 #include "common.h"
37 
38 #include <drivers/spi/adi_spi.h>
39 //#include <devices/rf/adf703x/adi_adf7030-1.h>
40 //#include <devices/rf/adf703x/adi_adf7030-1_reg.h>
41 #include <devices/rf/adf703x/adf7030-1__spi.h>
42 
43 #ifdef __ICCARM__
44 /*
45 * IAR MISRA C 2004 error suppressions.
46 *
47 * Pm140 (rule 11.3): a cast should not be performed between a pointer type and an integral type
48 * The rule makes an exception for memory-mapped register accesses.
49 *
50 * Pm073 (rule 14.7): a function should have a single point of exit.
51 * Pm143 (rule 14.7): a function should have a single point of exit at the end of the function.
52 * Multiple returns are used for error handling.
53 */
54 #pragma diag_suppress=Pm073,Pm143
55 #endif /* __ICCARM__ */
56 
59 /* Memory required for SPI driver */
60 uint8_t SPIMem[ADI_SPI_MEMORY_SIZE];
61 
62 /* SPI device handle */
63 ADI_SPI_HANDLE hSPIDevice;
64 
65 /* SPI transfers buffers */
66  uint8_t spi_txbuf[ADF7030_1_SPI_BUFFER_SIZE];
67  uint8_t spi_rxbuf[ADF7030_1_SPI_BUFFER_SIZE];
68 
69 
84  void
85 )
86 {
87  if(adi_spi_Open(SPI_DEV_NUM,
88  SPIMem,
89  ADI_SPI_MEMORY_SIZE,
90  &hSPIDevice) != ADI_SPI_SUCCESS)
91  {
92  return FAILURE;
93  }
94 
95  /* Enable underflow errors */
96  if(adi_spi_SetTransmitUnderflow(hSPIDevice, true) != ADI_SPI_SUCCESS)
97  {
98  return FAILURE;
99  }
100 
101  /* Set the SPI clock rate */
102  if(adi_spi_SetBitrate(hSPIDevice, SPI_DEV_BITRATE) != ADI_SPI_SUCCESS)
103  {
104  return FAILURE;
105  }
106 
107  /* Set the chip select */
108  if(adi_spi_SetChipSelect(hSPIDevice, ADI_SPI_CS3) != ADI_SPI_SUCCESS)
109  {
110  return FAILURE;
111  }
112 
113  /* Set the SPI clock phase */
114  if(adi_spi_SetClockPhase(hSPIDevice, false) != ADI_SPI_SUCCESS)
115  {
116  return FAILURE;
117  }
118 
119  /* Set the continuous transfer mode */
120  if(adi_spi_SetContinousMode(hSPIDevice, true) != ADI_SPI_SUCCESS)
121  {
122  return FAILURE;
123  }
124 
125  /* Disable DMA transfer mode */
126  if(adi_spi_EnableDmaMode(hSPIDevice, false) != ADI_SPI_SUCCESS)
127  {
128  return FAILURE;
129  }
130 
131  return SUCCESS;
132 }
133 
147  void
148 )
149 {
150  if(adi_spi_Close(hSPIDevice) != ADI_SPI_SUCCESS)
151  {
152  return FAILURE;
153  }
154 
155  return SUCCESS;
156 }
157 
174  const uint32_t RateHz
175 )
176 {
177  if(adi_spi_SetBitrate(hSPIDevice,RateHz) != ADI_SPI_SUCCESS)
178  {
179  return FAILURE;
180  }
181 
182  return SUCCESS;
183 }
184 
200  ADI_SPI_HANDLE hSPIDevice,
201  uint32_t * pPNTR
202 )
203 {
204  return(adf7030_1__SPI_wr_word_b_p( hSPIDevice, PNTR_SETUP_ADDR, 3, pPNTR));
205 }
206 
222  ADI_SPI_HANDLE hSPIDevice,
223  uint32_t * pPNTR
224 )
225 {
226  return(adf7030_1__SPI_rd_word_b_p( hSPIDevice, PNTR_SETUP_ADDR, 3, pPNTR));
227 }
228 
248  ADI_SPI_HANDLE hSPIDevice,
249  uint32_t Addr,
251  int32_t * ByteOffset
252 )
253 {
254  uint32_t mId = 0;
255  int32_t diff;
256 
257  *pPNTR_ID = 0;
258 
259  /* Search through ADF7030_1_SPI_PNTR[] for a Pointer within range of "Addr" */
260  for(uint32_t id = PNTR_SRAM_ADDR; id <= PNTR_CUSTOM2_ADDR; id++)
261  {
262  /* Calculate byte offset with the current ADF7030_1_SPI_PNTR[id] */
263  diff = (int32_t)Addr - (int32_t)ADF7030_1_SPI_PNTR[id];
264 
265  /* Stop search if offset within range */
266  if((diff > 0) && (diff <= 255))
267  {
268  mId = id;
269  *ByteOffset = diff;
270  }
271  else if(diff == 0)
272  {
273  mId = id;
274  *ByteOffset = diff;
275  }
276  }
277 
278  if(mId)
279  {
280  /* ADF7030_1_SPI_PNTR[] contains "Addr", Write Back pPNTR_ID variable */
281  *pPNTR_ID = mId;
282  }
283 }
284 
285 
300  ADI_SPI_HANDLE hSPIDevice,
301  uint32_t Addr
302 )
303 {
304  /* Update the host ADF7030_1_SPI_PNTR[PNTR_CUSTOM0_ADDR] to Addr value */
305  ADF7030_1_SPI_PNTR[PNTR_CUSTOM0_ADDR] = Addr;
306 
307  /* Update the Radio PHY spi pointer 0 */
308  return(adf7030_1__SPI_wr_word_b_p( hSPIDevice, PNTR_SETUP_ADDR, 1, &ADF7030_1_SPI_PNTR[PNTR_CUSTOM0_ADDR]));
309 }
310 
311 
344  ADI_SPI_HANDLE hSPIDevice,
345  uint32_t AddrIn,
346  uint32_t num_xfrs,
347  uint32_t *pDataIn
348 )
349 {
350  /* Transmit SPI command - use 3bytes offset to keep rest of data alligned on word boundary */
351  spi_txbuf[3] = ADF703x_SPI_MEM_WRITE |
352  ADF703x_SPI_MEM_BLOCK |
353  ADF703x_SPI_MEM_ADDRESS |
354  ADF703x_SPI_MEM_LONG;
355 
356  /* Write the starting address in the spi_txbuf */
357  *(((uint32_t *)spi_txbuf) + 1) = __REV(AddrIn);
358 
359  return(adf7030_1__SPI_Block_Xfer( hSPIDevice, 3, 0, AddrIn, num_xfrs << 2, pDataIn, NULL));
360  }
361 
393  ADI_SPI_HANDLE hSPIDevice,
394  uint32_t AddrIn,
395  uint32_t num_xfrs,
396  uint32_t * pDataOut
397 )
398 {
399  return(adf7030_1__SPI_rd_cmp_word_b_a(hSPIDevice, AddrIn, num_xfrs, pDataOut, NULL));
400 }
401 
438  ADI_SPI_HANDLE hSPIDevice,
439  uint32_t AddrIn,
440  uint32_t num_xfrs,
441  uint32_t * pDataOut,
442  uint32_t * pDataRef
443 )
444 {
445  /* Transmit SPI command - use 1bytes offset to keep rest of data alligned on word boundary */
446  spi_txbuf[1] = ADF703x_SPI_MEM_READ |
447  ADF703x_SPI_MEM_BLOCK |
448  ADF703x_SPI_MEM_ADDRESS |
449  ADF703x_SPI_MEM_LONG;
450 
451  /* Write the starting address in the spi_txbuf */
452  *((uint16_t *)spi_txbuf + 1) = __REV16(*((uint16_t *)&AddrIn + 1));
453  *((uint16_t *)spi_txbuf + 2) = __REV16(*((uint16_t *)&AddrIn + 0));
454  *((uint16_t *)spi_txbuf + 3) = 0xFFFF;
455 
456  return(adf7030_1__SPI_Block_Xfer( hSPIDevice, 1, 0, AddrIn, num_xfrs << 2, pDataOut, pDataRef));
457 }
458 
489  ADI_SPI_HANDLE hSPIDevice,
491  uint32_t num_xfrs,
492  uint32_t * pDataIn
493 )
494 {
495  /* Transmit SPI command - use 3bytes offset to keep rest of data alligned on word boundary */
496  spi_txbuf[3] = ADF703x_SPI_MEM_WRITE |
497  ADF703x_SPI_MEM_BLOCK |
498  ADF703x_SPI_MEM_POINTER |
499  ADF703x_SPI_MEM_LONG |
500  pntrID;
501 
502  return(adf7030_1__SPI_Block_Xfer( hSPIDevice, 3, pntrID, 0, num_xfrs << 2, pDataIn, NULL));
503 }
504 
533  ADI_SPI_HANDLE hSPIDevice,
535  uint32_t num_xfrs,
536  uint32_t * pDataOut
537 )
538 {
539  return(adf7030_1__SPI_rd_cmp_word_b_p(hSPIDevice, pntrID, num_xfrs, pDataOut, NULL));
540 }
541 
575  ADI_SPI_HANDLE hSPIDevice,
577  uint32_t num_xfrs,
578  uint32_t * pDataOut,
579  uint32_t * pDataRef
580 )
581 {
582  /* Transmit SPI command - use 1bytes offset to keep rest of data alligned on word boundary */
583  spi_txbuf[1] = ADF703x_SPI_MEM_READ |
584  ADF703x_SPI_MEM_BLOCK |
585  ADF703x_SPI_MEM_POINTER |
586  ADF703x_SPI_MEM_LONG |
587  pntrID;
588 
589  /* Add 16bits of NOPs in spi_txbuf */
590  *((uint16_t *)spi_txbuf + 1) = 0xFFFF;
591 
592  return(adf7030_1__SPI_Block_Xfer( hSPIDevice, 1, pntrID, 0, num_xfrs << 2, pDataOut, pDataRef));
593 }
594 
595 
625  ADI_SPI_HANDLE hSPIDevice,
627  uint32_t AddrIn,
628  uint32_t num_xfrs,
629  uint8_t * pDataIn
630 )
631 {
632  /* Transmit SPI command - use 2bytes offset to keep rest of data alligned on word boundary */
633  spi_txbuf[2] = ADF703x_SPI_MEM_WRITE |
634  ADF703x_SPI_MEM_BLOCK |
635  ADF703x_SPI_MEM_ADDRESS |
636  ADF703x_SPI_MEM_SHORT |
637  pntrID;
638 
639  /* Set Block offset from pntrID */
640  spi_txbuf[3] = (uint8_t)AddrIn;
641 
642  return(adf7030_1__SPI_Block_Xfer( hSPIDevice, 2, pntrID, AddrIn, num_xfrs, pDataIn, NULL));
643 }
644 
674  ADI_SPI_HANDLE hSPIDevice,
676  uint32_t AddrIn,
677  uint32_t num_xfrs,
678  uint8_t * pDataOut
679 )
680 {
681  return(adf7030_1__SPI_rd_cmp_byte_b_a(hSPIDevice, pntrID, AddrIn, num_xfrs, pDataOut, NULL));
682 }
683 
684 
719  ADI_SPI_HANDLE hSPIDevice,
721  uint32_t AddrIn,
722  uint32_t num_xfrs,
723  uint8_t * pDataOut,
724  uint8_t * pDataRef
725 )
726 {
727  /* Transmit SPI command - use 1bytes offset to keep rest of data alligned on word boundary */
728  spi_txbuf[1] = ADF703x_SPI_MEM_READ |
729  ADF703x_SPI_MEM_BLOCK |
730  ADF703x_SPI_MEM_ADDRESS |
731  ADF703x_SPI_MEM_SHORT |
732  pntrID;
733 
734  /* Set Block offset from pntrID */
735  spi_txbuf[2] = (uint8_t)AddrIn;
736 
737  /* Add 8bits of NOPs in spi_txbuf */
738  spi_txbuf[3] = 0xFF;
739 
740  return(adf7030_1__SPI_Block_Xfer( hSPIDevice, 1, pntrID, AddrIn, num_xfrs, pDataOut, pDataRef));
741 }
742 
771  ADI_SPI_HANDLE hSPIDevice,
773  uint32_t num_xfrs,
774  uint8_t * pDataIn
775 )
776 {
777  /* Transmit SPI command - use 3bytes offset to keep rest of data alligned on word boundary */
778  spi_txbuf[3] = ADF703x_SPI_MEM_WRITE |
779  ADF703x_SPI_MEM_BLOCK |
780  ADF703x_SPI_MEM_POINTER |
781  ADF703x_SPI_MEM_SHORT |
782  pntrID;
783 
784  return(adf7030_1__SPI_Block_Xfer( hSPIDevice, 3, pntrID, 0, num_xfrs, pDataIn, NULL));
785 }
786 
815  ADI_SPI_HANDLE hSPIDevice,
817  uint32_t num_xfrs,
818  uint8_t * pDataOut
819 )
820 {
821  return(adf7030_1__SPI_rd_cmp_byte_p_a(hSPIDevice, pntrID, num_xfrs, pDataOut, NULL));
822 }
823 
824 
858  ADI_SPI_HANDLE hSPIDevice,
860  uint32_t num_xfrs,
861  uint8_t * pDataOut,
862  uint8_t * pDataRef
863 )
864 {
865  /* Transmit SPI command - use 2bytes offset to keep rest of data alligned on word boundary */
866  spi_txbuf[2] = ADF703x_SPI_MEM_READ |
867  ADF703x_SPI_MEM_BLOCK |
868  ADF703x_SPI_MEM_POINTER |
869  ADF703x_SPI_MEM_SHORT |
870  pntrID;
871 
872  /* Add 8bits of NOPs in spi_txbuf */
873  spi_txbuf[3] = 0xFF;
874 
875  return(adf7030_1__SPI_Block_Xfer( hSPIDevice, 2, pntrID, 0, num_xfrs, pDataOut, pDataRef));
876 }
877 //Random address access (Not implemented yet)
914  ADI_SPI_HANDLE hSPIDevice,
915  uint32_t AddrIn,
916  uint32_t *pHostOffset,
917  uint32_t *pAddrIn,
918  uint32_t *pDataIn,
919  uint32_t num_xfrs
920 )
921 {
922  /* Crude checking of maximum transfert size */
923  if( num_xfrs > (ADF7030_1_SPI_MAX_TRX_SIZE >> 3))
924  {
925  return FAILURE;
926  }
927 
928  /* Are you using preloaded target address location? */
929  if(pHostOffset == NULL)
930  {
931 
932  }
933 
934  /* Transmit SPI command - use 3bytes offset to keep rest of data alligned on word boundary */
935  spi_txbuf[3] = ADF703x_SPI_MEM_WRITE |
936  ADF703x_SPI_MEM_RANDOM |
937  ADF703x_SPI_MEM_ADDRESS |
938  ADF703x_SPI_MEM_LONG;
939 
940  /* Initiate the SPI transfer */
941  if(adf7030_1__SPI_word_random_transaction( &hSPIDevice, //SPI handle
942  3, //SPI trx buffer offset
943  num_xfrs, //SPI nb_word to transfert
944  pAddrIn, //pointer to address buffer
945  pDataIn, //pointer to data buffer
946  true
947  ) != SUCCESS)
948  {
949  return FAILURE;
950  }
951 
952  return SUCCESS;
953 }
954 
955 //(optional) static uint32_t adf7030_1__SPI_wr_word_r_a(ADI_SPI_HANDLE hSPIDevice, uint32_t * pAddrIn, uint32_t * pDataIn, uint32_t num_xfrs); // (HRM 1.4.4.2.7)
956 //(optional) static uint32_t adf7030_1__SPI_rd_word_r_a(ADI_SPI_HANDLE hSPIDevice, uint32_t * pAddrIn, uint32_t * pDataOut, uint32_t num_xfrs); // (HRM 1.4.4.2.7)
957 //(optional) static uint32_t adf7030_1__SPI_wr_byte_r_a(ADI_SPI_HANDLE hSPIDevice, uint32_t pID, uint8_t * pOffset, uint8_t * pDataIn, uint32_t num_xfrs); // (HRM 1.4.4.2.8)
958 //(optional) static uint32_t adf7030_1__SPI_rd_byte_r_a(ADI_SPI_HANDLE hSPIDevice, uint32_t pID, uint8_t * pOffset, uint8_t * pDataOut, uint32_t num_xfrs); // (HRM 1.4.4.2.8)
959 
1004  ADI_SPI_HANDLE hSPIDevice,
1005  uint32_t cmdOffset,
1007  uint32_t Addr,
1008  uint32_t nbBytes,
1009  void * pDataIO,
1010  void * pDataRef
1011 )
1012 {
1013 
1014  /* Variable holding current value off full spi block (used when nbBytes > ADF7030_1_SPI_MAX_TRX_SIZE )*/
1015  uint32_t full_block_cnt = 0;
1016 
1017  /* Store the initial value of PNTR_CUSTOM0 */
1018  uint32_t copy_spi_pntr_custom0 = ADF7030_1_SPI_PNTR[PNTR_CUSTOM0_ADDR];
1019  uint32_t copy_spi_pntr_ID = ADF7030_1_SPI_PNTR[PNTR_ID];
1020 
1021  /* Transfert loop */
1022  bool_t spi_transaction_finished = (nbBytes) ? false : true;
1023 
1024  while(spi_transaction_finished == false)
1025  {
1026  uint32_t size;
1027 
1028  if( nbBytes > ADF7030_1_SPI_MAX_TRX_SIZE )
1029  {
1030  /* Full block transaction */
1031  size = ADF7030_1_SPI_MAX_TRX_SIZE;
1032  }
1033  else
1034  {
1035  /* Partial block transaction */
1036  size = nbBytes;
1037  spi_transaction_finished = true;
1038  }
1039 
1040  if(spi_txbuf[cmdOffset] & ADF703x_SPI_MEM_LONG)
1041  {
1042  /* Initiate the SPI word transfer */
1043  if(adf7030_1__SPI_word_block_transaction( &hSPIDevice, //SPI handle
1044  cmdOffset, //SPI trx buffer offset
1045  size >> 2, //SPI nb_word to transfert
1046  (uint32_t *)pDataIO, //pointer to Host data to transfert
1047  (uint32_t *)pDataRef //pointer to Host Ref data for comparison
1048  ) != SUCCESS)
1049  {
1050  return FAILURE;
1051  }
1052  }
1053  else
1054  {
1055  /* Initiate the SPI byte transfer */
1056  if(adf7030_1__SPI_byte_block_transaction( &hSPIDevice, //SPI handle
1057  cmdOffset, //SPI trx buffer offset
1058  size, //SPI nb_word to transfert
1059  (uint8_t *)pDataIO, //pointer to Host data to transfert
1060  (uint8_t *)pDataRef //pointer to Host Ref data for comparison
1061  ) != SUCCESS)
1062  {
1063  return FAILURE;
1064  }
1065 
1066  }
1067 
1068  /* Increment pntrID by ADF7030_1_SPI_MAX_TRX_SIZE for next SPI transaction */
1069  if(spi_transaction_finished == false)
1070  {
1071  uint32_t tmp_SPI_Prolog;
1072 
1073  switch(spi_txbuf[cmdOffset] & 0x78)
1074  {
1075  case( ADF703x_SPI_MEM_WRITE | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_ADDRESS | ADF703x_SPI_MEM_LONG ) :
1076  //ADF703x_SPI_MEM_WRITE | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_ADDRESS | ADF703x_SPI_MEM_LONG
1077 
1078  /* Change the next Address in the spi_txbuf */
1079  Addr += size;
1080 
1081  /* Write the starting address in the spi_txbuf */
1082  *(((uint32_t *)spi_txbuf) + 1) = __REV(Addr);
1083 
1084  break;
1085 
1086  case( ADF703x_SPI_MEM_READ | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_ADDRESS | ADF703x_SPI_MEM_LONG ) :
1087  //ADF703x_SPI_MEM_READ | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_ADDRESS | ADF703x_SPI_MEM_LONG
1088 
1089  /* Change the next Address in the spi_txbuf */
1090  Addr += size;
1091 
1092  /* Write the starting address in the spi_txbuf */
1093  *((uint16_t *)spi_txbuf + 1) = __REV16(*((uint16_t *)&Addr + 1));
1094  *((uint16_t *)spi_txbuf + 2) = __REV16(*((uint16_t *)&Addr + 0));
1095 
1096  break;
1097 
1098  case( ADF703x_SPI_MEM_WRITE | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_POINTER | ADF703x_SPI_MEM_LONG ) :
1099  case( ADF703x_SPI_MEM_READ | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_POINTER | ADF703x_SPI_MEM_LONG ) :
1100  case( ADF703x_SPI_MEM_WRITE | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_ADDRESS | ADF703x_SPI_MEM_SHORT ) :
1101  case( ADF703x_SPI_MEM_READ | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_ADDRESS | ADF703x_SPI_MEM_SHORT ) :
1102  case( ADF703x_SPI_MEM_WRITE | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_POINTER | ADF703x_SPI_MEM_SHORT ) :
1103  case( ADF703x_SPI_MEM_READ | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_POINTER | ADF703x_SPI_MEM_SHORT ) :
1104 
1105  //ADF703x_SPI_MEM_WRITE | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_POINTER | ADF703x_SPI_MEM_LONG | pntrID
1106  //ADF703x_SPI_MEM_READ | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_POINTER | ADF703x_SPI_MEM_LONG | pntrID
1107  //ADF703x_SPI_MEM_WRITE | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_ADDRESS | ADF703x_SPI_MEM_SHORT | pntrID;
1108  //ADF703x_SPI_MEM_READ | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_ADDRESS | ADF703x_SPI_MEM_SHORT | pntrID;
1109  //ADF703x_SPI_MEM_WRITE | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_POINTER | ADF703x_SPI_MEM_SHORT | pntrID;
1110  //ADF703x_SPI_MEM_READ | ADF703x_SPI_MEM_BLOCK | ADF703x_SPI_MEM_POINTER | ADF703x_SPI_MEM_SHORT | pntrID;
1111 
1112  /* Change the Host copy of SPI pointer 0 address for next block of byte transfer */
1113  ADF7030_1_SPI_PNTR[PNTR_CUSTOM0_ADDR] = copy_spi_pntr_ID + (size * ++full_block_cnt);
1114 
1115  /* Save current SPI prolog */
1116  tmp_SPI_Prolog = *(uint32_t *)spi_txbuf;
1117 
1118  /* Update the PHY Radio SPI pointer 0 */
1119  adf7030_1__SPI_wr_word_b_p( hSPIDevice, PNTR_SETUP_ADDR, 1, &ADF7030_1_SPI_PNTR[PNTR_CUSTOM0_ADDR]);
1120 
1121  /* Recall current SPI prolog */
1122  *(uint32_t *)spi_txbuf = tmp_SPI_Prolog;
1123 
1124  /* Update SPI command byte to use the SPI pointer 0 */
1125  spi_txbuf[cmdOffset] &= 0xF8;
1126  spi_txbuf[cmdOffset] |= PNTR_CUSTOM0_ADDR;
1127 
1128  break;
1129 
1130  default : return FAILURE;
1131  }
1132  }
1133 
1134 
1135  /* Increment pDataIO by size of the previous transaction */
1136  if(pDataIO != NULL)
1137  {
1138  pDataIO = (uint8_t *)pDataIO + size;
1139  }
1140 
1141  /* Increment the pDataRef by size of the previous transaction */
1142  if(pDataRef != NULL)
1143  {
1144  pDataRef = (uint8_t *)pDataRef + size;
1145  }
1146 
1147  /* Decrement the remaining nbBytes by the size of the previous transaction*/
1148  nbBytes -= size;
1149  }
1150 
1151  /* Restore the initial value of PNTR_CUSTOM0 if required */
1152  if(ADF7030_1_SPI_PNTR[PNTR_CUSTOM0_ADDR] != copy_spi_pntr_custom0)
1153  {
1154  /* Change the Host copy of SPI pointer 0 */
1155  ADF7030_1_SPI_PNTR[PNTR_CUSTOM0_ADDR] = copy_spi_pntr_custom0;
1156 
1157  /* Update the PHY Radio SPI pointer 0 */
1158  adf7030_1__SPI_wr_word_b_p( hSPIDevice, PNTR_SETUP_ADDR, 1, &ADF7030_1_SPI_PNTR[PNTR_CUSTOM0_ADDR]);
1159  }
1160 
1161  return SUCCESS;
1162 }
1163 
1164 
1191  ADI_SPI_HANDLE *hSPIDevice,
1192  uint32_t offset,
1193  uint32_t nb_word,
1194  uint32_t * pDataIO,
1195  uint32_t * pDataRef
1196 )
1197 {
1198  /* SPI transceiver instance */
1199  ADI_SPI_TRANSCEIVER Transceiver;
1200 
1201  /* Check if we are in Address mode */
1202  uint8_t Addr_en = ((spi_txbuf[offset] & ADF703x_SPI_MEM_ADDRESS) >> 4);
1203 
1204  /* Initialize the transceiver */
1205  Transceiver.TransmitterBytes = (4 - offset) + ((nb_word + Addr_en) << 2);
1206  Transceiver.ReceiverBytes = Transceiver.TransmitterBytes;
1207  Transceiver.pTransmitter = spi_txbuf + offset;
1208  Transceiver.pReceiver = spi_rxbuf + offset;
1209  Transceiver.nTxIncrement = 1u;
1210  Transceiver.nRxIncrement = Transceiver.nTxIncrement;
1211 
1212 
1213  /* Set Block address to 2nd unit32_t */
1214  uint32_t * pData = (((uint32_t *)spi_txbuf) + 1 + Addr_en);
1215 
1216  if(spi_txbuf[offset] & ADF703x_SPI_MEM_READ)
1217  {
1218  /* READ operation */
1219 
1220  /* Fill spi_txbuf with nb_word of NOPs */
1221  thumb_aligned_memset(pData, 0xFFFFFFFF, nb_word << 2);
1222  }
1223  else
1224  {
1225  /* WRITE operation */
1226 
1227  /* Copy nb_word from pDataIO to spi_rxbuf */
1228  //thumb_aligned_memcpy(pData, pDataIO, size_alligned);
1229  for(uint16_t i = 0; i < nb_word; i++)
1230  {
1231  *pData++ = __REV(*pDataIO++);
1232  }
1233  }
1234 
1235  /* Transmit the sequence */
1236  if(adi_spi_ReadWrite(*hSPIDevice, &Transceiver) != ADI_SPI_SUCCESS)
1237  {
1238  return FAILURE;
1239  }
1240 
1241  if(spi_txbuf[offset] & ADF703x_SPI_MEM_READ)
1242  {
1243  /* READ operation */
1244 
1245  /* Set Block address to 2nd unit32_t */
1246  pData = (((uint32_t *)spi_rxbuf) + 1 + Addr_en);
1247 
1248  if((pDataIO != NULL) && (pDataRef == NULL))
1249  {
1250  /* Copy nb_word from spi_rxbuf to pDataIO */
1251  for(uint16_t i = 0; i < nb_word; i++)
1252  {
1253  *pDataIO++ = __REV(*pData++);
1254  }
1255  }
1256  else if((pDataIO != NULL) && (pDataRef != NULL))
1257  {
1258  uint32_t word;
1259 
1260  /* Copy up to nb_word from spi_rxbuf to pDataIO and Check versus pDataRef */
1261  for(uint16_t i = 0; i < nb_word; i++)
1262  {
1263  word = __REV(*pData++);
1264  if(*pDataRef++ != word)
1265  {
1266  return FAILURE;
1267  }
1268  *pDataIO++ = word;
1269  }
1270  }
1271  else if((pDataIO == NULL) && (pDataRef != NULL))
1272  {
1273  /* Compare up to nb_word of spi_rxbuf versus pDataRef */
1274  for(uint16_t i = 0; i < nb_word; i++)
1275  {
1276  if(*pDataRef++ != __REV(*pData++))
1277  {
1278  return FAILURE;
1279  }
1280  }
1281  }
1282  else
1283  {
1284  /* Should never end up here */
1285  return FAILURE;
1286  }
1287  }
1288  else
1289  {
1290  /* WRITE operation */
1291 
1292  }
1293 
1294  return SUCCESS;
1295 }
1296 
1323  ADI_SPI_HANDLE *hSPIDevice,
1324  uint32_t offset,
1325  uint32_t nb_bytes,
1326  uint8_t * pDataIO,
1327  uint8_t * pDataRef
1328 )
1329 {
1330  /* SPI transceiver instance */
1331  ADI_SPI_TRANSCEIVER Transceiver;
1332 
1333  /* Initialize the transceiver */
1334  Transceiver.TransmitterBytes = (4 - offset) + nb_bytes;
1335  Transceiver.ReceiverBytes = Transceiver.TransmitterBytes;
1336  Transceiver.pTransmitter = spi_txbuf + offset;
1337  Transceiver.pReceiver = spi_rxbuf + offset;
1338  Transceiver.nTxIncrement = 1u;
1339  Transceiver.nRxIncrement = Transceiver.nTxIncrement;
1340 
1341 
1342  /* Set Block address to 2nd unit32_t */
1343  uint32_t * pData = (((uint32_t *)spi_txbuf) + 1);
1344 
1345  /* Set the size of alligned full words (32bits) */
1346  uint32_t size_alligned = (nb_bytes >> 2) << 2;
1347 
1348  /* Set the number of remaining bytes (8bits) */
1349  uint32_t rem_byte_num_xfrs = nb_bytes & 0x3;
1350 
1351  if(spi_txbuf[offset] & ADF703x_SPI_MEM_READ)
1352  {
1353  /* READ operation */
1354 
1355  /* Fill spi_txbuf with nb_word of NOPs */
1356  if(size_alligned) thumb_aligned_memset(pData, 0xFFFFFFFF, size_alligned);
1357 
1358  /* Fill spi_txbuf with rem_byte_num_xfrs of NOPs */
1359  if(rem_byte_num_xfrs)
1360  {
1361  uint8_t *pRemData = (uint8_t *)pData + size_alligned;
1362 
1363  for(uint32_t i = 0; i < rem_byte_num_xfrs; i++)
1364  {
1365  *pRemData++ = 0xFF;
1366  }
1367  }
1368  }
1369  else
1370  {
1371  /* WRITE operation */
1372 
1373  /* Copy nb_word from pDataIO to spi_rxbuf */
1374  if(size_alligned) thumb_aligned_memcpy(pData, pDataIO, size_alligned);
1375 
1376  /* Copy rem_byte_num_xfrs from pDataIO to spi_txbuf */
1377  if(rem_byte_num_xfrs)
1378  {
1379  uint8_t *pRemData = (uint8_t *)pData + size_alligned;
1380  pDataIO += size_alligned;
1381 
1382  for(uint32_t i = 0; i < rem_byte_num_xfrs; i++)
1383  {
1384  *pRemData++ = *pDataIO++;
1385  }
1386  }
1387  }
1388 
1389  /* Transmit the sequence */
1390  if(adi_spi_ReadWrite(*hSPIDevice, &Transceiver) != ADI_SPI_SUCCESS)
1391  {
1392  return FAILURE;
1393  }
1394 
1395  if(spi_txbuf[offset] & ADF703x_SPI_MEM_READ)
1396  {
1397  /* READ operation */
1398 
1399  /* Set Block address to 2nd unit32_t */
1400  pData = (((uint32_t *)spi_rxbuf) + 1);
1401 
1402  if((pDataIO != NULL) && (pDataRef == NULL))
1403  {
1404  /* Copy nb_word from spi_rxbuf to pDataIO */
1405  if(size_alligned) thumb_aligned_memcpy(pDataIO, pData, size_alligned);
1406 
1407  /* Copy rem_byte_num_xfrs from spi_rxbuf to pDataIO */
1408  if(rem_byte_num_xfrs)
1409  {
1410  uint8_t *pRemData = (uint8_t *)pData + size_alligned;
1411  pDataIO += size_alligned;
1412 
1413  for(uint32_t i = 0; i < rem_byte_num_xfrs; i++)
1414  {
1415  *pDataIO++ = *pRemData++;
1416  }
1417  }
1418  }
1419  else if((pDataIO != NULL) && (pDataRef != NULL))
1420  {
1421  uint8_t byte;
1422  uint8_t * pDataByte = (uint8_t *)pData;
1423 
1424  /* Copy up to nb_bytes from spi_rxbuf to pDataIO and Check versus pDataRef */
1425  for(uint16_t i = 0; i < nb_bytes; i++)
1426  {
1427  byte = *pDataByte++;
1428  if(*pDataRef++ != byte)
1429  {
1430  return FAILURE;
1431  }
1432  *pDataIO++ = byte;
1433  }
1434  }
1435  else if((pDataIO == NULL) && (pDataRef != NULL))
1436  {
1437  uint8_t * pDataByte = (uint8_t *)pData;
1438 
1439  /* Compare up to nb_bytes of spi_rxbuf versus pDataRef */
1440  for(uint16_t i = 0; i < nb_bytes; i++)
1441  {
1442  if(*pDataRef++ != *pDataByte++)
1443  {
1444  return FAILURE;
1445  }
1446  }
1447  }
1448  else
1449  {
1450  /* Should never end up here */
1451  return FAILURE;
1452  }
1453  }
1454  else
1455  {
1456  /* WRITE operation */
1457 
1458  }
1459 
1460 
1461  return SUCCESS;
1462 
1463 }
1464 
1486  ADI_SPI_HANDLE *hSPIDevice,
1487  uint32_t offset,
1488  uint32_t nb_word,
1489  uint32_t *pRemoteAddrIO,
1490  uint32_t *pHostDataIO,
1491  bool pHostDataIO_isArray
1492 )
1493 {
1494  /* SPI transceiver instance */
1495  ADI_SPI_TRANSCEIVER Transceiver;
1496 
1497  /* Check if we are in Writing mode */
1498  uint8_t Write_en = ((~(spi_txbuf[offset]) & ADF703x_SPI_MEM_READ) >> 6);
1499 
1500 
1501  /* Initialize the transceiver */
1502  Transceiver.TransmitterBytes = (4 - offset) + (nb_word << (2 + Write_en));
1503  Transceiver.ReceiverBytes = Transceiver.TransmitterBytes;
1504  Transceiver.pTransmitter = spi_txbuf + offset;
1505  Transceiver.pReceiver = spi_rxbuf + offset;
1506  Transceiver.nTxIncrement = 1u;
1507  Transceiver.nRxIncrement = Transceiver.nTxIncrement;
1508 
1509  /* Set Block address to 2nd unit32_t */
1510  uint32_t * pData = (((uint32_t *)spi_txbuf) + 1);
1511 
1512  if(Write_en)
1513  {
1514  /* WRITE operation */
1515 
1516  /* Copy nb_word from alternating pRemoteAddrIO & pHostDataIO to spi_txbuf */
1517  for(uint16_t i = 0; i < nb_word; i++)
1518  {
1519  uint32_t data = *(uint32_t *)pHostDataIO++;
1520 
1521  *pData++ = __REV(*pRemoteAddrIO++);
1522  *pData++ = __REV((pHostDataIO_isArray == true) ? *(uint32_t *)data : data);
1523  }
1524  }
1525  else
1526  {
1527  /* READ operation */
1528 
1529  /* Fill spi_txbuf with nb_word of pRemoteAddrIO */
1530  for(uint16_t i = 0; i < nb_word; i++)
1531  {
1532  *pData++ = __REV(*pRemoteAddrIO++);
1533  }
1534 
1535  /* Add two extra bytes for missaligned word read on the spi */
1536  Transceiver.TransmitterBytes += 2;
1537  Transceiver.ReceiverBytes = Transceiver.TransmitterBytes;
1538 
1539  /* Pad the spi_txbuf with 2bytes off extra SPI_NOP */
1540  *(uint16_t *)pData = 0xFFFF;
1541  }
1542 
1543  /* Transmit the sequence */
1544  if(adi_spi_ReadWrite(*hSPIDevice, &Transceiver) != ADI_SPI_SUCCESS)
1545  {
1546  return FAILURE;
1547  }
1548 
1549  if(!Write_en)
1550  {
1551  /* READ operation */
1552 
1553  /* Set Block address to 2nd unit32_t */
1554  uint16_t *pDataOut = (((uint16_t *)spi_rxbuf) + 4);
1555 
1556  /* Copy nb_word from spi_rxbuf to pDataIO */
1557  for(uint16_t i = 0; i < ((nb_word << 1) + 1); i++)
1558  {
1559  uint32_t data;
1560 
1561  data = __REV16(*pDataOut++) << 16;
1562  data |= __REV16(*pDataOut++);
1563 
1564  if(pHostDataIO_isArray == true)
1565  {
1566  *pHostDataIO++ = data;
1567  }
1568  else
1569  {
1570  uint32_t * pHostData = pHostDataIO++;
1571  *pHostData = data;
1572  }
1573  }
1574  }
1575 
1576  return SUCCESS;
1577 }
1578 
1598 /*
1599 uint32_t adf7030_1__SPI_byte_random_transaction(
1600  ADI_SPI_HANDLE *hSPIDevice,
1601  uint32_t offset,
1602  uint32_t nb_bytes,
1603  uint8_t * pDataIO
1604 )
1605 {
1606 
1607 }
1608 */
1609 
1610 #endif /* _ADF7030_1__SPI_C_ */
1611  /* End of group adf7030-1__spi SPI Interface layer */ /* End of group adf7030-1 adf7030-1 Driver */
uint32_t adf7030_1__SPI_word_random_transaction(ADI_SPI_HANDLE *hSPIDevice, uint32_t offset, uint32_t nb_word, uint32_t *pAddrIO, uint32_t *pDataIO, bool pDataIO_is_pointer)
Generic SPI Random Read/Write a number of words(s) to the adf7030-1.
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"...
uint32_t adf7030_1__SPI_rd_word_b_a(ADI_SPI_HANDLE hSPIDevice, uint32_t AddrIn, uint32_t num_xfrs, uint32_t *pDataOut)
Read a number of word(s) from the adf7030-1 to memory of Host Generic 32bits bloc address read from m...
uint32_t adf7030_1__SPI_word_block_transaction(ADI_SPI_HANDLE *hSPIDevice, uint32_t offset, uint32_t nb_bytes, uint32_t *pDataIO, uint32_t *pDataRef)
Generic SPI Block Read/Write a number of words(s) to the adf7030-1.
#define ADF7030_1_SPI_BUFFER_SIZE
uint32_t adf7030_1__SPI_SetMMapCustomPntr0(ADI_SPI_HANDLE hSPIDevice, uint32_t Addr)
Change the SPI Radio mmap custom pointers 0 location.
uint32_t adf7030_1__SPI_GetMMapPointers(ADI_SPI_HANDLE hSPIDevice, uint32_t *pPNTR)
Get SPI Radio mmap pointers access.
uint32_t adf7030_1__SPI_rd_byte_p_a(ADI_SPI_HANDLE hSPIDevice, ADI_ADF7030_1_RADIO_SPI_PNTR_TYPE pntrID, uint32_t num_xfrs, uint8_t *pDataOut)
Read a number of bytes(s) from memory of the adf7030-1 to Host starting at location pointed by "pntr"...
uint32_t adf7030_1__SPI_rd_cmp_word_b_a(ADI_SPI_HANDLE hSPIDevice, uint32_t AddrIn, uint32_t num_xfrs, uint32_t *pDataOut, uint32_t *pDataRef)
Read & Compare a number of word(s) from the adf7030-1 to memory of Host Generic 32bits bloc address r...
uint32_t adf7030_1__SPI_SetSpeed(const uint32_t RateHz)
Change SPI Host to PHY Communication bitrate.
uint32_t adf7030_1__SPI_rd_cmp_byte_b_a(ADI_SPI_HANDLE hSPIDevice, ADI_ADF7030_1_RADIO_SPI_PNTR_TYPE pntrID, uint32_t AddrIn, uint32_t num_xfrs, uint8_t *pDataOut, uint8_t *pDataRef)
Read & Compare a number of bytes(s) from memory of the adf7030-1 to Host starting at location pointed...
uint32_t adf7030_1__SPI_rd_word_b_p(ADI_SPI_HANDLE hSPIDevice, ADI_ADF7030_1_RADIO_SPI_PNTR_TYPE pntrID, uint32_t num_xfrs, uint32_t *pDataOut)
Read a number of word(s) from memory of the adf7030-1 to Host starting at location pointed by "pntr" ...
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"...
void adf7030_1__SPI_FindMMapPointer(ADI_SPI_HANDLE hSPIDevice, uint32_t Addr, ADI_ADF7030_1_RADIO_SPI_PNTR_TYPE *pPNTR_ID, int32_t *ByteOffset)
This function return the best Pointer id + offset for subsequent SPI transfert to the PHY "Addr" prov...
uint32_t adf7030_1__SPI_wr_word_r_a(ADI_SPI_HANDLE hSPIDevice, uint32_t AddrIn, uint32_t *pHostOffset, uint32_t *pAddrIn, uint32_t *pDataIn, uint32_t num_xfrs)
Write a number of word(s) from Host to memory of the adf7030-1 Generic 32bits random address write to...
ADI_ADF7030_1_RADIO_SPI_PNTR_TYPE
uint32_t adf7030_1__SPI_rd_byte_b_a(ADI_SPI_HANDLE hSPIDevice, ADI_ADF7030_1_RADIO_SPI_PNTR_TYPE pntrID, uint32_t AddrIn, uint32_t num_xfrs, uint8_t *pDataOut)
Read a number of bytes(s) from memory of the adf7030-1 to Host starting at location pointed by "pntr"...
uint32_t adf7030_1__SPI_Block_Xfer(ADI_SPI_HANDLE hSPIDevice, uint32_t cmdOffset, ADI_ADF7030_1_RADIO_SPI_PNTR_TYPE PNTR_ID, uint32_t Addr, uint32_t nbBytes, void *pDataIO, void *pDataRef)
Generic function to read or write a number of bytes between the Host and the PHY adf703x.
uint32_t adf7030_1__SPI_UnInit(void)
Uninitializes SPI device used to communication with the adf7030-1 PHY.
uint32_t adf7030_1__SPI_rd_cmp_word_b_p(ADI_SPI_HANDLE hSPIDevice, ADI_ADF7030_1_RADIO_SPI_PNTR_TYPE pntrID, uint32_t num_xfrs, uint32_t *pDataOut, uint32_t *pDataRef)
Read & Compare a number of word(s) from memory of the adf7030-1 to Host starting at location pointed ...
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_byte_block_transaction(ADI_SPI_HANDLE *hSPIDevice, uint32_t offset, uint32_t nb_bytes, uint8_t *pDataIO, uint8_t *pDataRef)
Generic SPI Block Read/Write a number of byte(s) to the adf7030-1.
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"...
uint32_t adf7030_1__SPI_Init(void)
Initializes SPI device for communication with the adf7030-1 PHY.
uint32_t adf7030_1__SPI_rd_cmp_byte_p_a(ADI_SPI_HANDLE hSPIDevice, ADI_ADF7030_1_RADIO_SPI_PNTR_TYPE pntrID, uint32_t num_xfrs, uint8_t *pDataOut, uint8_t *pDataRef)
Read & Compare a number of bytes(s) from memory of the adf7030-1 to Host starting at location pointed...
uint32_t adf7030_1__SPI_SetMMapPointers(ADI_SPI_HANDLE hSPIDevice, uint32_t *pPNTR)
Set SPI Radio mmap pointers access.