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.

Generating PWM

Other Parts Discussed in Thread: CC3200, ADS1198

Hello,

I want to generate a square wave of 2MHz (50% duty cycle).

I referred the PWM code and Interrupt code from the SDK, but couldn't modify them to generate 2MHz square wave.

How can i generate it using

1)PWM module.

2)General-Purpose-Timer-Interrupt (toggle GPIO port pin at 2MHz).

Any help would be much appreciated.

Thank you in advance.

Regards,

Abhishek.

  • Hi Abhishek,

    Let me check and will get back to you

    Thanks and Regards,
    Praveen
  • Hello Praveen,

    Thank you for replying.

    Awaiting you response.

    Warm regards,

    Abhishek.

  • Abhishek,

    You can refer to TRM section 9.3.2.4 for detailed explanation of PWM mode.

    But in short, the timer is running at 80 MHz so to get 2 MHz you should divide it by 40 this make the Load Value to be 39 (40 - 1 since it is a 0 base timer )

    To get a 50 % duty cycle the match should be 40/2 - 1 = 19.

    Here the code, I modified the PWM example.

    //****************************************************************************
    //
    //****************************************************************************
    void SetupTimerPWMMode(unsigned long ulBase, unsigned long ulTimer,
    unsigned long ulConfig, unsigned char ucInvert)
    {
    //
    // Set GPT - Configured Timer in PWM mode.
    //
    MAP_TimerConfigure(ulBase,ulConfig);
    MAP_TimerPrescaleSet(ulBase,ulTimer,0);

    //
    // Inverting the timer output if required
    //
    MAP_TimerControlLevel(ulBase,ulTimer,ucInvert);

    //
    // Load value set to ~0.5 ms time period
    //
    MAP_TimerLoadSet(ulBase,ulTimer,39);

    //
    // Match value set so as to output level 0
    //
    MAP_TimerMatchSet(ulBase,ulTimer,19);

    }

    And main()

    ....
    //
    // Configure the pinmux settings for the peripherals exercised
    //
    PinMuxConfig();

    //
    // Initialize the PWMs used for driving the LEDs
    //
    //InitPWMModules();


    SetupTimerPWMMode(TIMERA2_BASE, TIMER_B,
    (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PWM), 1);


    MAP_TimerEnable(TIMERA2_BASE,TIMER_B);


    while(1)
    {

    }
    ....

    Thanks and Regards,
    Praveen
  • Hello Praveen,

    Thank you very much.

    I will implement this and get back.

    Regards,

    Abhishek.

  • Hello Praveen,
    I implemented the PWM module as well as Generated interrupt using timer.

    Although the PWM module is working perfectly(Generating 2.048MHz), The timer interrupt is unable to generate 2.048MHz interrupt.

    I have toggled a GPIO pin on the timer interrupt, but it only toggles at a maximum frequency of 166.66KHz.

    I also changed the "timer" code from SDK, wherein i modified the reload value to 39.
    But there also i don't get 2.048MHz.

    Please help !!

    Warm regards,
    Abhishek.
  • Abhishek,

    Its not possible to generate such a high frequency using timer interrupts due to software overheads involved.

    Thanks and Regards,
    Praveen
  • Ok Praveen,
    Thank you so much for answering.
    You provided invaluable help.

    Warm regards,
    Abhishek.
  • Hello Praveen,
    Actually i am trying to interface ads1198 Analog-Front-end IC to CC3200 module.
    I needed 2.048MHz to drive the clock this IC.
    As recommended by you, i will use the PWM module to do so.

    Also, the ads1198 works with SPI interface.
    The given SPI code from SDK is confusing.
    If you can provide any documentation/link/code, it would be helpful.

    Thank you for helping out.

    Warm regards,
    Abhishek.
  • Hi Abhishek,

    I need this exact code, did you get this to work?

    Would you be able to provide me the code you eventually used to make this work?

    Glenn.
  • Hello Glenn,

    I have the following things going on:-

    1)I have generated 2.051MHz(50% duty cycle) square wave using PWM.

    2)Through observations, i concluded that it is not possible to generate frequencies beyond 166kHz using timer interrupts(pin toggling).

    3)I am still working with the ads1198 code.

    Which piece of code do you want me to provide??

    Kindly reply, and i will post it here.

    Warm regards,

    Abhishek.

  • Hi Abhishek,

    Thank you very much, I am interested in 1) the PWM and I am fine with the frequency limitations.

    Can I make a suggestion if you are able to, it would be great if you could post the code on Github (http://github.com) with a small application which demonstrates the code. This way I and others can easily see how the code works within an application.

    We all need help when we are developing, especially when starting out on a new platform, so it is great to be able to get assistance from people in this forum and open source code when available.

    Many Thanks!
    Glenn.
  • Hello Glenn,
    Yes definately i will post my code.
    Just need a day or two to do so..

    Thanks and regards,
    Abhishek.
  • Hi Abhishek,

    It has been a few days since you said you would get this done, I was wondering how this has progressed?

    Glenn.
  • Hello Glenn,

    Sorry for delayed response.

    Actually, i was busy with other things (which you have already figured out in other threads of mine!!).

    Well, i may not be able to post this into your github, but i am sending you the text file.

    I have used the httpserver code as base and build my application on it.

    The function to initialize the 2.048MHz PWM i.e InitPWMModules(); can be found in the static void HTTPServerTask(void *pvParameters) function.

    The PWM can be checked on Pin_64 using dso.

    Kindly update the code accordingly and update github.

    //****************************************************************************
    //
    //! Sets up the identified timers as PWM to drive the peripherals
    //!
    //! \param none
    //!
    //! This function sets up the folowing
    //!    1. TIMERA2 (TIMER B) as RED of RGB light
    //!    2. TIMERA3 (TIMER B) as YELLOW of RGB light
    //!    3. TIMERA3 (TIMER A) as GREEN of RGB light
    //!
    //! \return None.
    //
    //****************************************************************************
    void InitPWMModules()
    {
        //
        // Initialization of timers to generate PWM output
        //
        MAP_PRCMPeripheralClkEnable(PRCM_TIMERA2, PRCM_RUN_MODE_CLK);
        //MAP_PRCMPeripheralClkEnable(PRCM_TIMERA3, PRCM_RUN_MODE_CLK);
    
        //
        // TIMERA2 (TIMER B) as RED of RGB light. GPIO 9 --> PWM_5
        //
        SetupTimerPWMMode(TIMERA2_BASE, TIMER_B,
                (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PWM), 1);
        //
        // TIMERA3 (TIMER B) as YELLOW of RGB light. GPIO 10 --> PWM_6
        //
        //SetupTimerPWMMode(TIMERA3_BASE, TIMER_A,
                //(TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM | TIMER_CFG_B_PWM), 1);
        //
        // TIMERA3 (TIMER A) as GREEN of RGB light. GPIO 11 --> PWM_7
        //
        //SetupTimerPWMMode(TIMERA3_BASE, TIMER_B,
                //(TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM | TIMER_CFG_B_PWM), 1);
    
        MAP_TimerEnable(TIMERA2_BASE,TIMER_B);
        //MAP_TimerEnable(TIMERA3_BASE,TIMER_A);
        //MAP_TimerEnable(TIMERA3_BASE,TIMER_B);
    }
    
    //****************************************************************************
    //
    //!  \brief                     Handles HTTP Server Task
    //!
    //! \param[in]                  pvParameters is the data passed to the Task
    //!
    //! \return                        None
    //
    //****************************************************************************
    static void HTTPServerTask(void *pvParameters)
    {
        lRetVal = -1;
        InitializeAppVariables();
    
        //
        // Following function configure the device to default state by cleaning
        // the persistent settings stored in NVMEM (viz. connection profiles &
        // policies, power policy etc)
        //
        // Applications may choose to skip this step if the developer is sure
        // that the device is in its default state at start of applicaton
        //
        // Note that all profiles and persistent settings that were done on the
        // device will be lost
        //
        lRetVal = ConfigureSimpleLinkToDefaultState();
        if(lRetVal < 0)
        {
            if (DEVICE_NOT_IN_STATION_MODE == lRetVal)
                //UART_PRINT("Failed to configure the device in its default state\n\r");
    
            LOOP_FOREVER();
        }
    
        //UART_PRINT("Device is configured in default state \n\r");
    
        memset(g_ucSSID,'\0',AP_SSID_LEN_MAX);
    
        //Read Device Mode Configuration
        ReadDeviceConfiguration();
    
        //Connect to Network
        lRetVal = ConnectToNetwork();
    
        if(lRetVal != SUCCESS)
        {
            ADC_Stage = 0;
            AdcWrPtr = 0;
            ADCuartDiff = 0;
            AdcRdPtr = 0;
    
          //tcp_socket tasks
    
       lRetVal = ConfigureSimpleLinkToDefaultState();
    
        if(lRetVal < 0)
        {
          if (DEVICE_NOT_IN_STATION_MODE == lRetVal)
             //UART_PRINT("Failed to configure the device in its default state \n\r");
    
          LOOP_FOREVER();
        }
    
        //UART_PRINT("Device is configured in default state \n\r");
    
    
        lRetVal = sl_Start(0, 0, 0);
        if (lRetVal < 0)
        {
            //UART_PRINT("Failed to start the device \n\r");
            LOOP_FOREVER();
        }
    
        //UART_PRINT("Device started as STATION \n\r");
    
    
        //UART_PRINT("Connecting to AP: %s ...\r\n",Profile_Config.SSID);
    
        // Connecting to WLAN AP - Set with static parameters defined at common.h
        // After this call we will be connected and have IP address
        lRetVal = WlanConnect();
        if(lRetVal < 0)
        {
            //UART_PRINT("Connection to AP failed \n\r");
            LOOP_FOREVER();
        }
    
        //UART_PRINT("Connected to AP: %s \n\r",Profile_Config.SSID);
    
        /*UART_PRINT("Device IP: %d.%d.%d.%d\n\r\n\r",
                          SL_IPV4_BYTE(Machine_IP_Config.ipV4,3),
                          SL_IPV4_BYTE(Machine_IP_Config.ipV4,2),
                          SL_IPV4_BYTE(Machine_IP_Config.ipV4,1),
                          SL_IPV4_BYTE(Machine_IP_Config.ipV4,0));*/
    
         /*UART_PRINT("Default settings: SSID Name: %s, PORT = %d, Packet Count = %d, "
         "Destination IP: %d.%d.%d.%d\n\r",
         Profile_Config.SSID, g_uiPortNum, g_ulPacketCount,
         SL_IPV4_BYTE(Server_IP_Config.ServerIP,3),
         SL_IPV4_BYTE(Server_IP_Config.ServerIP,2),
         SL_IPV4_BYTE(Server_IP_Config.ServerIP,1),
         SL_IPV4_BYTE(Server_IP_Config.ServerIP,0));*/
    
         //here we will configure and initialize Timer0 interrupt to toggle PIN_62
         //Configure_Timer0_Interrupt();
    
         //Configure_ADC_CH_0_BAT_MON();
    
         //
         // Initialize the PWMs used for driving PIN_64
         //
         InitPWMModules();
    
        //
        // Initialize the I2C module @ 100Kbps
        //
        I2C_IF_Open(I2C_MASTER_MODE_STD); /* I2C_MASTER_MODE_FST for 400Kbps */
    
    
        //
        // Configure the STC3100 Battery Monitoring module
        //
        Configure_STC3100_BatMon();
    
    
        //
        // Configure the PCF8563 RTC module
        //
        Configure_PCF8563_RTC();
    
        RTC_Set_Current_TimeDate();
    
        //
        // Initialize the GSPI module
        //
        Init_SPI_ETH();
    
        //
        // Initialize the falling edge triggered ASIC dtat ready interrupt for driving PIN_61
        //
        Button_IF_Init(GPIOs3IntHandler);
    
    /*here we will configure and initialize TimerA1 interrupt for 100Hz.
    Various timer based tasks can be carried out here i.e. Battery monitoring every 10 seconds,
    RTC reading etc*/
         Configure_TimerA1_Interrupt();
    
    
         // open socket here
        BsdTcpClient(g_uiPortNum);
    
         while(1)
         {}
    

    Feel free to contact me if i didn't get anything from this.

    Thank you.

    Warm regards,

    Abhishek.

    P.S: Forgot to mention this in the text file:-

        //
        // Configure PIN_64 for TIMERPWM5 GT_PWM05
        //
        MAP_PinTypeTimer(PIN_64, PIN_MODE_3);

  • Hi Abhishek,

    Thank you very much for generously volunteering time from your busy schedule to help me with this. 

    Abhishek Ekhare said:
    Actually, i was busy with other things (which you have already figured out in other threads of mine!!).

    Yes I have seen your recent request for assistance and the many others you have made over the previous month or so. I hope the community has assisted you in getting up to speed so you can succeed at your job and build a product based on the CC3200.

    I am sure you appreciate all the help you have received from others, and I also hope you got something out of assisting another community member.

    Glenn.

  • Hello Glenn,

    Yes i got a lot of help from this community.

    Members are more than willing to help and rookies like me have been benefited a lot due to their help.

    And for github, i would like to contribute more to it and would be happy if others are also benefited by me.

    Kindly ask me if i could provide more towards github in future.

    Thanks and regards,

    Abhishek.

  • Abhishek Ekhare said:
    Members are more than willing to help and rookies like me have been benefited a lot due to their help.

    I'm not sure I would call someone who has a degree in engineering and 6+ years of professional experience a rookie. I do agree we all have to get up to speed on new platforms and this can take time, as there is much to read and learn. 

    I appreciate your offer to contribute further to Github, as suggested previously it would be great to have a working example of your code in a project and then uploaded to a Github repository you manage, that way others can see how it works within an application.

    Glenn.

  • Hello Glenn,
    Thank you very much for the encouragement.
    You are right, getting help quickly is the requirement of time.

    The ti e2e community has helped me a lot to speed up my development process.
    Looking forward for help in future as well.

    Warm regards,
    Abhishek.