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.

CC3135: Integration to microcontroller

Part Number: CC3135

Hi, I am trying to use CC3135 in my upcoming project. I have purchased BOOSTXL-CC3135 and trying to integrate it with my MB9AF312L microcontroller. The datasheet that I have has the connections and timing diagram to be used but I don't have the driver API (header file & C file) nor I have the command list. Where do I find these file?

Your help is highly appreciated.

  • Hi Nabeen,

    Please see the Network Processor's Programmer's Guide chapter on Porting the Host Driver: http://www.ti.com/lit/swru455
    You can find all device documentation on the CC3135 product page: www.ti.com/.../technicaldocuments

    You can also find the Wi-Fi host driver API guide in the Wi-Fi plugin documents folder.

    Best regards,
    Sarah
  • Hi Sarah,

    Thank for the link, I got the driver API. I am using MB9AF312L microcontroller which does not have CTS/RTS functionality on UART, hence the only option left for me is using SPI. I found the structure for UART but not for SPI in "device.h" file.

    How do I mention to API that I am using SPI and the associated pin for H.IRQ & nHib.

    I will require initial help for your side until I am able to communicate with the module.

    Thanks & Regards,
    Nabeen
  • Hi Nabeen,

    The default communication protocol for the host driver is SPI. You only need to define SL_IF_TYPE_UART if you are using UART.

    You should not have to make any changes to device.h or the rest of the host driver. You should only edit user.h and other files in the source/ti/drivers/net/wifi/porting folder. The user.h defines sl_IfOpen, sl_IfRead, etc., which can be used with either SPI or UART as described in the Implement the Interface Communication Abstract Layer section (19.5) of the NWP Programmer's Guide. You can use the cc_pal files as a guide for your porting.

    Best regards,
    Sarah
  • Dear Sarah,

    I appreciate your help.

    I gone through the programmers guide and the user.h header file as you instructed. For error free testing, I decided to use the SPI channel that I have interfaced to FLASH memory PART NO. AT45DB161E and is working perfectly from past 5 years. For testing WiFi on same channel, I removed the Flash memory from my PCB and given the same channel to BOOSTXL-CC3135 respective pins. The additional H.IRQ and nHib is connected to free interrupt pin and free GPIO on my PCB.


    I have attached my c code file of SPI_Flash_Memory, in which I am implementing WiFi CC3135 for your reference.

    Now to implement WiFi

    Step 1: call void FMemInit() function to initialize the SPI port and associated GPIO. RIGHT?

    Step 2: call _SlFd_t sl_IfOpen(char* pIfName , unsigned long flags) function, RIGHT? but here I could not understand what to pass in pIfName.

    As per user.h header file it says: 

    \param ifName - points to the interface name/path. The interface name is an optional attributes that the simple link driver receives on opening the device. in systems that the spi channel is not implemented as part of the os device drivers, this parameter could be NULL.

    Here, in my project I am not using any OS, so it should be NULL, right?

    If it is NULL, how this sl_IfOpen function will give me file descriptor when It knows nothing about the channel. 

    I hope I could make you understand my doubts and hope for your expertise on same.

    Thanking you and Regards,

    Nabeen Lal Amatya

    SPI_Flash_Memory.c
    #include "SPI_Flash_Memory.h"
    
    void ChipErase()
    {	FM_CS_LOW;
      	Delay(TCSS);//CS Setup Time = minimum 5 nS
      	spi_send(0xC7);
      	spi_send(0x94);
      	spi_send(0x80);
      	spi_send(0x9A);
    	FM_CS_HIGH;
    }
    ////////////////////////////////////////////////////////////////////////////////
    //	DESCRIPTION: Initializes Flash memory GPIO 
    //	STATUS : OK TESTED
    void FMemInit()
    { 
      // Initialize SPI ports for CSIO3
      //make flash memory serial data out pin as input
      //Select CPIO function
      MEM_PFR &= ~MEM_SO_PIN;
      //Set CPIO Pull-Up function
      MEM_PCR |= MEM_SO_PIN;
      //Make button pins inputs
      MEM_DDR &= ~MEM_SO_PIN;
      
      //make memory CLOCK pin as output
      MEM_PFR &= ~MEM_SCLK_PIN;    //Select CPIO function
      MEM_PDOR |= MEM_SCLK_PIN;     //Set Pin to turn off leds
      MEM_DDR |= MEM_SCLK_PIN;      //Make led pins outputs
      //make memory Serial Data IN pin as output
      MEM_PFR &= ~MEM_SI_PIN;    //Select CPIO function
      MEM_PDOR |= MEM_SI_PIN;     //Set Pin to turn off leds
      MEM_DDR |= MEM_SI_PIN;      //Make led pins outputs
      //make memory chip select pin as output
      MEM_PFR &= ~MEM_CS_PIN;    //Select CPIO function
      MEM_PDOR |= MEM_CS_PIN;     //Set Pin to turn off leds
      MEM_DDR |= MEM_CS_PIN;      //Make led pins outputs
      //make memory reset pin as output
      MEM_PFR &= ~MEM_RESET_PIN;    //Select CPIO function
      MEM_PDOR |= MEM_RESET_PIN;     //Set Pin to turn off leds
      MEM_DDR |= MEM_RESET_PIN;      //Make led pins outputs
      //make memory write protect pin as output
      MEM_PFR &= ~MEM_WP_PIN;    //Select CPIO function
      MEM_PDOR |= MEM_WP_PIN;     //Set Pin to turn off leds
      MEM_DDR |= MEM_WP_PIN;      //Make led pins outputs 
      
      FM_RESET_HIGH;  
      FM_WP_HIGH;
    }
    ////////////////////////////////////////////////////////////////////////////////
    //	DESCRIPTION: Sends Byte through SI pin and reads return_val (1 Byte) through SO pin 
    //	parameter 1: Byte to send
    //	return : return_val ( 1 byte data)
    //	STATUS : OK TESTED
    ////////////////////////////////////////////////////////////////////////////////
    uc spi_send(uc Byte)            //ok tested
    { uc i, return_val = 0x00;
      for(i=0;i<8;i++)
      { FM_SCLK_LOW;
        while((MEM_PDOR & MEM_SCLK_PIN) > 0);
        //write
        if(Byte & 0x80)
          FM_SI_HIGH;
        else
          FM_SI_LOW;
        Byte <<= 1;
        Delay(TSU);//data setup time min 2ns
        //read
        return_val <<= 1;
        if((MEM_PDIR & MEM_SO_PIN) > 0)
        { return_val |= 0X01;
        }
        FM_SCLK_HIGH;
        while((MEM_PDOR & MEM_SCLK_PIN) == 0);
        Delay(TWH);	//CLOCK HIGH TIME = min 6.8 nS
      }
      return return_val;
    }
    ////////////////////////////////////////////////////////////////////////////////
    //	DESCRIPTION: Random Memory Read, it will also use memory internal buffer
    //	Parameter1:	memory address from where to start reading
    //	Parameter2: variable where read data to place
    //	Parameter3: number of byte to read
    //	STATUS : OK 
    //	CAUTION: Please take care of memory interanl buffer to prevent data loss
    ////////////////////////////////////////////////////////////////////////////////
    void RandomMemRead(ui address,char *buff,int no_of_byte)	//OK TESTED
    {	PageToBuffer((address / BYTE_PER_PAGE),PAGE_TO_BUFF1);
    	if((address/BYTE_PER_PAGE) != ((address + no_of_byte)/BYTE_PER_PAGE))
    		PageToBuffer(((address + no_of_byte) / BYTE_PER_PAGE),PAGE_TO_BUFF2);
    	ReadWriteMemBuffer(MEM_READ,address,buff,no_of_byte);
    }
    /******************************************************************************/
    //	DESCRIPTION: Random Memory Write (read change write), it will also use memory internal buffer
    //	Parameter1:	memory address from where to start writing
    //	Parameter2: variable where memory data to be changed/write 
    //	Parameter3: number of byte to change/write
    //	STATUS : OK TESTED. 
    //	CAUTION: Please take care of memory interanl buffer to prevent data loss
    ////////////////////////////////////////////////////////////////////////////////
    void RandomMemWrite(ui address,char *buff,int no_of_byte)	//OK TESTED
    {	PageToBuffer((address/BYTE_PER_PAGE),PAGE_TO_BUFF1);
    	if((address/BYTE_PER_PAGE) != ((address + no_of_byte)/BYTE_PER_PAGE))
    		PageToBuffer(((address + no_of_byte) / BYTE_PER_PAGE),PAGE_TO_BUFF2);
    	ReadWriteMemBuffer(MEM_WRITE,address,buff,no_of_byte);
    	BufferToPage(BUFF1_TO_PAGE,(address/BYTE_PER_PAGE));
    	if((address/BYTE_PER_PAGE) != ((address + no_of_byte)/BYTE_PER_PAGE))
    		BufferToPage(BUFF2_TO_PAGE,((address + no_of_byte) / BYTE_PER_PAGE));
    }
    /******************************************************************************/
    //	STATUS : OK TESTED
    ////////////////////////////////////////////////////////////////////////////////
    void ReadMemReg(uc opcode, uc* buff,ui no_of_bytes)  //ok tested
    { FM_CS_LOW;
      Delay(TCSS);//CS Setup Time = minimum 5 nS
      spi_send(opcode);
      while(no_of_bytes > 0)
      { *buff = spi_send(0xff);
        no_of_bytes--;
        buff++;
      }
      FM_CS_HIGH;
      Delay(TCS);//min CS high time 50
    }
    /******************************************************************************/
    //	DESCRIPTION: Direct Memory Read, it will not use memory internal buffer
    //	Parameter1:	memory long address from where to start reading
    //	Parameter2: variable where memory data read to be copied 
    //	Parameter3: number of byte to read
    //	STATUS :	OK
    ////////////////////////////////////////////////////////////////////////////////
    void DirectMemRead(uli address, char * buff,ui no_of_bytes)
    { 	uc status_reg;
      	do
      	{ 	ReadMemReg(RD_FM_SR, &status_reg,1);
      	}	
    	while((status_reg & 0x80) == 0);
    	FM_CS_LOW;
      	Delay(TCSS);//CS Setup Time = minimum 5 nS
      	spi_send(CONTI_READ);	//command
      	//decoding address														|------- 1 byte --------||------ 2 byte ------||----- 3 byte --|
    	spi_send((address/BYTE_PER_PAGE)>>6);									//23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    	spi_send(((address/BYTE_PER_PAGE)<<2) | ((address%BYTE_PER_PAGE)>>8));	//x  x  P  P  P  P  P  P  P  P  P  P  P  P  B B B B B B B B B B
    	spi_send(address%BYTE_PER_PAGE);
    	spi_send(0xFF);//dummy byte
      	while(no_of_bytes > 0)
      	{ 	*buff = spi_send(0xFF);
        	no_of_bytes--;
        	buff++;
      	}
      	FM_CS_HIGH;
      	Delay(TCS);//min CS high time 50
    }
    /******************************************************************************/
    ////////////////////////////////////////////////////////////////////////////////
    //	DESCRIPTION: READS / WRITES BUFFER 1 and / or buffer 2, it always starts read/write from buffer 1.
    //				While read/write, if address exceeds BYTE_PER_PAGE byte it starts read/write from buffer 2 address 0 and upwards
    //	parameter 1: 	buff_1_2	read or write buffer 1 or 2
    //	parameter 2: 	address		Memory actual address that will be converted into buffer address leter 0-527
    //	parameter 3:	buff		data to read to or write from
    //	parameter 4:	no_of_bytes	number of bytes to read or write from / to buffer
    //	STATUS : OK TESTED
    //	CAUTION: Please take care of memory interanl buffer 2 to prevent data loss
    ////////////////////////////////////////////////////////////////////////////////
    void ReadWriteMemBuffer(boolean_t rw, ui address, char* buff, ui no_of_bytes)
    { 	uc status_reg,buff_1_2;
    	if(rw == MEM_READ)
    		buff_1_2 = RD_BUFF1;
    	else
    	  	buff_1_2 = WR_BUFF1;
    	
    	address = address%BYTE_PER_PAGE;//ADDRESS THAT REFLECTS INTO BUFFER
    	
    	while(no_of_bytes > 0)
    	{
    		do
    		{ 	ReadMemReg(RD_FM_SR, &status_reg,1);
    		}
    		while((status_reg & 0x80) == 0);
    	  
    		FM_CS_LOW;
    		Delay(TCSS);//CS Setup Time = minimum 5 nS
    	  //decoding address
    		spi_send(buff_1_2);
    		spi_send(0xff);
    		spi_send(address>>8);
    		spi_send(address&0xff);
    		if(buff_1_2 == RD_BUFF1 || buff_1_2 == RD_BUFF2)
    			spi_send(0xff); //dummy byte - time required to read by memory
    	  
    		while(no_of_bytes > 0)
    		{ 	if(rw == MEM_READ)
    				*buff = spi_send(0xFF);
    			else
    			  	spi_send(*buff);
    			no_of_bytes--;
    			buff++;
    			address++;
    			if((address % BYTE_PER_PAGE) == 0)
    			{	FM_CS_HIGH;
    				Delay(TCS);//min CS high time 50
    				address = 0;
    				//PutStringUsb("\r\nPage break encountered");
    				if(rw == MEM_READ)
    					buff_1_2 = RD_BUFF2;
    				else
    					buff_1_2 = WR_BUFF2;
    				break;
      			}
    		}
      	}
    	FM_CS_HIGH;
      	Delay(TCS);//min CS high time 50
    }
    /******************************************************************************/
    //	DESCRIPTION: writes buffer 1 or 2 into the memory page
    //	Parameter1:	use buffer 1 or 2 to write
    //	Parameter2: page number in memory where to write
    //	STATUS : OK TESTED
    ////////////////////////////////////////////////////////////////////////////////
    void BufferToPage(uc buff_1_2, ui page)
    { 	uc status_reg;
      	do
      	{	ReadMemReg(RD_FM_SR, &status_reg,1);
      	}
    	while((status_reg & 0x80) == 0);
      
      	FM_CS_LOW;
      	Delay(TCSS);//CS Setup Time = minimum 5 nS
      	spi_send(buff_1_2);//command 	 
      	//decoding address						|------- 1 byte --------||------ 2 byte ------||----- 3 byte --|
    	spi_send(page>>6);						//23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    	spi_send(page<<2);						//x  x  p  p  p  p  p  p  p  p  p  p  p  p  x x x x x x x x x x
    	spi_send(0xFF);
    	
    	FM_CS_HIGH;
      	Delay(TCS);//min CS high time 50
    }
    /******************************************************************************/
    ////////////////////////////////////////////////////////////////////////////////
    // 	Description : Reads Flash memory page to buffer 1 OR 2
    //	Parameter1: page = page no to read from FM
    //	Parameter2: use buffer 1 or 2 keep read page
    //	STATUS : OK TESTED
    ////////////////////////////////////////////////////////////////////////////////
    void PageToBuffer(ui page, uc buff_1_2)
    {	uc status_reg;
      	do
      	{ 	ReadMemReg(RD_FM_SR, &status_reg,1);
      	}
    	while((status_reg & 0x80) == 0);
      
      	FM_CS_LOW;
      	Delay(TCSS);//CS Setup Time = minimum 5 nS
      	spi_send(buff_1_2);//command 	 
      	//decoding address						|------- 1 byte --------||------ 2 byte -------||---- 3 byte --|
    	spi_send(page>>6);						//23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    	spi_send((page<<2));					//x  x  p  p  p  p  p  p  p  p  p  p  p  p  x x x x x x x x x x
    	spi_send(0xFF);
    	
    	FM_CS_HIGH;
      	Delay(TCS);//min CS high time 50
    }
    /******************************************************************************/
    ////////////////////////////////////////////////////////////////////////////////
    // 	Description : reads flash memory identification number (0x1F260000)
    //	STATUS : OK TESTED
    ////////////////////////////////////////////////////////////////////////////////
    unsigned char ReadIdentification()		//done
    {	uc ReturnVal;
      	FM_CS_LOW;
      	DelayInMilliSec(5);
      	spi_send(RD_FM_ID);
      	if(spi_send(0xff) == 0x1F)
      	{ 	if(spi_send(0xff) == 0x26)
        	{ 	if(spi_send(0xff) == 0x00)
          		{ 	ReturnVal = 0;		//success
    				/*if(spi_send(0xff) == 0x00)
            		{ 	ReturnVal = 0;		//success
    				}
    				else
    	  				ReturnVal = -1;	  //fail*/
          		}
          		else
            		ReturnVal = -1;	 //fail
        	}
        	else
          		ReturnVal = -1;		//fail
      	}
      	else
        	ReturnVal = -1; //fail
      	FM_CS_HIGH;
      	Delay(TCS);//min CS high time 50
      	return ReturnVal;   
    }
    /*******************************************************************************/
    ///////////////////////////////// Read Unique Identification ///////////////////
    // Description: reads flash memory unique identification number; every chip has its own unique 64 byte id no.
    // STATUS : PROGRAMMING
    //////////////////////////////////////////////////////////////////////////////////
    void ReadSerialInfoInCopyBuff()
    {	uc loc;
    	
    	FM_CS_LOW;
    	Delay(TCSS); // CS setup time min 5 ns
    	spi_send(READ_UID);
    	spi_send(0xFF);
    	spi_send(0xFF);
    	spi_send(0xFF);
    	//read first 64 byte as Serial information
    	for(loc =0;loc<13;loc++)
    	{	CopyBuff[loc] = spi_send(0xFF);
    	}
    	FM_CS_HIGH;
    	Delay(TCS);// min CS high time 50
    }
    
    void WriteValidSerialInfoFromCopyBuffToSecurityRegister()
    {	uc loc;
    	FM_CS_LOW;
    	Delay(TCSS); // CS setup time min 5 ns
    	spi_send(0x9B);
    	spi_send(0x00);
    	spi_send(0x00);
    	spi_send(0x00);
    	for(loc=0;loc<13;loc++)
    	{	
    		spi_send(CopyBuff[loc]);
    	}
    	FM_CS_HIGH;
    	Delay(TP);
    }
    long long ReadUniqueIdentification()
    {
    	uc temp;
    	long long temp1;
    	union union_temp temp2;
    	
    	FM_CS_LOW;
    	Delay(TCSS); // CS setup time min 5 ns
    	spi_send(READ_UID);
    	spi_send(0xFF);
    	spi_send(0xFF);
    	spi_send(0xFF);
    	for(temp =0; temp<64;temp++)
    	  	spi_send(0xFF);
    	for(temp =0,temp1 =0; temp<64;temp++)
    	{	
    	  	temp2.c[7-(temp%8)] = spi_send(0xFF);
    		if((temp+1)%8 == 0)
    		{
    		  	temp1 ^=temp2.ll;
    			//sprintf(CopyBuff,"-%lld",u.ll);
    		  	//PutStringUsb(CopyBuff);
    		}
    		
    	}
    	FM_CS_HIGH;
    	Delay(TCS);// min CS high time 50
    	return temp1;	
    }
    

  • Hi Nabeen,

    From your source code, it looks like FMemInit() is what you used to prepare your external flash. You do not need to do that for the CC3135.

    You should not call sl_IfOpen from your application. This is part of the host driver, which your application MCU interacts with through the host driver APIs. The first thing your application would call is sl_Start. This command will turn on the network processor, start the SPI instance, and handle communication with the network processor through the host driver using the host MCU-specific functions you have defined in user.h and implemented in cc_pal. I suggest looking at a simple SDK example like mqtt_client to see how your host MCU uses the host driver APIs.

    In the case of sl_IfOpen, you still need to define a function that can have plfName passed to it, but you can choose not to do anything with it. Please see the spi_Open() implementation for the SimpleLink MCU hosts in source/ti/drivers/net/wifi/porting/cc_pal.c for a reference.

    Since you mentioned using a non-OS application, I suggest you look at this thread which explains why some RTOS sync functions like semaphores and mutexes are still needed by the CC3135 host driver: https://e2e.ti.com/support/wireless-connectivity/wifi/f/968/t/690115

    Best regards,

    Sarah