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.

TM4C123GH6PM pwm generators prevents cc3000 wifi running

Other Parts Discussed in Thread: TM4C123GH6PM, SYSBIOS, SW-TM4C

HI guys!

Working on a project combining the TM4C123GH6PM, pwm outputs 0-3 + the CC3000 Boost wifi board.

The wifi setup should initialize after running a pwm_init() (setting all pwm parameters).

When not using (comment it out):

// PWM generator 0 and 1 enabled
PWMGenEnable(PWM1_BASE, PWM_GEN_0);
PWMGenEnable(PWM1_BASE, PWM_GEN_1);

The wifi is working fine and I am able to send data to it from my computer.

So, the problem is the two lines above. Has anybody experienced anything similar? Does the PWMGenEnable restrict other functions? Has the pwm1_base anything to do with it? Could it be synchronizing problems?

 For information, the EchoFxn() and pwmControl() run as Idle in the background.

Here is the code (important areas in bold and red):

/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/cfg/global.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/Memory.h>
#include <xdc/runtime/System.h>
#include <string.h>

/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>

/* TI-RTOS Header files */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/WiFi.h>
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/debug.h"
#include "driverlib/pwm.h"
#include "driverlib/pin_map.h"
#include "inc/hw_gpio.h"
#include "driverlib/rom.h"


/* SimpleLink Wi-Fi Host Driver Header files */
#include <cc3000_host_driver/include/common/cc3000_common.h>
#include <cc3000_host_driver/include/netapp.h>
#include <cc3000_host_driver/include/nvmem.h>
#include <cc3000_host_driver/include/socket.h>
#include <cc3000_host_driver/include/wlan.h>

/* Example/Board Header files */
#include "Board.h"

// TCP buffer size and port number
#define TCPPACKETSIZE 12
#define TCPPORT 1000

/* CC3000 firmware version compatible with this example */
#define PACKAGEID 1
#define PACKAGEBLDNUM 24

/* Flags set in callback */
Bool smartConfigFinished = FALSE;
Bool deviceConnected = FALSE;
Bool dhcpComplete = FALSE;

/* Buffer to hold data received */
Char buffer[TCPPACKETSIZE];
Char ipRecvd[4];

// PWM variables
volatile uint32_t PWM_FREQUENCY;
volatile uint32_t ui32Load;
volatile uint32_t ui32PWMClock;
volatile uint32_t pwm_motor_A;
volatile uint32_t pwm_motor_B;
volatile uint32_t pwm_motor_C;
volatile uint32_t pwm_motor_D;
/*
* ======== asynchCallback ========
* Callback for handling unsolicited events. A function pointer is passed in
* through the WiFi_Params to register the callback with the Host Driver.
*/
Void asynchCallback(long eventType, char *data, unsigned char length)
{
switch(eventType){
case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE:
/* Smart Config process has completed */
smartConfigFinished = TRUE;
break;

case HCI_EVNT_WLAN_UNSOL_CONNECT:
/* CC3000 connected to an AP */
deviceConnected = TRUE;
GPIO_write(Board_LED0, Board_LED_ON);
break;

case HCI_EVNT_WLAN_UNSOL_DISCONNECT:
/* CC3000 disconnected from an AP */
deviceConnected = FALSE;
GPIO_write(Board_LED0, Board_LED_OFF);
break;

case HCI_EVNT_WLAN_UNSOL_DHCP:
/* DHCP report */
dhcpComplete = TRUE;
ipRecvd[0] = data[3];
ipRecvd[1] = data[2];
ipRecvd[2] = data[1];
ipRecvd[3] = data[0];
break;
}
}

