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.

AM3505 WinCE BSP GPT10 PWM Question

Other Parts Discussed in Thread: AM3517, AM3505, SYSCONFIG

Hi,

I saw a couple queries from the forums but I couldn't figure this behavior.  I am using AM3505 and the hardware is very close to LogicPD AM3517 EVM. I am using WinCE 6.0 R3 12/2011 with BSP_WINCE_ARM_A8_01_02_00 core.  Pretty much I got all the SD, NAND, SPI, UART, Ethernet and SDIO working very well.  I was able to get GPT10 PWM output square wave when I use the low level hardware test codes without WinCE.  However, I followed existing OALPerformanceTimerInit() from PLATFORM\COMMON\SRC\SOC\CONNON_TI_V1\CONNON_TI\OAL\OMAP_GTP_TIMER\PROFILER\
profiler.c. I saw no output from GPMC_nCS5/SYS_NDMAREQ2/GPT10_PWM_EVT/GPIO_56. My guess is there something wrong with my WinCE BSP setup.  Please take a look and I appreciate your inputs:

Here is my low level test codes without WinCE/BSP:

#define PAD_CONFIG_BASE                   (0x48002000)
#define CONTROL_PADCONF_gpmc_ncs5         (PAD_CONFIG_BASE + 0x00B8)
#define TCLR      0x0024
#define TCRR      0x0028
#define TLDR      0x002C
#define TMAR      0x0038
#define SCPWM    (0x00000040)   // bit 7
#define AR       (0x00000002)   // bit 1
#define ST       (0x00000001)   // bit 0
void PWM10Setup(void)
{
    const uint32_t TLDR_SETTING = 0xFFFFFFE0;     // 32kHz clk,  1 ms tick
    config_pad(CONTROL_PADCONF_gpmc_ncs5, MODE3, PUPD_DIS, INPUT_DIS);
    OUT_REGL(GPTIMER10 + TCLR, 0x00000000);   // turn off timer
    CLRBIT_REGL(CM_CLKSEL_CORE, (1 << 6)); // do not use 26 Mhz system clock
    OUT_REGL(GPTIMER10 + TLDR, TLDR_SETTING);
    OUT_REGL(GPTIMER10 + TMAR, (TLDR_SETTING + 2));
    OUT_REGL(GPTIMER10 + TCRR, TLDR_SETTING);
    OUT_REGL(GPTIMER10 + TCLR, (0x0000181C | SCPWM | AR | ST));
}

My WinCE BSP codes:
----- PLATFORM\MYBSP\SRC\INC\bsp_padcfg.h
#define GPIO_PADS   \
    PAD_ENTRY(GPMC_nCS4,    INPUT_ENABLED | PULL_RESISTOR_ENABLED | PULLUP_RESISTOR | MUXMODE(4)) /* GPIO_55  */    \
    PAD_ENTRY(GPMC_nCS5,    INPUT_DISABLED | PULL_RESISTOR_DISABLED | MUXMODE(3)) /* SW_OUT  */ \
    . . . . .
    
----- PLATFORM\MYBSP\SRC\BSP_COMMON\BSPCFG\bspcfg.c
OMAP_DEVICE BSPGetPwmGPTDevice()
{
    return OMAP_DEVICE_GPTIMER10;
}
    
----- PLATFORM\COMMON\SRC\SOC\CONNON_TI_V1\CONNON_TI\OAL\OMAP_GTP_TIMER\PROFILER\profiler.c
#define GPTIMER_TCLR_SCPWM              (1 << 7)

OMAP_GPTIMER_REGS   *g_pPwmTimer = NULL;
const UINT32 TLDR_SETTING = 0xFFFFFFE0;     // 32kHz clk,  1 ms tick
...
void OALPwmGpt10Init()
{
    UINT32 deviceAddress;
    OMAP_DEVICE pwmDevice = BSPGetPwmGPTDevice();
    
    if (pwmDevice == OMAP_DEVICE_NONE)
    {
        return;
    }

    OALMSG(1, (L">>>> OALPwmGpt10Init device: %d\r\n", pwmDevice));

    deviceAddress = GetAddressByDevice(pwmDevice);
    OALMSG(1, (L">>>> device physical address: 0x%x\r\n", deviceAddress));
    
    g_pPwmTimer = OALPAtoUA(deviceAddress);
    OALMSG(1, (L">>>> device virtual address: 0x%x\r\n", g_pPwmTimer));

    OALMSG(1, (L">>>> Soft reset GPT10 and wait until finished <<<<\r\n"));
    // Soft reset GPTIMER and wait until finished
    SETREG32(&g_pPwmTimer->TIOCP, SYSCONFIG_SOFTRESET);
    while ((INREG32(&g_pPwmTimer->TISTAT) & GPTIMER_TISTAT_RESETDONE) == 0);

    OALMSG(1, (L">>>> Turning off GPT10 <<<<\r\n"));
    // Turn off timer. Tried with and without this with same result.
    OUTREG32(&g_pPwmTimer->TCLR, 0);
    
    // 32kHz source clock is already set in PlatformSetup()
    //srcClock = BSPGetSysTimer32KClock(&clockFrequency);
    //PrcmDeviceSetSourceClocks(pwmDevice,1,&srcClock);

    OALMSG(1, (L">>>> Set the load register value <<<<\r\n"));
    // Set the load register value.
    OUTREG32(&g_pPwmTimer->TLDR, TLDR_SETTING);
    
    OUTREG32(&g_pPwmTimer->TMAR, (TLDR_SETTING + 2));
    
    OUTREG32(&g_pPwmTimer->TCRR, TLDR_SETTING);
    
    // 0x0000181C | SCPWM | AR | ST
    OUTREG32(&g_pPwmTimer->TCLR, GPTIMER_TCLR_PT |
            GPTIMER_TCLR_TRG_OVERFLOWMATCH |
            GPTIMER_TCLR_PTV_DIV_256 |
            GPTIMER_TCLR_SCPWM |
            GPTIMER_TCLR_AR |
            GPTIMER_TCLR_ST);

    //  Start the timer.  Also set for auto reload
    SETREG32(&g_pPwmTimer->TCLR, GPTIMER_TCLR_ST);
    while ((INREG32(&g_pPwmTimer->TWPS) & GPTIMER_TWPS_TCLR) != 0);

    OALMSG(1, (L">>>> OALPwmGpt10Init done...\r\n"));
}

