This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC3100 Fs Module causes DMA Error within TI-RTOS

Other Parts Discussed in Thread: CC3100, SYSBIOS

I am using TI-RTOS with a CC3100 BoosterPack and Tiva C LaunchPad (TM4C123) and have successfully used most of the SimpleLink Host APIs in my application. However I have been unable to use the Fs module.

When ever  I run the below piece of code I get a DMA error code: 1 (Error is located in the  EK_TM4C123GXL file)

/* File Doesn't exit create a new of 63 KB file */
iRetVal = sl_FsOpen((unsigned char *)USER_FILE_NAME,  FS_MODE_OPEN_CREATE(65536,_FS_FILE_OPEN_FLAG_COMMIT|_FS_FILE_PUBLIC_WRITE), &ulToken, &lFileHandle);

I have been successfully able to use the Fs module in a bare metal example, that does not use TI-RTOS.

In my debugging, it looked like something was happening within the Ti-RTOS DMA libraries. Though I was unable to pin point after a day of debugging.

Has the Fs module for the CC3100 been confirmed to function with TI-RTOS?

Glenn.

 

  • Hi Glenn,

    This error occurs when a DMA transfer is set to read/write flash memory on Tiva devices.  Unfortunately, the DMA cannot access flash and this error is received when we try to do so.  It is likely that the compiler is placing one of your function parameters in flash.  Can you verify that all parameters used in the sl_FsOpen call are either defined in the local scope of where the function is being called or as non-const global variables?

    Thanks,

    -- Emmanuel

  • Hi Emmanuel,

    Yes, I made sure that all variables are in local scope, all except the Macro FS_MODE_OPEN_WRITE.

    I have simplified the code, by just asking for a file to open, which should return a negative number if the file does not exist. I still get the same DMA error. See code below.

     retVal = sl_FsOpen(slfilename, FS_MODE_OPEN_WRITE, &Token, &fileHandle);

    Thanks for your assistance.

    Glenn.

  • Hi Glenn,

    What version of TI-RTOS for TivaC are you using?

    I was not able to reproduce the problem on TI-RTOS 2.0.2.36.  Can you add the function below to the beginning EK_TM4C123GXL_errorDMAHwi function?

           int i;
    
           for (i = 0; i < 32; i++) {
                  if ((int)EK_TM4C123GXL_DMAControlTable[i].pvSrcEndAddr < 0x20000000) {
                         System_printf("DMA channel %d source address is 0x%x\n", i,
                               EK_TM4C123GXL_DMAControlTable[i].pvSrcEndAddr);
                  }
                  if ((int)EK_TM4C123GXL_DMAControlTable[i].pvDstEndAddr < 0x20000000) {
                         System_printf("DMA channel %d source address is 0x%x\n", i,
                               EK_TM4C123GXL_DMAControlTable[i].pvDstEndAddr);
    
                  }
           }
    

    This function will print the flash addresses that the DMA tried to access.  You can then use the Memory Browser to see the data.  

    Finally, would it be possible to post your code.

    -- Emmanuel

     

  • Hi Emmanuel,

    Thanks for your assistance.

    I am using the same version of TI-RTOS 2.0.2.36

    This is the output from the code you provided...address is 0x0

    0
    DMA channel 25 source address is 0x0
    DMA channel 26 source address is 0x0
    DMA channel 26 source address is 0x0
    DMA channel 27 source address is 0x0
    DMA channel 27 source address is 0x0
    DMA channel 28 source address is 0x0
    DMA channel 28 source address is 0x0
    DMA channel 29 source address is 0x0
    DMA channel 29 source address is 0x0
    DMA channel 30 source address is 0x0
    DMA channel 30 source address is 0x0
    DMA channel 31 source address is 0x0
    DMA channel 31 source address is 0x0
    DMA error code: 1
    DMA error!!

    __ASM__, addressClock, callbackHwi, colorsPtr, currButton, dataLength, g_ulTimerInts, prevButton, processedRawData, ti_sysbios_family_arm_m3_Hwi_resetVectors, xdc_runtime_Text_charTab__A
    20004880 0000A119 0000BF89 0000BF89 0000BF89
    0000BF89 0000BF89 0000BF89 0000BF89 0000BF89
    0000BF89 0000BF89 0000BF89 0000BF89 0000BC39

    Here is the code

    // Globals
    #define SL_FILE_NAME    "MacDonalds.txt"
    #define BUF_SIZE        2048
    
    #define SIZE_64K        65536
    
    union
    {
        UINT8 g_Buf[BUF_SIZE];
        UINT32 demobuf[BUF_SIZE/4];
    } uNvmemBuf;
    
    const UINT8    oldMacDonald[] = "Old MacDonald had a farm,E-I-E-I-O, \
            And on his farm he had a cow, \
            E-I-E-I-O, \
    :
            E-I-E-I-O.";
    
    // Function
    int updateConfig()
    {
        INT32         fileHandle = -1;
    
        UINT32        Token = 0;
        UINT16        loop = 0;
        INT32         retVal = 0;
    
    
        unsigned char * slfilename = "config.txt";
    
        /* open a user file for writing */
        //retVal = sl_FsOpen((unsigned char *)SL_FILE_NAME, FS_MODE_OPEN_WRITE, &Token, &fileHandle);
        retVal = sl_FsOpen(slfilename, FS_MODE_OPEN_WRITE, &Token, &fileHandle);  <-- CRASHES HERE
    
        if(retVal < 0)
        {
    :
        return 0;
    }
    
    
    Void echoFxn(UArg arg0, UArg arg1)
    {
        WiFi_Handle       handle;
        WiFi_Params       wifiParams;
        _NetCfgIpV4Args_t ipV4;
        uint8_t           len = sizeof(ipV4);
        uint8_t           dhcpIsOn;
        int               nbytes;
        int               status;
        int               selectRes;
        int               slSocket;
        fd_set            readSet;
        timeval           timeout;
        sockaddr_in       localAddr;
        sockaddr_in       client_addr;
        socklen_t         addrlen = sizeof(client_addr);
        int 		      processStatus;
        int				  configValue;
    
        ULong       currButton;
        ULong		deleteButton;
        ULong       prevButton = 0;
    
        /* Turn LED OFF. It will be used as a connection indicator */
        GPIO_write(Board_LED0, Board_LED_OFF); //Blue
        GPIO_write(Board_LED1, Board_LED_OFF); //Green
        GPIO_write(Board_LED2, Board_LED_OFF); //Red
    
        /* Open WiFi driver */
        WiFi_Params_init(&wifiParams);
        wifiParams.bitRate = SPI_BIT_RATE;
        handle = WiFi_open(Board_WIFI, Board_SPI_CC3100, NULL, &wifiParams);
        if (handle == NULL) {
            System_abort("WiFi driver failed to open.");
        }
    
    
        /*
         * Host driver starts the network processor.
         *
         * sl_Start returns the network processor operating mode:
         *      ROLE_STA (0x00): configured as a station
         *      ROLE_AP  (0x02): configured as an access point
         */
    
        configValue = sl_Start(NULL, NULL, NULL);
        if (configValue < 0) {
            System_abort("Could not initialize WiFi");
        }
    
    
        // Holding down button switches the connection mode
        deleteButton = GPIO_read(Board_BUTTON1);
        if(deleteButton == 0) //&& (prevButton != 0))
        {
        	    if (configValue == ROLE_STA) {
    
           	        /* Change mode to access point */
            	    configValue = sl_WlanSetMode(ROLE_AP);
    
        	        // Set SSID name for AP mode
        	        unsigned char  str[33] = "LightServerAP";
        	        unsigned short  length = strlen((const char *)str);
        	        sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SSID, length, str);
    
        	        // Set security type for AP mode
        	        //Security options are:
        	        //Open security: SL_SEC_TYPE_OPEN
        	        //WEP security:  SL_SEC_TYPE_WEP
        	        //WPA security:  SL_SEC_TYPE_WPA
        	        unsigned char  val = SL_SEC_TYPE_OPEN;
        	        sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SECURITY_TYPE, 1, (unsigned char *)&val);
    
        	        //Set Password for for AP mode (for WEP or for WPA) example:
        	        //Password - for WPA: 8 - 63 characters
        	        //           for WEP: 5 / 13 characters (ascii)
        	        //unsigned char  str[65];
        	        //unsigned short  len = strlen(password);
        	        //memset(str, 0, 65);
        	        //memcpy(str, password, len);
        	        //sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_PASSWORD, len, (unsigned char *)str);
    
        	        /* Restart the network processor */
        	        configValue = sl_Stop(0);
        	        configValue = sl_Start(NULL, NULL, NULL);
        	    }
        	    else if  (configValue == ROLE_AP) {
        	        /* Change mode to wireless station */
        	        configValue = sl_WlanSetMode(ROLE_STA);
    
        	        /* Restart the network processor */
        	        configValue = sl_Stop(0);
        	        configValue = sl_Start(NULL, NULL, NULL);
        	    }
        }
    
    
        // We are in Station Mode, so need to connect to Wifi Router/Access Point
        if (configValue == ROLE_STA)
        {
            // Turn LED to Red to indicate that device is attempting to connected to Wifi Router
            GPIO_write(Board_LED0, Board_LED_OFF); //Blue
            GPIO_write(Board_LED1, Board_LED_OFF); //Green
            GPIO_write(Board_LED2, Board_LED_ON); //Red
    
    		/*
    		 * Wait for the WiFi to connect to an AP. If a profile for the AP in
    		 * use has not been stored yet, press Board_BUTTON0 to start SmartConfig.
    		 */
    		while ((deviceConnected != true) || (ipAcquired != true)) {
    			/*
    			 *  Start SmartConfig if a button is pressed. This could be done with
    			 *  GPIO interrupts, but for simplicity polling is used to check the
    			 *  button.
    			 */
    
    			currButton = GPIO_read(Board_BUTTON1);
    			if((currButton == 0) && (prevButton != 0))
    			{
    				smartConfigFxn();
    			}
    			prevButton = currButton;
    			Task_sleep(50);
    		}
        }
    
        // Set the color of LED to indicate which mode we are in
        if (configValue == ROLE_STA)
        {
            // Turn LED to Blue to indicate that device is connected in Station Mode
            GPIO_write(Board_LED0, Board_LED_ON); //Blue
            GPIO_write(Board_LED1, Board_LED_OFF); //Green
            GPIO_write(Board_LED2, Board_LED_OFF); //Red
        }
        else
        {
            // Turn LED to Green to indicate that device is in AP mode
            GPIO_write(Board_LED0, Board_LED_OFF); //Blue
            GPIO_write(Board_LED1, Board_LED_ON); //Green
            GPIO_write(Board_LED2, Board_LED_OFF); //Red
        }
    
        /* Print IP address */
        sl_NetCfgGet(SL_IPV4_STA_P2P_CL_GET_INFO, &dhcpIsOn, &len,
                     (unsigned char *)&ipV4);
        System_printf("CC3100 has connected to an AP and acquired an IP address.\n");
        System_printf("IP Address: %d.", SL_IPV4_BYTE(ipV4.ipV4, 3));
        System_printf("%d.", SL_IPV4_BYTE(ipV4.ipV4, 2));
        System_printf("%d.", SL_IPV4_BYTE(ipV4.ipV4, 1));
        System_printf("%d", SL_IPV4_BYTE(ipV4.ipV4, 0));
        System_printf("\n");
        System_flush();
    
        /* Create a UDP socket */
        slSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (slSocket < 0) {
            System_printf("Error: socket not created.");
            WiFi_close(handle);
            Task_exit();
        }
    
        memset((char *)&localAddr, 0, sizeof(localAddr));
        localAddr.sin_family = AF_INET;
        localAddr.sin_addr.s_addr = htonl(0);
        localAddr.sin_port = htons(UDPPORT);
        status = bind(slSocket, (const sockaddr *)&localAddr, sizeof(localAddr));
        if (status < 0) {
            System_printf("Error: bind failed.");
            close(slSocket);
            WiFi_close(handle);
            Task_exit();
        }
    
        SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
        SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_1, SSI_MODE_MASTER, 1000000, 16);
    
        // Enable the SPI SSI0 module.
        SSIEnable(SSI0_BASE);
    
       //////////////////
       updateConfig();    <--CALLS THE FUNCTION
       /////////////////

    Glenn

  • I just realised that it is not printing out all the DMA channels, and suspected this was due to the System_print buffer running out of space. Hence I added System_flush() so everything would print out.

    Here is the updated debug code

    	int i;
    
    	for (i = 0; i < 32; i++) {
    	       if ((int)EK_TM4C123GXL_DMAControlTable[i].pvSrcEndAddr < 0x20000000) {
    	              System_printf("DMA channel %d source address is 0x%x\n", i,
    	                    EK_TM4C123GXL_DMAControlTable[i].pvSrcEndAddr);
    	              System_flush();
    	       }
    	       if ((int)EK_TM4C123GXL_DMAControlTable[i].pvDstEndAddr < 0x20000000) {
    	              System_printf("DMA channel %d source address is 0x%x\n", i,
    	                    EK_TM4C123GXL_DMAControlTable[i].pvDstEndAddr);
    	              System_flush();
    	       }
    	}

    Here is the output now - have a look at DMA channel 13 and DMA12 seems to be missing

    DMA channel 0 source address is 0x0
    DMA channel 0 source address is 0x0
    DMA channel 1 source address is 0x0
    DMA channel 1 source address is 0x0
    DMA channel 2 source address is 0x0
    DMA channel 2 source address is 0x0
    DMA channel 3 source address is 0x0
    DMA channel 3 source address is 0x0
    DMA channel 4 source address is 0x0
    DMA channel 4 source address is 0x0
    DMA channel 5 source address is 0x0
    DMA channel 5 source address is 0x0
    DMA channel 6 source address is 0x0
    DMA channel 6 source address is 0x0
    DMA channel 7 source address is 0x0
    DMA channel 7 source address is 0x0
    DMA channel 8 source address is 0x0
    DMA channel 8 source address is 0x0
    DMA channel 9 source address is 0x0
    DMA channel 9 source address is 0x0
    DMA channel 10 source address is 0x0
    DMA channel 10 source address is 0x0
    DMA channel 11 source address is 0x0
    DMA channel 11 source address is 0x0
    DMA channel 13 source address is 0x3d87
    DMA channel 14 source address is 0x0
    DMA channel 14 source address is 0x0
    DMA channel 15 source address is 0x0
    DMA channel 15 source address is 0x0
    DMA channel 16 source address is 0x0
    DMA channel 16 source address is 0x0
    DMA channel 17 source address is 0x0
    DMA channel 17 source address is 0x0
    DMA channel 18 source address is 0x0
    DMA channel 18 source address is 0x0
    DMA channel 19 source address is 0x0
    DMA channel 19 source address is 0x0
    DMA channel 20 source address is 0x0
    DMA channel 20 source address is 0x0
    DMA channel 21 source address is 0x0
    DMA channel 21 source address is 0x0
    DMA channel 22 source address is 0x0
    DMA channel 22 source address is 0x0
    DMA channel 23 source address is 0x0
    DMA channel 23 source address is 0x0
    DMA channel 24 source address is 0x0
    DMA channel 24 source address is 0x0
    DMA channel 25 source address is 0x0
    DMA channel 25 source address is 0x0
    DMA channel 26 source address is 0x0
    DMA channel 26 source address is 0x0
    DMA channel 27 source address is 0x0
    DMA channel 27 source address is 0x0
    DMA channel 28 source address is 0x0
    DMA channel 28 source address is 0x0
    DMA channel 29 source address is 0x0
    DMA channel 29 source address is 0x0
    DMA channel 30 source address is 0x0
    DMA channel 30 source address is 0x0
    DMA channel 31 source address is 0x0
    DMA channel 31 source address is 0x0
    DMA error code: 1
    DMA error!!

    This what is at DMA13 address

    $C$SL13
    666E6F63 742E6769
    C0007478

    Glenn.

  • Hi Glenn,

    Thanks for the code.  The problem occurs by defining slfilename as an unsigned char *.  During compile time the "config.txt" string is placed in flash and slfilename just points to its flash address.  Thus, the DMA tries to read from flash and you get the error.  You should define the string as a local variable (in RAM) then use a pointer to it in the sl_FsOpen call.

    Please see my code changes below:

        INT32         fileHandle = -1;
        UINT32        Token = 0;
        INT32         retVal = 0;
        char slfilename [] = "config.txt";
    
        /* open a user file for writing */
        //retVal = sl_FsOpen((unsigned char *)SL_FILE_NAME, FS_MODE_OPEN_WRITE, &Token, &fileHandle);
        retVal = sl_FsOpen((unsigned char *) &slfilename, FS_MODE_OPEN_CREATE(65536,_FS_FILE_OPEN_FLAG_COMMIT|_FS_FILE_PUBLIC_WRITE), &Token, &fileHandle);

    Let me know if this helps,

    -- Emmanuel

  • Emmanuel,

    Thank you very much, this resolved the issue!

    Just a note to others, this is slightly different to the actual sample code provided with the CC3100 SDK. You need to specifically point to the location &fileName

    Glenn.

  • Addressed to TI folks, I suppose:  The sample code in the CC3100/3200 .... User's Guide has this use of constant strings.  Cut and paste TI sample code, compile it, and run it, and the DMA blows a gasket on the flash.  The documents and any other sample code should be amended, and this issue highlighted.

    I wasted some time on this problem; of course I don't mind the fact that the system works that way - it's normal - but I do mind that TI's samples blow up.