|
- /*******************************************************************************
- This module contains WINC3400 SPI protocol bus APIs implementation.
-
- File Name:
- nmspi.c
-
- Summary:
- This module contains WINC3400 SPI protocol bus APIs implementation.
-
- Description:
- This module contains WINC3400 SPI protocol bus APIs implementation.
- *******************************************************************************/
-
- //DOM-IGNORE-BEGIN
- /*******************************************************************************
- * Copyright (C) 2021 Microchip Technology Inc. and its subsidiaries.
- *
- * Subject to your compliance with these terms, you may use Microchip software
- * and any derivatives exclusively with Microchip products. It is your
- * responsibility to comply with third party license terms applicable to your
- * use of third party software (including open source software) that may
- * accompany Microchip software.
- *
- * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
- * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
- * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
- * PARTICULAR PURPOSE.
- *
- * IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
- * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
- * WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
- * BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
- * FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
- * ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
- * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
- *******************************************************************************/
-
- //#include "osal/osal.h"
- #include "nm_common.h"
-
- #include "nmspi.h"
- #include "spi.h"
- #include "BoardCfg.h"
- //#include "wdrv_winc_common.h"
- //#include "wdrv_winc_spi.h"
-
- #define NMI_PERIPH_REG_BASE 0x1000
- #define NMI_INTR_REG_BASE (NMI_PERIPH_REG_BASE+0xa00)
- #define NMI_CHIPID (NMI_PERIPH_REG_BASE)
- #define NMI_PIN_MUX_0 (NMI_PERIPH_REG_BASE + 0x408)
- #define NMI_INTR_ENABLE (NMI_INTR_REG_BASE)
-
- #define NMI_SPI_REG_BASE 0xe800
- #define NMI_SPI_CTL (NMI_SPI_REG_BASE)
- #define NMI_SPI_MASTER_DMA_ADDR (NMI_SPI_REG_BASE+0x4)
- #define NMI_SPI_MASTER_DMA_COUNT (NMI_SPI_REG_BASE+0x8)
- #define NMI_SPI_SLAVE_DMA_ADDR (NMI_SPI_REG_BASE+0xc)
- #define NMI_SPI_SLAVE_DMA_COUNT (NMI_SPI_REG_BASE+0x10)
- #define NMI_SPI_TX_MODE (NMI_SPI_REG_BASE+0x20)
- #define NMI_SPI_PROTOCOL_CONFIG (NMI_SPI_REG_BASE+0x24)
- #define NMI_SPI_INTR_CTL (NMI_SPI_REG_BASE+0x2c)
- #define NMI_SPI_MISC_CTRL (NMI_SPI_REG_BASE+0x48)
-
- #define NMI_SPI_PROTOCOL_OFFSET (NMI_SPI_PROTOCOL_CONFIG-NMI_SPI_REG_BASE)
-
- #define SPI_BASE NMI_SPI_REG_BASE
-
- //#define CMD_DMA_WRITE 0xc1
- //#define CMD_DMA_READ 0xc2
- #define CMD_INTERNAL_WRITE 0xc3
- #define CMD_INTERNAL_READ 0xc4
- //#define CMD_TERMINATE 0xc5
- //#define CMD_REPEAT 0xc6
- #define CMD_DMA_EXT_WRITE 0xc7
- #define CMD_DMA_EXT_READ 0xc8
- #define CMD_SINGLE_WRITE 0xc9
- #define CMD_SINGLE_READ 0xca
- #define CMD_RESET 0xcf
-
- #define N_OK 0
- #define N_FAIL -1
- #define N_RESET -2
- #define N_RETRY -3
-
- #define SPI_RESP_RETRY_COUNT (10)
- #define SPI_RETRY_COUNT (10)
- #define DATA_PKT_SZ_256 256
- #define DATA_PKT_SZ_512 512
- #define DATA_PKT_SZ_1K 1024
- #define DATA_PKT_SZ_4K (4 * 1024)
- #define DATA_PKT_SZ_8K (8 * 1024)
- #define DATA_PKT_SZ DATA_PKT_SZ_8K
-
- static uint8_t gu8Crc_off = 0;
- unsigned char mWifiSPIBaudrate;
-
- //static OSAL_MUTEX_HANDLE_TYPE s_spiLock = 0;
-
- static inline int8_t spi_read(uint8_t *b, uint16_t sz)
- {
- //JFM WINC Low Level
- int i;
- WIFI_SPI_SS_PIN = 0;
- for(i = 0; i < sz; i++)
- {
- *b++ = SPITransaction(0xAA,mWifiSPIBaudrate);
- }
- WIFI_SPI_SS_PIN = 1;
-
-
- return N_OK;
-
- }
-
- static inline int8_t spi_write(uint8_t *b, uint16_t sz)
- {
-
- //JFM WINC Low Level
- int i;
- WIFI_SPI_SS_PIN = 0;
- for(i = 0; i < sz; i++)
- {
- SPITransaction(*b++,mWifiSPIBaudrate);
- }
- WIFI_SPI_SS_PIN = 1;
-
- return N_OK;
- }
-
- /********************************************
-
- Crc7
-
- ********************************************/
-
- static const uint8_t crc7_syndrome_table[256] = {
- 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
- 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
- 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26,
- 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e,
- 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d,
- 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45,
- 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14,
- 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c,
- 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b,
- 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13,
- 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42,
- 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a,
- 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69,
- 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21,
- 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70,
- 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38,
- 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e,
- 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36,
- 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67,
- 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f,
- 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
- 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
- 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55,
- 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d,
- 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a,
- 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52,
- 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03,
- 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b,
- 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28,
- 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60,
- 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31,
- 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79
- };
-
- static uint8_t crc7_byte(uint8_t crc, uint8_t data)
- {
- return crc7_syndrome_table[(crc << 1) ^ data];
- }
-
- static uint8_t crc7(uint8_t crc, const uint8_t *buffer, uint32_t len)
- {
- while (len--)
- crc = crc7_byte(crc, *buffer++);
- return crc;
- }
-
- /********************************************
-
- Spi protocol Function
-
- ********************************************/
-
- static int8_t spi_cmd(uint8_t cmd, uint32_t adr, uint32_t u32data, uint32_t sz, uint8_t clockless)
- {
- uint8_t bc[9];
- uint8_t len = 5;
-
- bc[0] = cmd;
- switch (cmd)
- {
- case CMD_SINGLE_READ: /* single word (4 bytes) read */
- bc[1] = (uint8_t)(adr >> 16);
- bc[2] = (uint8_t)(adr >> 8);
- bc[3] = (uint8_t)adr;
- len = 5;
- break;
-
- case CMD_INTERNAL_READ: /* internal register read */
- bc[1] = (uint8_t)(adr >> 8);
- if(clockless)
- bc[1] |= (1 << 7);
- bc[2] = (uint8_t)adr;
- bc[3] = 0x00;
- len = 5;
- break;
- #ifdef CMD_TERMINATE
- case CMD_TERMINATE: /* termination */
- bc[1] = 0x00;
- bc[2] = 0x00;
- bc[3] = 0x00;
- len = 5;
- break;
- #endif
- #ifdef CMD_REPEAT
- case CMD_REPEAT: /* repeat */
- bc[1] = 0x00;
- bc[2] = 0x00;
- bc[3] = 0x00;
- len = 5;
- break;
- #endif
- case CMD_RESET: /* reset */
- bc[1] = 0xff;
- bc[2] = 0xff;
- bc[3] = 0xff;
- len = 5;
- break;
- #if defined(CMD_DMA_WRITE) || defined(CMD_DMA_READ)
- case CMD_DMA_WRITE: /* dma write */
- case CMD_DMA_READ: /* dma read */
- bc[1] = (uint8_t)(adr >> 16);
- bc[2] = (uint8_t)(adr >> 8);
- bc[3] = (uint8_t)adr;
- bc[4] = (uint8_t)(sz >> 8);
- bc[5] = (uint8_t)(sz);
- len = 7;
- break;
- #endif
- case CMD_DMA_EXT_WRITE: /* dma extended write */
- case CMD_DMA_EXT_READ: /* dma extended read */
- bc[1] = (uint8_t)(adr >> 16);
- bc[2] = (uint8_t)(adr >> 8);
- bc[3] = (uint8_t)adr;
- bc[4] = (uint8_t)(sz >> 16);
- bc[5] = (uint8_t)(sz >> 8);
- bc[6] = (uint8_t)(sz);
- len = 8;
- break;
-
- case CMD_INTERNAL_WRITE: /* internal register write */
- bc[1] = (uint8_t)(adr >> 8);
- if(clockless) bc[1] |= (1 << 7);
- bc[2] = (uint8_t)(adr);
- bc[3] = (uint8_t)(u32data >> 24);
- bc[4] = (uint8_t)(u32data >> 16);
- bc[5] = (uint8_t)(u32data >> 8);
- bc[6] = (uint8_t)(u32data);
- len = 8;
- break;
-
- case CMD_SINGLE_WRITE: /* single word write */
- bc[1] = (uint8_t)(adr >> 16);
- bc[2] = (uint8_t)(adr >> 8);
- bc[3] = (uint8_t)(adr);
- bc[4] = (uint8_t)(u32data >> 24);
- bc[5] = (uint8_t)(u32data >> 16);
- bc[6] = (uint8_t)(u32data >> 8);
- bc[7] = (uint8_t)(u32data);
- len = 9;
- break;
-
- default:
- return N_FAIL;
- }
-
- if (!gu8Crc_off)
- {
- bc[len-1] = (crc7(0x7f, (const uint8_t *)&bc[0], len-1)) << 1;
- }
- else
- {
- len -= 1;
- }
-
- if (N_OK != spi_write(bc, len))
- {
- M2M_ERR("[spi_cmd]: Failed cmd write, bus error...\r\n");
- return N_FAIL;
- }
-
- return N_OK;
- }
-
- static int8_t spi_cmd_rsp(uint8_t cmd)
- {
- uint8_t rsp;
- int8_t s8RetryCnt;
-
- /**
- Command/Control response
- **/
- if ((cmd == CMD_RESET)
- #ifdef CMD_TERMINATE
- || (cmd == CMD_TERMINATE)
- #endif
- #ifdef CMD_REPEAT
- || (cmd == CMD_REPEAT)
- #endif
- )
- {
- if (N_OK != spi_read(&rsp, 1))
- return N_FAIL;
- }
-
- /* wait for response */
- s8RetryCnt = SPI_RESP_RETRY_COUNT;
- do
- {
- if (N_OK != spi_read(&rsp, 1))
- {
- M2M_ERR("[spi_cmd_rsp]: Failed cmd response read, bus error...\r\n");
- return N_FAIL;
- }
- }
- while((rsp != cmd) && (s8RetryCnt-- > 0));
-
- if (s8RetryCnt < 0)
- {
- M2M_ERR("[spi_cmd_rsp]: Failed cmd response read\n");
- return N_FAIL;
- }
- /**
- State response
- **/
- /* wait for response */
- s8RetryCnt = SPI_RESP_RETRY_COUNT;
- do
- {
- if (N_OK != spi_read(&rsp, 1))
- {
- M2M_ERR("[spi_cmd_rsp]: Failed cmd response read, bus error...\r\n");
- return N_FAIL;
- }
- }
- while((rsp != 0x00) && (s8RetryCnt-- > 0));
-
- if (s8RetryCnt < 0)
- {
- M2M_ERR("[spi_cmd_rsp]: Failed cmd response read\n");
- return N_FAIL;
- }
-
- return N_OK;
- }
-
- static void spi_reset(void)
- {
- nm_sleep(1);
- spi_cmd(CMD_RESET, 0, 0, 0, 0);
- spi_cmd_rsp(CMD_RESET);
- nm_sleep(1);
- }
-
- /********************************************
-
- Spi Internal Read/Write Function
-
- ********************************************/
-
- static int8_t spi_data_read(uint8_t *b, uint16_t sz,uint8_t clockless)
- {
- int16_t retry, ix, nbytes;
- int8_t result = N_OK;
- uint8_t crc[2];
- uint8_t rsp;
-
- /**
- Data
- **/
- ix = 0;
- do {
- if (sz <= DATA_PKT_SZ)
- nbytes = sz;
- else
- nbytes = DATA_PKT_SZ;
-
- /**
- Data Response header
- **/
- retry = SPI_RESP_RETRY_COUNT;
- do
- {
- if (N_OK != spi_read(&rsp, 1))
- {
- M2M_ERR("[spi_data_read]: Failed data response read, bus error...\r\n");
- result = N_FAIL;
- break;
- }
- if ((rsp & 0xf0) == 0xf0)
- break;
- }
- while (retry--);
-
- if (result == N_FAIL)
- break;
-
- if (retry <= 0)
- {
- M2M_ERR("[spi_data_read]: Failed data response read...(%02x)\r\n", rsp);
- result = N_FAIL;
- break;
- }
-
- /**
- Read bytes
- **/
- if (N_OK != spi_read(&b[ix], nbytes))
- {
- M2M_ERR("[spi_data_read]: Failed data block read, bus error...\r\n");
- result = N_FAIL;
- break;
- }
- if(!clockless)
- {
- /**
- Read Crc
- **/
- if (!gu8Crc_off)
- {
- if (N_OK != spi_read(crc, 2))
- {
- M2M_ERR("[spi_data_read]: Failed data block CRC read, bus error...\r\n");
- result = N_FAIL;
- break;
- }
- }
- }
- ix += nbytes;
- sz -= nbytes;
-
- } while (sz);
-
- return result;
- }
-
- static int8_t spi_data_write(uint8_t *b, uint16_t sz)
- {
- int16_t ix = 0;
- uint16_t nbytes;
- int8_t result = N_OK;
- uint8_t cmd, order, crc[2] = {0};
- //uint8_t rsp;
-
- /**
- Data
- **/
- do
- {
- if (sz <= DATA_PKT_SZ)
- nbytes = sz;
- else
- nbytes = DATA_PKT_SZ;
-
- /**
- Write command
- **/
- cmd = 0xf0;
- if (ix == 0)
- {
- if (sz <= DATA_PKT_SZ)
- order = 0x3;
- else
- order = 0x1;
- }
- else
- {
- if (sz <= DATA_PKT_SZ)
- order = 0x3;
- else
- order = 0x2;
- }
-
- cmd |= order;
- if (N_OK != spi_write(&cmd, 1))
- {
- M2M_ERR("[spi_data_write]: Failed data block cmd write, bus error...\r\n");
- result = N_FAIL;
- break;
- }
-
- /**
- Write data
- **/
- if (N_OK != spi_write(&b[ix], nbytes))
- {
- M2M_ERR("[spi_data_write]: Failed data block write, bus error...\r\n");
- result = N_FAIL;
- break;
- }
-
- /**
- Write Crc
- **/
- if (!gu8Crc_off)
- {
- if (N_OK != spi_write(crc, 2))
- {
- M2M_ERR("[spi_data_write]: Failed data block CRC write, bus error...\r\n");
- result = N_FAIL;
- break;
- }
- }
-
- ix += nbytes;
- sz -= nbytes;
- }
- while (sz);
-
- return result;
- }
-
- /********************************************
-
- Spi interfaces
-
- ********************************************/
-
- static int8_t spi_write_reg(uint32_t u32Addr, uint32_t u32Val)
- {
- uint8_t cmd = CMD_SINGLE_WRITE;
- uint8_t clockless = 0;
-
- if (u32Addr <= 0x30)
- {
- /**
- NMC1000 clockless registers.
- **/
- cmd = CMD_INTERNAL_WRITE;
- clockless = 1;
- }
-
- if (spi_cmd(cmd, u32Addr, u32Val, 4, clockless) != N_OK)
- {
- M2M_ERR("[spi_write_reg]: Failed cmd, write reg (%08" PRIx32 ")...\r\n", u32Addr);
- return N_FAIL;
- }
-
- if (spi_cmd_rsp(cmd) != N_OK)
- {
- M2M_ERR("[spi_write_reg]: Failed cmd response, write reg (%08" PRIx32 ")...\r\n", u32Addr);
- return N_FAIL;
- }
-
- return N_OK;
- }
-
- static int8_t spi_write_block(uint32_t u32Addr, uint8_t *puBuf, uint16_t u16Sz)
- {
- uint8_t len;
- uint8_t rsp[3];
-
- /**
- Command
- **/
- if (spi_cmd(CMD_DMA_EXT_WRITE, u32Addr, 0, u16Sz, 0) != N_OK)
- {
- M2M_ERR("[spi_write_block]: Failed cmd, write block (%08" PRIx32 ")...\r\n", u32Addr);
- return N_FAIL;
- }
-
- if (spi_cmd_rsp(CMD_DMA_EXT_WRITE) != N_OK)
- {
- M2M_ERR("[spi_write_block]: Failed cmd response, write block (%08" PRIx32 ")...\r\n", u32Addr);
- return N_FAIL;
- }
-
- /**
- Data
- **/
- if (spi_data_write(puBuf, u16Sz) != N_OK)
- {
- M2M_ERR("[spi_write_block]: Failed block data write...\r\n");
- return N_FAIL;
- }
- /**
- Data RESP
- **/
- if (!gu8Crc_off)
- len = 2;
- else
- len = 3;
-
- if (N_OK != spi_read(&rsp[0], len))
- {
- M2M_ERR("[spi_write_block]: Failed bus error...\r\n");
- return N_FAIL;
- }
-
- if((rsp[len-1] != 0) || (rsp[len-2] != 0xC3))
- {
- M2M_ERR("[spi_write_block]: Failed data response read, %x %x %x\r\n", rsp[0], rsp[1], rsp[2]);
- return N_FAIL;
- }
-
- return N_OK;
- }
-
- static int8_t spi_read_reg(uint32_t u32Addr, uint32_t* pu32RetVal)
- {
- uint8_t cmd = CMD_SINGLE_READ;
- uint8_t tmp[4];
- uint8_t clockless = 0;
-
- if (u32Addr <= 0xff)
- {
- /**
- NMC1000 clockless registers.
- **/
- cmd = CMD_INTERNAL_READ;
- clockless = 1;
- }
-
- if (spi_cmd(cmd, u32Addr, 0, 4, clockless) != N_OK)
- {
- M2M_ERR("[spi_read_reg]: Failed cmd, read reg (%08" PRIx32 ")...\r\n", u32Addr);
- return N_FAIL;
- }
-
- if (spi_cmd_rsp(cmd) != N_OK)
- {
- M2M_ERR("[spi_read_reg]: Failed cmd response, read reg (%08" PRIx32 ")...\r\n", u32Addr);
- return N_FAIL;
- }
-
- /* to avoid endianess issues */
- if (spi_data_read(&tmp[0], 4, clockless) != N_OK)
- {
- M2M_ERR("[spi_read_reg]: Failed data read...\r\n");
- return N_FAIL;
- }
-
- *pu32RetVal = ((uint32_t)tmp[0]) |
- ((uint32_t)tmp[1] << 8) |
- ((uint32_t)tmp[2] << 16) |
- ((uint32_t)tmp[3] << 24);
-
- return N_OK;
- }
-
- static int8_t spi_read_block(uint32_t u32Addr, uint8_t *puBuf, uint16_t u16Sz)
- {
- /**
- Command
- **/
- if (spi_cmd(CMD_DMA_EXT_READ, u32Addr, 0, u16Sz, 0) != N_OK)
- {
- M2M_ERR("[spi_read_block]: Failed cmd, read block (%08" PRIx32 ")...\r\n", u32Addr);
- return N_FAIL;
- }
-
- if (spi_cmd_rsp(CMD_DMA_EXT_READ) != N_OK)
- {
- M2M_ERR("[spi_read_block]: Failed cmd response, read block (%08" PRIx32 ")...\r\n", u32Addr);
- return N_FAIL;
- }
-
- /**
- Data
- **/
- if (spi_data_read(puBuf, u16Sz, 0) != N_OK)
- {
- M2M_ERR("[spi_read_block]: Failed block data read...\r\n");
- return N_FAIL;
- }
-
- return N_OK;
- }
-
- static void spi_init_pkt_sz(void)
- {
- uint32_t val32;
-
- /* Make sure SPI max. packet size fits the defined DATA_PKT_SZ. */
- val32 = nm_spi_read_reg(SPI_BASE+0x24);
- val32 &= ~(0x7 << 4);
- switch(DATA_PKT_SZ)
- {
- case 256: val32 |= (0 << 4); break;
- case 512: val32 |= (1 << 4); break;
- case 1024: val32 |= (2 << 4); break;
- case 2048: val32 |= (3 << 4); break;
- case 4096: val32 |= (4 << 4); break;
- case 8192: val32 |= (5 << 4); break;
- }
- nm_spi_write_reg(SPI_BASE+0x24, val32);
- }
-
- /********************************************
-
- Bus interfaces
-
- ********************************************/
-
- int8_t nm_spi_reset(void)
- {
- // if (OSAL_RESULT_TRUE != OSAL_MUTEX_Lock(&s_spiLock, OSAL_WAIT_FOREVER))
- // return M2M_ERR_BUS_FAIL;
-
- spi_cmd(CMD_RESET, 0, 0, 0, 0);
- spi_cmd_rsp(CMD_RESET);
-
- // OSAL_MUTEX_Unlock(&s_spiLock);
-
- return M2M_SUCCESS;
- }
-
- void nm_spi_lock_init(void)
- {
- // OSAL_MUTEX_Create(&s_spiLock);
- }
-
- /*
- * @fn nm_spi_init
- * @brief Initialize the SPI
- * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
- */
- int8_t nm_spi_init(void)
- {
- uint32_t chipid;
- uint32_t reg = 0;
-
- mWifiSPIBaudrate = SPICalculateBRG(PERIPHERAL_FREQ, WIFI_MODULE_SPI_BAUDRATE);
-
- /**
- configure protocol
- **/
- gu8Crc_off = 0;
-
- if (nm_spi_read_reg_with_ret(NMI_SPI_PROTOCOL_CONFIG, ®) != M2M_SUCCESS)
- {
- /* Read failed. Try with CRC off. This might happen when module
- is removed but chip isn't reset*/
- gu8Crc_off = 1;
- M2M_ERR("[nm_spi_init]: Failed internal read protocol with CRC on, retrying with CRC off...\r\n");
-
- if (nm_spi_read_reg_with_ret(NMI_SPI_PROTOCOL_CONFIG, ®) != M2M_SUCCESS)
- {
- // Reaad failed with both CRC on and off, something went bad
- M2M_ERR("[nm_spi_init]: Failed internal read protocol...\r\n");
-
- return M2M_ERR_BUS_FAIL;
- }
- }
- if(gu8Crc_off == 0)
- {
- reg &= ~0xc; /* disable CRC checking */
- reg &= ~0x70;
- reg |= (0x5 << 4);
-
- if (nm_spi_write_reg(NMI_SPI_PROTOCOL_CONFIG, reg) != M2M_SUCCESS)
- {
- M2M_ERR("[nm_spi_init]: Failed internal write protocol reg...\r\n");
-
- return M2M_ERR_BUS_FAIL;
- }
-
- gu8Crc_off = 1;
- }
-
- /**
- make sure can read back chip id correctly
- **/
- if (nm_spi_read_reg_with_ret(0x1000, &chipid) != M2M_SUCCESS)
- {
- M2M_ERR("[nm_spi_init]: Fail cmd read chip id...\r\n");
- return M2M_ERR_BUS_FAIL;
- }
-
- M2M_DBG("[nm_spi_init]: chipid (%08x)\r\n", (unsigned int)chipid);
- spi_init_pkt_sz();
-
- return M2M_SUCCESS;
- }
-
- /*
- * @fn nm_spi_deinit
- * @brief DeInitialize the SPI
- * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
- */
- int8_t nm_spi_deinit(void)
- {
- gu8Crc_off = 0;
- // OSAL_MUTEX_Delete(&s_spiLock);
- return M2M_SUCCESS;
- }
-
- /*
- * @fn nm_spi_read_reg
- * @brief Read register
- * @param [in] u32Addr
- * Register address
- * @return Register value
- */
- uint32_t nm_spi_read_reg(uint32_t u32Addr)
- {
- uint32_t u32Val;
-
- nm_spi_read_reg_with_ret(u32Addr, &u32Val);
-
- return u32Val;
- }
-
- /*
- * @fn nm_spi_read_reg_with_ret
- * @brief Read register with error code return
- * @param [in] u32Addr
- * Register address
- * @param [out] pu32RetVal
- * Pointer to u32 variable used to return the read value
- * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
- */
- int8_t nm_spi_read_reg_with_ret(uint32_t u32Addr, uint32_t* pu32RetVal)
- {
- uint8_t retry = SPI_RETRY_COUNT;
-
- // if (OSAL_RESULT_TRUE != OSAL_MUTEX_Lock(&s_spiLock, OSAL_WAIT_FOREVER))
- // return M2M_ERR_BUS_FAIL;
-
- while(retry--)
- {
- if (spi_read_reg(u32Addr, pu32RetVal) == N_OK)
- {
- // OSAL_MUTEX_Unlock(&s_spiLock);
-
- return M2M_SUCCESS;
- }
-
- M2M_ERR("Reset and retry %d %" PRIx32 "\r\n", retry, u32Addr);
- spi_reset();
- }
-
- // OSAL_MUTEX_Unlock(&s_spiLock);
-
- return M2M_ERR_BUS_FAIL;
- }
-
- /*
- * @fn nm_spi_write_reg
- * @brief write register
- * @param [in] u32Addr
- * Register address
- * @param [in] u32Val
- * Value to be written to the register
- * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
- */
- int8_t nm_spi_write_reg(uint32_t u32Addr, uint32_t u32Val)
- {
- uint8_t retry = SPI_RETRY_COUNT;
-
- // if (OSAL_RESULT_TRUE != OSAL_MUTEX_Lock(&s_spiLock, OSAL_WAIT_FOREVER))
- // return M2M_ERR_BUS_FAIL;
-
- while(retry--)
- {
- if (spi_write_reg(u32Addr, u32Val) == N_OK)
- {
- // OSAL_MUTEX_Unlock(&s_spiLock);
-
- return M2M_SUCCESS;
- }
-
- M2M_ERR("Reset and retry %d %" PRIx32 " %" PRIx32 "\r\n", retry, u32Addr, u32Val);
- spi_reset();
- }
-
- // OSAL_MUTEX_Unlock(&s_spiLock);
-
- return M2M_ERR_BUS_FAIL;
- }
-
- /*
- * @fn nm_spi_read_block
- * @brief Read block of data
- * @param [in] u32Addr
- * Start address
- * @param [out] puBuf
- * Pointer to a buffer used to return the read data
- * @param [in] u16Sz
- * Number of bytes to read. The buffer size must be >= u16Sz
- * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
- */
- int8_t nm_spi_read_block(uint32_t u32Addr, uint8_t *puBuf, uint16_t u16Sz)
- {
- uint8_t retry = SPI_RETRY_COUNT;
- uint8_t tmpBuf[2] = {0,0};
- uint8_t *puTmpBuf;
-
- // if (OSAL_RESULT_TRUE != OSAL_MUTEX_Lock(&s_spiLock, OSAL_WAIT_FOREVER))
- // return M2M_ERR_BUS_FAIL;
-
- if (u16Sz == 1)
- {
- u16Sz = 2;
- puTmpBuf = tmpBuf;
- }
- else
- {
- puTmpBuf = puBuf;
- }
-
- while(retry--)
- {
- if (spi_read_block(u32Addr, puTmpBuf, u16Sz) == N_OK)
- {
- // OSAL_MUTEX_Unlock(&s_spiLock);
-
- if (puTmpBuf == tmpBuf)
- *puBuf = *tmpBuf;
-
- return M2M_SUCCESS;
- }
-
- M2M_ERR("Reset and retry %d %" PRIx32 " %d\r\n", retry, u32Addr, u16Sz);
- spi_reset();
- }
-
- // OSAL_MUTEX_Unlock(&s_spiLock);
-
- return M2M_ERR_BUS_FAIL;
- }
-
- /*
- * @fn nm_spi_write_block
- * @brief Write block of data
- * @param [in] u32Addr
- * Start address
- * @param [in] puBuf
- * Pointer to the buffer holding the data to be written
- * @param [in] u16Sz
- * Number of bytes to write. The buffer size must be >= u16Sz
- * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
- */
- int8_t nm_spi_write_block(uint32_t u32Addr, uint8_t *puBuf, uint16_t u16Sz)
- {
- uint8_t retry = SPI_RETRY_COUNT;
-
- // if (OSAL_RESULT_TRUE != OSAL_MUTEX_Lock(&s_spiLock, OSAL_WAIT_FOREVER))
- // return M2M_ERR_BUS_FAIL;
-
- //Workaround hardware problem with single byte transfers over SPI bus
- if (u16Sz == 1)
- u16Sz = 2;
-
- while(retry--)
- {
- if (spi_write_block(u32Addr, puBuf, u16Sz) == N_OK)
- {
- // OSAL_MUTEX_Unlock(&s_spiLock);
-
- return M2M_SUCCESS;
- }
-
- M2M_ERR("Reset and retry %d %" PRIx32 " %d\r\n", retry, u32Addr, u16Sz);
- spi_reset();
- }
-
- // OSAL_MUTEX_Unlock(&s_spiLock);
-
- return M2M_ERR_BUS_FAIL;
- }
-
- //DOM-IGNORE-END
|