Example #1
0
static inline int __attribute__((always_inline)) read_lradc(int src)
{
    BF_CLR(LRADC_CTRL1, LRADCx_IRQ(src));
    BF_SETV(LRADC_CTRL0, SCHEDULE, 1 << src);
    while(!BF_RD(LRADC_CTRL1, LRADCx_IRQ(src)));
    return BF_RDn(LRADC_CHn, src, VALUE);
}
Example #2
0
struct imx233_timrot_info_t imx233_timrot_get_info(unsigned timer_nr)
{
    struct imx233_timrot_info_t info;
    memset(&info, 0, sizeof(info));
    info.src = BF_RDn(TIMROT_TIMCTRLn, timer_nr, SELECT);
    info.prescale = BF_RDn(TIMROT_TIMCTRLn, timer_nr, PRESCALE);
    info.reload = BF_RDn(TIMROT_TIMCTRLn, timer_nr, RELOAD);
    info.polarity = BF_RDn(TIMROT_TIMCTRLn, timer_nr, POLARITY);
    info.fixed_count = BF_RDn(TIMROT_TIMCOUNTn, timer_nr, FIXED_COUNT);
    info.run_count = BF_RDn(TIMROT_TIMCOUNTn, timer_nr, RUNNING_COUNT);
    return info;
}
Example #3
0
struct imx233_pwm_info_t imx233_pwm_get_info(int channel)
{
#define ENTRY(mode, name, val) [BV_PWM_PERIODn_##mode##_STATE__##name] = val
    static char active_state[] =
    {
        ENTRY(ACTIVE, 0, '0'), ENTRY(ACTIVE, 1, '1'), ENTRY(ACTIVE, HI_Z, 'Z')
    };
    static char inactive_state[] =
    {
        ENTRY(INACTIVE, 0, '0'), ENTRY(INACTIVE, 1, '1'), ENTRY(INACTIVE, HI_Z, 'Z')
    };
#undef ENTRY
    struct imx233_pwm_info_t info;
    memset(&info, 0, sizeof(info));
    info.enabled = imx233_pwm_is_enabled(channel);
    info.cdiv = pwm_cdiv_table[BF_RDn(PWM_PERIODn, channel, CDIV)];
    info.period = BF_RDn(PWM_PERIODn, channel, PERIOD) + 1;
    info.active = BF_RDn(PWM_ACTIVEn, channel, ACTIVE);
    info.inactive = BF_RDn(PWM_ACTIVEn, channel, INACTIVE);
    info.active_state = active_state[BF_RDn(PWM_PERIODn, channel, ACTIVE_STATE)];
    info.inactive_state = inactive_state[BF_RDn(PWM_PERIODn, channel, INACTIVE_STATE)];
    return info;
}
Example #4
0
int gpmi_wait_for_dma(uint32_t u32usec, uint32_t chipSelect)
{
    reg32_t     r32ChipDmaNumber = NAND0_APBH_CH; // + chipSelect;
    bool        bTimedOut = FALSE;
    int  rtStatus = SUCCESS;

#if 1 //def RTOS_THREADX
    // Wait for the IRQ to unlock the spinlock.
    int lockResult = spinlock_lock(&g_gpmi.dmaInfo.irqSpinlock, u32usec);

    // Note that, in the RTOS_THREADX case, SEMA.PHORE register can easily be nonzero if the CPU is running fast.
    // (The DMA engine can trigger the ISR at the end of the DMA, before decrementing
    // the SEMA.PHORE count, thus creating a race condition that lets us find a
    // nonzero SEMA.PHORE value here.)
    //
    // Since SEMA.PHORE can still be nonzero, we cannot use it as
    // evidence of timeout.  We have to rely on the RTOS timeout indicator.
    bTimedOut = (lockResult != 0); //( TX_SUCCESS != retCode_tx_semaphore );

#else   // RTOS_THREADX not defined
    // Poll for DMA completion.
    {
        uint64_t u64StartTime;

        // Microsecond read - always read at start of transaction so that if
        // ThreadX times out, that time is included in the overall timeout time.
        u64StartTime = g_gpmi.dmaInfo.uStartDMATime;

        // End of DMA chain will decrement the hardware semaphore.  Poll the hardware semaphore for
        // DMA completion.
        do {
            i32Sema = HW_APBH_CHn_SEMA_RD(r32ChipDmaNumber) & BM_APBH_CHn_SEMA_PHORE;
        } while ((i32Sema != 0) && ( (hw_profile_GetMicroseconds() - u64StartTime) < u32usec));
    }

    // Re-read the hardware semaphore in case a higher-priority thread caused the timeout between semaphore
    // and timeout test.
    i32Sema = HW_APBH_CHn_SEMA_RD(r32ChipDmaNumber) & BM_APBH_CHn_SEMA_PHORE;

    bTimedOut = (0 != i32Sema);
    
#endif  // ifdef RTOS_THREADX

    //
    // If timeout: return error,
    //       else: return BAR field from last DMA command
    //

    if ( bTimedOut )
    {
        // The DMA has not completed within the alotted time.
        //
        // Clean up.

        //! @todo Since we don't know exactly what caused the timeout, it 
        //! could be beneficial to also reset the GPMI block here.
        //! Note, however, that soft-resetting the GPMI block changes
        //! its register settings.  Thus, it would also be necessary to
        //! re-initialize the GPMI settings completely.  Otherwise the
        //! GPMI may not work.

        // abort dma by resetting channel
//         BW_APBH_CHANNEL_CTRL_RESET_CHANNEL(1 << r32ChipDmaNumber);
//         
//         // Wait for the reset to complete
//         while ( HW_APBH_CHANNEL_CTRL.B.RESET_CHANNEL & (0x1 << r32ChipDmaNumber) )
//         {
//             ;
//         }
// 
//         //
//         // Okay, this is important.
//         // When we read from the NAND using GPMI with ECC,
//         // there will be an ECC interrupt upon completion of the ECC correction.
//         // Thereafter, these actions must happen in sequence:
//         //     1.  ECC status must be read.
//         //     2.  ECC ISR must be reenabled.
//         //     3.  ECC-completion must be cleared, which frees the ECC
//         //         block to process the next data.
//         // The status must be read before the ECC-completion is cleared, or
//         // the next ECC cycle will overwrite the status.  In the case of a
//         // successful DMA and ECC, the code that reads the ECC status
//         // also performs steps 2 and 3.
//         // 
//         // Q:  What happens if the DMA times-out for some reason?
//         // A:  Somebody may have to clean-up by using steps 2 and 3.
//         //     That somebody is us.
//         //
// 
//         // If there was an ECC-completion expected...
//         if (kNandGpmiDmaWaitMask_Ecc & g_gpmi.dmaInfo.u16DmaWaitMask)
//         {
//             // ...then we have to clear the ECC-completion and the ECC circuit.
// 
//             // It is not necessary to reset the BCH block after an "uncorrectable" error.
//             // In fact, due to a 378x chip bug it is not possible to reset the
//             // BCH block after it has been used to transfer data.
// 
//             // Clear the ECC-completion.
//             gpmi_clear_ecc_isr_enable( );
//         }

        rtStatus = ERROR_DDI_NAND_GPMI_DMA_TIMEOUT;
    }
    else
    {
        // The DMA descriptor chain was set up with the alternate meaning
        // of the BAR register.  Rather than containing an
        // address at this point, it contains a return-code that indicates whether
        // the "success" or "failure" part of the chain executed last.
        // So, here we get that return code.
        rtStatus = (int)BF_RDn(APBH_CHn_BAR, r32ChipDmaNumber, ADDRESS);
    }

    return rtStatus;
}
Example #5
0
////////////////////////////////////////////////////////////////////////////////
//! See hw_lradc.h for details.
////////////////////////////////////////////////////////////////////////////////
bool hw_lradc_GetToggleFlag(hw_lradc_Channel_t eChannel)
{
    // Return the TOGGLE flag of a LRADC channel
    return ((bool)(BF_RDn(LRADC_CHn, eChannel, TOGGLE)));
}