/* * The MIT License (MIT) * * Copyright (c) 2023 Vekatech Ltd. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ /* FSP has available API for PWM (r_gpt) R_GPT_Open ( ... ) R_GPT_Stop ( ... ) R_GPT_Start ( ... ) R_GPT_Reset ( ... ) R_GPT_Enable ( ... ) R_GPT_Disable ( ... ) R_GPT_PeriodSet ( ... ) R_GPT_DutyCycleSet ( ... ) R_GPT_InfoGet ( ... ) R_GPT_StatusGet ( ... ) R_GPT_CounterSet ( ... ) R_GPT_OutputEnable ( ... ) R_GPT_OutputDisable ( ... ) R_GPT_AdcTriggerSet ( ... ) R_GPT_CallbackSet ( ... ) R_GPT_Close ( ... ) and this is (The Lazy way) ... but looking to other drivers implementation (for example AGT [ra_timer.c/h]), Renesas want to be hard, so ... (The Hard way it is) */ #include "hal_data.h" #include "ra_config.h" #include "ra_gpio.h" #include "ra_sci.h" // #include "ra_int.h" #include "ra_utils.h" #include "ra_gpt.h" #if defined(RA4M1) #define GPT_CH_SIZE 8 #define CH_GAP 0 #elif defined(RA4W1) #define GPT_CH_SIZE 9 #define CH_GAP (ch == 6) || (ch == 7) #elif defined(RA6M1) #define GPT_CH_SIZE 13 #define CH_GAP 0 #elif defined(RA6M2) || defined(RA6M3) #define GPT_CH_SIZE 14 #define CH_GAP 0 #elif defined(RA6M5) #define GPT_CH_SIZE 10 #define CH_GAP 0 #else #error "CMSIS MCU Series is not specified." #endif enum GPT_SOURCE { GPT_PCLKD = 0, GPT_PCLKD4, GPT_PCLKD16, GPT_PCLKD64, GPT_PCLKD256, GPT_PCLKD1024 }; static R_GPT0_Type *gpt_regs[GPT_CH_SIZE] = { #if defined(RA4M1) R_GPT0, // GPT320 General PWM Timer 0 (32-bit) R_GPT1, // GPT321 General PWM Timer 1 (32-bit) R_GPT2, // GPT162 General PWM Timer 2 (16-bit) R_GPT3, // GPT163 General PWM Timer 3 (16-bit) R_GPT4, // GPT164 General PWM Timer 4 (16-bit) R_GPT5, // GPT165 General PWM Timer 5 (16-bit) R_GPT6, // GPT166 General PWM Timer 6 (16-bit) R_GPT7, // GPT167 General PWM Timer 7 (16-bit) #elif defined(RA4W1) R_GPT0, // GPT320 General PWM Timer 0 (32-bit) R_GPT1, // GPT321 General PWM Timer 1 (32-bit) R_GPT2, // GPT322 General PWM Timer 2 (32-bit) R_GPT3, // GPT323 General PWM Timer 3 (32-bit) R_GPT4, // GPT164 General PWM Timer 4 (16-bit) R_GPT5, // GPT165 General PWM Timer 5 (16-bit) NULL, // N/A PWM Timer 6 (Does not exist) NULL, // N/A PWM Timer 7 (Does not exist) R_GPT8 // GPT168 General PWM Timer 8 (16-bit) #elif defined(RA6M1) || defined(RA6M2) || defined(RA6M3) R_GPT0, // GPT32EH0 General PWM Timer 0 (32-bit) R_GPT1, // GPT32EH1 General PWM Timer 1 (32-bit) R_GPT2, // GPT32EH2 General PWM Timer 2 (32-bit) R_GPT3, // GPT32EH3 General PWM Timer 3 (32-bit) R_GPT4, // GPT32E4 General PWM Timer 4 (32-bit) R_GPT5, // GPT32E5 General PWM Timer 5 (32-bit) R_GPT6, // GPT32E6 General PWM Timer 6 (32-bit) R_GPT7, // GPT32E7 General PWM Timer 7 (32-bit) R_GPT8, // GPT328 General PWM Timer 8 (32-bit) R_GPT9, // GPT329 General PWM Timer 9 (32-bit) R_GPT10, // GPT3210 General PWM Timer 10 (32-bit) R_GPT11, // GPT3211 General PWM Timer 11 (32-bit) R_GPT12, // GPT3212 General PWM Timer 12 (32-bit) #if defined(RA6M2) || defined(RA6M3) R_GPT13, // GPT3213 General PWM Timer 13 (32-bit) #endif #elif defined(RA6M5) R_GPT0, // GPT320 General PWM Timer 0 (32-bit) R_GPT1, // GPT321 General PWM Timer 1 (32-bit) R_GPT2, // GPT322 General PWM Timer 2 (32-bit) R_GPT3, // GPT323 General PWM Timer 3 (32-bit) R_GPT4, // GPT164 General PWM Timer 4 (16-bit) R_GPT5, // GPT165 General PWM Timer 5 (16-bit) R_GPT6, // GPT166 General PWM Timer 6 (16-bit) R_GPT7, // GPT167 General PWM Timer 7 (16-bit) R_GPT8, // GPT168 General PWM Timer 8 (16-bit) R_GPT9, // GPT169 General PWM Timer 9 (16-bit) #else #error "CMSIS MCU Series is not specified." #endif }; #define GPT_TMR_PINS_SIZE sizeof(ra_gpt_timer_pins) / sizeof(ra_af_pin_t) static const ra_af_pin_t ra_gpt_timer_pins[] = { #if defined(RA4M1) { AF_GPT2, 0, P107 }, { AF_GPT2, 0, P213 }, { AF_GPT2, 0, P300 }, { AF_GPT2, 0, P415 }, // GTIOC0A { AF_GPT2, 0, P106 }, { AF_GPT2, 0, P108 }, { AF_GPT2, 0, P212 }, { AF_GPT2, 0, P414 }, // GTIOC0B { AF_GPT2, 1, P105 }, { AF_GPT2, 1, P109 }, { AF_GPT2, 1, P405 }, // GTIOC1A { AF_GPT2, 1, P104 }, { AF_GPT2, 1, P110 }, { AF_GPT2, 1, P406 }, // GTIOC1B { AF_GPT2, 2, P103 }, { AF_GPT2, 2, P113 }, { AF_GPT2, 2, P500 }, // GTIOC2A { AF_GPT2, 2, P102 }, { AF_GPT2, 2, P114 }, { AF_GPT2, 2, P501 }, // GTIOC2B { AF_GPT2, 3, P111 }, { AF_GPT2, 3, P403 }, // GTIOC3A { AF_GPT2, 3, P112 }, { AF_GPT2, 3, P404 }, { AF_GPT2, 3, P502 }, // GTIOC3B { AF_GPT2, 4, P115 }, { AF_GPT2, 4, P205 }, { AF_GPT2, 4, P302 }, // GTIOC4A { AF_GPT2, 4, P204 }, { AF_GPT2, 4, P301 }, { AF_GPT2, 4, P608 }, // GTIOC4B { AF_GPT2, 5, P101 }, { AF_GPT2, 5, P203 }, { AF_GPT2, 5, P409 }, { AF_GPT2, 5, P609 }, // GTIOC5A { AF_GPT2, 5, P100 }, { AF_GPT2, 5, P202 }, { AF_GPT2, 5, P408 }, { AF_GPT2, 5, P610 }, // GTIOC5B { AF_GPT2, 6, P400 }, { AF_GPT2, 6, P411 }, { AF_GPT2, 6, P601 }, // GTIOC6A { AF_GPT2, 6, P401 }, { AF_GPT2, 6, P410 }, { AF_GPT2, 6, P600 }, // GTIOC6B { AF_GPT2, 7, P304 }, { AF_GPT2, 7, P603 }, // GTIOC7A { AF_GPT2, 7, P303 }, { AF_GPT2, 7, P602 }, // GTIOC7B #elif defined(RA4W1) { AF_GPT2, 0, P213 }, { AF_GPT2, 0, P300 }, // GTIOC0A { AF_GPT2, 0, P108 }, { AF_GPT2, 0, P212 }, { AF_GPT2, 0, P414 }, // GTIOC0B { AF_GPT2, 1, P105 }, { AF_GPT2, 1, P109 }, // GTIOC1A { AF_GPT2, 1, P104 }, { AF_GPT2, 1, P110 }, // GTIOC1B { AF_GPT2, 2, P103 }, // GTIOC2A { AF_GPT2, 2, P102 }, { AF_GPT2, 2, P501 }, // GTIOC2B { AF_GPT2, 3, P111 }, // GTIOC3A { AF_GPT2, 3, P404 }, // GTIOC3B { AF_GPT2, 4, P205 }, // GTIOC4A { AF_GPT2, 4, P204 }, // GTIOC4B { AF_GPT2, 5, P101 }, { AF_GPT2, 5, P409 }, // GTIOC5A { AF_GPT2, 5, P100 }, // GTIOC5B { AF_GPT2, 8, P107 }, // GTIOC8A { AF_GPT2, 8, P106 }, // GTIOC8B #elif defined(RA6M1) { AF_GPT2, 0, P213 }, { AF_GPT2, 0, P415 }, // GTIOC0A { AF_GPT2, 0, P212 }, { AF_GPT2, 0, P414 }, // GTIOC0B { AF_GPT2, 1, P105 }, { AF_GPT2, 1, P405 }, // GTIOC1A { AF_GPT2, 1, P104 }, { AF_GPT2, 1, P406 }, // GTIOC1B { AF_GPT2, 2, P113 }, // GTIOC2A { AF_GPT2, 2, P114 }, // GTIOC2B { AF_GPT2, 3, P403 }, // GTIOC3A { AF_GPT2, 3, P404 }, // GTIOC3B { AF_GPT2, 4, P115 }, { AF_GPT2, 4, P205 }, { AF_GPT2, 4, P302 }, // GTIOC4A { AF_GPT2, 4, P301 }, { AF_GPT2, 4, P608 }, // GTIOC4B { AF_GPT2, 5, P101 }, { AF_GPT2, 5, P609 }, // GTIOC5A { AF_GPT2, 5, P100 }, { AF_GPT2, 5, P610 }, // GTIOC5B { AF_GPT2, 6, P400 }, { AF_GPT2, 6, P601 }, // GTIOC6A { AF_GPT2, 6, P401 }, { AF_GPT2, 6, P600 }, // GTIOC6B { AF_GPT2, 7, P304 }, // GTIOC7A { AF_GPT2, 7, P303 }, { AF_GPT2, 7, P602 }, // GTIOC7B { AF_GPT2, 8, P107 }, // GTIOC8A { AF_GPT2, 8, P106 }, // GTIOC8B { AF_GPT2, 9, P411 }, // GTIOC9A { AF_GPT2, 9, P410 }, // GTIOC9B { AF_GPT2, 10, P409 }, // GTIOC10A { AF_GPT2, 10, P408 }, // GTIOC10B { AF_GPT2, 11, P500 }, // GTIOC11A { AF_GPT2, 11, P501 }, // GTIOC11B { AF_GPT2, 12, P502 }, // GTIOC12A { AF_GPT2, 12, P503 }, // GTIOC12B #elif defined(RA6M2) { AF_GPT2, 0, P213 }, { AF_GPT2, 0, P415 }, { AF_GPT2, 0, P512 }, // GTIOC0A { AF_GPT2, 0, P212 }, { AF_GPT2, 0, P414 }, { AF_GPT2, 0, P511 }, // GTIOC0B { AF_GPT2, 1, P105 }, { AF_GPT2, 1, P405 }, // GTIOC1A { AF_GPT2, 1, P104 }, { AF_GPT2, 1, P406 }, // GTIOC1B { AF_GPT2, 2, P113 }, { AF_GPT2, 2, P713 }, // GTIOC2A { AF_GPT2, 2, P114 }, { AF_GPT2, 2, P712 }, // GTIOC2B { AF_GPT2, 3, P403 }, // GTIOC3A { AF_GPT2, 3, P404 }, // GTIOC3B { AF_GPT2, 4, P115 }, { AF_GPT2, 4, P205 }, { AF_GPT2, 4, P302 }, // GTIOC4A { AF_GPT2, 4, P204 }, { AF_GPT2, 4, P301 }, { AF_GPT2, 4, P608 }, // GTIOC4B { AF_GPT2, 5, P101 }, { AF_GPT2, 5, P203 }, { AF_GPT2, 5, P609 }, { AF_GPT2, 5, P700 }, // GTIOC5A { AF_GPT2, 5, P100 }, { AF_GPT2, 5, P202 }, { AF_GPT2, 5, P610 }, { AF_GPT2, 5, P701 }, // GTIOC5B { AF_GPT2, 6, P400 }, { AF_GPT2, 6, P601 }, { AF_GPT2, 6, P702 }, // GTIOC6A { AF_GPT2, 6, P401 }, { AF_GPT2, 6, P600 }, { AF_GPT2, 6, P703 }, // GTIOC6B { AF_GPT2, 7, P304 }, { AF_GPT2, 7, P603 }, // GTIOC7A { AF_GPT2, 7, P303 }, { AF_GPT2, 7, P602 }, // GTIOC7B { AF_GPT2, 8, P107 }, { AF_GPT2, 8, P605 }, // GTIOC8A { AF_GPT2, 8, P106 }, { AF_GPT2, 8, P604 }, // GTIOC8B { AF_GPT2, 9, P411 }, // GTIOC9A { AF_GPT2, 9, P410 }, // GTIOC9B { AF_GPT2, 10, P409 }, // GTIOC10A { AF_GPT2, 10, P408 }, // GTIOC10B { AF_GPT2, 11, P500 }, // GTIOC11A { AF_GPT2, 11, P501 }, // GTIOC11B { AF_GPT2, 12, P502 }, // GTIOC12A { AF_GPT2, 12, P503 }, // GTIOC12B { AF_GPT2, 13, P504 }, // GTIOC13A { AF_GPT2, 13, P505 }, // GTIOC13B #elif defined(RA6M3) { AF_GPT2, 0, P213 }, { AF_GPT2, 0, P415 }, { AF_GPT2, 0, P512 }, // GTIOC0A { AF_GPT2, 0, P212 }, { AF_GPT2, 0, P414 }, { AF_GPT2, 0, P511 }, // GTIOC0B { AF_GPT2, 1, P105 }, { AF_GPT2, 1, P405 }, // GTIOC1A { AF_GPT2, 1, P104 }, { AF_GPT2, 1, P406 }, // GTIOC1B { AF_GPT2, 2, P113 }, { AF_GPT2, 2, P713 }, // GTIOC2A { AF_GPT2, 2, P114 }, { AF_GPT2, 2, P712 }, // GTIOC2B { AF_GPT2, 3, P403 }, // GTIOC3A { AF_GPT2, 3, P404 }, // GTIOC3B { AF_GPT2, 4, P115 }, { AF_GPT2, 4, P205 }, { AF_GPT2, 4, P302 }, // GTIOC4A { AF_GPT2, 4, P204 }, { AF_GPT2, 4, P301 }, { AF_GPT2, 4, P608 }, // GTIOC4B { AF_GPT2, 5, P101 }, { AF_GPT2, 5, P203 }, { AF_GPT2, 5, P609 }, { AF_GPT2, 5, P700 }, // GTIOC5A { AF_GPT2, 5, P100 }, { AF_GPT2, 5, P202 }, { AF_GPT2, 5, P610 }, { AF_GPT2, 5, P701 }, // GTIOC5B { AF_GPT2, 6, P400 }, { AF_GPT2, 6, P601 }, { AF_GPT2, 6, P702 }, // GTIOC6A { AF_GPT2, 6, P401 }, { AF_GPT2, 6, P600 }, { AF_GPT2, 6, P703 }, // GTIOC6B { AF_GPT2, 7, P304 }, { AF_GPT2, 7, P603 }, // GTIOC7A { AF_GPT2, 7, P303 }, { AF_GPT2, 7, P602 }, // GTIOC7B { AF_GPT2, 8, P107 }, { AF_GPT2, 8, P605 }, // GTIOC8A { AF_GPT2, 8, P106 }, { AF_GPT2, 8, P604 }, // GTIOC8B { AF_GPT2, 9, P411 }, // GTIOC9A { AF_GPT2, 9, P410 }, // GTIOC9B { AF_GPT2, 10, P409 }, // GTIOC10A { AF_GPT2, 10, P408 }, // GTIOC10B { AF_GPT2, 11, P500 }, // GTIOC11A { AF_GPT2, 11, P501 }, // GTIOC11B { AF_GPT2, 12, P502 }, { AF_GPT2, 12, P908 }, // GTIOC12A { AF_GPT2, 12, P503 }, { AF_GPT2, 12, P907 }, // GTIOC12B { AF_GPT2, 13, P504 }, { AF_GPT2, 13, P906 }, // GTIOC13A { AF_GPT2, 13, P505 }, { AF_GPT2, 13, P905 }, // GTIOC13B #elif defined(RA6M5) { AF_GPT2, 0, P213 }, { AF_GPT2, 0, P300 }, { AF_GPT2, 0, P415 }, { AF_GPT2, 0, P512 }, // GTIOC0A { AF_GPT2, 0, P108 }, { AF_GPT2, 0, P212 }, { AF_GPT2, 0, P414 }, { AF_GPT2, 0, P511 }, // GTIOC0B { AF_GPT2, 1, P105 }, { AF_GPT2, 1, P109 }, { AF_GPT2, 1, P405 }, // GTIOC1A { AF_GPT2, 1, P104 }, { AF_GPT2, 1, P110 }, { AF_GPT2, 1, P406 }, // GTIOC1B { AF_GPT2, 2, P103 }, { AF_GPT2, 2, P113 }, { AF_GPT2, 2, P713 }, // GTIOC2A { AF_GPT2, 2, P102 }, { AF_GPT2, 2, P114 }, { AF_GPT2, 2, P712 }, // GTIOC2B { AF_GPT2, 3, P111 }, { AF_GPT2, 3, P403 }, // GTIOC3A { AF_GPT2, 3, P112 }, { AF_GPT2, 3, P404 }, // GTIOC3B { AF_GPT2, 4, P115 }, { AF_GPT2, 4, P205 }, { AF_GPT2, 4, P302 }, // GTIOC4A { AF_GPT2, 4, P204 }, { AF_GPT2, 4, P301 }, { AF_GPT2, 4, P608 }, // GTIOC4B { AF_GPT2, 5, P101 }, { AF_GPT2, 5, P203 }, { AF_GPT2, 5, P609 }, { AF_GPT2, 5, P700 }, // GTIOC5A { AF_GPT2, 5, P100 }, { AF_GPT2, 5, P202 }, { AF_GPT2, 5, P610 }, { AF_GPT2, 5, P701 }, // GTIOC5B { AF_GPT2, 6, P400 }, { AF_GPT2, 6, P407 }, { AF_GPT2, 6, P601 }, { AF_GPT2, 6, P702 }, // GTIOC6A { AF_GPT2, 6, P401 }, { AF_GPT2, 6, P408 }, { AF_GPT2, 6, P600 }, { AF_GPT2, 6, P703 }, // GTIOC6B { AF_GPT2, 7, P304 }, { AF_GPT2, 7, P603 }, // GTIOC7A { AF_GPT2, 7, P303 }, { AF_GPT2, 7, P602 }, // GTIOC7B { AF_GPT2, 8, P107 }, { AF_GPT2, 8, P605 }, // GTIOC8A { AF_GPT2, 8, P106 }, { AF_GPT2, 8, P604 }, // GTIOC8B { AF_GPT2, 9, P411 }, // GTIOC9A { AF_GPT2, 9, P410 }, // GTIOC9B #else #error "CMSIS MCU Series is not specified." #endif }; static float ra_gpt_freq[GPT_CH_SIZE]; static volatile uint16_t ra_gpt_div[GPT_CH_SIZE]; static void ra_gpt_timer_set_pin(uint32_t pin) { bool find = false; uint32_t ch; uint32_t af; find = ra_af_find_ch_af((ra_af_pin_t *)&ra_gpt_timer_pins, GPT_TMR_PINS_SIZE, pin, &ch, &af); if (find) { // GPIO_MODE_OUTPUT_PP ra_gpio_config(pin, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_LOW_POWER, af); } } static void ra_gpt_timer_release_pin(uint32_t pin) { bool find = false; uint32_t ch; uint32_t af; find = ra_af_find_ch_af((ra_af_pin_t *)&ra_gpt_timer_pins, GPT_TMR_PINS_SIZE, pin, &ch, &af); if (find) { // GPIO_PULLUP ra_gpio_config(pin, GPIO_MODE_INPUT, GPIO_NOPULL, GPIO_LOW_POWER, AF_GPIO); } } bool ra_gpt_timer_is_pwm_pin(uint32_t pin) { uint32_t ch; uint32_t af; return ra_af_find_ch_af((ra_af_pin_t *)&ra_gpt_timer_pins, GPT_TMR_PINS_SIZE, pin, &ch, &af); } void ra_gpt_timer_start(uint32_t ch) { if (CH_GAP || (ch >= GPT_CH_SIZE)) { return; } gpt_regs[ch]->GTCR_b.CST = 1; } void ra_gpt_timer_stop(uint32_t ch) { if (CH_GAP || (ch >= GPT_CH_SIZE)) { return; } gpt_regs[ch]->GTCR_b.CST = 0; } void ra_gpt_timer_set_freq(uint32_t ch, float freq) { R_GPT0_Type *gpt_reg = gpt_regs[ch]; uint8_t source = 0; uint32_t period = 0; ra_gpt_freq[ch] = 0.0f; if ((!gpt_reg) || (ch >= GPT_CH_SIZE) || (freq == ra_gpt_freq[ch]) || (freq == 0.0f)) { return; } ra_gpt_div[ch] = 0; #ifdef RA4M1 if (ch <= 1) { // 32bit #elif defined(RA4W1) || defined(RA6M5) if (ch <= 3) { // 32bit #elif defined(RA6M1) || defined(RA6M2) || defined(RA6M3) if (1) { // all is 32bit #else #error What is the width of the timer? (How many bits) #endif // float min_freq = ((float)PCLK)/4294967295.0f; if ((freq > (float)(PCLK / 2)) || (freq <= 0.0f)) { return; } else { source = GPT_PCLKD; period = (uint32_t)((float)(PCLK) / freq); } } else { // 16bit float min_freq = ((float)PCLK) / 65565.0f; if (freq > (float)(PCLK / 2)) { return; } else if (freq > min_freq) { source = GPT_PCLKD; period = (uint16_t)((float)(PCLK) / freq); } else if (freq > (min_freq / 4.0f)) { source = GPT_PCLKD4; ra_gpt_div[ch] = 4; period = (uint16_t)(((float)(PCLK) / 4.0f) / freq); } else if (freq > (min_freq / 16.0f)) { source = GPT_PCLKD16; ra_gpt_div[ch] = 16; period = (uint16_t)(((float)(PCLK) / 16.0f) / freq); } else if (freq > (min_freq / 64.0f)) { source = GPT_PCLKD64; ra_gpt_div[ch] = 64; period = (uint16_t)(((float)(PCLK) / 64.0f) / freq); } else if (freq > (min_freq / 256.0f)) { source = GPT_PCLKD256; ra_gpt_div[ch] = 256; period = (uint16_t)(((float)(PCLK) / 256.0f) / freq); } else if (freq > (min_freq / 1024.0f)) { source = GPT_PCLKD1024; ra_gpt_div[ch] = 1024; period = (uint16_t)(((float)(PCLK) / 1024.0f) / freq); } else { return; } } ra_gpt_freq[ch] = freq; float dutyA = (gpt_reg->GTIOR_b.OAE && gpt_reg->GTCCR[0] && gpt_reg->GTPR)? (float)(gpt_reg->GTCCR[0] + 1) / (float)(gpt_reg->GTPR + 1) : 0.0f; float dutyB = (gpt_reg->GTIOR_b.OBE && gpt_reg->GTCCR[0] && gpt_reg->GTPR)? (float)(gpt_reg->GTCCR[1] + 1) / (float)(gpt_reg->GTPR + 1) : 0.0f; if (gpt_reg->GTCR_b.CST) { // running if ((gpt_reg->GTCR >> 23) != source) { // Can't use gpt_reg->GTCR_b.TPCS this structure is declared wrong by FPS v2.3.0 so get the whole reg gpt_reg->GTCR_b.CST = 0; // stop counter gpt_reg->GTCR_b.TPCS = source << 1; // Again gpt_reg->GTCR_b.TPCS is wrong and incoming value should be shifted gpt_reg->GTPR = period - 1; gpt_reg->GTPBR = period - 1; if (dutyA > 0.0f) { dutyA = dutyA * ((float)(period)); gpt_reg->GTCCR[0] = (uint32_t)(dutyA - 1.0f); gpt_reg->GTCCR[2] = gpt_reg->GTCCR[0]; } if (dutyB > 0.0f) { dutyB = dutyB * ((float)(period)); gpt_reg->GTCCR[1] = (uint32_t)(dutyB - 1.0f); gpt_reg->GTCCR[3] = gpt_reg->GTCCR[1]; } gpt_reg->GTCNT = 0ul; // clear counter gpt_reg->GTCR_b.CST = 1; // start counter } else { // gpt_reg->GTPR = period-1; gpt_reg->GTPBR = period - 1; if (dutyA > 0.0f) { dutyA = dutyA * ((float)(period)); // gpt_reg->GTCCR[0] = (uint32_t)(dutyA - 1.0f); gpt_reg->GTCCR[2] = (uint32_t)(dutyA - 1.0f); } if (dutyB > 0.0f) { dutyB = dutyB * ((float)(period)); // gpt_reg->GTCCR[1] = (uint32_t)(dutyB - 1.0f); gpt_reg->GTCCR[3] = (uint32_t)(dutyB - 1.0f); } } } else { // stopped gpt_reg->GTCR_b.TPCS = source << 1; gpt_reg->GTPR = period - 1; gpt_reg->GTPBR = period - 1; if (dutyA > 0.0f) { dutyA = dutyA * ((float)(period)); gpt_reg->GTCCR[0] = (uint32_t)(dutyA - 1.0f); gpt_reg->GTCCR[2] = gpt_reg->GTCCR[0]; } if (dutyB > 0.0f) { dutyB = dutyB * ((float)(period)); gpt_reg->GTCCR[1] = (uint32_t)(dutyB - 1.0f); gpt_reg->GTCCR[3] = gpt_reg->GTCCR[1]; } } } float ra_gpt_timer_get_freq(uint32_t ch) { return (CH_GAP || (ch >= GPT_CH_SIZE))? 0.0f : ra_gpt_freq[ch]; } float ra_gpt_timer_tick_time(uint32_t ch) { if (CH_GAP || (ch >= GPT_CH_SIZE)) { return 0.0f; } else { float NS = 1000000000.0f; if (ra_gpt_div[ch]) { NS *= (float)ra_gpt_div[ch]; } return NS / (float)(PCLK); } } /* void ra_gpt_timer_set_period(uint32_t ch, uint32_t ns) { R_GPT0_Type *gpt_reg = gpt_regs[ch]; if((!gpt_reg) || (ch >= GPT_CH_SIZE)) return; if(ch <= 3) { //32bit } else { //16bit } } */ uint32_t ra_gpt_timer_get_period(uint32_t ch) { R_GPT0_Type *gpt_reg = gpt_regs[ch]; if ((!gpt_reg) || (ch >= GPT_CH_SIZE)) { return 0ul; } else { return gpt_reg->GTPR + 1; } } void ra_gpt_timer_set_duty(uint32_t ch, uint8_t id, uint32_t duty) { R_GPT0_Type *gpt_reg = gpt_regs[ch]; if ((!gpt_reg) || (ch >= GPT_CH_SIZE)) { return; } else { if (gpt_reg->GTCR_b.CST) { gpt_reg->GTCCR[(id == 'A')? 2 : 3] = duty? duty - 1 : duty; } else { gpt_reg->GTCCR[(id == 'A')? 0 : 1] = duty? duty - 1 : duty; if (id == 'A') { gpt_reg->GTCCR[2] = gpt_reg->GTCCR[0]; } else { gpt_reg->GTCCR[3] = gpt_reg->GTCCR[1]; } } } } uint32_t ra_gpt_timer_get_duty(uint32_t ch, uint8_t id) { R_GPT0_Type *gpt_reg = gpt_regs[ch]; if ((!gpt_reg) || (ch >= GPT_CH_SIZE)) { return 0ul; } else if (id == 'A') { return (gpt_reg->GTCCR[0])? gpt_reg->GTCCR[0] + 1 : 0; } else { return (gpt_reg->GTCCR[1])? gpt_reg->GTCCR[1] + 1 : 0; } } void ra_gpt_timer_init(uint32_t pwm_pin, uint32_t ch, uint8_t id, uint32_t duty, float freq) { R_GPT0_Type *gpt_reg = gpt_regs[ch]; if ((!gpt_reg) || (ch >= GPT_CH_SIZE)) { return; } #ifdef RA4M1 if (ch <= 1) { #elif defined(RA4W1) if (ch <= 3) { #elif defined(RA6M1) || defined(RA6M2) || defined(RA6M3) if (ch <= 7) { #elif defined(RA6M5) if (ch <= 9) { #else #error Choose proper clock enable BIT! #endif #ifdef RA6M5 // R_MSTP_MSTPCRE_MSTPE22_Msk - R_MSTP_MSTPCRE_MSTPE31_Msk ra_mstpcre_start(1UL << (31 - ch)); #else ra_mstpcrd_start(R_MSTP_MSTPCRD_MSTPD5_Msk); #endif } else { ra_mstpcrd_start(R_MSTP_MSTPCRD_MSTPD6_Msk); } ra_gpt_timer_stop(ch); // Stop the timer gpt_reg->GTCR_b.MD = 0; // Set operating mode gpt_reg->GTUDDTYC_b.UD = 1; // Set count direction gpt_reg->GTBER_b.PR = 1; // Set buffer operation for the period ra_gpt_timer_set_freq(ch, freq); // Set count clock & cycle gpt_reg->GTCNT = 0; // Set initial value for counter if (id == 'A') { gpt_reg->GTIOR_b.GTIOA = 0x9; // Set GTIOC pin function (Initial low -> Low at GTCCRA/B compare match -> High at cycle end) gpt_reg->GTIOR_b.OAE = 1; // Enable GTIOC pin output gpt_reg->GTBER_b.CCRA = 1; // Set buffer operation for the duty gpt_reg->GTCCR[0] = duty? duty - 1 : duty; // Set compare match value gpt_reg->GTCCR[2] = gpt_reg->GTCCR[0]; } else { gpt_reg->GTIOR_b.GTIOB = 0x9; gpt_reg->GTIOR_b.OBE = 1; gpt_reg->GTBER_b.CCRB = 1; gpt_reg->GTCCR[1] = duty? duty - 1 : duty; gpt_reg->GTCCR[3] = gpt_reg->GTCCR[1]; } ra_gpt_timer_set_pin(pwm_pin); if (gpt_reg->GTPR && gpt_reg->GTCCR[(id == 'A')? 0 : 1]) { ra_gpt_timer_start(ch); } } void ra_gpt_timer_deinit(uint32_t pwm_pin, uint32_t ch, uint8_t id) { if (CH_GAP || (ch >= GPT_CH_SIZE)) { return; } ra_gpt_timer_stop(ch); ra_gpt_div[ch] = 0; ra_gpt_freq[ch] = 0; gpt_regs[ch]->GTPR = 0; gpt_regs[ch]->GTPBR = 0; if (id == 'A') { gpt_regs[ch]->GTIOR_b.OAE = 0; gpt_regs[ch]->GTCCR[0] = 0; gpt_regs[ch]->GTCCR[2] = 0; } else { gpt_regs[ch]->GTIOR_b.OBE = 0; gpt_regs[ch]->GTCCR[1] = 0; gpt_regs[ch]->GTCCR[3] = 0; } #ifdef RA4M1 if (ch <= 1) { #elif defined(RA4W1) if (ch <= 3) { #elif defined(RA6M1) || defined(RA6M2) || defined(RA6M3) if (ch <= 7) { #elif defined(RA6M5) if (ch <= 9) { #else #error Choose proper clock enable BIT! #endif #ifdef RA6M5 ra_mstpcre_stop(1UL << (31 - ch)); #else ra_mstpcrd_stop(R_MSTP_MSTPCRD_MSTPD5_Msk); #endif } else { ra_mstpcrd_stop(R_MSTP_MSTPCRD_MSTPD6_Msk); } ra_gpt_timer_release_pin(pwm_pin); }