----- UART3 trace show GPT10 started but no PWM
>>>> OALPwmGpt10Init device: 5
>>>> device physical address: 0x48086000
>>>> device virtual address: 0xb6086000
>>>> EnableDeviceClocks
>>>> Soft reset GPT10 and wait until finished <<<<
>>>> Turning off GPT10 <<<<
>>>> Set the load register value <<<<
>>>> OALPwmGpt10Init done...

  • This really looks like a pad configuration issue. The line you added to GPIO_PADS in bsp_padcfg.h will be configured in the OEMInit function at OAL initialization (init.c):

     

    static const PAD_INFO gpioPads[] = {GPIO_PADS END_OF_PAD_ARRAY};

    ...

    if (!RequestAndConfigurePadArray(gpioPads)) OALMSG(OAL_ERROR, (TEXT("Failed to request pads for the GPIOs\r\n")));

     

    Can you make sure this code is actually called in your BSP? Have you at least rebuilt the OAL after making this change in bsp_padcfg.h?

  • Also note that GPMC_nCS5 is also configured by GPMC_PADS, which is probably also used by the NAND flash driver. Although there is a reservation mechanism that should protect the NAND driver from chaging the configuration that was made before on this pad, it could be safer to simply remove the following line from GPMC_PADS:

    PAD_ENTRY(GPMC_nCS5,        INPUT_DISABLED | MUXMODE(0))     \

     

  • Hi,

    Thanks for the inputs. I had been made several changes on the pad configuration for my control lines, LEDs, chip selects, etc and the pad configuration works for me.  For the GPT10, I moved GPMC_nCS5 from GPMC_PADS to GPIO_PADS to minize the code changes. My thinking was there would not be any different if the GPMC_nCS5 was configured in GPMC_PADS or GPIO_PADS.  Yes, I did a clean rebuild of the solution. Here are my actual GPMC_PADS and GPIO_PADS. I could not find anywhere in the BSP that is using GPT10 to cause a conflict.  Do you know if GPT10 use anywhere? Thanks.

    #define GPMC_PADS \
        PAD_ENTRY(GPMC_A1,          INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_A2,          INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_A3,          INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_A4,          INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_A5,          INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_A6,          INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_A7,          INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_A8,          INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_A9,          INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_A10,         INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_D0,          INPUT_ENABLED | MUXMODE(0))      \
        PAD_ENTRY(GPMC_D1,          INPUT_ENABLED | MUXMODE(0))      \
        PAD_ENTRY(GPMC_D2,          INPUT_ENABLED | MUXMODE(0))      \
        PAD_ENTRY(GPMC_D3,          INPUT_ENABLED | MUXMODE(0))      \
        PAD_ENTRY(GPMC_D4,          INPUT_ENABLED | MUXMODE(0))      \
        PAD_ENTRY(GPMC_D5,          INPUT_ENABLED | MUXMODE(0))      \
        PAD_ENTRY(GPMC_D6,          INPUT_ENABLED | MUXMODE(0))      \
        PAD_ENTRY(GPMC_D7,          INPUT_ENABLED | MUXMODE(0))      \
        PAD_ENTRY(GPMC_D8,          INPUT_ENABLED | MUXMODE(0))      \
        PAD_ENTRY(GPMC_D9,          INPUT_ENABLED | MUXMODE(0))      \
        PAD_ENTRY(GPMC_D10,         INPUT_ENABLED | MUXMODE(0))      \
        PAD_ENTRY(GPMC_D11,         INPUT_ENABLED | MUXMODE(0))      \
        PAD_ENTRY(GPMC_D12,         INPUT_ENABLED | MUXMODE(0))      \
        PAD_ENTRY(GPMC_D13,         INPUT_ENABLED | MUXMODE(0))      \
        PAD_ENTRY(GPMC_D14,         INPUT_ENABLED | MUXMODE(0))      \
        PAD_ENTRY(GPMC_D15,         INPUT_ENABLED | MUXMODE(0))      \
        PAD_ENTRY(GPMC_nCS0,        INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_nCS1,        INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_nCS2,        INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_nCS3,        INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_nCS7,        INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_CLK,         INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_nADV_ALE,    INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_nOE,         INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_nWE,         INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_nBE0_CLE,    INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_nWP,         INPUT_DISABLED | MUXMODE(0))     \
        PAD_ENTRY(GPMC_WAIT0,       INPUT_ENABLED | MUXMODE(0))      \
        PAD_ENTRY(GPMC_WAIT1,       INPUT_ENABLED | MUXMODE(0))

    #define GPIO_PADS   \
        PAD_ENTRY(GPMC_nCS4,    INPUT_ENABLED | PULL_RESISTOR_ENABLED | PULLUP_RESISTOR | MUXMODE(4)) /* GPIO_55  */    \
        PAD_ENTRY(GPMC_nCS5,    INPUT_DISABLED | PULL_RESISTOR_ENABLED | PULLUP_RESISTOR | MUXMODE(3)) /* sw_out  */    \
        PAD_ENTRY(MCBSP1_FSR,   INPUT_ENABLED | PULL_RESISTOR_ENABLED | PULLUP_RESISTOR | MUXMODE(4)) /* GPIO_157 */    \
        PAD_ENTRY(MCBSP_CLKS,   INPUT_ENABLED | PULL_RESISTOR_ENABLED | PULLUP_RESISTOR | MUXMODE(4)) /* GPIO 160 */    \
        PAD_ENTRY(SYS_NIRQ,     INPUT_ENABLED | PULL_RESISTOR_ENABLED | PULLUP_RESISTOR | MUXMODE(4)) /* GPIO 0   */    \
        PAD_ENTRY(GPMC_WAIT3,   INPUT_ENABLED | PULL_RESISTOR_ENABLED | PULLUP_RESISTOR | MUXMODE(4)) /* GPIO_65  */

  • Please see my previous response.  Thanks,

    Dennis

  • Hi,

    I am hoping to get some more inputs.  My understanding is my pad configuration is correct  for GPMC_nCS5 .  I will attempt to dump the pad configuration for GPMC_nCS5 to make sure.  Please comment assuming the pad configuration is correct.

    Thanks,

    Dennis

  • This still sounds like a pad configuration issue; however, if you say that you removed all references to GPMC_nCS5 except for in GPIO_PADS (and GPIO_PADS is being used in OEMInit(), and was not removed), then this looks like it should work.

    Beyond the pad configuration and pin multiplexing, you might try setting GPO_CFG before enabling the timer. You should also make a call to EnableDeviceClocks for GPTIMER10.

    To verify that the multiplexing is correct, you might try muxing the pin for GPIO and use the GPIO driver to test toggling the output. This would validate that the multiplexing settings are working using a driver that is known to work. Once you verify this, then you will know that the problem is isolated to the timer configuration and usage.

  • Adeneo Embedded support team said:
    you might try setting GPO_CFG before enabling the timer

    Do you mean clearing GPO_CFG (TCLR bit 14) for PWM mode before enabling the timer?

     Thanks,

    Dennis

  • Yes, TCLR[14]. It should already have a reset value of 0 to put it to pwm output mode, I was suggesting you should explicitly set it to 0 again before enabling your timer.

  • I was able to read TCLR, a value of 0, by using INREG32(&g_pPwmTimer->TCLR) after EnableDeviceClocks(). The interesting thing is I followed your suggestion to reset/clear GPO_CFG before EnableDeviceClocks(). I could not.  As the matter of fact, I was not be able to read (INREG32(&g_pPwmTimer->TCLR)) or write (OUTREG32(&g_pPwmTimer->TCLR), 0) to TCLR register. I couldn't reset/clear TCLR[14] with CLRREG32(&g_pPwmTimer->TCLR, (1 << 14)).   According to to technical reference manual, I used the GPT10 TCLR device address 0x48086024 which is mapped to &g_pPwmTimer->TCLR of 0xb6086024. Look like there is a memory access violation when I access  &g_pPwmTimer->TCLR before EnableDeviceClocks().  OEMInit() is just hang in this case.

    Since I posted this issue, I tried all possible ways to resolve this. I made sure the hardware worked and I was able to see PWM from oscilloscope without WinCE/BSP. I did this in 10 lines of code. I made sure I was able to toggle the same GPIO_56 in pad mode 4. That works too. I confirm the GPT10_PWM pad configuration has pad mode 3. My main concern is EnableDeviceClocks() is actually use so many tables point to registers. The device ID is correct but I afraid there is problems in those tables. Have you ever seen GPT10_PWM works?

    Thanks.