Staging:CC3220 Idle Profile Application

Overview
This application exercises the Low Power Deep Sleep (LPDS) mode for CC3220 device using power management module in TI-drivers. Rest of the peripherals used for this reference application also uses TI-drivers, which makes it quite easy to manage their configuration across an LPDS cycle.

Application details
Before jumping into the details of this application, it is convenient to understand the TI-drivers

TI Drivers
TI Drivers provides an easy and intuitive driver interface for various peripherals of simplelink family devices. CC3220 device have multiple power modes, which can be exercised by the user as per the requirement of their application. Power management drivers (which is part of TI-drivers) makes it easier to specify the power policy for application processor. The TI-drivers provides a power management structure for the application which can be used to configure the power policy, wake up sources and other power related configurations. The drivers take care of dependency on various peripheral to make sure that the system doesn't enter low power mode while a peripheral is in transaction phase, thus providing a smooth transition between different power modes. For more information regarding TI Drivers, please refer to \tidrivers_simplelink\docs\

Program Flow
The user can configure the following power config structure in cc_launchpad.c file * * ======== PowerCC3200_config ======== * In this configuration, Power management is disabled since runPolicy * is set to 0. Power management can be enabled from main by calling * Power_enablePolicy, or by changing runPolicy to 1 in this structure. * const PowerCC3200_ConfigV1 PowerCC3200_config = { .policyInitFxn = &PowerCC3200_initPolicy,       /* policy Initialization Function */ .policyFxn = &PowerCC3200_sleepPolicy,          /* policy function  */ .enterLPDSHookFxn = SaveContext,                /* hook function before entering LPDS*/ .resumeLPDSHookFxn = RestoreContext,            /* hook function after coming out of LPDS*/ .enablePolicy = false,                          /* flag to enable the power management */ .enableGPIOWakeupLPDS = true,                   /* flag to enable GPIO as wake up source for LPDS */ .enableGPIOWakeupShutdown = false,              /* flag to enable GPIO as wake up source for hibernate*/ .enableNetworkWakeupLPDS = true,                /* flag to enable Network as wake up source for LPDS*/ .wakeupGPIOSourceLPDS = PRCM_LPDS_GPIO13,       /* which GPIO to be used as LPDS wake up source*/ .wakeupGPIOTypeLPDS = PRCM_LPDS_FALL_EDGE,      /* which GPIO interrupt type will wake up the MCU from hibernate – ex. Falling edge, rising edge*/ .wakeupGPIOFxnLPDS = gpioButtonFxn1,            /* function to be called, if GPIO is LPDS wake-up cause*/ .wakeupGPIOFxnLPDSArg = PRCM_LPDS_GPIO13,       /* argument for the above function */ .wakeupGPIOSourceShutdown = 0,                  /* which GPIO to be used as hibernate wake up source*/ .wakeupGPIOTypeShutdown = 0,                    /* which GPIO interrupt type will wake up the MCU from hibernate – ex. Falling edge, rising edge*/ .ramRetentionMaskLPDS = PRCM_SRAM_COL_1 |       /* 256KB RAM is divided into 4 blocks of 64KB each. user can choose to retain any number of blocks in LPDS */ PRCM_SRAM_COL_2 | PRCM_SRAM_COL_3 | PRCM_SRAM_COL_4, .keepDebugActiveDuringLPDS = false,             /* whether to keep the debug interface alive when entering Into LPDS or not */ .ioRetentionShutdown = PRCM_IO_RET_GRP_1,       /* The group of IOs to be retained  in Hibernate. */   .pinParkDefs = parkInfo,                         /* parking structure for LPDS */ .numPins = sizeof(parkInfo) /                   /* number of entries in the Pin parking structure */ sizeof(PowerCC3200_ParkInfo) };

To start with, the required peripheral drivers needs to be initialized. The configuration for each of these peripheral is specified in cc_launchpad.c file. //   // Board Initialization //   BoardInit; Board_initGeneral; Board_initGPIO; Board_initSPI; // start timer for simplelink host driver simplelink_timerA2_start;

//   // Initialise the UART terminal //   g_tUartHndl = InitTerm;
 * 1) ifndef NOTERM

if (g_tUartHndl == NULL) {       while(FOREVER); }

// remove uart receive from LPDS dependency UART_control(g_tUartHndl, UART_CMD_RXDISABLE, NULL); Which will be followed by creation of two tasks.
 * 1) endif //NOTERM