/*
* ======== smartConfigFxn ========
* Starts the Smart Config process which allows the user to tell the CC3000
* which AP to connect to, using a smart phone app. Downloads available here:
* http://www.ti.com/tool/smartconfig
*/
Void smartConfigFxn(Void)
{
UChar subnetMask[] = {0, 0, 0, 0};
UChar ipAddr[] = {0, 0, 0, 0};
UChar defaultGateway[] = {0, 0, 0, 0};
UChar dnsServer[] = {0, 0, 0, 0};

/* Acquire an IP address */
netapp_dhcp((unsigned long *)ipAddr, (unsigned long *)subnetMask,
(unsigned long *)defaultGateway, (unsigned long *)dnsServer);

/* Delete current policy */
wlan_ioctl_set_connection_policy(0, 0, 0);

/* Restart the CC3000 */
wlan_stop();
Task_sleep(50);
wlan_start(0);

/* Set Smart Config prefix and start Smart Config */
wlan_smart_config_set_prefix("TTT");
wlan_smart_config_start(0);

/* Wait for Smart Config to finish. LED will blink until complete. */
while (smartConfigFinished == 0) {
Task_sleep(400);
GPIO_toggle(Board_LED0);
}

/* Configure to connect automatically to the AP retrieved */
wlan_ioctl_set_connection_policy(0, 0, 1);

GPIO_write(Board_LED0, Board_LED_OFF);

/* Restart the CC3000 */
wlan_stop();
Task_sleep(50);
wlan_start(0);

/* Set connection flag to 'disconnected' */
deviceConnected = 0;
dhcpComplete = 0;

/* Mask out all non-required events */
wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE | HCI_EVNT_WLAN_UNSOL_INIT |
HCI_EVNT_WLAN_ASYNC_PING_REPORT);
}

/*
* ======== echoFxn ========
* Prints IP address and echos messages through TCP.
*
* Task for this function is created statically. See the project's .cfg file.
*/
Int nbytes;
Int status;
Int clientfd;
int n = 0;

Void echoFxn()
{
if(n == 0)
{
// Bool flag = TRUE;
Long lSocket;
sockaddr_in sLocalAddr;
sockaddr_in client_addr;
socklen_t addrlen = sizeof(client_addr);
UChar spNum[2] = {0};
ULong currButton;
ULong prevButton = 0;
WiFi_Params params;
WiFi_Handle handle;

/* Turn LED off. It will be used as a connection indicator */
GPIO_write(Board_LED0, Board_LED_OFF);

/* Open WiFi */
WiFi_Params_init(&params);
params.bitRate = 4000000;
handle = WiFi_open(Board_WIFI, Board_SPI_CC3000, asynchCallback, &params);

/* Mask out all non-required events */
wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE | HCI_EVNT_WLAN_UNSOL_INIT |
HCI_EVNT_WLAN_ASYNC_PING_REPORT);

/* Check service pack version */
nvmem_read_sp_version(spNum);
if ((spNum[0] != PACKAGEID) || (spNum[1] != PACKAGEBLDNUM)) {
System_printf("You are using service pack version %d.%d! This example "
"is recommended for use\nwith %d.%d. Run the TI-RTOS "
"CC3000 Patcher example to get this version.\n\n",
spNum[0], spNum[1], PACKAGEID, PACKAGEBLDNUM);
System_flush();
}

/*
* Wait for the WiFi device to connect to an AP. If a profile for the AP in
* use has not been stored yet, press Board_BUTTON0 to put the CC3000 in
* Smart Config mode.
*/
while ((deviceConnected != TRUE) || (dhcpComplete != TRUE)) {
/*
* Start Smart Config 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_BUTTON0);
if((currButton == 0) && (prevButton != 0))
{
smartConfigFxn();
}
prevButton = currButton;
Task_sleep(50);
}

System_printf("CC3000 has connected to AP and acquired an IP address.\n");

/* Print IP address */
System_printf("IP Address: %d.%d.%d.%d\n", ipRecvd[0], ipRecvd[1],
ipRecvd[2], ipRecvd[3]);
System_flush();

/* Echo data using TCP */
lSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (lSocket == -1) {
System_printf("socket failed\n");
Task_exit();
}

memset((char *)&sLocalAddr, 0, sizeof(sLocalAddr));
sLocalAddr.sin_family = AF_INET;
sLocalAddr.sin_addr.s_addr = htonl(0);
sLocalAddr.sin_port = htons(TCPPORT);

status = bind(lSocket, (const sockaddr*)&sLocalAddr, sizeof(sLocalAddr));
if (status < 0) {
System_printf("bind failed\n");
closesocket(lSocket);
Task_exit();
}

if (listen(lSocket, 0) == -1){
System_printf("listen failed\n");
closesocket(lSocket);
Task_exit();
}

do {
/* Wait for incoming request */
clientfd = accept(lSocket, (sockaddr*)&client_addr, &addrlen);
Task_sleep(300);
} while (clientfd == SOC_IN_PROGRESS);

if (clientfd == -1) {
System_printf("accept failed\n");
closesocket(lSocket);
Task_exit();
}

if(nbytes == -1)
{
System_printf("Closing clientfd 0x%x.\n", clientfd);
closesocket(clientfd);
closesocket(lSocket);

WiFi_close(handle);
}
}

n = 1;
nbytes = recv(clientfd, buffer, TCPPACKETSIZE, 0); // read tcp buffer
pwm_motor_A = (buffer[0]-48)*100 + (buffer[1]-48)*10 + (buffer[2]-48)*1; // decode buffer index 0-3 = motor_A
pwm_motor_B = (buffer[3]-48)*100 + (buffer[4]-48)*10 + (buffer[5]-48)*1; // decode buffer index 4-7 = motor_B
pwm_motor_C = (buffer[6]-48)*100 + (buffer[7]-48)*10 + (buffer[8]-48)*1; // decode buffer index 8-11 = motor_C
pwm_motor_D = (buffer[9]-48)*100 + (buffer[10]-48)*10 + (buffer[11]-48)*1; // decode buffer index 12-15 = motor_D
}

