Having problems getting SPI master to work with CC3100 wifi chip.
Using TI SPI porting diagnostics to verify operation.
Based on recommendations, attempted to switch to using nrfx spim approach.
If I run through the test loop by stepping over all the functions with the debugger it works fine.
If I run at speed I either get an assert or a flood of interrupts even if the CC3100 is disabled when the interrupt storm starts.
Running short on ideas on how to get this to work.
Disabled all other functions for now so only the basic gpiote and spi functions are being used.
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "nordic_common.h"
#include "nrf_sdm.h"
//#include "ble.h"
//#include "ble_hci.h"
//#include "ble_srv_common.h"
#include "nrf_sdh.h"
#include "nrf_sdh_ble.h"
#include "nrf_sdh_soc.h"
//#include "nrf_drv_gpiote.h"
#include "nrfx_spim.h"
#include "app_util.h"
#include "app_error.h"
#include "app_util.h"
#include "app_timer.h"
#include "app_gpiote.h"
#include "bsp_btn_ble.h"
//#include "peer_manager.h"
//#include "peer_manager_handler.h"
//#include "fds.h"
//#include "nrf_fstorage.h"
//#include "ble_conn_state.h"
//#include "nrf_ble_gatt.h"
//#include "nrf_ble_scan.h"
//#include "nrf_pwr_mgmt.h"
#include "simplelink.h"
#include "sl_common.h"
#include "medsense.h"
#include "user.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "SEGGER_RTT.h"
//#include "SEGGER_RTT_printf.h"
#define NRFX_SPIM_SCK_PIN 5
#define NRFX_SPIM_MOSI_PIN 4
#define NRFX_SPIM_MISO_PIN 3
#define NRFX_SPIM_SS_PIN 2
//#define NRFX_SPIM_DCX_PIN
extern volatile P_EVENT_HANDLER pIrqEventHandler;
extern volatile unsigned char pBuf[8];
int irgcnt = 0;
#define SPI_INSTANCE 0 /**< SPI instance index. */
const nrfx_spim_t spi = NRFX_SPIM_INSTANCE(SPI_INSTANCE); /**< SPI instance. */
volatile bool spi_xfer_done; /**< Flag used to indicate that SPI instance completed the transfer. */
#define TEST_STRING "Nordic123456789012345678901234567890"
uint8_t m_tx_buf[] = TEST_STRING; /**< TX buffer. */
uint8_t m_rx_buf[sizeof(TEST_STRING) + 1]; /**< RX buffer. */
const uint8_t m_length = sizeof(m_tx_buf); /**< Transfer length. */
nrfx_spim_xfer_desc_t xfer_desc ; //= NRFX_SPIM_XFER_TRX(m_tx_buf, m_length, m_rx_buf, m_length);
nrfx_spim_config_t spi_config = NRFX_SPIM_DEFAULT_CONFIG;
nrfx_spim_xfer_desc_t * p_xfer;
#define NRF_LOG_INFO(...) SEGGER_RTT_printf(0 , __VA_ARGS__)
#define APP_BLE_CONN_CFG_TAG 1 /**< A tag identifying the SoftDevice BLE configuration. */
#define APP_BLE_OBSERVER_PRIO 3 /**< Application's BLE observer priority. You shouldn't need to modify this value. */
#define APP_SOC_OBSERVER_PRIO 1 /**< Applications' SoC observer priority. You shouldn't need to modify this value. */
#define SEC_PARAM_BOND 1 /**< Perform bonding. */
#define SEC_PARAM_MITM 0 /**< Man In The Middle protection not required. */
#define SEC_PARAM_LESC 0 /**< LE Secure Connections not enabled. */
#define SEC_PARAM_KEYPRESS 0 /**< Keypress notifications not enabled. */
#define SEC_PARAM_IO_CAPABILITIES BLE_GAP_IO_CAPS_NONE /**< No I/O capabilities. */
#define SEC_PARAM_OOB 0 /**< Out Of Band data not available. */
#define SEC_PARAM_MIN_KEY_SIZE 7 /**< Minimum encryption key size. */
#define SEC_PARAM_MAX_KEY_SIZE 16 /**< Maximum encryption key size. */
#define SCAN_DURATION_WITELIST 3000 /**< Duration of the scanning in units of 10 milliseconds. */
#define TARGET_UUID BLE_UUID_GATT /**< Target device name that application is looking for. */
/**@brief Variable length data encapsulation in terms of length and pointer to data */
typedef struct
{
uint8_t * p_data; /**< Pointer to data. */
uint16_t data_len; /**< Length of data. */
}data_t;
NRF_BLE_GATT_DEF(m_gatt); /**< GATT module instance. */
NRF_BLE_SCAN_DEF(m_scan); /**< Scanning Module instance. */
static uint16_t m_conn_handle; /**< Current connection handle. */
static bool m_whitelist_disabled; /**< True if whitelist has been temporarily disabled. */
static bool m_memory_access_in_progress; /**< Flag to keep track of ongoing operations on persistent memory. */
static bool m_erase_bonds; /**< Bool to determine if bonds should be erased before scanning starts. Based on button push upon startup. */
/**< Scan parameters requested for scanning and connection. */
static ble_gap_scan_params_t const m_scan_param =
{
.active = 0x01,
.interval = NRF_BLE_SCAN_SCAN_INTERVAL,
.window = NRF_BLE_SCAN_SCAN_WINDOW,
.filter_policy = BLE_GAP_SCAN_FP_WHITELIST,
.timeout = SCAN_DURATION_WITELIST,
.scan_phys = BLE_GAP_PHY_1MBPS,
};
bool startup = true;
static void scan_start(void);
static char const m_target_periph_name[] = "Nordic_GATTS"; /**< If you want to connect to a peripheral using a given advertising name, type its name here. */
static bool is_connect_per_addr = false; /**< If you want to connect to a peripheral with a given address, set this to true and put the correct address in the variable below. */
static ble_gap_addr_t const m_target_periph_addr =
{
/* Possible values for addr_type:
BLE_GAP_ADDR_TYPE_PUBLIC,
BLE_GAP_ADDR_TYPE_RANDOM_STATIC,
BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE,
BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. */
.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC,
.addr = {0x8D, 0xFE, 0x23, 0x86, 0x77, 0xD9}
};
//**********Simplelink items
/*
#define _u32 uint32_t
#define _i32 int32_t
#define i32 int32_t
*/
#define VERSION_OFFSET (8)
#define UCF_OFFSET (20)
#define CHUNK_LEN (1024)
#define LEN_128KB (131072)
#define find_min(a,b) (((a) < (b)) ? (a) : (b))
char printBuffer[1024];
typedef enum
{
size512KB = 0,
size1MB,
size2MB,
size4MB,
size8MB,
size16MB
}sflashSize_e;
sflashSize_e flashSize = size1MB;;
#define APPLICATION_VERSION "1.3.0"
/* Use bit 32:
* 1 in a 'status_variable', the device has completed the ping operation
* 0 in a 'status_variable', the device has not completed the ping operation
*/
#define STATUS_BIT_PING_DONE 31
#define HOST_NAME "www.ti.com"
/*
* Values for below macros shall be modified for setting the 'Ping' properties
*/
#define PING_INTERVAL 1000 /* In msecs */
#define PING_TIMEOUT 3000 /* In msecs */
#define PING_PKT_SIZE 20 /* In bytes */
#define NO_OF_ATTEMPTS 3
/*
/* Application specific status/error codes */
/*
typedef enum{
LAN_CONNECTION_FAILED = -0x7D0, /* Choosing this number to avoid overlap with host-driver's error codes */
// INTERNET_CONNECTION_FAILED = LAN_CONNECTION_FAILED - 1,
// DEVICE_NOT_IN_STATION_MODE = INTERNET_CONNECTION_FAILED - 1,
// STATUS_CODE_MAX = -0xBB8
//}e_AppStatusCodes;
//*/
#define IS_PING_DONE(status_variable) GET_STATUS_BIT(status_variable, \
STATUS_BIT_PING_DONE)
/*
* GLOBAL VARIABLES -- Start
*/
extern volatile uint32_t g_Status;
extern volatile uint32_t g_PingPacketsRecv;
extern volatile uint32_t g_GatewayIP;
/*
* GLOBAL VARIABLES -- End
*/
/*
* STATIC FUNCTION DEFINITIONS -- Start
*/
extern int32_t configureSimpleLinkToDefaultState();
static int32_t establishConnectionWithAP();
static int32_t checkLanConnection();
static int32_t checkInternetConnection();
static int32_t initializeAppVariables();
static void displayBanner();
// End if Simplelink items
static app_gpiote_user_id_t m_example_user_id;
static void example_gpiote_event_handler(uint32_t event_pins_low_to_high, uint32_t event_pins_high_to_low);
/**@brief Function for asserts in the SoftDevice.
*
* @details This function will be called in case of an assert in the SoftDevice.
*
* @warning This handler is an example only and does not fit a final product. You need to analyze
* how your product is supposed to react in case of Assert.
* @warning On assert from the SoftDevice, the system can only recover on reset.
*
* @param[in] line_num Line number of the failing ASSERT call.
* @param[in] p_file_name File name of the failing ASSERT call.
*/
void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
{
app_error_handler(0xDEADBEEF, line_num, p_file_name);
}
static void soc_evt_handler(uint32_t evt_id, void * p_context)
{
switch (evt_id)
{
case NRF_EVT_FLASH_OPERATION_SUCCESS:
/* fall through */
case NRF_EVT_FLASH_OPERATION_ERROR:
if (m_memory_access_in_progress)
{
m_memory_access_in_progress = false;
scan_start();
}
break;
default:
// No implementation needed.
break;
}
}
/**@brief Function for initializing the BLE stack.
*
* @details Initializes the SoftDevice and the BLE event interrupt.
*/
/**@brief Function for disabling the use of whitelist for scanning.
*/
static void whitelist_disable(void)
{
if (!m_whitelist_disabled)
{
NRF_LOG_INFO("Whitelist temporarily disabled.");
m_whitelist_disabled = true;
nrf_ble_scan_stop();
scan_start();
}
}
/**@brief Function for handling events from the BSP module.
*
* @param[in] event Event generated by button press.
*/
/**@brief Function for initializing logging. */
static void log_init(void)
{
ret_code_t err_code = NRF_LOG_INIT(NULL);
APP_ERROR_CHECK(err_code);
NRF_LOG_DEFAULT_BACKENDS_INIT();
}
/**@brief Function for initializing the timer. */
static void timer_init(void)
{
ret_code_t err_code = app_timer_init();
APP_ERROR_CHECK(err_code);
}
static void idle_state_handle(void)
{
if (NRF_LOG_PROCESS() == false)
{
nrf_pwr_mgmt_run();
}
}
/**@brief Function for initializing all the modules used in this example application.
*/
static void modules_init(void)
{
int status = 0;
int x;
// Initialize.
SEGGER_RTT_Init();
log_init();
NRF_LOG_INFO("lOGGING started.\r\n");
status = SEGGER_RTT_WriteString(0, "writing to channel 0\r\n");
gpio_init();
nrfx_gpiote_out_set(LED_RED);
nrfx_gpiote_out_set(LED_GREEN);
nrfx_gpiote_out_set(LED_BLUE);
for (x = 0; x < 5 ; x++)
{
nrfx_gpiote_out_clear(LED_GREEN);
delay_ms(200);
nrfx_gpiote_out_set(LED_GREEN);
delay_ms(200);
}
NRF_LOG_INFO("Module Init completed.\r\n");
}
void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent)
{
/*
* Most of the general errors are not FATAL are are to be handled
* appropriately by the application
*/
CLI_Write((_u8 *)" [GENERAL EVENT] handler \n\r");
if(pDevEvent == NULL)
{
CLI_Write((_u8 *)" [General EVENT] NULL Pointer Error \n\r");
return;
}
/*
SL_DEVICE_GENERAL_ERROR_EVENT = 1,
SL_DEVICE_ABORT_ERROR_EVENT,
SL_DEVICE_DRIVER_ASSERT_ERROR_EVENT,
SL_DEVICE_DRIVER_TIMEOUT_CMD_COMPLETE,
SL_DEVICE_DRIVER_TIMEOUT_SYNC_PATTERN,
SL_DEVICE_DRIVER_TIMEOUT_ASYNC_EVENT,
SL_DEVICE_ERROR_MAX
*/
switch(pDevEvent->Event)
{
case SL_DEVICE_GENERAL_ERROR_EVENT :
CLI_Write((_u8 *)" [GENERAL EVENT] handler SL_DEVICE_GENERAL_ERROR_EVENT \n\r");
break;
case SL_DEVICE_ABORT_ERROR_EVENT :
CLI_Write((_u8 *)" [GENERAL EVENT] handler SL_DEVICE_ABORT_ERROR_EVENT\n\r");
break;
case SL_DEVICE_DRIVER_ASSERT_ERROR_EVENT :
CLI_Write((_u8 *)" [GENERAL EVENT] handler SL_DEVICE_DRIVER_ASSERT_ERROR_EVENT\n\r");
break;
case SL_DEVICE_DRIVER_TIMEOUT_CMD_COMPLETE :
CLI_Write((_u8 *)" [GENERAL EVENT] handler SL_DEVICE_DRIVER_TIMEOUT_CMD_COMPLETE\n\r");
break;
case SL_DEVICE_DRIVER_TIMEOUT_SYNC_PATTERN :
CLI_Write((_u8 *)" [GENERAL EVENT] handler SL_DEVICE_DRIVER_TIMEOUT_SYNC_PATTERN \n\r");
break;
case SL_DEVICE_DRIVER_TIMEOUT_ASYNC_EVENT :
CLI_Write((_u8 *)" [GENERAL EVENT] handler SL_DEVICE_DRIVER_TIMEOUT_ASYNC_EVENT\n\r");
break;
case SL_DEVICE_ERROR_MAX :
CLI_Write((_u8 *)" [GENERAL EVENT] handler SL_DEVICE_ERROR_MAX\n\r");
break;
default :
CLI_Write((_u8 *)" [GENERAL EVENT] handler number %d \n\r", pDevEvent->Event );
}
}
void Button_IRQHandler(void)
{/// GPIOTE IRQ service routine
nrfx_gpiote_out_toggle(LED_RED);
nrfx_gpiote_out_clear(CC_NRST_PIN);
nrfx_gpiote_out_clear(CC_NHIB_PIN);
nrf_delay_ms(10);
nrfx_gpiote_out_clear(CC_NRST_PIN);
nrfx_gpiote_in_event_enable(CC_IRQ_PIN, false);
nrfx_spim_abort(&spi);
if (startup) return;
sd_nvic_DisableIRQ(GPIOTE_IRQn);
g_btn_state = (BTN_STATE_RESTORE_AP_MODE);
//NRF_GPIOTE->EVENTS_IN[0] = 0;
setLED(LED_RED, LED_MODE_STATIC, 0);
#ifdef SYSTEM_DEBUG
printUART("-> SYS: Restoring WIFI AP mode ...\n");
#endif
setDefaultFLASH();
while((NRF_P0->IN & (1<<(PBTN_PIN))) == 0x00000000);
#ifdef SYSTEM_DEBUG
printUART("-> SYS: Rebooting...\n\n\n");
#endif
delay_ms(200);
while((NRF_P0->IN & (1<<(PBTN_PIN))) == 0x00000000);
sd_nvic_SystemReset();
}
void CC3100_IRQHandler(void)
{/// GPIOTE IRQ service routine
sd_nvic_DisableIRQ(GPIOTE_IRQn);
if(pIrqEventHandler) //
{
// pIrqEventHandler = Button_IRQHandler;
pIrqEventHandler(0);
}
sd_nvic_EnableIRQ(GPIOTE_IRQn);
}
void CC_MOSI_PIN_IRQHandler(void)
{
return;
}
void gpio_init(void)
{
ret_code_t err_code;
// APP_GPIOTE_INIT(1);
if (!nrfx_gpiote_is_init())
{
err_code = nrfx_gpiote_init();
APP_ERROR_CHECK(err_code);
}
nrfx_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_SIMPLE(true);
err_code = nrfx_gpiote_out_init(CC_NRST_PIN, &out_config);
APP_ERROR_CHECK(err_code);
nrf_gpio_cfg(CC_NRST_PIN,NRF_GPIO_PIN_DIR_OUTPUT,NRF_GPIO_PIN_INPUT_CONNECT ,NRF_GPIO_PIN_NOPULL ,
NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_SENSE_HIGH );
err_code = nrfx_gpiote_out_init(CC_NCS_PIN, &out_config);
APP_ERROR_CHECK(err_code);
err_code = nrfx_gpiote_out_init(CC_MOSI_PIN, &out_config);
APP_ERROR_CHECK(err_code);
err_code = nrfx_gpiote_out_init(CC_SCK_PIN, &out_config);
APP_ERROR_CHECK(err_code);
err_code = nrfx_gpiote_out_init(CC_NHIB_PIN, &out_config);
APP_ERROR_CHECK(err_code);
nrf_gpio_cfg(CC_NHIB_PIN,NRF_GPIO_PIN_DIR_OUTPUT,NRF_GPIO_PIN_INPUT_CONNECT ,NRF_GPIO_PIN_NOPULL ,
NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_SENSE_HIGH );
err_code = nrfx_gpiote_out_init(LED_RED, &out_config);
APP_ERROR_CHECK(err_code);
err_code = nrfx_gpiote_out_init(LED_GREEN, &out_config);
APP_ERROR_CHECK(err_code);
err_code = nrfx_gpiote_out_init(LED_BLUE, &out_config);
APP_ERROR_CHECK(err_code);
// Make a configuration for input pins. This is suitable for both pins in this example.
nrfx_gpiote_in_config_t in_config = {// = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);
.is_watcher = false, \
.hi_accuracy = true, \
.pull = NRF_GPIO_PIN_PULLUP, \
.sense = NRF_GPIOTE_POLARITY_HITOLO
};
err_code = nrfx_gpiote_in_init(BUTTON_2, &in_config, Button_IRQHandler);
APP_ERROR_CHECK(err_code);
in_config.hi_accuracy = true;
in_config.pull = NRF_GPIO_PIN_PULLUP;
in_config.sense = NRF_GPIOTE_POLARITY_LOTOHI;
err_code = nrfx_gpiote_in_init(CC_IRQ_PIN, &in_config, CC3100_IRQHandler);
APP_ERROR_CHECK(err_code);
nrfx_gpiote_in_event_enable(CC_IRQ_PIN, true);
nrfx_gpiote_in_event_enable(BUTTON_2, true);
nrfx_gpiote_out_clear(CC_NHIB_PIN);
nrfx_gpiote_out_clear(CC_NRST_PIN);
nrf_gpio_cfg(NRFX_SPIM_SS_PIN,NRF_GPIO_PIN_DIR_OUTPUT,NRF_GPIO_PIN_INPUT_DISCONNECT ,NRF_GPIO_PIN_PULLUP ,
NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE );
nrf_gpio_cfg(CC_MOSI_PIN,NRF_GPIO_PIN_DIR_OUTPUT,NRF_GPIO_PIN_INPUT_DISCONNECT ,NRF_GPIO_PIN_PULLUP ,
NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE );
nrf_gpio_cfg(CC_SCK_PIN,NRF_GPIO_PIN_DIR_OUTPUT,NRF_GPIO_PIN_INPUT_DISCONNECT ,NRF_GPIO_PIN_PULLUP ,
NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE );
}
static void example_gpiote_event_handler(uint32_t event_pins_low_to_high, uint32_t event_pins_high_to_low)
{
nrfx_gpiote_out_toggle(LED_RED);
}
void spim_event_handler(nrfx_spim_evt_t const * p_event,
void * p_context)
{
irgcnt++;
if (irgcnt > 20 )
{
NRF_LOG_INFO(" Run away spi interrupt ?");
}
spi_xfer_done = true;
NRF_LOG_INFO("Transfer completed.\r\n");
// if (m_rx_buf[0] != 0)
if ((xfer_desc.p_tx_buffer != 0) && (xfer_desc.tx_length > 0))
{
NRF_LOG_INFO("Sent :");
NRF_LOG_HEXDUMP_INFO(xfer_desc.p_tx_buffer, xfer_desc.tx_length);
NRF_LOG_INFO("\r\n");
}
if ((xfer_desc.p_rx_buffer != 0) && (xfer_desc.rx_length > 0))
{
NRF_LOG_INFO(" Received:");
NRF_LOG_HEXDUMP_INFO(xfer_desc.p_rx_buffer, xfer_desc.rx_length);
NRF_LOG_INFO("\r\n");
}
NRF_LOG_FLUSH();
}
void TestIrqHandler()
{
NRF_LOG_INFO(" IRQ Received:\r\n");
}
int main(void)
{
unsigned int retVal = -1;
modules_init();
p_xfer = &xfer_desc;
xfer_desc.p_rx_buffer = m_rx_buf;
xfer_desc.p_tx_buffer = m_tx_buf;
xfer_desc.rx_length = m_length;
xfer_desc.tx_length = m_length;
spi_config.frequency = NRF_SPIM_FREQ_125K;
spi_config.ss_pin = NRFX_SPIM_SS_PIN;
spi_config.miso_pin = NRFX_SPIM_MISO_PIN;
spi_config.mosi_pin = NRFX_SPIM_MOSI_PIN;
spi_config.sck_pin = NRFX_SPIM_SCK_PIN;
// spi_config.dcx_pin = NRFX_SPIM_DCX_PIN;
// spi_config.use_hw_ss = true;
spi_config.ss_active_high = false;
APP_ERROR_CHECK(nrfx_spim_init(&spi, &spi_config, spim_event_handler, NULL));
nrf_gpio_cfg(NRFX_SPIM_SCK_PIN,NRF_GPIO_PIN_DIR_OUTPUT,NRF_GPIO_PIN_INPUT_CONNECT ,NRF_GPIO_PIN_PULLUP ,
NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_SENSE_HIGH );
nrf_gpio_cfg(NRFX_SPIM_MOSI_PIN,NRF_GPIO_PIN_DIR_OUTPUT,NRF_GPIO_PIN_INPUT_CONNECT ,NRF_GPIO_PIN_PULLUP ,
NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_SENSE_HIGH );
nrf_gpio_cfg(NRFX_SPIM_SS_PIN,NRF_GPIO_PIN_DIR_OUTPUT,NRF_GPIO_PIN_INPUT_CONNECT ,NRF_GPIO_PIN_PULLUP ,
NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_SENSE_HIGH );
CC3100_startup();
CC3100_InterruptEnable();
NRF_LOG_FLUSH();
spi_xfer_done = true;
for (int i = 1; i < 11; i++)
for (int i = 1; i < 11; i++)
{
while (!spi_xfer_done) {__NOP;}
{
NRF_LOG_INFO("*****Starting Pass : %d \r\n", i);
// CC3100_InterruptEnable();
irgcnt = 0;
TestSpi();
// spi_Close(1);
__NOP;
}
}
CC3100_wifi_disable();
NRF_LOG_INFO("Completed 10 cycles\r\n");
}
functions
#include "stdint.h"
#include "custom_board.h"
#include "user.h"
#include "sl_common.h"
#include "simplelink.h"
#include "nrfx_gpiote.h"
#include "nrfx_spim.h"
#include "nrf_delay.h"
#include "medsense.h"
#include "daignostic.h"
#include "SEGGER_RTT.h"
//#include "user.h"
//#include "user.h"
volatile P_EVENT_HANDLER pIrqEventHandler ;
const uint8_t g_firmware_version[6] = "1.0.3";
//extern volatile P_EVENT_HANDLER pIrqEventHandler;
extern const nrfx_spim_t spi;
extern volatile bool spi_xfer_done;
extern TEST_STRING;
extern uint8_t m_tx_buf[];
extern uint8_t m_rx_buf[(sizeof(TEST_STRING) + 1)]; /**< RX buffer. */
extern const uint8_t m_length; /**< Transfer length. */
extern spim_event_handler;
extern nrfx_spim_xfer_desc_t xfer_desc;
volatile uint8_t g_led_blink_pin;
volatile uint32_t g_led_blink_period;
volatile uint32_t g_led_blink_timer;
volatile uint8_t g_led_flag;
volatile uint8_t g_flash_sms;
volatile uint32_t g_flash_timer;
const uint32_t FLASH_USER_SIGN[FLASH_USER_SIGN_WSIZE] = {0x474F4749, 0x4341534D, 0x49523230, 0x31360000};
volatile uint32_t g_flash_page[FLASH_PAGE_SIZE_IN_WORDS];
static volatile SlSockAddrIn_t Addr;
static volatile SlSockAddrIn_t LocalAddr;
static volatile SlSockAddrIn_t Rem_Addr;
//void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent);
//void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent);
//void SimpleLinkHttpServerCallback(SlHttpServerEvent_t *pHttpEvent, SlHttpServerResponse_t *pHttpResponse);
void SimpleLinkPingReport(SlPingReport_t *pPingReport);
void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent);
//void SimpleLinkSockEventHandler(SlSockEvent_t *pSock);
volatile uint8_t g_btn_state;
volatile uint8_t g_ble_rx_buff[BLE_RX_BUFF_SIZE];
volatile uint16_t g_ble_rx_buff_len;
volatile uint8_t g_ble_rx_data[BLE_RX_DATA_BUFF_SIZE];
volatile uint16_t g_ble_rx_data_widx;
volatile uint16_t g_ble_rx_data_ridx;
volatile uint8_t g_ble_tx_buff[WIFI_BUFF_SIZE];
volatile uint16_t g_blef_tx_count;
volatile uint8_t g_flash_update;
volatile uint8_t g_wifi_tx_buff[WIFI_BUFF_SIZE];
volatile uint8_t g_wifi_rx_buff[WIFI_RX_BUFF_SIZE];
volatile uint8_t g_wifi_pkt[WIFI_BUFF_SIZE];
volatile uint16_t g_wifi_rx_buff_widx;
volatile uint16_t g_wifi_rx_buff_ridx;
volatile uint8_t g_wifi_status;
volatile uint8_t g_wifi_error;
volatile uint8_t g_wifi_mode;
volatile uint8_t g_wifi_ssid[WIFI_SSID_SIZE];
volatile uint8_t g_wifi_passwd[WIFI_PASSWD_SIZE];
volatile uint32_t g_wifi_port;
volatile uint32_t g_wifi_enc;
volatile uint32_t g_wifi_remote_server_ip;
volatile uint8_t g_device_name[DEVICE_NAME_SIZE];
volatile uint8_t g_device_id[DEVICE_ID_SIZE];
volatile uint8_t g_flash_write_data[FLASH_WRITE_DATA_SIZE];
volatile uint8_t g_wifi_local_ip_str[20];
volatile uint8_t g_wifi_remote_server_ip_str[20];
volatile int16_t g_wifi_remote_cli_socket = -1;
//#include "wifi.h"
volatile int16_t g_wifi_ser_socket = -1;
volatile int16_t g_wifi_local_cli_socket = -1;
volatile uint8_t g_wifi_data[WIFI_BUFF_SIZE];
volatile uint16_t g_wifi_rx_buff_byte_cnt;
volatile uint16_t g_wifi_pkt_len;
volatile uint8_t g_wifi_pkt_type;
volatile uint32_t g_wifi_rc_conn_timer;
typedef struct
{
unsigned char connection_type;/* 0-STA,3-P2P_CL */
unsigned char ssid_len;
unsigned char ssid_name[32];
unsigned char go_peer_device_name_len;
unsigned char go_peer_device_name[32];
unsigned char bssid[6];
unsigned char reason_code;
unsigned char padding[2];
} sl_protocol_wlanConnectAsyncResponse_t;
const uint8_t c_wifi_preambule[3] = {0xA5, 0xAA, 0x5A};
/*
void CC3100_IRQHandler(void)
{/// GPIOTE IRQ service routine
if(NRF_GPIOTE->EVENTS_IN[0] == 1)
{
NVIC_DisableIRQ(GPIOTE_IRQn);
g_btn_state = (BTN_STATE_RESTORE_AP_MODE);
NRF_GPIOTE->EVENTS_IN[0] = 0;
setLED(LED_RED, LED_MODE_STATIC, 0);
#ifdef SYSTEM_DEBUG
printUART("-> SYS: Restoring WIFI AP mode ...\n");
#endif
setDefaultFLASH();
while((NRF_P0->IN & (1<<(PBTN_PIN))) == 0x00000000);
#ifdef SYSTEM_DEBUG
printUART("-> SYS: Rebooting...\n\n\n");
#endif
delay_ms(200);
while((NRF_P0->IN & (1<<(PBTN_PIN))) == 0x00000000);
NVIC_SystemReset();
}
if(NRF_GPIOTE->EVENTS_IN[1] == 1)
{
NRF_GPIOTE->EVENTS_IN[1] = 0;
chkCC3100IRQ();
}
}
*/
void CC3100_ERROR(unsigned int error)
{
if (error < 0) SEGGER_RTT_printf(0,"Error number : %d ",error);
return;
}
/*
void ASSERT_ON_ERROR(retVal)
{
NRF_LOG_INFO("Assert from simplelink function : %d", retVal);
}
*/
void CC3100_wifi_disable()
{
nrfx_gpiote_out_clear(CC_NHIB_PIN);
// nrfx_gpiote_out_clear(CC_NRST_PIN);
// nrfx_gpiote_out_set(CC_NCS_PIN);
// nrfx_gpiote_in_event_enable(CC_IRQ_PIN, false);
// sd_nvic_DisableIRQ(GPIOTE_IRQn);
g_wifi_ser_socket = -1;
g_wifi_local_cli_socket = -1;
g_wifi_remote_cli_socket = -1;
}
void CC3100_startup()
{
// nrfx_gpiote_in_event_enable(CC_IRQ_PIN, true);
//sd_nvic_EnableIRQ(GPIOTE_IRQn);
// nrfx_gpiote_out_set(CC_NCS_PIN);
nrfx_gpiote_out_set(CC_NRST_PIN);
nrfx_gpiote_out_clear(CC_NHIB_PIN);
// nrf_delay_ms(30) ; //cc3100 has 25 ms startup
// nrfx_gpiote_out_set(CC_NCS_PIN);
nrf_delay_ms(1400);
}
void CC3100_shutdown()
{
// nrfx_gpiote_in_event_enable(CC_IRQ_PIN, true);
//sd_nvic_EnableIRQ(GPIOTE_IRQn);
nrfx_gpiote_out_clear(CC_NHIB_PIN);
nrfx_gpiote_out_clear(CC_NRST_PIN);
nrfx_gpiote_out_set(CC_NCS_PIN);
// nrfx_gpiote_out_set(CC_NCS_PIN);
nrfx_gpiote_out_set(CC_NCS_PIN);
}
void CC3100_wifi_enable()
{
// nrfx_gpiote_in_event_enable(CC_IRQ_PIN, true);
//sd_nvic_EnableIRQ(GPIOTE_IRQn);
nrfx_gpiote_out_set(CC_NHIB_PIN);
// nrfx_gpiote_out_set(CC_NRST_PIN);
// nrfx_gpiote_out_set(CC_NCS_PIN);
// nrfx_gpiote_out_clear(CC_NCS_PIN);
nrf_delay_ms(70);
}
void CC3100_InterruptEnable()
{
nrfx_gpiote_in_event_enable(CC_IRQ_PIN, true);
sd_nvic_EnableIRQ(GPIOTE_IRQn);
}
void CC3100_InterruptDisable()
{
//NVIC_DisableIRQ(GPIOTE_IRQn);
nrfx_gpiote_in_event_disable(CC_IRQ_PIN);
sd_nvic_DisableIRQ(GPIOTE_IRQn);
}
void MaskIntHdlr()
{
IntIsMasked = TRUE;
}
void UnMaskIntHdlr()
{
IntIsMasked = FALSE;
}
void Delay(unsigned long interval)
{/// system delay func
delay_ms(interval);
}
void chkCC3100IRQ(void)
{
if(pIrqEventHandler)
{
pIrqEventHandler(0);
}
}
unsigned int spi_Close(Fd_t fd)
{
// CC3100_InterruptDisable();
nrfx_spim_uninit(&spi);
return 0;
}
unsigned int spi_Open(char *ifName, unsigned long flags)
{
return 1;
}
unsigned int spi_Write(Fd_t fd, unsigned char *pBuff, int len)
{
spi_xfer_done = false;
xfer_desc.p_tx_buffer = pBuff;
xfer_desc.tx_length = len;
xfer_desc.rx_length = 0;
xfer_desc.p_rx_buffer = 0;
unsigned int ret = nrfx_spim_xfer(&spi, &xfer_desc, 0);
//delay_us(5);
// nrf_delay_ms(30);
if (ret != 0)
{
NRF_LOG_INFO("Write error : %d",ret);
}
return m_length;
}
unsigned int spi_Read(Fd_t fd, unsigned char *pBuff, int len)
{
unsigned int retval = 1;
spi_xfer_done = false;
xfer_desc.p_rx_buffer = pBuff;
xfer_desc.rx_length = len;
xfer_desc.tx_length = 0;
xfer_desc.p_tx_buffer = 0;
unsigned int ret = nrfx_spim_xfer(&spi, &xfer_desc, 0);
// nrf_delay_us(5);
// CC3100_InterruptDisable();
if (ret != 0)
{
NRF_LOG_INFO("Write error : %d",ret);
}
return len;
}
int32_t initializeAppVariables(void)
{
g_Status = 0;
g_PingPacketsRecv = 0;
g_StationIP = 0;
g_GatewayIP = 0;
return SUCCESS;
}
//int registerInterruptHandler(P_EVENT_HANDLER hdl , void* pValue)
int registerInterruptHandler( P_EVENT_HANDLER InterruptHdl , void *pValue)
{
pIrqEventHandler = (P_EVENT_HANDLER)InterruptHdl;
return 0;
}
Moved the code to a PCA10040 DK and also used a TI CC3100 DK and connected via SPI.
This reproduces the same behavior and allows me to capture the spi with a logic analyzer.
The code being executed after initialization is just this portion of the TI porting diagnostics
/* Turn on the device */
sl_DeviceEnable();
SetTestStage(TEST_STAGE_ENABLE_PASSED);
/* Wait until we get an increment on IRQ value */
while( irqCheck == g_irqCounter )
{
}
SetTestStage(TEST_STAGE_SPI_IRQ_PASSED);
/* Generate the sync pattern for getting the response */
sl_IfWrite(FD, (unsigned char *)&H2NCnysPattern, SYNC_PATTERN_LEN);
SetTestStage(TEST_STAGE_SPI_WRITE_PASSED);
/* Read 4 bytes from the Spi */
unsigned int ret = sl_IfRead(FD, &pBuf[0], 4);
/* Sync on read pattern */
while ( ! N2H_SYNC_PATTERN_MATCH(pBuf, TxSeqNum))
{
/* Read next 4 bytes to Low 4 bytes of buffer */
if(0 == (SyncCnt % SYNC_PATTERN_LEN))
{
sl_IfRead(FD, &pBuf[4], 4);
}
/* Shift Buffer Up for checking if the sync is shifted */
for(ShiftIdx = 0; ShiftIdx < 7; ShiftIdx++)
{
pBuf[ShiftIdx] = pBuf[ShiftIdx+1];
}
pBuf[7] = 0;
SyncCnt++;
}
/*Sync pattern found. If needed, complete number of read bytes to multiple
* of 4 (protocol align) */
SyncCnt %= SYNC_PATTERN_LEN;
The init sequence for the TI seems to be ok per trace

