Exemplo n.º 1
0
/*******************************************************************************
* Function Name: r_dtc_check_DMAC_locking_sw
* Description  : Checks all DMAC channel locking.
* Arguments    : none -
* Return Value : true -
*                    All DMAC channels are unlocked. 
*                false -
*                    One or some DMAC channels are locked.
*******************************************************************************/
static bool r_dtc_check_DMAC_locking_sw(void)
{
    bool ret = true;

#if ((0 != BSP_CFG_USER_LOCKING_ENABLED) || (bsp_lock_t != BSP_CFG_USER_LOCKING_TYPE) \
      || (DTC_ENABLE != DTC_CFG_USE_DMAC_FIT_MODULE))
        /* defined(0 != BSP_CFG_USER_LOCKING_ENABLED) */
        /*  or defined(DTC_ENABLE !=DTC_CFG_USE_DMAC_FIT_MODULE) */
        /*  or defined(bsp_lock_t != BSP_CFG_USER_LOCKING_TYPE) */
        /* User has to do the locking check of DMAC by themselves. */
        ret = r_dtc_check_DMAC_locking_byUSER();
#else
    uint32_t channel;
    uint32_t dmac_lock_num = 0;

    for (channel = 0; channel < DMAC_NUM_CHANNELS; channel++)
    {
        if (false == R_BSP_HardwareLock((mcu_lock_t)(BSP_LOCK_DMAC0 + channel)))
        {
            dmac_lock_num++;
        }
        else
        {
            R_BSP_HardwareUnlock((mcu_lock_t)(BSP_LOCK_DMAC0 + channel));
        }
    }

    if (0 == dmac_lock_num)
    {
        ret = true;
    }
    else
    {
        ret = false;
    }