Void pwmInit()
{
// PWM settings
PWM_FREQUENCY = 400;
pwm_motor_A = 440;
pwm_motor_B = 440;
pwm_motor_C = 440;
pwm_motor_D = 440;

SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
SysCtlPWMClockSet(SYSCTL_PWMDIV_64);

SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); // connector J1, pin PE4 and PE5
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); // connector J3, pin PD0 and PD1

// PWM PD0, motor A
GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_0);
GPIOPinConfigure(GPIO_PD0_M1PWM0);

// PWM PD1, motor B
GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_1);
GPIOPinConfigure(GPIO_PD1_M1PWM1);

// PWM PE4, motor C
GPIOPinTypePWM(GPIO_PORTE_BASE, GPIO_PIN_4);
GPIOPinConfigure(GPIO_PE4_M1PWM2);

// PWM PE5, motor D
GPIOPinTypePWM(GPIO_PORTE_BASE, GPIO_PIN_5);
GPIOPinConfigure(GPIO_PE5_M1PWM3);

// PWM clk and frequency
ui32PWMClock = SysCtlClockGet() / 64;
ui32Load = (ui32PWMClock / PWM_FREQUENCY) - 1;
PWMGenConfigure(PWM1_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN);
PWMGenPeriodSet(PWM1_BASE, PWM_GEN_0, ui32Load);
PWMGenConfigure(PWM1_BASE, PWM_GEN_1, PWM_GEN_MODE_DOWN);
PWMGenPeriodSet(PWM1_BASE, PWM_GEN_1, ui32Load);

// PWM 0 and 1
PWMPulseWidthSet(PWM1_BASE, PWM_OUT_0, (pwm_motor_A * ui32Load) / 1000);
PWMPulseWidthSet(PWM1_BASE, PWM_OUT_1, (pwm_motor_B * ui32Load) / 1000);
PWMOutputState(PWM1_BASE, PWM_OUT_0_BIT, true);
PWMOutputState(PWM1_BASE, PWM_OUT_1_BIT, true);

// PWM 2 and 3
PWMPulseWidthSet(PWM1_BASE, PWM_OUT_2, (pwm_motor_C * ui32Load) / 1000);
PWMPulseWidthSet(PWM1_BASE, PWM_OUT_3, (pwm_motor_D * ui32Load) / 1000);
PWMOutputState(PWM1_BASE, PWM_OUT_2_BIT, true);
PWMOutputState(PWM1_BASE, PWM_OUT_3_BIT, true);

// PWM generator 0 and 1 enabled
PWMGenEnable(PWM1_BASE, PWM_GEN_0);
PWMGenEnable(PWM1_BASE, PWM_GEN_1);
}

