1 /******************************************************************************
2 *
3 * Copyright (C) 2018 ST Microelectronics S.A.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *
18 ******************************************************************************/
19 #define LOG_TAG "StEse-SpiLayerInterface"
20 #include "SpiLayerInterface.h"
21 #include <errno.h>
22 #include <string.h>
23 #include <sys/time.h>
24 #include "SpiLayerComm.h"
25 #include "SpiLayerDriver.h"
26 #include "T1protocol.h"
27 #include "android_logmsg.h"
28 #include "utils-lib/Atp.h"
29
30 #define SPI_BITS_PER_WORD 8
31 #define SPI_MODE SPI_MODE_0
32
33 #define KHZ_TO_HZ 1000
34
35 static bool mFirstActivation = false;
36
37 /*******************************************************************************
38 **
39 ** Function SpiLayerInterface_init
40 **
41 ** Description Initialize the SPI link access
42 **
43 ** Parameters tSpiDriver - hardware information
44 **
45 ** Returns 0 if connection could be initialized, -1 otherwise.
46 **
47 *******************************************************************************/
SpiLayerInterface_init(SpiDriver_config_t * tSpiDriver)48 int SpiLayerInterface_init(SpiDriver_config_t* tSpiDriver) {
49 STLOG_HAL_D("Initializing SPI Driver interface...");
50
51 // Configure the SPI before start the data exchange with the eSE
52 char* spiDevPath = tSpiDriver->pDevName;
53
54 int DevHandle = SpiLayerDriver_open(spiDevPath);
55 tSpiDriver->pDevHandle = (void*)((intptr_t)DevHandle);
56 if (DevHandle == -1) {
57 // Error configuring the SPI bus
58 STLOG_HAL_E("Error configuring the SPI bus.");
59 return -1;
60 }
61
62 if (!mFirstActivation) {
63 if (SpiLayerInterface_setup() == -1) {
64 return -1;
65 }
66 mFirstActivation = true;
67 STLOG_HAL_D("SPI bus working at ATP.msf = %i KHz", ATP.msf);
68 }
69
70 STLOG_HAL_D("SPI Driver interface initialized.");
71 return 0;
72 }
73
74 /*******************************************************************************
75 **
76 ** Function SpiLayerInterface_transcieveTpdu
77 **
78 ** Description Sends a TPDU to the SE, waits for the response
79 ** and returns it.
80 **
81 ** Parameters cmdTpdu -The TPDU to be sent.
82 ** respTpdu -The memory position where to store the response.
83 ** numberOfBwt-The maximum number of BWT to wait.
84 **
85 ** Returns bytesRead if data was read, 0 if timeout expired with
86 ** no response, -1 otherwise
87 **
88 *******************************************************************************/
SpiLayerInterface_transcieveTpdu(Tpdu * cmdTpdu,Tpdu * respTpdu,int numberOfBwt)89 int SpiLayerInterface_transcieveTpdu(Tpdu* cmdTpdu, Tpdu* respTpdu,
90 int numberOfBwt) {
91 // Send the incoming Tpdu to the slave
92 if (SpiLayerComm_writeTpdu(cmdTpdu) < 0) {
93 return -1;
94 }
95
96 if (numberOfBwt <= 0) {
97 STLOG_HAL_W("Buffer overflow happened, restoring numberOfBwt");
98 numberOfBwt = DEFAULT_NBWT;
99 }
100 // Wait for response
101 int result = SpiLayerComm_waitForResponse(respTpdu, numberOfBwt);
102
103 // Unable to receive the response from slave
104 if (result == -1) {
105 return -1;
106 } else if (result == -2) {
107 // 0 bytes read
108 return 0;
109 }
110
111 // Read the response
112 int bytesRead = SpiLayerComm_readTpdu(respTpdu);
113 if (bytesRead < 0) {
114 STLOG_HAL_E("Error when reading from SPI interface (%d).", bytesRead);
115 return -1;
116 }
117 STLOG_HAL_D("%d bytes read from SPI interface", bytesRead);
118
119 uint8_t buffer[(5 + respTpdu->len)];
120 uint16_t length = Tpdu_toByteArray(respTpdu, buffer);
121 if (length > 0) {
122 DispHal("Rx", buffer, length);
123 }
124 return bytesRead;
125 }
126
127 /*******************************************************************************
128 **
129 ** Function SpiLayerInterface_close
130 **
131 ** Description Close the device
132 **
133 ** Parameters pDevHandle - device handle
134 **
135 ** Returns None
136 **
137 *******************************************************************************/
SpiLayerInterface_close(void * pDevHandle)138 void SpiLayerInterface_close(void* pDevHandle) {
139 if (NULL != pDevHandle) {
140 STLOG_HAL_D("SpiLayerInterface_close");
141 SpiLayerDriver_close();
142 }
143 }
144 /*******************************************************************************
145 **
146 ** Function SpiLayerInterface_setup
147 **
148 ** Description Read the ATP by performing SE reset and negotiate the IFSD.
149 **
150 ** Parameters pDevHandle - device handle
151 **
152 ** Returns 0 if connection could be initialized, -1 otherwise.
153 **
154 *******************************************************************************/
SpiLayerInterface_setup()155 int SpiLayerInterface_setup() {
156 // First of all, read the ATP from the slave
157 if (SpiLayerComm_readAtp() != 0) {
158 // Error reading the ATP
159 STLOG_HAL_E("Error reading the ATP.");
160 return -1;
161 }
162 T1protocol_resetSequenceNumbers();
163 // Negotiate IFS value
164 if (T1protocol_doRequestIFS() != 0) {
165 return -1;
166 }
167 return 0;
168 }
169