#endif

    return ret;
}
Exemplo n.º 2
0
/******************************************************************************
* Function Name: adc_open
* Description  : This function applies power to the A/D peripheral, sets the
*                operational mode, trigger sources, interrupt priority, and
*                configurations common to all channels and sensors. If interrupt
*                priority is non-zero, the function takes a callback function
*                pointer for notifying the user at interrupt level whenever a
*                scan has completed.
*
* NOTE: The temperature sensor on the RX210 functionally behaves like a
*       regular software trigger. But instead of using the ADST bit, it has its
*       own PGAEN bit. For this bit to work, you must also have TRSA=0x0A,
*       TRGE=1, MSTP(TEMPS)=0, and TSEN=1.
*       The ADST bit will work with this configuration and will also work with
*       just MSTP(TEMPS)=0 and TSEN=1. However, the value read does not include
*       the temperature sensor gain value. This behavior is not documented in
*       the HW Manual, and accuracy is unknown.
*       Because of this, and portability concerns, the driver API is written
*       to look like the temp sensor runs on a normal software trigger.
*
*       -Gain values will always be read.
*       -ADST could be used to check for scan complete when using PGAEN.
*
* Arguments    : mode-
*                    Operational mode (see enumeration below)
*                p_cfg-
*                    Pointer to configuration structure (see below)
*                p_callback-
*                    Optional pointer to function called from interrupt when
*                    a scan completes
* Return Value : ADC_SUCCESS-
*                    Successful
*                ADC_ERR_AD_LOCKED-
*                    Open() call is in progress elsewhere
*                ADC_ERR_AD_NOT_CLOSED-
*                    Peripheral is still running in another mode; Perform
*                    R_ADC_Close() first
*                ADC_ERR_INVALID_ARG-
*                    mode or element of p_cfg structure has invalid value.
*                ADC_ERR_ILLEGAL_ARG-
*                    an argument is illegal based upon mode
*                ADC_ERR_MISSING_PTR-
*                    p_cfg pointer is FIT_NO_PTR/NULL
*******************************************************************************/
adc_err_t adc_open(adc_mode_t const       mode,
                   adc_cfg_t * const      p_cfg,
                   void         (* const  p_callback)(void *p_args))
{


#if ADC_CFG_PARAM_CHECKING_ENABLE == 1
    if ((p_cfg == NULL) || (p_cfg == FIT_NO_PTR))
    {
        return ADC_ERR_MISSING_PTR;
    }

    /* Check for valid argument values */
    if ((mode >= ADC_MODE_MAX)
     || ((p_cfg->trigger >= ADC_TRIG_HW_MAX) && (p_cfg->trigger != ADC_TRIG_SOFTWARE))
     || (p_cfg->priority > BSP_MCU_IPL_MAX)
     || (p_cfg->add_cnt >= ADC_ADD_MAX)
     || (p_cfg->trigger == ADC_TRIG_PLACEHOLDER)
     || ((p_cfg->clearing != ADC_CLEAR_AFTER_READ_OFF) && (p_cfg->clearing != ADC_CLEAR_AFTER_READ_ON)))

    {
        return ADC_ERR_INVALID_ARG;
    }

    /* If interrupt driven, must have callback function */
    if ((p_cfg->priority != 0)
     && ((p_callback == NULL) || (p_callback == FIT_NO_FUNC)))
    {
        return ADC_ERR_ILLEGAL_ARG;
    }

    if (p_cfg->add_cnt == ADC_ADD_OFF)
    {
        /* Check alignment values only if addition is off */
        if ((p_cfg->alignment != ADC_ALIGN_LEFT) && (p_cfg->alignment != ADC_ALIGN_RIGHT))
        {
            return ADC_ERR_INVALID_ARG;
        }
    }
    else // addition on
    {
        /* Addition not allowed with temperature sensor on RX210 */
        if (mode == ADC_MODE_SS_TEMPERATURE)
        {
            return ADC_ERR_ILLEGAL_ARG;
        }
    }

    /* For portability, only allow software trigger because that is the functional
     * behavior of the sensor. Will map to actual "synchronous temperature trigger"
     * (0x0A) later. */
    if ((mode == ADC_MODE_SS_TEMPERATURE) && (p_cfg->trigger != ADC_TRIG_SOFTWARE))
    {
        return ADC_ERR_ILLEGAL_ARG;
    }


    /* In double trigger mode, SW and async triggers not allowed */
    if ((mode == ADC_MODE_SS_ONE_CH_DBLTRIG)
     && ((p_cfg->trigger == ADC_TRIG_SOFTWARE) || (p_cfg->trigger == ADC_TRIG_ASYNC_ADTRG0)))
    {
        return ADC_ERR_ILLEGAL_ARG;
    }

    /* Group checking; only synchronous triggers allowed; must be unique */
    if ((mode == ADC_MODE_SS_MULTI_CH_GROUPED) || (mode == ADC_MODE_SS_MULTI_CH_GROUPED_DBLTRIG_A))
    {
        if ((p_cfg->trigger == ADC_TRIG_ASYNC_ADTRG0)
         || (p_cfg->trigger_groupb == ADC_TRIG_ASYNC_ADTRG0)
         || (p_cfg->trigger_groupb == ADC_TRIG_PLACEHOLDER)
         || (p_cfg->trigger == p_cfg->trigger_groupb)
         || (p_cfg->trigger == ADC_TRIG_SOFTWARE)
         || (p_cfg->trigger_groupb == ADC_TRIG_SOFTWARE))
        {
            return ADC_ERR_ILLEGAL_ARG;
        }

        if ((p_cfg->priority_groupb > BSP_MCU_IPL_MAX)
         || (p_cfg->trigger >= ADC_TRIG_HW_MAX)
         || (p_cfg->trigger_groupb >= ADC_TRIG_HW_MAX))
        {
            return ADC_ERR_INVALID_ARG;
        }

        if ((p_cfg->priority_groupb != 0)   // interrupt driven; must have callback func
         && ((p_callback == NULL) || (p_callback == FIT_NO_FUNC)))
        {
            return ADC_ERR_ILLEGAL_ARG;
        }
    }
#endif // parameter checking


    if (g_dcb.opened == true)
    {
        return ADC_ERR_AD_NOT_CLOSED;
    }
    if (R_BSP_HardwareLock(BSP_LOCK_S12AD) == false)
    {
        return ADC_ERR_AD_LOCKED;
    }


    /* APPLY POWER TO PERIPHERAL */

    R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_LPC_CGC_SWR);
    MSTP(S12AD) = 0;
    if (mode == ADC_MODE_SS_TEMPERATURE)
    {
        MSTP(TEMPS) = 0;
    }
    R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_LPC_CGC_SWR);

    S12AD.ADCSR.WORD = 0;
    S12AD.ADEXICR.WORD = 0;
    TEMPS.TSCR.BYTE = 0;


    /* SET MODE RELATED REGISTER FIELDS */

    g_dcb.mode = mode;
    if ((mode == ADC_MODE_SS_MULTI_CH_GROUPED)
     || (mode == ADC_MODE_SS_MULTI_CH_GROUPED_DBLTRIG_A))
    {
        S12AD.ADCSR.BIT.ADCS = ADC_ADCS_GROUP_SCAN;
    }
    else
    {
        if ((mode == ADC_MODE_CONT_ONE_CH) || (mode == ADC_MODE_CONT_MULTI_CH))
        {
            S12AD.ADCSR.BIT.ADCS = ADC_ADCS_CONT_SCAN;
        }
        // other modes have ADCS=0
    }

    if ((mode == ADC_MODE_SS_ONE_CH_DBLTRIG)
     || (mode == ADC_MODE_SS_MULTI_CH_GROUPED_DBLTRIG_A))
    {
        S12AD.ADCSR.BIT.DBLE = 1;                   // enable double trigger
    }


    /* SET TRIGGER AND INTERRUPT PRIORITY REGISTER FIELDS */

    if (mode == ADC_MODE_SS_TEMPERATURE)
    {
        S12AD.ADSTRGR.BIT.TRSA = 0x0A;  // synchronous temperature trigger
    }
    if (p_cfg->trigger != ADC_TRIG_SOFTWARE)
    {
        S12AD.ADSTRGR.BIT.TRSA = p_cfg->trigger;
    }
    if (p_cfg->trigger == ADC_TRIG_ASYNC_ADTRG0)
    {
        S12AD.ADCSR.BIT.EXTRG = 1;      // set ext trigger for async trigger
    }
    if (S12AD.ADCSR.BIT.ADCS == ADC_ADCS_GROUP_SCAN)
    {
        S12AD.ADSTRGR.BIT.TRSB = p_cfg->trigger_groupb;
        IPR(S12AD,GBADI) = p_cfg->priority_groupb;
    }
    IPR(S12AD,S12ADI0) = p_cfg->priority;


    /* SET REGISTER FIELDS FOR REMAINING PARAMETERS */

    S12AD.ADADC.BIT.ADC = p_cfg->add_cnt;
    S12AD.ADCER.WORD = (uint16_t) (p_cfg->alignment | p_cfg->clearing);

    /* SAVE CALLBACK FUNCTION POINTER */
    g_dcb.callback = p_callback;


    /* MARK DRIVER AS OPENED */
    g_dcb.opened = true;
    R_BSP_HardwareUnlock(BSP_LOCK_S12AD);

    return ADC_SUCCESS;
}
Exemplo n.º 3
0
/*******************************************************************************
* Function Name: r_dtc_release_hw_lock
* Description  : release hardware lock BSP_LOCK_DTC.
* Arguments    : None.
* Return Value : None.
*******************************************************************************/
static void r_dtc_release_hw_lock(void)
{
    R_BSP_HardwareUnlock(BSP_LOCK_DTC);
    return;
}
Exemplo n.º 4
0
/***********************************************************************************************************************
* Function Name: R_MTU_Control
* Description  : This function is responsible for handling special hardware or software operations for the MTU channel.
* Arguments    : channel-
*                   The channel number
*                cmd
*                   Enumerated command code
*                pcmd_data
*                   Pointer to the command-data structure parameter of type void that is used to reference the location
*                   of any data specific to the command that is needed for its completion.
* Return Value : MTU_SUCCESS-
*                   Command successfully completed.
*                MTU_TIMERS_ERR_CH_NOT_OPEN-
*                   The channel has not been opened.  Perform R_MTU_Open() first
*                MTU_TIMERS_ERR_BAD_CHAN-
*                   Channel number is invalid for part
*                MTU_TIMERS_ERR_UNKNOWN_CMD-
*                   Control command is not recognized.
*                MTU_TIMERS_ERR_NULL_PTR-
*                   pcmd_data  pointer or handle is NULL
*                MTU_TIMERS_ERR_INVALID_ARG-
*                   An element of the pcmd_data structure contains an invalid value.
*                MTU_TIMERS_ERR_LOCK-
*                      The lock could not be acquired. The channel is busy.
***********************************************************************************************************************/
mtu_err_t  R_MTU_Control (mtu_channel_t channel,
                          mtu_cmd_t     cmd,
                          void          *pcmd_data)
{
    mtu_capture_status_t * p_capture_data;
    mtu_timer_status_t   * p_timer_data;
    mtu_group_t    * p_group_data;
    mtu_capture_set_edge_t  * p_cap_edge_data;
    uint8_t temp_byte;

    /* Command function data structure definitions. One for each command in mtu_timer_cmd_t. */
    #if MTU_CFG_REQUIRE_LOCK == 1
    bool        lock_result = false;
    #endif

    mtu_handle_t  my_handle;
    mtu_timer_chnl_settings_t *pconfig; // Store a pointer to the user's config structure.

    #if MTU_CFG_PARAM_CHECKING_ENABLE == 1
    if (MTU_CHANNEL_MAX <= channel)   // First check for channel number out of range
    {
        return MTU_ERR_BAD_CHAN;
    }

    switch(cmd) /* Check for valid command and data. */
    {
        case MTU_CMD_START:
        case MTU_CMD_STOP:
        case MTU_CMD_SAFE_STOP:
        case MTU_CMD_RESTART:
        case MTU_CMD_CLEAR_EVENTS:
        break;

        case MTU_CMD_GET_STATUS:
        case MTU_CMD_SYNCHRONIZE:
        case MTU_CMD_SET_CAPT_EDGE:
            if ((NULL == pcmd_data) || (FIT_NO_PTR == pcmd_data))
            {
                return MTU_ERR_NULL_PTR;
            }
        break;

        default:
        {
           /* Error, command not recognized. */
           return MTU_ERR_UNKNOWN_CMD;
        }
    }

    if (!g_mtu_channel_mode[channel])
    {
        return MTU_ERR_CH_NOT_OPENED;
    }
    #endif

    #if MTU_CFG_REQUIRE_LOCK == 1
    /* Attempt to acquire lock for this MTU channel. Prevents reentrancy conflict. */
    lock_result = R_BSP_HardwareLock((mcu_lock_t)(BSP_LOCK_MTU0 + channel));

    if(false == lock_result)
    {
        return MTU_ERR_LOCK; /* The control function is currently locked. */
    }
    #endif

    my_handle = g_mtu_handles[channel];

    pconfig = my_handle->p_mtu_chnl_tmr_settings;

    switch(cmd)
    {
        case MTU_CMD_START:       // Activate clocking
        {
            if ((NULL != pcmd_data) && (FIT_NO_PTR != pcmd_data)) // A channel group specifier was provided
            {
                p_group_data =  (mtu_group_t *)pcmd_data;

                temp_byte = (uint8_t) *p_group_data;

                if(!mtu_check_group(temp_byte) || (temp_byte & ~MTU_TSTR_MASK)) // Error in group parameter.
                {
                    #if MTU_CFG_REQUIRE_LOCK == 1
                    R_BSP_HardwareUnlock((mcu_lock_t)(BSP_LOCK_MTU0 + channel));
                    #endif
                    return MTU_ERR_INVALID_ARG;
                }

                mtu_interrupts_group_enable(temp_byte);
                MTU.TSTR.BYTE = temp_byte;  //Set the start bits for the group.
            }
            else    // Just this channel.
            {
                mtu_interrupts_enable(channel);
                MTU.TSTR.BYTE |= g_mtu_tstr_bits[channel];
            }
        }
        break;

        case MTU_CMD_STOP:       // Pause clocking
        {
            if ((NULL != pcmd_data) && (FIT_NO_PTR != pcmd_data)) // A channel group specifier was provided
            {
                p_group_data =  (mtu_group_t *)pcmd_data;

                temp_byte = (uint8_t) *p_group_data;
                temp_byte &= MTU_TSTR_MASK; // Protect reserved TSTR bits.

                if(!mtu_check_group(temp_byte) || (temp_byte & ~MTU_TSTR_MASK)) // Error in group parameter.
                {
                    #if MTU_CFG_REQUIRE_LOCK == 1
                    R_BSP_HardwareUnlock((mcu_lock_t)(BSP_LOCK_MTU0 + channel));
                    #endif
                    return MTU_ERR_INVALID_ARG;
                }

                mtu_interrupts_group_disable(temp_byte);
                MTU.TSTR.BYTE &= (~temp_byte);  // clear the start bits for this group.
            }
            else    // Just this channel.
            {
                mtu_interrupts_disable(channel);
                MTU.TSTR.BYTE &= (uint8_t)(~(g_mtu_tstr_bits[channel]));
            }
        }
        break;

        case MTU_CMD_SAFE_STOP:   // Stop clocking and set outputs to safe state
        {
            // First stop the clocking.
            MTU.TSTR.BYTE &= (uint8_t)(~(g_mtu_tstr_bits[channel]));
            // Now re-write the TIOR register to revert to 'initial' MTIOC output state.
            if((0 != pconfig->timer_a.freq) && (MTU_ACTION_OUTPUT & pconfig->timer_a.actions.do_action))
            {
                *my_handle->regs.tiorh |= pconfig->timer_a.actions.output;  // Set bits in lower nibble
            }
            if((0 != pconfig->timer_b.freq) && (MTU_ACTION_OUTPUT & pconfig->timer_b.actions.do_action))
            {
                *my_handle->regs.tiorh |=  (pconfig->timer_b.actions.output << 4); // Move bits to upper nibble
            }
            if((0 != pconfig->timer_c.freq) && (MTU_ACTION_OUTPUT & pconfig->timer_c.actions.do_action))
            {
                *my_handle->regs.tiorl |= pconfig->timer_c.actions.output;  // Set bits in lower nibble
            }
            if((0 != pconfig->timer_d.freq) && (MTU_ACTION_OUTPUT & pconfig->timer_d.actions.do_action))
            {
                *my_handle->regs.tiorl |=  (pconfig->timer_d.actions.output << 4); // Move bits to upper nibble
            }

        }
        break;

        case MTU_CMD_RESTART:      // Zero the counter then resume clocking
        {
            *my_handle->regs.tcnt = 0;                 // Clear the counter TCNT register.
            mtu_interrupts_enable(channel);
            MTU.TSTR.BYTE |= g_mtu_tstr_bits[channel]; // Start counting.
        }
        break;

        case MTU_CMD_GET_STATUS:   // Retrieve the current status of the channel
        {
            if (MTU_MODE_COMPARE_MATCH == g_mtu_channel_mode[channel])
            {
                /* Copy void pcmd_data pointer over to a concrete type. */
                p_timer_data =  (mtu_timer_status_t *)pcmd_data;
                /* Return timer status to application */
                p_timer_data->timer_running = (bool)(MTU.TSTR.BYTE & g_mtu_tstr_bits[channel]); // Running status
                p_timer_data->timer_count = *my_handle->regs.tcnt;    // The current timer count value.
            }
            else if  (MTU_MODE_INPUT_CAPTURE == g_mtu_channel_mode[channel])
            {
                /* Cast void pcmd_data pointer to a concrete type. */
                p_capture_data =  (mtu_capture_status_t *)pcmd_data;

                /* Return a snapshot of TGR capture interrupts that have fired. */
                p_capture_data->capture_flags = mtu_interrupts_check(channel);

                p_capture_data->timer_count = *my_handle->regs.tcnt;    // The current timer count value.

                /* Grab the TGR register values. */
                p_capture_data->capt_a_count = *my_handle->regs.tgra;
                p_capture_data->capt_b_count = *my_handle->regs.tgrb;
                /* Not all channels have TGRC and TGRD */
                if (NULL != my_handle->regs.tgrc)
                {
                    p_capture_data->capt_c_count = *my_handle->regs.tgrc;
                }
                else
                {
                    p_capture_data->capt_c_count = 0;
                }
                if (NULL != my_handle->regs.tgrd)
                {
                    p_capture_data->capt_d_count = *my_handle->regs.tgrd;
                }
                else
                {
                    p_capture_data->capt_d_count = 0;
                }
            }
        }
        break;

        case MTU_CMD_CLEAR_EVENTS:      // Clears the interrupt flags for the channel
        {
            mtu_interrupts_clear(channel);
        }
        break;

        case MTU_CMD_SET_CAPT_EDGE:      // Set the detection edge polarity for input capture.
        {
            if  (MTU_MODE_INPUT_CAPTURE == g_mtu_channel_mode[channel])
            {
                 /* Cast void pcmd_data pointer to a concrete type. */
                p_cap_edge_data =  (mtu_capture_set_edge_t *)pcmd_data;

                if ((MTU_CHANNEL_1 == channel) || (MTU_CHANNEL_2 == channel))
                {
                    if((MTU_CAP_SRC_C == p_cap_edge_data->capture_src) || (MTU_CAP_SRC_D == p_cap_edge_data->capture_src))
                    {
                        #if MTU_CFG_REQUIRE_LOCK == 1
                        R_BSP_HardwareUnlock((mcu_lock_t)(BSP_LOCK_MTU0 + channel));
                        #endif
                        return MTU_ERR_INVALID_ARG; // Resource not present on these channels.
                    }
                }
                switch (p_cap_edge_data->capture_src)
                {
                    case MTU_CAP_SRC_A:
                    {
                        *my_handle->regs.tiorl &= 0xF0;                           // First clear the lower nibble.
                        *my_handle->regs.tiorh |= p_cap_edge_data->capture_edge;  // Set bits in lower nibble
                    }
                    break;
                    case MTU_CAP_SRC_B:
                    {
                        *my_handle->regs.tiorl &= 0x0F;                                  // First clear the upper nibble.
                        *my_handle->regs.tiorh |=  (p_cap_edge_data->capture_edge << 4); // Move bits to upper nibble
                    }
                    break;
                    case MTU_CAP_SRC_C:
                    {
                        *my_handle->regs.tiorl &= 0xF0;                           // First clear the lower nibble.
                        *my_handle->regs.tiorl |= p_cap_edge_data->capture_edge;  // Set bits in lower nibble
                    }
                    break;
                    case MTU_CAP_SRC_D:
                    {
                        *my_handle->regs.tiorl &= 0x0F;                                   // First clear the upper nibble.
                        *my_handle->regs.tiorl |= (p_cap_edge_data->capture_edge << 4);   // Move bits to upper nibble
                    }
                    break;
                }
            }
            else    // Command not valid for this mode.
            {
                #if MTU_CFG_REQUIRE_LOCK == 1
                R_BSP_HardwareUnlock((mcu_lock_t)(BSP_LOCK_MTU0 + channel));
                #endif
                return MTU_ERR_INVALID_ARG;
            }

        }
        break;

        case MTU_CMD_SYNCHRONIZE:
        {
            /* Copy void pcmd_data pointer over to a concrete type. */
            p_group_data =  (mtu_group_t *)pcmd_data;

            temp_byte = (uint8_t) *p_group_data;
            temp_byte &= MTU_TSYR_MASK; // Protect reserved TSYR bits.

            if(!mtu_check_group(temp_byte))
            {
                #if MTU_CFG_REQUIRE_LOCK == 1
                R_BSP_HardwareUnlock((mcu_lock_t)(BSP_LOCK_MTU0 + channel));
                #endif
                return MTU_ERR_INVALID_ARG;
            }

            MTU.TSYR.BYTE = temp_byte;  //Set the SYNCn 0-4 bits.
        }
        break;

        default:
        {
            //Nothing -- unreachable.
        }
    }

    #if MTU_CFG_REQUIRE_LOCK == 1
    R_BSP_HardwareUnlock((mcu_lock_t)(BSP_LOCK_MTU0 + channel));
    #endif

    return MTU_SUCCESS;
}