Void pwmControl()
{
PWMPulseWidthSet(PWM1_BASE, PWM_OUT_0, (pwm_motor_A * ui32Load) / 1000);
PWMPulseWidthSet(PWM1_BASE, PWM_OUT_1, (pwm_motor_B * ui32Load) / 1000);
PWMPulseWidthSet(PWM1_BASE, PWM_OUT_2, (pwm_motor_C * ui32Load) / 1000);
PWMPulseWidthSet(PWM1_BASE, PWM_OUT_3, (pwm_motor_D * ui32Load) / 1000);
}
/*
* ======== main ========
*/
Int main(Void)
{
/* Call board init functions. */
Board_initGeneral();
Board_initGPIO();
Board_initWiFi();

pwmInit();

/* Turn on user LED */
GPIO_write(Board_LED0, Board_LED_ON);

System_printf("Starting the Quad Control CC3000 system\n");
/* SysMin will only print to the console when you call flush or exit */
System_flush();

/* Start BIOS */
BIOS_start();

return (0);
}

  • After a quick scan of this code i see a couple of issues and potential errors.

    1) You call SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); but the comments point to port D as does the rest of the code.  Make sure if you want port D or port F and make sure all your code uses the correct GPIO port mapping for the pins and features you want.

    2) PD0 and PD1 may be tied externally on the board to other pins.  This was done to make SPI and I2C available at the same place on the BoosterPack connector.  This may be causing a conflict if you want to use them independently.  Find the schematic, in the users manual for the kit, find the zero ohms that connect PD0 and PD1 to other pins and remove them from your board.

    Dexter

  • Alexander Waldejer said:
    Does the PWMGenEnable restrict other functions? Has the pwm1_base anything to do with it? Could it be synchronizing problems?

    No, no and no!  As other responder has almost noted - you do not, "SysCtlPeripheralEnable()" Port D - at least such fact escapes "evidence log" as presented here.  He goes on and indeed, "nails" the potential for mayhem introduced by the, "non-standard" cross-connect of MCU pins - afflicted upon Port D, pins 0 & 1.

    Gentle protest must sound against the statments, "may be tied & may be causing a conflict!"  (i.e. the well proven "unwise," dead-shorting of MCU pins - for hallowed, non ARM, past "compatibility...") 

    Similarly it, "may be detrimental to health" to ingest cyanide.  Avoidance/roadblocks to that potential occurrence are the classic means of prevention.  Might it be that certain decision makers here have invited that potentially deadly ingredient "too close" to our dining table?  (and then inadequately highlighted its "unexpected" presence...)

    That same, "inadequacy of warning" inflicts the two NMI pins - and continues unabated - despite the endless shipwrecks - many washing upon these forlorn shores...

  • Thanks for the response.

    I corrected the Port F - Port D error. Still having problems.

    From the CC3000 SimpleLink Boost datasheet i have the following J9 and J10 pin setup:

    And from the TM4C123GH6PM manual corresponding pins on J1 and J2:

    What I read is that my setup has no conflicts. Do you guys see anything else?

    I'm guessing "reserved" pins = not tied up to anything = it can be used for other configurations?

  • The conflict is on TM4C123G LaunchPad pins 2.06 and 2.07.  Note that PD0 and PD1 are connected to this pins by R9 and R10.

    Remove R9 and R10 in order to use PD0 and PD1.

    R9 and R10 provide I2C to pins 2.06 and 2.07.  If I2C is not needed on those pins then R9 and R10 can be removed without consequence.  I2C was needed on those pins per the BoosterPack standard in place at time of the TM4C123G LaunchPad release.

    Dexter

  • Okey, so now I have the CC3000 board manually wired. The only pins being used on the launchpad is J2: 2.1, 2.2 and 2.3, and J1: 1.1, 1.2 and 1.7.

    Just as a test, I did a new download of the RTOS tcpEchoCC3000 and run it without any changes. With and without the manually wiring between the boards, the code is getting stuck and not working as before.

    When pausing the debug I get the following loop:

    Any suggestions? I also tried running the CC3000 patcher which also came along the CC3000 SDK. Neither this would run properly. 

    It seems to me that after running my customized code (the first post), everything seems to go wrong... :P

    The PWM output I tried to run out on PD0 and PD1 could not physically cause a defect on the CC3000?

  • It is not likely that the PWM on PD0 and PD1 damaged the CC3000 or the Tiva device.  

    We (Tiva group) recently went through and revamped the CC3000 examples that you are using. Those examples originally came from the CC3000 team.

    The updated and known working examples are now posted in TivaWare 2.1.12573.  This was just released this week.  Try the examples in the new TivaWare release under C:\ti\TivaWare_C_Series-2.1.0.12573\examples\boards\ek-tm4c123gxl-boost-cc3000\ assuming you use the default install directories.

    Dexter

  • Previous post omitted URL of TivaWare 2.1 download page.

    Try these and let us know.  Be sure to follow the readme.txt instructions for setting things up as well.

    http://software-dl.ti.com/tiva-c/SW-TM4C/latest/index_FDS.html

  • Hi again!

    So, what has been done since last post:

    - downloaded tivaware 2.1
    - ran the newest cc3000 pather
    - ran the basic wifi application
    - managed to run the smartconfig by activating the board through hyperterminal on my computer
    - smartconfig through my HTC android

    Everything seems to be working except actually establishing a connection to my AP.
    The hyperterminal continues to send me the message: "Received unsolicited disconnect from CC3000".

    I tracked it down to the following line of code:

    I also tried running the earlier CC3000 sdk example tcpEcho without it working. Any suggestions?

  • Alexander,


    This is just a status message telling you that the CC3000 received a disconnect message. It is the same thing that will be triggered if you run the "disconnect" command. This seems to indicate that you are connecting, then disconnecting from the access point.
    This is not a bug in the code, though it may indicate trouble with keeping the connection between the access point and your cc3000.

    Just to make sure, you have run smart config on the board and smart phone and the light changed color on the board correct? Then you reset it and are seeing the disconnect messages, correct? If this is the case can you try running the ping command and see if you get anything?

    Oh, one more thing, is your wifi encrypted or unencrypted?

    -Austin

  • Ok.

    So i double checked my wifi and deactivated the encryption. The smartconfig is working properly and the board is indicating connection with a yellowish color.

    Funny though, the encrypted wifi (WPA/WPA2) was never an issue before... 

    Anyway, it connects to the AP.

    Though when trying to run me TcpClient app (visual studio) and connecting to 192.168.0.101 port 1000, it seems like the board refuses the client request. My exception message in visual studio is the classis: "No connection could be made because the target machine actively refused it".

    This is a problem both when using the tcpEcho TIRTOS example and the Basic wifi application.

    Any suggestions?

  • Alexander,

    The basic wifi app provided as part of the latest release of tivaware supports TCP and UDP. Try doing UDP, it will more than likely be successful. For TCP the board can only currently work as a client, so you'll need a TCP server to connect to. (this is purely a software limitation of the demo and should be resolved in the next release). Also please make sure that you set up a port on the board first, if you just run smart config and then try to ping the board it wont work, because there is no port open. You will need to do the following commands at a minimum.

    smartconfig    // to set up the wifi on the board, one time command
    socketopen udp // open a udp socket
    bind 8080      // bind the current socket to port 8080

    At this point you can ping the board from your computer, open the command line or terminal and run 'ping 192.168.1.101' or whatever the equivalent ip for your board is, (your board should report the IP it grabs on the UART terminal) This should work regardless of whether you are using TCP or UDP.

    For your TCP Client app, it probably wont work, the microcontroller currently only supports being a client, which means whatever it is connecting to needs to be a server. For example I've loaded a TCP program on my android tablet, connected to the same network, set the tablet up as a TCP server, connected to it from the microcontroller using 'senddata 192.168.1.102 8080 helloworld' (where the tablet is at address 192..168.1.102 with a TCP server running on port 8080) and everything works. I believe the issue you are experiencing is related to not using a TCP server.

    -Austin

    PS: just to note, if you'd like to use the Tiva board as a TCP server its simple enough to do, we just didnt include it as part of the basic wifi demo application.