//   // Task creation for providing host_irq as a wake up source(LPDS) //   osi_TaskCreate(UDPServerTask,                (const signed char *)"UDP Server waiting to recv packets",                OSI_STACK_SIZE, NULL, tskIDLE_PRIORITY+1, NULL ); //   // setting up timer and gpio as source for wake up from lPDS //   osi_TaskCreate(TimerGPIOTask, (const signed char*)                   "Configuring Timer and GPIO as wake src",                   OSI_STACK_SIZE, NULL, 1, NULL );
 * 1) One for creating and handling UDP Server
 * 2) Other for setting timer as wake source from low power modes (GPIO will be configured from the config structure)

Task 1: UDPServerTask
//   // waiting for the other task to start simplelink and connection to the AP    // osi_MsgQRead(&g_tConnectionFlag, &ucSyncMsg, OSI_WAIT_FOREVER); .   .    //    // creating a UDP socket //   iSockDesc = sl_Socket(SL_AF_INET,SL_SOCK_DGRAM, 0); .   .    //    // waiting on a UDP packet //   iRetVal = sl_RecvFrom(iSockDesc, g_cBuffer, BUFF_SIZE, 0,                          ( SlSockAddr_t *)&sClientAddr                          (SlSocklen_t*)&iAddrSize ); if(iRetVal > 0) {       //        // signal the other task about receiving the UDP packet //       osi_MsgQWrite(&g_tWkupSignalQueue, &ucQueueMsg, OSI_WAIT_FOREVER); }
 * 1) Blocked on a message from the Other Task(waiting for simplelink start and connection to AP).
 * 2) Creates a UDP server and wait for UDP packet in a while loop. As soon as the NWP subsystem receives any UDP packet, it will bring the APPS subsystem out of LPDS, if not already.

Task 2: TimerGPIOTask
//   // starting the simplelink //   iRetVal = sl_Start(NULL, NULL, NULL); ..   ..    //    // Swtich to STA mode if device is not //   SwitchToStaMode(iRetVal); //   // Set the power management policy of NWP //   iRetVal = sl_WlanPolicySet(SL_WLAN_POLICY_PM, SL_WLAN_NORMAL_POLICY, NULL, 0); ..   ..    //    // connecting to the Access Point //   if(-1 == WlanConnect) ..   ..    /*     *  This function enables the Power policy function to run * in the idle loop. Alternatively, you can set the field * 'enablePolicy' in the Power_config structure (CC3200_LP.c)     *  to 1. */   Power_enablePolicy;
 * 1) Starts simplelink, switch to station mode(if not already), set NWP power policy and connects to the AP.
 * 2) Upon successful connection unblocks the other task.
 * 3) Enables Power policy for the APPS MCU.
 * 4) configure wake up timer duration

//       // waits for the message from the various interrupt handlers(GPIO,        // Timer) and the UDPServerTask. //       ucQueueMsg = 0; iRetVal = osi_MsgQRead(&g_tWkupSignalQueue, &ucQueueMsg, 5000);

RTOS support
The IAR project for this application is based on FreeRTOS, whereas the CCS project is based on TI-RTOS. A separate example (idle profile nonos) is provided in the SDK, which exercises the LPDS using TI-drivers in non-OS environment.

Source Files briefly explained

 * main.c - The main file implementing the idle profile.
 * cc_launchpad.c - contains Initialization and configuration for peripherals used.

Supporting Files

Common Files
 * pinmux.c - Generated by the PinMUX utility.
 * startup_*.c - IDE specific startup functions (not required when working with TI-RTOS)
 * uart_if.c - abstraction layer built on top of uart interface from ti-drivers package
 * timer_if.c - interface file for general purpose timers

Usage

 * Setup a serial communication application (HyperTerminal/TeraTerm). For detail info visit CC31xx & CC32xx Terminal Setting

On the host PC. The settings are:   - Port: Enumerated COM port (XDS110 Class Application/User UART)    - Baud rate: 115200    - Data: 8 bit    - Parity: None    - Stop: 1 bit    - Flow control: None


 * Run the application preferably from FLASH rather than from the debugger as debugger would disconnect in LPDS.
 * Different prints on serial communication will tell the cause of wake up from the LPDS.
 * Red LED (GPIO 09) will turn off whenever the device enters LPDS.



Limitations/Known Issues
None