/****************************************************************************** Function Name : main Description : Main task Arguments : none Return value : none ******************************************************************************/ void main(void) { lvd_err_t err; lvd_config_t channel1_cfg; channel1_cfg.e_action = LVD_ACTION_RESET; channel1_cfg.e_trigger = LVD_TRIGGER_FALL; channel1_cfg.e_voltage_level =LVD_VOLTAGE_CH1_2_95; err = R_LVD_Open(LVD_CHANNEL_1, &channel1_cfg, NULL); bool ret = false; /* Reserve the CMT0 for FreeRTOS */ ret = R_BSP_HardwareLock((mcu_lock_t)(BSP_LOCK_CMT0)); while (false == ret) /* can't lock the CMT0 resource */ { while (1); } WDT_FEED /* Inicialização das variaveis EEPROM */ eepromInit(); eepromConsistencyCheck(); /* Initialize USB */ usb_main(); /* Initialize RTOS */ FreeRTOSConfig(); /* Start tasks - only returns if something bad happened! */ vTaskStartScheduler(); while (1) { } }
/******************************************************************************* * 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; }
/****************************************************************************** * 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; }
/******************************************************************************* * Function Name: r_dtc_acquire_hw_lock * Description : Gets the hardware lock BSP_LOCK_DTC. * Arguments : None. * Return Value : true - * The lock is acquired successfully * false - * Fails to get the lock *******************************************************************************/ static bool r_dtc_acquire_hw_lock(void) { return R_BSP_HardwareLock(BSP_LOCK_DTC); }
/*********************************************************************************************************************** * 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; }