1 /**
2 *
3 * \file
4 *
5 * \brief This module contains NMC1000 SPI protocol bus APIs implementation.
6 *
7 * Copyright (c) 2016-2017 Atmel Corporation. All rights reserved.
8 *
9 * \asf_license_start
10 *
11 * \page License
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above copyright notice,
20 * this list of conditions and the following disclaimer in the documentation
21 * and/or other materials provided with the distribution.
22 *
23 * 3. The name of Atmel may not be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
27 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
29 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
30 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 *
38 * \asf_license_stop
39 *
40 */
41 #include "common/include/nm_common.h"
42
43 #ifdef CONF_WINC_USE_SPI
44
45 /* Don't force USE_OLD_SPI_SW, instead we will pass it from Zephyr side
46 #define USE_OLD_SPI_SW
47 */
48
49 #include "bus_wrapper/include/nm_bus_wrapper.h"
50 #include "nmspi.h"
51
52 #define NMI_PERIPH_REG_BASE 0x1000
53 #define NMI_INTR_REG_BASE (NMI_PERIPH_REG_BASE+0xa00)
54 #define NMI_CHIPID (NMI_PERIPH_REG_BASE)
55 #define NMI_PIN_MUX_0 (NMI_PERIPH_REG_BASE + 0x408)
56 #define NMI_INTR_ENABLE (NMI_INTR_REG_BASE)
57
58 #define NMI_SPI_REG_BASE 0xe800
59 #define NMI_SPI_CTL (NMI_SPI_REG_BASE)
60 #define NMI_SPI_MASTER_DMA_ADDR (NMI_SPI_REG_BASE+0x4)
61 #define NMI_SPI_MASTER_DMA_COUNT (NMI_SPI_REG_BASE+0x8)
62 #define NMI_SPI_SLAVE_DMA_ADDR (NMI_SPI_REG_BASE+0xc)
63 #define NMI_SPI_SLAVE_DMA_COUNT (NMI_SPI_REG_BASE+0x10)
64 #define NMI_SPI_TX_MODE (NMI_SPI_REG_BASE+0x20)
65 #define NMI_SPI_PROTOCOL_CONFIG (NMI_SPI_REG_BASE+0x24)
66 #define NMI_SPI_INTR_CTL (NMI_SPI_REG_BASE+0x2c)
67 #define NMI_SPI_MISC_CTRL (NMI_SPI_REG_BASE+0x48)
68
69 #define NMI_SPI_PROTOCOL_OFFSET (NMI_SPI_PROTOCOL_CONFIG-NMI_SPI_REG_BASE)
70
71 #define SPI_BASE NMI_SPI_REG_BASE
72
73 #define CMD_DMA_WRITE 0xc1
74 #define CMD_DMA_READ 0xc2
75 #define CMD_INTERNAL_WRITE 0xc3
76 #define CMD_INTERNAL_READ 0xc4
77 #define CMD_TERMINATE 0xc5
78 #define CMD_REPEAT 0xc6
79 #define CMD_DMA_EXT_WRITE 0xc7
80 #define CMD_DMA_EXT_READ 0xc8
81 #define CMD_SINGLE_WRITE 0xc9
82 #define CMD_SINGLE_READ 0xca
83 #define CMD_RESET 0xcf
84
85 #define N_OK 1
86 #define N_FAIL 0
87 #define N_RESET -1
88 #define N_RETRY -2
89
90 #define SPI_RESP_RETRY_COUNT (10)
91 #define SPI_RETRY_COUNT (10)
92 #define DATA_PKT_SZ_256 256
93 #define DATA_PKT_SZ_512 512
94 #define DATA_PKT_SZ_1K 1024
95 #define DATA_PKT_SZ_4K (4 * 1024)
96 #define DATA_PKT_SZ_8K (8 * 1024)
97 #define DATA_PKT_SZ DATA_PKT_SZ_8K
98
99 static uint8 gu8Crc_off = 0;
100
nmi_spi_read(uint8 * b,uint16 sz)101 static sint8 nmi_spi_read(uint8* b, uint16 sz)
102 {
103 tstrNmSpiRw spi;
104 spi.pu8InBuf = NULL;
105 spi.pu8OutBuf = b;
106 spi.u16Sz = sz;
107 return nm_bus_ioctl(NM_BUS_IOCTL_RW, &spi);
108 }
109
nmi_spi_write(uint8 * b,uint16 sz)110 static sint8 nmi_spi_write(uint8* b, uint16 sz)
111 {
112 tstrNmSpiRw spi;
113 spi.pu8InBuf = b;
114 spi.pu8OutBuf = NULL;
115 spi.u16Sz = sz;
116 return nm_bus_ioctl(NM_BUS_IOCTL_RW, &spi);
117 }
118 #ifndef USE_OLD_SPI_SW
nmi_spi_rw(uint8 * bin,uint8 * bout,uint16 sz)119 static sint8 nmi_spi_rw(uint8 *bin,uint8* bout,uint16 sz)
120 {
121 tstrNmSpiRw spi;
122 spi.pu8InBuf = bin;
123 spi.pu8OutBuf = bout;
124 spi.u16Sz = sz;
125 return nm_bus_ioctl(NM_BUS_IOCTL_RW, &spi);
126 }
127 #endif
128 /********************************************
129
130 Crc7
131
132 ********************************************/
133
134 static const uint8 crc7_syndrome_table[256] = {
135 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
136 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
137 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26,
138 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e,
139 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d,
140 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45,
141 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14,
142 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c,
143 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b,
144 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13,
145 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42,
146 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a,
147 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69,
148 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21,
149 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70,
150 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38,
151 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e,
152 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36,
153 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67,
154 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f,
155 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
156 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
157 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55,
158 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d,
159 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a,
160 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52,
161 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03,
162 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b,
163 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28,
164 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60,
165 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31,
166 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79
167 };
168
169
crc7_byte(uint8 crc,uint8 data)170 static uint8 crc7_byte(uint8 crc, uint8 data)
171 {
172 return crc7_syndrome_table[(crc << 1) ^ data];
173 }
174
crc7(uint8 crc,const uint8 * buffer,uint32 len)175 static uint8 crc7(uint8 crc, const uint8 *buffer, uint32 len)
176 {
177 while (len--)
178 crc = crc7_byte(crc, *buffer++);
179 return crc;
180 }
181
182 /********************************************
183
184 Spi protocol Function
185
186 ********************************************/
187
188 #define CMD_DMA_WRITE 0xc1
189 #define CMD_DMA_READ 0xc2
190 #define CMD_INTERNAL_WRITE 0xc3
191 #define CMD_INTERNAL_READ 0xc4
192 #define CMD_TERMINATE 0xc5
193 #define CMD_REPEAT 0xc6
194 #define CMD_DMA_EXT_WRITE 0xc7
195 #define CMD_DMA_EXT_READ 0xc8
196 #define CMD_SINGLE_WRITE 0xc9
197 #define CMD_SINGLE_READ 0xca
198 #define CMD_RESET 0xcf
199
200 #define DATA_PKT_SZ_256 256
201 #define DATA_PKT_SZ_512 512
202 #define DATA_PKT_SZ_1K 1024
203 #define DATA_PKT_SZ_4K (4 * 1024)
204 #define DATA_PKT_SZ_8K (8 * 1024)
205 #define DATA_PKT_SZ DATA_PKT_SZ_8K
206
spi_cmd(uint8 cmd,uint32 adr,uint32 u32data,uint32 sz,uint8 clockless)207 static sint8 spi_cmd(uint8 cmd, uint32 adr, uint32 u32data, uint32 sz,uint8 clockless)
208 {
209 uint8 bc[9];
210 uint8 len = 5;
211 sint8 result = N_OK;
212
213 bc[0] = cmd;
214 switch (cmd) {
215 case CMD_SINGLE_READ: /* single word (4 bytes) read */
216 bc[1] = (uint8)(adr >> 16);
217 bc[2] = (uint8)(adr >> 8);
218 bc[3] = (uint8)adr;
219 len = 5;
220 break;
221 case CMD_INTERNAL_READ: /* internal register read */
222 bc[1] = (uint8)(adr >> 8);
223 if(clockless) bc[1] |= (1 << 7);
224 bc[2] = (uint8)adr;
225 bc[3] = 0x00;
226 len = 5;
227 break;
228 case CMD_TERMINATE: /* termination */
229 bc[1] = 0x00;
230 bc[2] = 0x00;
231 bc[3] = 0x00;
232 len = 5;
233 break;
234 case CMD_REPEAT: /* repeat */
235 bc[1] = 0x00;
236 bc[2] = 0x00;
237 bc[3] = 0x00;
238 len = 5;
239 break;
240 case CMD_RESET: /* reset */
241 bc[1] = 0xff;
242 bc[2] = 0xff;
243 bc[3] = 0xff;
244 len = 5;
245 break;
246 case CMD_DMA_WRITE: /* dma write */
247 case CMD_DMA_READ: /* dma read */
248 bc[1] = (uint8)(adr >> 16);
249 bc[2] = (uint8)(adr >> 8);
250 bc[3] = (uint8)adr;
251 bc[4] = (uint8)(sz >> 8);
252 bc[5] = (uint8)(sz);
253 len = 7;
254 break;
255 case CMD_DMA_EXT_WRITE: /* dma extended write */
256 case CMD_DMA_EXT_READ: /* dma extended read */
257 bc[1] = (uint8)(adr >> 16);
258 bc[2] = (uint8)(adr >> 8);
259 bc[3] = (uint8)adr;
260 bc[4] = (uint8)(sz >> 16);
261 bc[5] = (uint8)(sz >> 8);
262 bc[6] = (uint8)(sz);
263 len = 8;
264 break;
265 case CMD_INTERNAL_WRITE: /* internal register write */
266 bc[1] = (uint8)(adr >> 8);
267 if(clockless) bc[1] |= (1 << 7);
268 bc[2] = (uint8)(adr);
269 bc[3] = (uint8)(u32data >> 24);
270 bc[4] = (uint8)(u32data >> 16);
271 bc[5] = (uint8)(u32data >> 8);
272 bc[6] = (uint8)(u32data);
273 len = 8;
274 break;
275 case CMD_SINGLE_WRITE: /* single word write */
276 bc[1] = (uint8)(adr >> 16);
277 bc[2] = (uint8)(adr >> 8);
278 bc[3] = (uint8)(adr);
279 bc[4] = (uint8)(u32data >> 24);
280 bc[5] = (uint8)(u32data >> 16);
281 bc[6] = (uint8)(u32data >> 8);
282 bc[7] = (uint8)(u32data);
283 len = 9;
284 break;
285 default:
286 result = N_FAIL;
287 break;
288 }
289
290 if (result) {
291 if (!gu8Crc_off)
292 bc[len-1] = (crc7(0x7f, (const uint8 *)&bc[0], len-1)) << 1;
293 else
294 len-=1;
295
296 if (M2M_SUCCESS != nmi_spi_write(bc, len)) {
297 M2M_ERR("[nmi spi]: Failed cmd write, bus error...\n");
298 result = N_FAIL;
299 }
300 }
301
302 return result;
303 }
304
spi_data_rsp(uint8 cmd)305 static sint8 spi_data_rsp(uint8 cmd)
306 {
307 uint8 len;
308 uint8 rsp[3];
309 sint8 result = N_OK;
310
311 if (!gu8Crc_off)
312 len = 2;
313 else
314 len = 3;
315
316 if (M2M_SUCCESS != nmi_spi_read(&rsp[0], len)) {
317 M2M_ERR("[nmi spi]: Failed bus error...\n");
318 result = N_FAIL;
319 goto _fail_;
320 }
321
322 if((rsp[len-1] != 0)||(rsp[len-2] != 0xC3))
323 {
324 M2M_ERR("[nmi spi]: Failed data response read, %x %x %x\n",rsp[0],rsp[1],rsp[2]);
325 result = N_FAIL;
326 goto _fail_;
327 }
328 _fail_:
329
330 return result;
331 }
332
spi_cmd_rsp(uint8 cmd)333 static sint8 spi_cmd_rsp(uint8 cmd)
334 {
335 uint8 rsp;
336 sint8 result = N_OK;
337 sint8 s8RetryCnt;
338
339 /**
340 Command/Control response
341 **/
342 if ((cmd == CMD_RESET) ||
343 (cmd == CMD_TERMINATE) ||
344 (cmd == CMD_REPEAT)) {
345 if (M2M_SUCCESS != nmi_spi_read(&rsp, 1)) {
346 result = N_FAIL;
347 goto _fail_;
348 }
349 }
350
351 /* wait for response */
352 s8RetryCnt = SPI_RESP_RETRY_COUNT;
353 do
354 {
355 if (M2M_SUCCESS != nmi_spi_read(&rsp, 1)) {
356 M2M_ERR("[nmi spi]: Failed cmd response read, bus error...\n");
357 result = N_FAIL;
358 goto _fail_;
359 }
360 } while((rsp != cmd) && (s8RetryCnt-- >0));
361
362 /**
363 State response
364 **/
365 /* wait for response */
366 s8RetryCnt = SPI_RESP_RETRY_COUNT;
367 do
368 {
369 if (M2M_SUCCESS != nmi_spi_read(&rsp, 1)) {
370 M2M_ERR("[nmi spi]: Failed cmd response read, bus error...\n");
371 result = N_FAIL;
372 goto _fail_;
373 }
374 } while((rsp != 0x00) && (s8RetryCnt-- >0));
375
376 _fail_:
377
378 return result;
379 }
380 #ifndef USE_OLD_SPI_SW
spi_cmd_complete(uint8_t cmd,uint32_t adr,uint8_t * b,uint32_t sz,uint8_t clockless)381 static int spi_cmd_complete(uint8_t cmd, uint32_t adr, uint8_t *b, uint32_t sz, uint8_t clockless)
382 {
383 uint8_t wb[32], rb[32];
384 uint8_t wix, rix;
385 uint32_t len2;
386 uint8_t rsp;
387 int len = 0;
388 int result = N_OK;
389
390 wb[0] = cmd;
391 switch (cmd) {
392 case CMD_SINGLE_READ: /* single word (4 bytes) read */
393 wb[1] = (uint8_t)(adr >> 16);
394 wb[2] = (uint8_t)(adr >> 8);
395 wb[3] = (uint8_t)adr;
396 len = 5;
397 break;
398 case CMD_INTERNAL_READ: /* internal register read */
399 wb[1] = (uint8_t)(adr >> 8);
400 if(clockless == 1) wb[1] |= (1 << 7);
401 wb[2] = (uint8_t)adr;
402 wb[3] = 0x00;
403 len = 5;
404 break;
405 case CMD_TERMINATE: /* termination */
406 wb[1] = 0x00;
407 wb[2] = 0x00;
408 wb[3] = 0x00;
409 len = 5;
410 break;
411 case CMD_REPEAT: /* repeat */
412 wb[1] = 0x00;
413 wb[2] = 0x00;
414 wb[3] = 0x00;
415 len = 5;
416 break;
417 case CMD_RESET: /* reset */
418 wb[1] = 0xff;
419 wb[2] = 0xff;
420 wb[3] = 0xff;
421 len = 5;
422 break;
423 case CMD_DMA_WRITE: /* dma write */
424 case CMD_DMA_READ: /* dma read */
425 wb[1] = (uint8_t)(adr >> 16);
426 wb[2] = (uint8_t)(adr >> 8);
427 wb[3] = (uint8_t)adr;
428 wb[4] = (uint8_t)(sz >> 8);
429 wb[5] = (uint8_t)(sz);
430 len = 7;
431 break;
432 case CMD_DMA_EXT_WRITE: /* dma extended write */
433 case CMD_DMA_EXT_READ: /* dma extended read */
434 wb[1] = (uint8_t)(adr >> 16);
435 wb[2] = (uint8_t)(adr >> 8);
436 wb[3] = (uint8_t)adr;
437 wb[4] = (uint8_t)(sz >> 16);
438 wb[5] = (uint8_t)(sz >> 8);
439 wb[6] = (uint8_t)(sz);
440 len = 8;
441 break;
442 case CMD_INTERNAL_WRITE: /* internal register write */
443 wb[1] = (uint8_t)(adr >> 8);
444 if(clockless == 1) wb[1] |= (1 << 7);
445 wb[2] = (uint8_t)(adr);
446 wb[3] = b[3];
447 wb[4] = b[2];
448 wb[5] = b[1];
449 wb[6] = b[0];
450 len = 8;
451 break;
452 case CMD_SINGLE_WRITE: /* single word write */
453 wb[1] = (uint8_t)(adr >> 16);
454 wb[2] = (uint8_t)(adr >> 8);
455 wb[3] = (uint8_t)(adr);
456 wb[4] = b[3];
457 wb[5] = b[2];
458 wb[6] = b[1];
459 wb[7] = b[0];
460 len = 9;
461 break;
462 default:
463 result = N_FAIL;
464 break;
465 }
466
467 if (result != N_OK) {
468 return result;
469 }
470
471 if (!gu8Crc_off) {
472 wb[len-1] = (crc7(0x7f, (const uint8_t *)&wb[0], len-1)) << 1;
473 } else {
474 len -=1;
475 }
476
477 #define NUM_SKIP_BYTES (1)
478 #define NUM_RSP_BYTES (2)
479 #define NUM_DATA_HDR_BYTES (1)
480 #define NUM_DATA_BYTES (4)
481 #define NUM_CRC_BYTES (2)
482 #define NUM_DUMMY_BYTES (3)
483
484 if ((cmd == CMD_RESET) ||
485 (cmd == CMD_TERMINATE) ||
486 (cmd == CMD_REPEAT)) {
487 len2 = len + (NUM_SKIP_BYTES + NUM_RSP_BYTES + NUM_DUMMY_BYTES);
488 } else if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) {
489 if (!gu8Crc_off) {
490 len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES
491 + NUM_CRC_BYTES + NUM_DUMMY_BYTES);
492 } else {
493 len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES
494 + NUM_DUMMY_BYTES);
495 }
496 } else {
497 len2 = len + (NUM_RSP_BYTES + NUM_DUMMY_BYTES);
498 }
499 #undef NUM_DUMMY_BYTES
500
501 if(len2 > (sizeof(wb)/sizeof(wb[0]))) {
502 M2M_ERR("[nmi spi]: spi buffer size too small (%d) (%d)\n",
503 len2, (sizeof(wb)/sizeof(wb[0])));
504 result = N_FAIL;
505 return result;
506 }
507 /* zero spi write buffers. */
508 for(wix = len; wix< len2; wix++) {
509 wb[wix] = 0;
510 }
511 rix = len;
512
513 if (nmi_spi_rw(wb, rb, len2) != M2M_SUCCESS) {
514 M2M_ERR("[nmi spi]: Failed cmd write, bus error...\n");
515 result = N_FAIL;
516 return result;
517 }
518
519 #if 0
520 {
521 int jj;
522 printk("--- cnd = %x, len=%d, len2=%d\n", cmd, len, len2);
523 for(jj=0; jj<sizeof(wb)/sizeof(wb[0]); jj++) {
524
525 if(jj >= len2) break;
526 if(((jj+1)%16) != 0) {
527 if((jj%16) == 0) {
528 printk("wb[%02x]: %02x ", jj, wb[jj]);
529 } else {
530 printk("%02x ", wb[jj]);
531 }
532 } else {
533 printk("%02x\n", wb[jj]);
534 }
535 }
536 printk("\n");
537
538 for(jj=0; jj<sizeof(rb)/sizeof(rb[0]); jj++) {
539
540 if(jj >= len2) break;
541 if(((jj+1)%16) != 0) {
542 if((jj%16) == 0) {
543 printk("rb[%02x]: %02x ", jj, rb[jj]);
544 } else {
545 printk("%02x ", rb[jj]);
546 }
547 } else {
548 printk("%02x\n", rb[jj]);
549 }
550 }
551 printk("\n");
552 }
553 #endif
554
555 /**
556 Command/Control response
557 **/
558 if ((cmd == CMD_RESET) ||
559 (cmd == CMD_TERMINATE) ||
560 (cmd == CMD_REPEAT)) {
561 rix++; /* skip 1 byte */
562 }
563
564 rsp = rb[rix++];
565
566
567 if (rsp != cmd) {
568 M2M_ERR("[nmi spi]: Failed cmd response, cmd (%02x), resp (%02x)\n", cmd, rsp);
569 result = N_FAIL;
570 return result;
571 }
572
573 /**
574 State response
575 **/
576 rsp = rb[rix++];
577 if (rsp != 0x00) {
578 M2M_ERR("[nmi spi]: Failed cmd state response state (%02x)\n", rsp);
579 result = N_FAIL;
580 return result;
581 }
582
583 if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)
584 || (cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) {
585 int retry;
586 //uint16_t crc1, crc2;
587 uint8_t crc[2];
588 /**
589 Data Respnose header
590 **/
591 retry = SPI_RESP_RETRY_COUNT;
592 do {
593 /* ensure there is room in buffer later to read data and crc */
594 if(rix < len2) {
595 rsp = rb[rix++];
596 } else {
597 retry = 0;
598 break;
599 }
600 if (((rsp >> 4) & 0xf) == 0xf)
601 break;
602 } while (retry--);
603
604 if (retry <= 0) {
605 M2M_ERR("[nmi spi]: Error, data read response (%02x)\n", rsp);
606 result = N_RESET;
607 return result;
608 }
609
610 if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) {
611 /**
612 Read bytes
613 **/
614 if((rix+3) < len2) {
615 b[0] = rb[rix++];
616 b[1] = rb[rix++];
617 b[2] = rb[rix++];
618 b[3] = rb[rix++];
619 } else {
620 M2M_ERR("[nmi spi]: buffer overrun when reading data.\n");
621 result = N_FAIL;
622 return result;
623 }
624
625 if (!gu8Crc_off) {
626 /**
627 Read Crc
628 **/
629 if((rix+1) < len2) {
630 crc[0] = rb[rix++];
631 crc[1] = rb[rix++];
632 } else {
633 M2M_ERR("[nmi spi]: buffer overrun when reading crc.\n");
634 result = N_FAIL;
635 return result;
636 }
637 }
638 } else if((cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) {
639 int ix;
640
641 /* some data may be read in response to dummy bytes. */
642 for(ix=0; (rix < len2) && (ix < sz);) {
643 b[ix++] = rb[rix++];
644 }
645 #if 0
646 if(ix) M2M_INFO("ttt %d %d\n", sz, ix);
647 #endif
648 sz -= ix;
649
650 if(sz > 0) {
651 int nbytes;
652
653 if (sz <= (DATA_PKT_SZ-ix)) {
654 nbytes = sz;
655 } else {
656 nbytes = DATA_PKT_SZ-ix;
657 }
658
659 /**
660 Read bytes
661 **/
662 if (nmi_spi_read(&b[ix], nbytes) != M2M_SUCCESS) {
663 M2M_ERR("[nmi spi]: Failed data block read, bus error...\n");
664 result = N_FAIL;
665 goto _error_;
666 }
667
668 /**
669 Read Crc
670 **/
671 if (!gu8Crc_off) {
672 if (nmi_spi_read(crc, 2) != M2M_SUCCESS) {
673 M2M_ERR("[nmi spi]: Failed data block crc read, bus error...\n");
674 result = N_FAIL;
675 goto _error_;
676 }
677 }
678
679
680 ix += nbytes;
681 sz -= nbytes;
682 }
683
684 /* if any data in left unread, then read the rest using normal DMA code.*/
685 while(sz > 0) {
686 int nbytes;
687
688 if (sz <= DATA_PKT_SZ) {
689 nbytes = sz;
690 } else {
691 nbytes = DATA_PKT_SZ;
692 }
693
694 /**
695 read data response only on the next DMA cycles not
696 the first DMA since data response header is already
697 handled above for the first DMA.
698 **/
699 /**
700 Data Respnose header
701 **/
702 retry = SPI_RESP_RETRY_COUNT;
703 do {
704 if (nmi_spi_read(&rsp, 1) != M2M_SUCCESS) {
705 M2M_ERR("[nmi spi]: Failed data response read, bus error...\n");
706 result = N_FAIL;
707 break;
708 }
709 if (((rsp >> 4) & 0xf) == 0xf)
710 break;
711 } while (retry--);
712
713 if (result == N_FAIL)
714 break;
715
716
717 /**
718 Read bytes
719 **/
720 if (nmi_spi_read(&b[ix], nbytes) != M2M_SUCCESS) {
721 M2M_ERR("[nmi spi]: Failed data block read, bus error...\n");
722 result = N_FAIL;
723 break;
724 }
725
726 /**
727 Read Crc
728 **/
729 if (!gu8Crc_off) {
730 if (nmi_spi_read(crc, 2) != M2M_SUCCESS) {
731 M2M_ERR("[nmi spi]: Failed data block crc read, bus error...\n");
732 result = N_FAIL;
733 break;
734 }
735 }
736
737 ix += nbytes;
738 sz -= nbytes;
739 }
740 }
741 }
742 _error_:
743 return result;
744 }
745 #endif
746 #if defined USE_OLD_SPI_SW
spi_data_read(uint8 * b,uint16 sz,uint8 clockless)747 static sint8 spi_data_read(uint8 *b, uint16 sz,uint8 clockless)
748 {
749 sint16 retry, ix, nbytes;
750 sint8 result = N_OK;
751 uint8 crc[2];
752 uint8 rsp;
753
754 /**
755 Data
756 **/
757 ix = 0;
758 do {
759 if (sz <= DATA_PKT_SZ)
760 nbytes = sz;
761 else
762 nbytes = DATA_PKT_SZ;
763
764 /**
765 Data Respnose header
766 **/
767 retry = SPI_RESP_RETRY_COUNT;
768 do {
769 if (M2M_SUCCESS != nmi_spi_read(&rsp, 1)) {
770 M2M_ERR("[nmi spi]: Failed data response read, bus error...\n");
771 result = N_FAIL;
772 break;
773 }
774 if (((rsp >> 4) & 0xf) == 0xf)
775 break;
776 } while (retry--);
777
778 if (result == N_FAIL)
779 break;
780
781 if (retry <= 0) {
782 M2M_ERR("[nmi spi]: Failed data response read...(%02x)\n", rsp);
783 result = N_FAIL;
784 break;
785 }
786
787 /**
788 Read bytes
789 **/
790 if (M2M_SUCCESS != nmi_spi_read(&b[ix], nbytes)) {
791 M2M_ERR("[nmi spi]: Failed data block read, bus error...\n");
792 result = N_FAIL;
793 break;
794 }
795 if(!clockless)
796 {
797 /**
798 Read Crc
799 **/
800 if (!gu8Crc_off) {
801 if (M2M_SUCCESS != nmi_spi_read(crc, 2)) {
802 M2M_ERR("[nmi spi]: Failed data block crc read, bus error...\n");
803 result = N_FAIL;
804 break;
805 }
806 }
807 }
808 ix += nbytes;
809 sz -= nbytes;
810
811 } while (sz);
812
813 return result;
814 }
815 #endif
816
spi_data_write(uint8 * b,uint16 sz)817 static sint8 spi_data_write(uint8 *b, uint16 sz)
818 {
819 sint16 ix;
820 uint16 nbytes;
821 sint8 result = 1;
822 uint8 cmd, order, crc[2] = {0};
823 //uint8 rsp;
824
825 /**
826 Data
827 **/
828 ix = 0;
829 do {
830 if (sz <= DATA_PKT_SZ)
831 nbytes = sz;
832 else
833 nbytes = DATA_PKT_SZ;
834
835 /**
836 Write command
837 **/
838 cmd = 0xf0;
839 if (ix == 0) {
840 if (sz <= DATA_PKT_SZ)
841 order = 0x3;
842 else
843 order = 0x1;
844 } else {
845 if (sz <= DATA_PKT_SZ)
846 order = 0x3;
847 else
848 order = 0x2;
849 }
850 cmd |= order;
851 if (M2M_SUCCESS != nmi_spi_write(&cmd, 1)) {
852 M2M_ERR("[nmi spi]: Failed data block cmd write, bus error...\n");
853 result = N_FAIL;
854 break;
855 }
856
857 /**
858 Write data
859 **/
860 if (M2M_SUCCESS != nmi_spi_write(&b[ix], nbytes)) {
861 M2M_ERR("[nmi spi]: Failed data block write, bus error...\n");
862 result = N_FAIL;
863 break;
864 }
865
866 /**
867 Write Crc
868 **/
869 if (!gu8Crc_off) {
870 if (M2M_SUCCESS != nmi_spi_write(crc, 2)) {
871 M2M_ERR("[nmi spi]: Failed data block crc write, bus error...\n");
872 result = N_FAIL;
873 break;
874 }
875 }
876
877 ix += nbytes;
878 sz -= nbytes;
879 } while (sz);
880
881
882 return result;
883 }
884
885 /********************************************
886
887 Spi Internal Read/Write Function
888
889 ********************************************/
890
891 /********************************************
892
893 Spi interfaces
894
895 ********************************************/
896
spi_write_reg(uint32 addr,uint32 u32data)897 static sint8 spi_write_reg(uint32 addr, uint32 u32data)
898 {
899 uint8 retry = SPI_RETRY_COUNT;
900 sint8 result = N_OK;
901 uint8 cmd = CMD_SINGLE_WRITE;
902 uint8 clockless = 0;
903
904 _RETRY_:
905 if (addr <= 0x30)
906 {
907 /**
908 NMC1000 clockless registers.
909 **/
910 cmd = CMD_INTERNAL_WRITE;
911 clockless = 1;
912 }
913 else
914 {
915 cmd = CMD_SINGLE_WRITE;
916 clockless = 0;
917 }
918
919 #if defined USE_OLD_SPI_SW
920 result = spi_cmd(cmd, addr, u32data, 4, clockless);
921 if (result != N_OK) {
922 M2M_ERR("[nmi spi]: Failed cmd, write reg (%08x)...\n", (unsigned int)addr);
923 goto _FAIL_;
924 }
925
926 result = spi_cmd_rsp(cmd);
927 if (result != N_OK) {
928 M2M_ERR("[nmi spi]: Failed cmd response, write reg (%08x)...\n", (unsigned int)addr);
929 goto _FAIL_;
930 }
931
932 #else
933
934 result = spi_cmd_complete(cmd, addr, (uint8*)&u32data, 4, clockless);
935 if (result != N_OK) {
936 M2M_ERR( "[nmi spi]: Failed cmd, write reg (%08x)...\n", addr);
937 goto _FAIL_;
938 }
939
940 #endif
941 _FAIL_:
942 if(result != N_OK)
943 {
944 nm_bsp_sleep(1);
945 spi_cmd(CMD_RESET, 0, 0, 0, 0);
946 spi_cmd_rsp(CMD_RESET);
947 M2M_ERR("Reset and retry %d %lx %lx\n",retry,addr,u32data);
948 nm_bsp_sleep(1);
949 retry--;
950 if(retry) goto _RETRY_;
951 }
952
953 return result;
954 }
955
nm_spi_write(uint32 addr,uint8 * buf,uint16 size)956 static sint8 nm_spi_write(uint32 addr, uint8 *buf, uint16 size)
957 {
958 sint8 result;
959 uint8 retry = SPI_RETRY_COUNT;
960 uint8 cmd = CMD_DMA_EXT_WRITE;
961
962
963 _RETRY_:
964 /**
965 Command
966 **/
967 #if defined USE_OLD_SPI_SW
968 //Workaround hardware problem with single byte transfers over SPI bus
969 if (size == 1)
970 size = 2;
971
972 result = spi_cmd(cmd, addr, 0, size,0);
973 if (result != N_OK) {
974 M2M_ERR("[nmi spi]: Failed cmd, write block (%08x)...\n", (unsigned int)addr);
975 goto _FAIL_;
976 }
977
978 result = spi_cmd_rsp(cmd);
979 if (result != N_OK) {
980 M2M_ERR("[nmi spi ]: Failed cmd response, write block (%08x)...\n", (unsigned int)addr);
981 goto _FAIL_;
982 }
983 #else
984 result = spi_cmd_complete(cmd, addr, NULL, size, 0);
985 if (result != N_OK) {
986 M2M_ERR( "[nmi spi]: Failed cmd, write block (%08x)...\n", addr);
987 goto _FAIL_;
988 }
989 #endif
990
991 /**
992 Data
993 **/
994 result = spi_data_write(buf, size);
995 if (result != N_OK) {
996 M2M_ERR("[nmi spi]: Failed block data write...\n");
997 goto _FAIL_;
998 }
999 /**
1000 Data RESP
1001 **/
1002 result = spi_data_rsp(cmd);
1003 if (result != N_OK) {
1004 M2M_ERR("[nmi spi]: Failed block data write...\n");
1005 goto _FAIL_;
1006 }
1007
1008 _FAIL_:
1009 if(result != N_OK)
1010 {
1011 nm_bsp_sleep(1);
1012 spi_cmd(CMD_RESET, 0, 0, 0, 0);
1013 spi_cmd_rsp(CMD_RESET);
1014 M2M_ERR("Reset and retry %d %lx %d\n",retry,addr,size);
1015 nm_bsp_sleep(1);
1016 retry--;
1017 if(retry) goto _RETRY_;
1018 }
1019
1020
1021 return result;
1022 }
1023
spi_read_reg(uint32 addr,uint32 * u32data)1024 static sint8 spi_read_reg(uint32 addr, uint32 *u32data)
1025 {
1026 uint8 retry = SPI_RETRY_COUNT;
1027 sint8 result = N_OK;
1028 uint8 cmd = CMD_SINGLE_READ;
1029 uint8 tmp[4];
1030 uint8 clockless = 0;
1031
1032 _RETRY_:
1033
1034 if (addr <= 0xff)
1035 {
1036 /**
1037 NMC1000 clockless registers.
1038 **/
1039 cmd = CMD_INTERNAL_READ;
1040 clockless = 1;
1041 }
1042 else
1043 {
1044 cmd = CMD_SINGLE_READ;
1045 clockless = 0;
1046 }
1047
1048 #if defined USE_OLD_SPI_SW
1049 result = spi_cmd(cmd, addr, 0, 4, clockless);
1050 if (result != N_OK) {
1051 M2M_ERR("[nmi spi]: Failed cmd, read reg (%08x)...\n", (unsigned int)addr);
1052 goto _FAIL_;
1053 }
1054
1055 result = spi_cmd_rsp(cmd);
1056 if (result != N_OK) {
1057 M2M_ERR("[nmi spi]: Failed cmd response, read reg (%08x)...\n", (unsigned int)addr);
1058 goto _FAIL_;
1059 }
1060
1061 /* to avoid endianess issues */
1062 result = spi_data_read(&tmp[0], 4, clockless);
1063 if (result != N_OK) {
1064 M2M_ERR("[nmi spi]: Failed data read...\n");
1065 goto _FAIL_;
1066 }
1067 #else
1068 result = spi_cmd_complete(cmd, addr, (uint8*)&tmp[0], 4, clockless);
1069 if (result != N_OK) {
1070 M2M_ERR( "[nmi spi]: Failed cmd, read reg (%08x)...\n", addr);
1071 goto _FAIL_;
1072 }
1073
1074 #endif
1075
1076 *u32data = tmp[0] |
1077 ((uint32)tmp[1] << 8) |
1078 ((uint32)tmp[2] << 16) |
1079 ((uint32)tmp[3] << 24);
1080
1081 _FAIL_:
1082 if(result != N_OK)
1083 {
1084
1085 nm_bsp_sleep(1);
1086 spi_cmd(CMD_RESET, 0, 0, 0, 0);
1087 spi_cmd_rsp(CMD_RESET);
1088 M2M_ERR("Reset and retry %d %lx\n",retry,addr);
1089 nm_bsp_sleep(1);
1090 retry--;
1091 if(retry) goto _RETRY_;
1092 }
1093
1094 return result;
1095 }
1096
nm_spi_read(uint32 addr,uint8 * buf,uint16 size)1097 static sint8 nm_spi_read(uint32 addr, uint8 *buf, uint16 size)
1098 {
1099 uint8 cmd = CMD_DMA_EXT_READ;
1100 sint8 result;
1101 uint8 retry = SPI_RETRY_COUNT;
1102 #if defined USE_OLD_SPI_SW
1103 uint8 tmp[2];
1104 uint8 single_byte_workaround = 0;
1105 #endif
1106
1107 _RETRY_:
1108
1109 /**
1110 Command
1111 **/
1112 #if defined USE_OLD_SPI_SW
1113 if (size == 1)
1114 {
1115 //Workaround hardware problem with single byte transfers over SPI bus
1116 size = 2;
1117 single_byte_workaround = 1;
1118 }
1119 result = spi_cmd(cmd, addr, 0, size,0);
1120 if (result != N_OK) {
1121 M2M_ERR("[nmi spi]: Failed cmd, read block (%08x)...\n", (unsigned int)addr);
1122 goto _FAIL_;
1123 }
1124
1125 result = spi_cmd_rsp(cmd);
1126 if (result != N_OK) {
1127 M2M_ERR("[nmi spi]: Failed cmd response, read block (%08x)...\n", (unsigned int)addr);
1128 goto _FAIL_;
1129 }
1130
1131 /**
1132 Data
1133 **/
1134 if (single_byte_workaround)
1135 {
1136 result = spi_data_read(tmp, size,0);
1137 buf[0] = tmp[0];
1138 }
1139 else
1140 result = spi_data_read(buf, size,0);
1141
1142 if (result != N_OK) {
1143 M2M_ERR("[nmi spi]: Failed block data read...\n");
1144 goto _FAIL_;
1145 }
1146 #else
1147 result = spi_cmd_complete(cmd, addr, buf, size, 0);
1148 if (result != N_OK) {
1149 M2M_ERR("[nmi spi]: Failed cmd, read block (%08x)...\n", addr);
1150 goto _FAIL_;
1151 }
1152 #endif
1153
1154 _FAIL_:
1155 if(result != N_OK)
1156 {
1157 nm_bsp_sleep(1);
1158 spi_cmd(CMD_RESET, 0, 0, 0, 0);
1159 spi_cmd_rsp(CMD_RESET);
1160 M2M_ERR("Reset and retry %d %lx %d\n",retry,addr,size);
1161 nm_bsp_sleep(1);
1162 retry--;
1163 if(retry) goto _RETRY_;
1164 }
1165
1166 return result;
1167 }
1168
1169 /********************************************
1170
1171 Bus interfaces
1172
1173 ********************************************/
1174
spi_init_pkt_sz(void)1175 static void spi_init_pkt_sz(void)
1176 {
1177 uint32 val32;
1178
1179 /* Make sure SPI max. packet size fits the defined DATA_PKT_SZ. */
1180 val32 = nm_spi_read_reg(SPI_BASE+0x24);
1181 val32 &= ~(0x7 << 4);
1182 switch(DATA_PKT_SZ)
1183 {
1184 case 256: val32 |= (0 << 4); break;
1185 case 512: val32 |= (1 << 4); break;
1186 case 1024: val32 |= (2 << 4); break;
1187 case 2048: val32 |= (3 << 4); break;
1188 case 4096: val32 |= (4 << 4); break;
1189 case 8192: val32 |= (5 << 4); break;
1190
1191 }
1192 nm_spi_write_reg(SPI_BASE+0x24, val32);
1193 }
1194
nm_spi_reset(void)1195 sint8 nm_spi_reset(void)
1196 {
1197 spi_cmd(CMD_RESET, 0, 0, 0, 0);
1198 spi_cmd_rsp(CMD_RESET);
1199 return M2M_SUCCESS;
1200 }
1201
1202 /*
1203 * @fn nm_spi_init
1204 * @brief Initialize the SPI
1205 * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
1206 * @author M. Abdelmawla
1207 * @date 11 July 2012
1208 * @version 1.0
1209 */
nm_spi_init(void)1210 sint8 nm_spi_init(void)
1211 {
1212 uint32 chipid;
1213 uint32 reg = 0;
1214
1215
1216 /**
1217 configure protocol
1218 **/
1219 gu8Crc_off = 0;
1220
1221 // TODO: We can remove the CRC trials if there is a definite way to reset
1222 // the SPI to it's initial value.
1223 if (!spi_read_reg(NMI_SPI_PROTOCOL_CONFIG, ®)) {
1224 /* Read failed. Try with CRC off. This might happen when module
1225 is removed but chip isn't reset*/
1226 gu8Crc_off = 1;
1227 M2M_ERR("[nmi spi]: Failed internal read protocol with CRC on, retyring with CRC off...\n");
1228 if (!spi_read_reg(NMI_SPI_PROTOCOL_CONFIG, ®)){
1229 // Reaad failed with both CRC on and off, something went bad
1230 M2M_ERR( "[nmi spi]: Failed internal read protocol...\n");
1231 return 0;
1232 }
1233 }
1234 if(gu8Crc_off == 0)
1235 {
1236 reg &= ~0xc; /* disable crc checking */
1237 reg &= ~0x70;
1238 reg |= (0x5 << 4);
1239 if (!spi_write_reg(NMI_SPI_PROTOCOL_CONFIG, reg)) {
1240 M2M_ERR( "[nmi spi]: Failed internal write protocol reg...\n");
1241 return 0;
1242 }
1243 gu8Crc_off = 1;
1244 }
1245
1246 /**
1247 make sure can read back chip id correctly
1248 **/
1249 if (!spi_read_reg(0x1000, &chipid)) {
1250 M2M_ERR("[nmi spi]: Fail cmd read chip id...\n");
1251 return M2M_ERR_BUS_FAIL;
1252 }
1253
1254 M2M_DBG("[nmi spi]: chipid (%08x)\n", (unsigned int)chipid);
1255 spi_init_pkt_sz();
1256
1257
1258 return M2M_SUCCESS;
1259 }
1260
1261 /*
1262 * @fn nm_spi_init
1263 * @brief DeInitialize the SPI
1264 * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
1265 * @author Samer Sarhan
1266 * @date 27 Feb 2015
1267 * @version 1.0
1268 */
nm_spi_deinit(void)1269 sint8 nm_spi_deinit(void)
1270 {
1271 gu8Crc_off = 0;
1272 return M2M_SUCCESS;
1273 }
1274
1275 /*
1276 * @fn nm_spi_read_reg
1277 * @brief Read register
1278 * @param [in] u32Addr
1279 * Register address
1280 * @return Register value
1281 * @author M. Abdelmawla
1282 * @date 11 July 2012
1283 * @version 1.0
1284 */
nm_spi_read_reg(uint32 u32Addr)1285 uint32 nm_spi_read_reg(uint32 u32Addr)
1286 {
1287 uint32 u32Val;
1288
1289 spi_read_reg(u32Addr, &u32Val);
1290
1291 return u32Val;
1292 }
1293
1294 /*
1295 * @fn nm_spi_read_reg_with_ret
1296 * @brief Read register with error code return
1297 * @param [in] u32Addr
1298 * Register address
1299 * @param [out] pu32RetVal
1300 * Pointer to u32 variable used to return the read value
1301 * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
1302 * @author M. Abdelmawla
1303 * @date 11 July 2012
1304 * @version 1.0
1305 */
nm_spi_read_reg_with_ret(uint32 u32Addr,uint32 * pu32RetVal)1306 sint8 nm_spi_read_reg_with_ret(uint32 u32Addr, uint32* pu32RetVal)
1307 {
1308 sint8 s8Ret;
1309
1310 s8Ret = spi_read_reg(u32Addr,pu32RetVal);
1311
1312 if(N_OK == s8Ret) s8Ret = M2M_SUCCESS;
1313 else s8Ret = M2M_ERR_BUS_FAIL;
1314
1315 return s8Ret;
1316 }
1317
1318 /*
1319 * @fn nm_spi_write_reg
1320 * @brief write register
1321 * @param [in] u32Addr
1322 * Register address
1323 * @param [in] u32Val
1324 * Value to be written to the register
1325 * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
1326 * @author M. Abdelmawla
1327 * @date 11 July 2012
1328 * @version 1.0
1329 */
nm_spi_write_reg(uint32 u32Addr,uint32 u32Val)1330 sint8 nm_spi_write_reg(uint32 u32Addr, uint32 u32Val)
1331 {
1332 sint8 s8Ret;
1333
1334 s8Ret = spi_write_reg(u32Addr, u32Val);
1335
1336 if(N_OK == s8Ret) s8Ret = M2M_SUCCESS;
1337 else s8Ret = M2M_ERR_BUS_FAIL;
1338
1339 return s8Ret;
1340 }
1341
1342 /*
1343 * @fn nm_spi_read_block
1344 * @brief Read block of data
1345 * @param [in] u32Addr
1346 * Start address
1347 * @param [out] puBuf
1348 * Pointer to a buffer used to return the read data
1349 * @param [in] u16Sz
1350 * Number of bytes to read. The buffer size must be >= u16Sz
1351 * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
1352 * @author M. Abdelmawla
1353 * @date 11 July 2012
1354 * @version 1.0
1355 */
nm_spi_read_block(uint32 u32Addr,uint8 * puBuf,uint16 u16Sz)1356 sint8 nm_spi_read_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz)
1357 {
1358 sint8 s8Ret;
1359
1360 s8Ret = nm_spi_read(u32Addr, puBuf, u16Sz);
1361
1362 if(N_OK == s8Ret) s8Ret = M2M_SUCCESS;
1363 else s8Ret = M2M_ERR_BUS_FAIL;
1364
1365 return s8Ret;
1366 }
1367
1368 /*
1369 * @fn nm_spi_write_block
1370 * @brief Write block of data
1371 * @param [in] u32Addr
1372 * Start address
1373 * @param [in] puBuf
1374 * Pointer to the buffer holding the data to be written
1375 * @param [in] u16Sz
1376 * Number of bytes to write. The buffer size must be >= u16Sz
1377 * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
1378 * @author M. Abdelmawla
1379 * @date 11 July 2012
1380 * @version 1.0
1381 */
nm_spi_write_block(uint32 u32Addr,uint8 * puBuf,uint16 u16Sz)1382 sint8 nm_spi_write_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz)
1383 {
1384 sint8 s8Ret;
1385
1386 s8Ret = nm_spi_write(u32Addr, puBuf, u16Sz);
1387
1388 if(N_OK == s8Ret) s8Ret = M2M_SUCCESS;
1389 else s8Ret = M2M_ERR_BUS_FAIL;
1390
1391 return s8Ret;
1392 }
1393
1394 #endif
1395