1 /*
2  * Copyright 2012-2020 NXP
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <errno.h>
17 #include <fcntl.h>
18 #include <stdlib.h>
19 #include <sys/ioctl.h>
20 #include <sys/select.h>
21 #include <termios.h>
22 #include <unistd.h>
23 
24 #include <phUwbStatus.h>
25 #include <phNxpLog.h>
26 #include <phTmlUwb_spi.h>
27 #include <string.h>
28 #include "phNxpUciHal_utils.h"
29 #include "phNxpUciHal.h"
30 /*********************** Global Variables *************************************/
31 /* UCI HAL Control structure */
32 extern phNxpUciHal_Control_t nxpucihal_ctrl;
33 
34 /*******************************************************************************
35 **
36 ** Function         phTmlUwb_spi_open_and_configure
37 **
38 ** Description      Open and configure SR100
39 **
40 ** Parameters       pDevName    - device node path
41 **                  pLinkHandle - device handle
42 **
43 ** Returns          UWB status:
44 **                  UWBSTATUS_SUCCESS - open_and_configure operation success
45 **                  UWBSTATUS_INVALID_DEVICE - device open operation failure
46 **
47 *******************************************************************************/
phTmlUwb_spi_open_and_configure(const char * pDevName,void ** pLinkHandle)48 tHAL_UWB_STATUS phTmlUwb_spi_open_and_configure(const char* pDevName, void** pLinkHandle)
49 {
50   int nHandle;
51 
52   NXPLOG_TML_D("Opening port=%s\n", pDevName);
53   /* open port */
54   nHandle = open(pDevName, O_RDWR);
55   if (nHandle < 0) {
56     NXPLOG_TML_E("_spi_open() Failed: retval %x", nHandle);
57     *pLinkHandle = NULL;
58     return UWBSTATUS_INVALID_DEVICE;
59   }
60 
61   *pLinkHandle = (void*)((intptr_t)nHandle);
62 
63   return UWBSTATUS_SUCCESS;
64 }
65 
66 /*******************************************************************************
67 **
68 ** Function         phTmlUwb_spi_write
69 **
70 ** Description      Writes requested number of bytes from given buffer into
71 **                  SR100
72 **
73 ** Parameters       pDevHandle       - valid device handle
74 **                  pBuffer          - buffer for read data
75 **                  nNbBytesToWrite  - number of bytes requested to be written
76 **
77 ** Returns          numWrote   - number of successfully written bytes
78 **                  -1         - write operation failure
79 **
80 *******************************************************************************/
phTmlUwb_spi_write(void * pDevHandle,uint8_t * pBuffer,size_t nNbBytesToWrite)81 int phTmlUwb_spi_write(void* pDevHandle, uint8_t* pBuffer, size_t nNbBytesToWrite)
82 {
83   int ret;
84   ssize_t numWrote;
85 
86   if (NULL == pDevHandle) {
87     NXPLOG_TML_E("_spi_write() device is null");
88     return -1;
89   }
90 
91   if (nNbBytesToWrite == 0) {
92     NXPLOG_TML_E("_spi_write() with 0 bytes");
93     return -1;
94   }
95 
96   numWrote = write((intptr_t)pDevHandle, pBuffer, nNbBytesToWrite);
97   if (numWrote == -1) {
98     NXPLOG_TML_E("_spi_write() failed: %d", errno);
99     return -1;
100   } else if (numWrote != nNbBytesToWrite) {
101     NXPLOG_TML_E("_spi_write() size mismatch %zd != %zd", nNbBytesToWrite, numWrote);
102   }
103 
104   return numWrote;
105 }
106 
107 /*******************************************************************************
108 **
109 ** Function         phTmlUwb_spi_read
110 **
111 ** Description      Reads requested number of bytes from SR100 device into
112 **                  given buffer
113 **
114 ** Parameters       pDevHandle       - valid device handle
115 **                  pBuffer          - buffer for read data
116 **                  nNbBytesToRead   - number of bytes requested to be read
117 **
118 ** Returns          numRead   - number of successfully read bytes
119 **                  -1        - read operation failure
120 **
121 *******************************************************************************/
phTmlUwb_spi_read(void * pDevHandle,uint8_t * pBuffer,size_t nNbBytesToRead)122 int phTmlUwb_spi_read(void* pDevHandle, uint8_t* pBuffer, size_t nNbBytesToRead)
123 {
124   ssize_t ret_Read;
125 
126   if (NULL == pDevHandle) {
127     NXPLOG_TML_E("_spi_read() error handle");
128     return -1;
129   }
130 
131   ret_Read = read((intptr_t)pDevHandle, pBuffer, nNbBytesToRead);
132   if (ret_Read == -1) {
133      NXPLOG_TML_E("_spi_read() error: %d", errno);
134   } else if((nxpucihal_ctrl.fw_dwnld_mode) && ((0xFF == pBuffer[0]) || ((0x00 == pBuffer[0]) && (0x00 == pBuffer[3])))) {
135       NXPLOG_TML_E("_spi_read() error: Invalid UCI packet");
136       /* To Avoid spurious interrupt after FW download */
137       ret_Read = 0;
138   }
139 
140   return ret_Read;
141 }
142 
143 /*******************************************************************************
144 **
145 ** Function         phTmlUwb_Spi_Ioctl
146 **
147 ** Description      Reset SR100, using VEN pin
148 **
149 ** Parameters       pDevHandle     - valid device handle
150 **                  level          - reset level
151 **
152 ** Returns           0   - reset operation success
153 **                  -1   - reset operation failure
154 **
155 *******************************************************************************/
phTmlUwb_Spi_Ioctl(void * pDevHandle,phTmlUwb_ControlCode_t eControlCode,long arg)156 int phTmlUwb_Spi_Ioctl(void* pDevHandle, phTmlUwb_ControlCode_t eControlCode , long arg) {
157   NXPLOG_TML_D("phTmlUwb_Spi_Ioctl(), cmd %d,  arg %ld", static_cast<int>(eControlCode), arg);
158   int ret = 1;
159   if (NULL == pDevHandle) {
160     return -1;
161   }
162   switch(eControlCode){
163     case phTmlUwb_ControlCode_t::SetPower:
164       ioctl((intptr_t)pDevHandle, SRXXX_SET_PWR, arg);
165       break;
166     case phTmlUwb_ControlCode_t::EnableFwdMode:
167       ioctl((intptr_t)pDevHandle, SRXXX_SET_FWD, arg);
168       break;
169     case phTmlUwb_ControlCode_t::EnableThroughPut:
170       //ioctl((intptr_t)pDevHandle, SRXXX_GET_THROUGHPUT, arg);
171       break;
172     case phTmlUwb_ControlCode_t::EseReset:
173       ioctl((intptr_t)pDevHandle, SRXXX_ESE_RESET, arg);
174       break;
175     default:
176       NXPLOG_TML_D("phTmlUwb_Spi_Ioctl(), Invalid command");
177       ret = -1;
178   }
179   return ret;
180 }
181 
182 /*******************************************************************************
183 **
184 ** Function         phTmlUwb_spi_close
185 **
186 ** Description      Closes SR100 device
187 **
188 ** Parameters       pDevHandle - device handle
189 **
190 ** Returns          None
191 **
192 *******************************************************************************/
phTmlUwb_spi_close(void * pDevHandle)193 void phTmlUwb_spi_close(void* pDevHandle) {
194   if (NULL != pDevHandle) {
195     close((intptr_t)pDevHandle);
196   }
197 
198   return;
199 }
200