But I stopped execution after ~ 5 seconds because of the spim event handler getting called thousands of times .
Debug excerpt:
From debug message in spim event handler: Run away spi interrupt ? IRQ Count : 2458Transfer completed. Run away spi interrupt ? IRQ Count : 2459Transfer completed. Run away spi interrupt ? IRQ Count : 2460Transfer completed. Run away spi interrupt ? IRQ Count : 2461Transfer completed. Run away spi interrupt ? IRQ Count : 2462Transfer completed. Run away spi interrupt ? IRQ Count : 2463Transfer completed. Run away spi interrupt ? IRQ Count : 2464Transfer completed. Run away spi interrupt ? IRQ Count : 2465Transfer completed. Run away spi interrupt ? IRQ Count : 2466Transfer completed. Run away spi interrupt ? IRQ Count : 2467Transfer completed. Run away spi interrupt ? IRQ Count : 2468Transfer completed. Run away spi interrupt ? IRQ Count : 2469Transfer completed. Run away spi interrupt ? IRQ Count : 2470Transfer completed. Run away spi interrupt ? IRQ Count : 2471Transfer completed. Run away spi interrupt ? IRQ Count : 2472Transfer completed. Run away spi interrupt ? IRQ Count : 2473Transfer completed. Run away spi interrupt ? IRQ Count : 2474Transfer completed. Run away spi interrupt ? IRQ Count : 2475Transfer completed. Run away spi interrupt ? IRQ Count : 2476Transfer completed. Run away spi interrupt ? IRQ Count : 2477Transfer completed. Run away spi interrupt ? IRQ Count : 2478Transfer completed. Run away spi interrupt ? IRQ Count : 2479Transfer completed. Run away spi interrupt ? IRQ Count : 2480Transfer completed.
The logic analyzer capture (Waveforms is provided in case you can view).

While there where no spi tranfer request, above is what was on the spi buss.
I am pretty puzzled at this point.
I also saw a few cases where the CS remained low (active ) long after the transfer was over.
Will include if I catch it again.
Would appreciate any help.
Also I looked at the Registers when it was in this mode here is that info
