uint32_t analogRead(uint32_t pin) { uint32_t val = 0; /* allow for channel or pin numbers */ if (pin < 6) pin += A0; PinDescription *p = &g_APinDescription[pin]; /* Disable pull-up and set pin mux for ADC output */ SET_PIN_MODE(p->ulSocPin, ADC_MUX_MODE); SET_PIN_PULLUP(p->ulSocPin,0); /* Reset sequence pointer */ SET_ARC_MASK(ADC_CTRL, ADC_SEQ_PTR_RST); /* Update sequence table */ WRITE_ARC_REG(p->ulAdcChan, ADC_SEQ); /* Reset sequence pointer & start sequencer */ SET_ARC_MASK(ADC_CTRL, ADC_SEQ_PTR_RST | ADC_SEQ_START | ADC_ENABLE); /* Poll for ADC data ready status (DATA_A) */ while((READ_ARC_REG(ADC_INTSTAT) & ADC_INT_DATA_A) == 0); /* Pop the data sample from FIFO to sample register */ SET_ARC_MASK(ADC_SET, ADC_POP_SAMPLE); /* Read sample from sample register */ val = READ_ARC_REG( ADC_SAMPLE); /* Clear the DATA_A status bit */ SET_ARC_MASK( ADC_CTRL, ADC_CLR_DATA_A); return mapResolution(val, ADC_RESOLUTION, _readResolution); }
static void update_PWM_value(uint32_t ulPin, uint32_t ulValue, uint32_t PWM_channel) { PWM_Channels_Value[PWM_channel] = (2^PWM_RESOLUTION - 1) - mapResolution(ulValue, _writeResolution, PWM_RESOLUTION); if ((NRF_GPIOTE->CONFIG[PWM_channel] & GPIOTE_CONFIG_MODE_Msk) == (GPIOTE_CONFIG_MODE_Disabled << GPIOTE_CONFIG_MODE_Pos)) { PWM_Channels_Start[PWM_channel] = 1; } }
uint32_t analogRead(uint32_t pin) { uint32_t valueRead = 0; if (pin < A0) { pin += A0; } pinPeripheral(pin, PIO_ANALOG); // Disable DAC, if analogWrite() was used previously to enable the DAC if ((g_APinDescription[pin].ulADCChannelNumber == ADC_Channel0) || (g_APinDescription[pin].ulADCChannelNumber == DAC_Channel0)) { syncDAC(); DAC->CTRLA.bit.ENABLE = 0x00; // Disable DAC //DAC->CTRLB.bit.EOEN = 0x00; // The DAC output is turned off. syncDAC(); } syncADC(); ADC->INPUTCTRL.bit.MUXPOS = g_APinDescription[pin].ulADCChannelNumber; // Selection for the positive ADC input // Control A /* * Bit 1 ENABLE: Enable * 0: The ADC is disabled. * 1: The ADC is enabled. * Due to synchronization, there is a delay from writing CTRLA.ENABLE until the peripheral is enabled/disabled. The * value written to CTRL.ENABLE will read back immediately and the Synchronization Busy bit in the Status register * (STATUS.SYNCBUSY) will be set. STATUS.SYNCBUSY will be cleared when the operation is complete. * * Before enabling the ADC, the asynchronous clock source must be selected and enabled, and the ADC reference must be * configured. The first conversion after the reference is changed must not be used. */ syncADC(); ADC->CTRLA.bit.ENABLE = 0x01; // Enable ADC // Start conversion syncADC(); ADC->SWTRIG.bit.START = 1; // Clear the Data Ready flag ADC->INTFLAG.reg = ADC_INTFLAG_RESRDY; // Start conversion again, since The first conversion after the reference is changed must not be used. syncADC(); ADC->SWTRIG.bit.START = 1; // Store the value while (ADC->INTFLAG.bit.RESRDY == 0); // Waiting for conversion to complete valueRead = ADC->RESULT.reg; syncADC(); ADC->CTRLA.bit.ENABLE = 0x00; // Disable ADC syncADC(); return mapResolution(valueRead, _ADCResolution, _readResolution); }
uint32_t analogRead(uint32_t ulPin) { uint32_t ulValue = 0; uint32_t ulChannel; if (ulPin < A0) ulPin += A0; ulChannel = g_APinDescription[ulPin].ulADCChannelNumber ; if (ulPin >= PINS_COUNT || ulChannel == NONE ) { return -1; } pinMode(ulPin,AN_INPUT); #if defined (STM32F10X_HD) || (STM32F10X_MD) ADC_RegularChannelConfig(ADC1, g_APinDescription[ulPin].ulADCChannelNumber, 1, ADC_SampleTime_55Cycles5); #elif defined (STM32F40_41xxx) ADC_RegularChannelConfig(ADC1, g_APinDescription[ulPin].ulADCChannelNumber, 1, ADC_SampleTime_15Cycles); #endif //Start ADC1 Software Conversion #if defined (STM32F10X_HD) || (STM32F10X_MD) ADC_SoftwareStartConvCmd(ADC1, ENABLE); #elif defined (STM32F40_41xxx) ADC_SoftwareStartConv(ADC1); #endif // Wait until conversion completion // while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); // Read the value ulValue = ADC_GetConversionValue(ADC1); ulValue = mapResolution(ulValue, ADC_RESOLUTION, _readResolution); return ulValue; }
uint32_t analogRead(uint32_t ulPin) { uint32_t ulValue = 0; uint8_t pselValue = 0; if ((ulPin > 0) && (ulPin < PINS_COUNT)) // Only pins 1-6 is avaliable for using as ADC inputs { pselValue = (1 << (ulPin + 1)); // Calculate PSEL value if (analog_reference == ADC_CONFIG_REFSEL_External) NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos)| // 10bit ADC resolution (adc_input_selection << ADC_CONFIG_INPSEL_Pos)| // DEFAULT: Analog input specified by PSEL with 1/3 prescaling used as input for the conversion (ADC_CONFIG_REFSEL_External << ADC_CONFIG_REFSEL_Pos)| (pselValue << ADC_CONFIG_PSEL_Pos)| // Select ADC input (external_reference << ADC_CONFIG_EXTREFSEL_Pos); // DEFAULT: Use analog reference 0 as reference if selected external reference else NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos)| // 10bit ADC resolution (adc_input_selection << ADC_CONFIG_INPSEL_Pos)| // DEFAULT: Analog input specified by PSEL with 1/3 prescaling used as input for the conversion (analog_reference << ADC_CONFIG_REFSEL_Pos)| // DEFAULT: Use supply voltage with 1/3 prescaling as reference for conversion. Only usable when supply voltage is between 2.5V and 3.6V (pselValue << ADC_CONFIG_PSEL_Pos)| // Select ADC input (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos); NRF_ADC->INTENCLR = 0xFFFFFFFF; NRF_ADC->ENABLE = (ADC_ENABLE_ENABLE_Enabled << ADC_ENABLE_ENABLE_Pos); // Enable ADC NRF_ADC->TASKS_START = 1; // Start A-D conversion NRF_ADC->EVENTS_END = 0; while (! NRF_ADC->EVENTS_END) // Wait for end of conversion ; ulValue = NRF_ADC->RESULT; // Read the value ulValue = mapResolution(ulValue, ADC_RESOLUTION, _readResolution); NRF_ADC->ENABLE = (ADC_ENABLE_ENABLE_Disabled << ADC_ENABLE_ENABLE_Pos); // Disable ADC NRF_ADC->TASKS_STOP = 1; // GPIOs release regarding PAN028 NRF_ADC->CONFIG = (ADC_CONFIG_RES_8bit << ADC_CONFIG_RES_Pos) | (ADC_CONFIG_INPSEL_SupplyTwoThirdsPrescaling << ADC_CONFIG_INPSEL_Pos) | (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) | (ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos) | (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos); } return ulValue; }
// Right now, PWM output only works on the pins with // hardware support. These are defined in the appropriate // pins_*.c file. For the rest of the pins, we default // to digital output. void analogWrite( uint32_t ulPin, uint32_t ulValue ) { #if 0 // pwm test #if 1 // port configuration *(volatile unsigned int *)0x44000010 |= 1 << 8; //GPIOx->OUTENSET //PAD_AFConfig(PAD_PC, GPIO_Pin_8, 0x01/*PAD_AF1*/); ///< PAD Config - LED used 2nd Function // (0x01 << 8) *(volatile unsigned int *)(0x41002080 + 0x20) &= ~0x03/*PAD_AF1*/; // (0x01 << 8) // *(volatile unsigned int *)(0x41002080 + 0x20) |= 0x01/*PAD_AF1*/; // (0x01 << 8) *(volatile unsigned int *)0x44000010 |= 1 << 9; //GPIOx->OUTENSET *(volatile unsigned int *)(0x41002080 + 0x24) &= ~0x03/*PAD_AF1*/; // (0x01 << 8) // *(volatile unsigned int *)(0x41002080 + 0x24) |= 0x01/*PAD_AF1*/; // (0x01 << 8) #endif // port configuration //------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------ /* Select Timer/Counter mode as Timer mode */ //PWM_CHn->TCMR = PWM_CHn_TCMR_TimerMode; // *(volatile unsigned int *)0x40005324 = (0x0ul); // ch3 *(volatile unsigned int *)0x40005024 = (0x0); /* Set Prescale register value */ //PWM_CHn->PR = PWM_TimerModeInitStruct->PWM_CHn_PR; // *(volatile unsigned int *)0x40005314 = (20000000 / 1000000) / 10 - 1; //PrescalerValue - 1; *(volatile unsigned int *)0x40005014 = (20000000 / 1000000) / 10 - 1; //PrescalerValue - 1; /* Set Match register value */ //PWM_CHn->MR = PWM_TimerModeInitStruct->PWM_CHn_MR; // *(volatile unsigned int *)0x40005318 = 80000; *(volatile unsigned int *)0x40005018 = 80000; /* Set Limit register value */ //PWM_CHn->LR = PWM_TimerModeInitStruct->PWM_CHn_LR; // *(volatile unsigned int *)0x4000531C = 100000; // 80% duty cycle *(volatile unsigned int *)0x4000501C = 100000; // 80% duty cycle /* Select Up-down mode */ //PWM_CHn->UDMR = PWM_TimerModeInitStruct->PWM_CHn_UDMR; // *(volatile unsigned int *)0x40005320 = (0x0ul); //PWM_CHn_UDMR_UpCount *(volatile unsigned int *)0x40005020 = (0x0); //PWM_CHn_UDMR_UpCount /* Select Periodic mode */ //PWM_CHn->PDMR = PWM_TimerModeInitStruct->PWM_CHn_PDMR; // *(volatile unsigned int *)0x40005334 = (0x1ul); //PWM_CHn_PDMR_Periodic *(volatile unsigned int *)0x40005034 = (0x1); //PWM_CHn_PDMR_Periodic //------------------------------------------------------------------------------------------ /* Select Timer/Counter mode as Timer mode */ //PWM_CHn->TCMR = PWM_CHn_TCMR_TimerMode; // *(volatile unsigned int *)0x40005324 = (0x0ul); // ch3 *(volatile unsigned int *)0x40005124 = (0x0ul); /* Set Prescale register value */ //PWM_CHn->PR = PWM_TimerModeInitStruct->PWM_CHn_PR; // *(volatile unsigned int *)0x40005314 = (20000000 / 1000000) / 10 - 1; //PrescalerValue - 1; *(volatile unsigned int *)0x40005114 = (20000000 / 1000000) / 10 - 1; //PrescalerValue - 1; /* Set Match register value */ //PWM_CHn->MR = PWM_TimerModeInitStruct->PWM_CHn_MR; // *(volatile unsigned int *)0x40005318 = 80000; *(volatile unsigned int *)0x40005118 = 80000; /* Set Limit register value */ //PWM_CHn->LR = PWM_TimerModeInitStruct->PWM_CHn_LR; // *(volatile unsigned int *)0x4000531C = 100000; // 80% duty cycle *(volatile unsigned int *)0x4000511C = 100000; // 80% duty cycle /* Select Up-down mode */ //PWM_CHn->UDMR = PWM_TimerModeInitStruct->PWM_CHn_UDMR; // *(volatile unsigned int *)0x40005320 = (0x0ul); //PWM_CHn_UDMR_UpCount *(volatile unsigned int *)0x40005120 = (0x0ul); //PWM_CHn_UDMR_UpCount /* Select Periodic mode */ //PWM_CHn->PDMR = PWM_TimerModeInitStruct->PWM_CHn_PDMR; // *(volatile unsigned int *)0x40005334 = (0x1ul); //PWM_CHn_PDMR_Periodic *(volatile unsigned int *)0x40005134 = (0x1ul); //PWM_CHn_PDMR_Periodic //------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------ //PWM->SSR &= PWM_SSR_SS3_Stop; // *(volatile unsigned int *)0x40005804 &= ~(0x1ul << 3); *(volatile unsigned int *)0x40005804 &= ~(0x1ul << 0); //PWM_CHn->PEEER = outputEnDisable; // *(volatile unsigned int *)0x40005328 = (0x2ul); *(volatile unsigned int *)0x40005028 = (0x2ul); //------------------------------------------------------------------------------------------ //PWM->SSR &= PWM_SSR_SS3_Stop; // *(volatile unsigned int *)0x40005804 &= ~(0x1ul << 3); *(volatile unsigned int *)0x40005804 &= ~(0x1ul << 1); //PWM_CHn->PEEER = outputEnDisable; // *(volatile unsigned int *)0x40005328 = (0x2ul); *(volatile unsigned int *)0x40005128 = (0x2ul); //------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------ //PWM->SSR |= PWM_SSR_SS3_Start; // *(volatile unsigned int *)0x40005804 |= (0x1ul << 3); *(volatile unsigned int *)0x40005804 |= (0x1ul << 0); //------------------------------------------------------------------------------------------ //PWM->SSR |= PWM_SSR_SS3_Start; // *(volatile unsigned int *)0x40005804 |= (0x1ul << 3); *(volatile unsigned int *)0x40005804 |= (0x1ul << 1); while( !((*(volatile unsigned long *) 0x4000D018) & (0x01 << 7)) ) ; *(volatile unsigned long *) 0x4000D000 = 'P'; while( !((*(volatile unsigned long *) 0x4000D018) & (0x01 << 7)) ) ; *(volatile unsigned long *) 0x4000D000 = 'W'; while( !((*(volatile unsigned long *) 0x4000D018) & (0x01 << 7)) ) ; *(volatile unsigned long *) 0x4000D000 = 'M'; while(1); #endif #if 1 //------------------------------------------------------------------------------------------ *(volatile unsigned int *)(0x42000010 + pwm_pin_tbl[ulPin].port_num) |= 1 << pwm_pin_tbl[ulPin].pin_num; //GPIOx->OUTENSET //PAD_AFConfig(PAD_PC, GPIO_Pin_8, 0x01/*PAD_AF1*/); ///< PAD Config - LED used 2nd Function // (0x01 << 8) *(volatile unsigned int *)(0x41002000 + pwm_pin_tbl[ulPin].af_base + pwm_pin_tbl[ulPin].pin_num * 4) &= ~0x03/*PAD_AF1*/; // (0x01 << 8) *(volatile unsigned int *)(0x41002000 + pwm_pin_tbl[ulPin].af_base + pwm_pin_tbl[ulPin].pin_num * 4) |= pwm_pin_tbl[ulPin].af_num/*PAD_AF1*/; // (0x01 << 8) //------------------------------------------------------------------------------------------ //PWM-n /* Select Timer/Counter mode as Timer mode */ *(volatile unsigned int *)(0x40005024 + pwm_pin_tbl[ulPin].pwm_num) = (0x0); /* Set Prescale register value */ *(volatile unsigned int *)(0x40005014 + pwm_pin_tbl[ulPin].pwm_num) = (20000000 / 1000000) / 10 - 1; //PrescalerValue - 1; /* Set Match register value */ *(volatile unsigned int *)(0x40005018 + pwm_pin_tbl[ulPin].pwm_num) = 400 * ulValue; //MR /* Set Limit register value */ *(volatile unsigned int *)(0x4000501C + pwm_pin_tbl[ulPin].pwm_num) = 102400; // 80% duty cycle /* Select Up-down mode */ *(volatile unsigned int *)(0x40005020 + pwm_pin_tbl[ulPin].pwm_num) = (0x0); //PWM_CHn_UDMR_UpCount /* Select Periodic mode */ *(volatile unsigned int *)(0x40005034 + pwm_pin_tbl[ulPin].pwm_num) = (0x1); //PWM_CHn_PDMR_Periodic //------------------------------------------------------------------------------------------ //PWM->SSR &= PWM_SSR_SS3_Stop; *(volatile unsigned int *)0x40005804 &= ~(0x1 << pwm_pin_tbl[ulPin].pwm_pin); //PWM_CHn->PEEER = outputEnDisable; *(volatile unsigned int *)(0x40005028 + pwm_pin_tbl[ulPin].pwm_num) = 0x2; //------------------------------------------------------------------------------------------ //PWM->SSR |= PWM_SSR_SS3_Start; *(volatile unsigned int *)0x40005804 |= (0x1ul << pwm_pin_tbl[ulPin].pwm_pin); #if 0 // pwm serial character out while( !((*(volatile unsigned long *) 0x4000D018) & (0x01 << 7)) ) ; *(volatile unsigned long *) 0x4000D000 = 'P'; while( !((*(volatile unsigned long *) 0x4000D018) & (0x01 << 7)) ) ; *(volatile unsigned long *) 0x4000D000 = 'W'; while( !((*(volatile unsigned long *) 0x4000D018) & (0x01 << 7)) ) ; *(volatile unsigned long *) 0x4000D000 = 'M'; #endif // pwm serial character out #endif #if 0 uint32_t attr = g_APinDescription[ulPin].ulPinAttribute ; // uint32_t pwm_name = g_APinDescription[ulPin].ulTCChannel ; uint8_t isTC = 0 ; uint8_t Channelx ; Tc* TCx ; Tcc* TCCx ; if ( (attr & PIN_ATTR_ANALOG) == PIN_ATTR_ANALOG ) { if ( ulPin == 24 ) // Only 1 DAC on A0 (PA02) { ulValue = mapResolution(ulValue, _writeResolution, DAC_RESOLUTION); DAC->DATA.reg = ulValue & 0x3FF; // Dac on 10 bits. DAC->CTRLA.bit.ENABLE = 1; // DAC Enabled ///////////////////////////////////// syncDAC(); return; } } if ( (attr & PIN_ATTR_PWM) == PIN_ATTR_PWM ) { if ( (g_APinDescription[ulPin].ulPinType == PIO_TIMER) || g_APinDescription[ulPin].ulPinType == PIO_TIMER_ALT ) { pinPeripheral( ulPin, g_APinDescription[ulPin].ulPinType ) ; } switch ( g_APinDescription[ulPin].ulPWMChannel ) { case PWM3_CH0 : TCx = TC3 ; Channelx = 0 ; isTC = 1 ; break; case PWM3_CH1: TCx = TC3 ; Channelx = 1; isTC = 1; break; case PWM0_CH0 : TCCx = TCC0; Channelx = 0; break; case PWM0_CH1 : TCCx = TCC0; Channelx = 1; break; case PWM0_CH4 : TCCx = TCC0; Channelx = 0; break; case PWM0_CH5 : TCCx = TCC0; Channelx = 1; break; case PWM0_CH6 : TCCx = TCC0; Channelx = 2; break; case PWM0_CH7 : TCCx = TCC0; Channelx = 3; break; case PWM1_CH0 : TCCx = TCC1; Channelx = 0; break; case PWM1_CH1 : TCCx = TCC1; Channelx = 1; break; case PWM2_CH0 : TCCx = TCC2; Channelx = 0; break; case PWM2_CH1 : TCCx = TCC2; Channelx = 1; break; } // Enable clocks according to TCCx instance to use switch ( GetTCNumber( g_APinDescription[ulPin].ulPWMChannel ) ) { case 0: // TCC0 //Enable GCLK for TCC0 (timer counter input clock) GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC0_TCC1 )) ; break; case 1: // TCC1 //Enable GCLK for TCC1 (timer counter input clock) GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC0_TCC1 )) ; break; case 2: // TCC2 //Enable GCLK for TCC2 (timer counter input clock) GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC2_TC3 )) ; break; case 3: // TC3 //Enable GCLK for TC3 (timer counter input clock) GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC2_TC3 )); break; case 4: // TC4 //Enable GCLK for TC4 (timer counter input clock) GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TC4_TC5 )); break; case 5: // TC5 //Enable GCLK for TC5 (timer counter input clock) GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TC4_TC5 )) ; break; } // Set PORT if ( isTC ) { // -- Configure TC //DISABLE TCx TCx->COUNT8.CTRLA.reg &=~(TC_CTRLA_ENABLE); //Set Timer counter Mode to 8 bits TCx->COUNT8.CTRLA.reg |= TC_CTRLA_MODE_COUNT8; //Set TCx as normal PWM TCx->COUNT8.CTRLA.reg |= TC_CTRLA_WAVEGEN_NPWM; //Set TCx in waveform mode Normal PWM TCx->COUNT8.CC[Channelx].reg = (uint8_t) ulValue; //Set PER to maximum counter value (resolution : 0xFF) TCx->COUNT8.PER.reg = 0xFF; // Enable TCx TCx->COUNT8.CTRLA.reg |= TC_CTRLA_ENABLE; } else { // -- Configure TCC //DISABLE TCCx TCCx->CTRLA.reg &=~(TCC_CTRLA_ENABLE); //Set TCx as normal PWM TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM; //Set TCx in waveform mode Normal PWM TCCx->CC[Channelx].reg = (uint32_t)ulValue; //Set PER to maximum counter value (resolution : 0xFF) TCCx->PER.reg = 0xFF; //ENABLE TCCx TCCx->CTRLA.reg |= TCC_CTRLA_ENABLE ; } return ; } // -- Defaults to digital write pinMode( ulPin, OUTPUT ) ; if ( ulValue < 128 ) { digitalWrite( ulPin, LOW ) ; } else { digitalWrite( ulPin, HIGH ) ; } #endif }
// Right now, PWM output only works on the pins with // hardware support. These are defined in the appropriate // pins_*.c file. For the rest of the pins, we default // to digital output. void analogFastWrite(uint32_t pin, uint32_t value) { PinDescription pinDesc = g_APinDescription[pin]; uint32_t attr = pinDesc.ulPinAttribute; if ((attr & PIN_ATTR_ANALOG) == PIN_ATTR_ANALOG) { // DAC handling code if (pin != PIN_A0) { // Only 1 DAC on A0 (PA02) return; } value = mapResolution(value, _writeResolution, 10); syncDAC(); DAC->DATA.reg = value & 0x3FF; // DAC on 10 bits. syncDAC(); DAC->CTRLA.bit.ENABLE = 0x01; // Enable DAC syncDAC(); return; } if ((attr & PIN_ATTR_PWM) == PIN_ATTR_PWM) { value = mapResolution(value, _writeResolution, 8); // change to 10 for 10 bit... must also change TCx->COUNT8.PER.reg = 0x3FF uint32_t tcNum = GetTCNumber(pinDesc.ulPWMChannel); uint8_t tcChannel = GetTCChannelNumber(pinDesc.ulPWMChannel); static bool tcEnabled[TCC_INST_NUM+TC_INST_NUM]; if (!tcEnabled[tcNum]) { tcEnabled[tcNum] = true; if (attr & PIN_ATTR_TIMER) { #if !(ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10603) // Compatibility for cores based on SAMD core <=1.6.2 if (pinDesc.ulPinType == PIO_TIMER_ALT) { pinPeripheral(pin, PIO_TIMER_ALT); } else #endif { pinPeripheral(pin, PIO_TIMER); } } else { // We suppose that attr has PIN_ATTR_TIMER_ALT bit set... pinPeripheral(pin, PIO_TIMER_ALT); } uint16_t GCLK_CLKCTRL_IDs[] = { GCLK_CLKCTRL_ID(GCM_TCC0_TCC1), // TCC0 GCLK_CLKCTRL_ID(GCM_TCC0_TCC1), // TCC1 GCLK_CLKCTRL_ID(GCM_TCC2_TC3), // TCC2 GCLK_CLKCTRL_ID(GCM_TCC2_TC3), // TC3 GCLK_CLKCTRL_ID(GCM_TC4_TC5), // TC4 GCLK_CLKCTRL_ID(GCM_TC4_TC5), // TC5 GCLK_CLKCTRL_ID(GCM_TC6_TC7), // TC6 GCLK_CLKCTRL_ID(GCM_TC6_TC7), // TC7 }; GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_IDs[tcNum]); while (GCLK->STATUS.bit.SYNCBUSY == 1); // Set PORT if (tcNum >= TCC_INST_NUM) { // -- Configure TC Tc* TCx = (Tc*) GetTC(pinDesc.ulPWMChannel); // Disable TCx TCx->COUNT8.CTRLA.bit.ENABLE = 0; syncTC_8(TCx); // Set Timer counter Mode to 8 bits, normal PWM TCx->COUNT8.CTRLA.reg |= TC_CTRLA_MODE_COUNT8 | TC_CTRLA_WAVEGEN_NPWM; syncTC_8(TCx); // Set the initial value TCx->COUNT8.CC[tcChannel].reg = (uint8_t) value; syncTC_8(TCx); // Set PER to maximum counter value (resolution : 0xFF) TCx->COUNT8.PER.reg = 0xFF; syncTC_8(TCx); // Enable TCx TCx->COUNT8.CTRLA.bit.ENABLE = 1; syncTC_8(TCx); } else { // -- Configure TCC Tcc* TCCx = (Tcc*) GetTC(pinDesc.ulPWMChannel); // Disable TCCx TCCx->CTRLA.bit.ENABLE = 0; syncTCC(TCCx); // Set TCx as normal PWM TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM; syncTCC(TCCx); // Set the initial value TCCx->CC[tcChannel].reg = (uint32_t) value; syncTCC(TCCx); // Set PER to maximum counter value (resolution : 0xFF) TCCx->PER.reg = 0xFF; //change to 0x43FF for 10 bit... must also change mapping above syncTCC(TCCx); // Enable TCCx TCCx->CTRLA.bit.ENABLE = 1; syncTCC(TCCx); } } else { if (tcNum >= TCC_INST_NUM) { Tc* TCx = (Tc*) GetTC(pinDesc.ulPWMChannel); TCx->COUNT8.CC[tcChannel].reg = (uint8_t) value; syncTC_8(TCx); } else { Tcc* TCCx = (Tcc*) GetTC(pinDesc.ulPWMChannel); TCCx->CTRLBSET.bit.LUPD = 1; syncTCC(TCCx); TCCx->CCB[tcChannel].reg = (uint32_t) value; syncTCC(TCCx); TCCx->CTRLBCLR.bit.LUPD = 1; syncTCC(TCCx); } } return; } // -- Defaults to digital write pinMode(pin, OUTPUT); value = mapResolution(value, _writeResolution, 8); if (value < 128) { digitalWrite(pin, LOW); } else { digitalWrite(pin, HIGH); } }
void analogWrite(uint32_t ulPin, uint32_t ulValue) { if (ulValue == 0) { digitalWrite(ulPin, LOW); return; } if (ulValue == 255) { digitalWrite(ulPin, HIGH); return; } if (Timer1_Compare_Unit_Occupied_by_Pin[0] == ulPin) { update_PWM_value(ulPin, ulValue, 0); } else if (Timer1_Compare_Unit_Occupied_by_Pin[1] == ulPin) { update_PWM_value(ulPin, ulValue, 1); } else if (Timer1_Compare_Unit_Occupied_by_Pin[2] == ulPin) { update_PWM_value(ulPin, ulValue, 2); } else if (Timer2_Compare_Unit_Occupied_by_Pin[0] == ulPin) { update_PWM_value(ulPin, ulValue, 3); } else { if ((Timer1_Compare_Unit_Occupied_by_Pin[0] == 255) && (Timer1_Compare_Unit_Occupied_by_Pin[1] == 255) && (Timer1_Compare_Unit_Occupied_by_Pin[2] == 255)) { // Timer1 is not used: need to initialize it // Configure ulPin as output digitalWrite(ulPin, LOW); pinMode(ulPin, OUTPUT); if (ulValue > 0) { // Configure GPIOTE channel "gpiote_channel" to toggle the PWM pin state // Note that we can only connect one GPIOTE task to an output pin nrf_gpiote_task_config(0, ulPin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW); } GPIOTE_Channels_Occupied[ulPin] = 0; NRF_TIMER1->TASKS_STOP = 1; NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer; //NRF_TIMER1->PRESCALER = 6; // Source clock frequency is divided by 2^6 = 64 NRF_TIMER1->PRESCALER = 0; // Source clock frequency is divided by 2^6 = 64 ///////////////////////////////////////// //NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_08Bit; NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_16Bit; //////////////////////////// // Clears the timer, sets it to 0 NRF_TIMER1->TASKS_CLEAR = 1; NRF_TIMER1->CC[0] = (2^PWM_RESOLUTION - 1); NRF_TIMER1->CC[1] = (2^PWM_RESOLUTION - 1); NRF_TIMER1->CC[2] = (2^PWM_RESOLUTION - 1); NRF_TIMER1->CC[3] = 0; NRF_TIMER1->EVENTS_COMPARE[0] = 0; NRF_TIMER1->EVENTS_COMPARE[1] = 0; NRF_TIMER1->EVENTS_COMPARE[2] = 0; NRF_TIMER1->EVENTS_COMPARE[3] = 0; // Interrupt setup NRF_TIMER1->INTENSET = (TIMER_INTENSET_COMPARE3_Enabled << TIMER_INTENSET_COMPARE3_Pos); attachInterrupt(TIMER1_IRQn, TIMER1_Interrupt); // Start clock NRF_TIMER1->TASKS_START = 1; turn_On_PPI_to_GPIO_for_PWM(ulPin, 0, NRF_TIMER1, 0); PWM_Channels_Value[0] = (2^PWM_RESOLUTION - 1) - mapResolution(ulValue, _writeResolution, PWM_RESOLUTION); Timer1_Compare_Unit_Occupied_by_Pin[0] = ulPin; Pin_Occupied_for_PWM[ulPin] = 1; } else { if (Timer1_Compare_Unit_Occupied_by_Pin[0] == 255) { // Configure ulPin as output digitalWrite(ulPin, LOW); pinMode(ulPin, OUTPUT); if (ulValue > 0) { // Configure GPIOTE channel "gpiote_channel" to toggle the PWM pin state // Note that we can only connect one GPIOTE task to an output pin nrf_gpiote_task_config(0, ulPin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW); } GPIOTE_Channels_Occupied[ulPin] = 0; turn_On_PPI_to_GPIO_for_PWM(ulPin, 0, NRF_TIMER1, 0); PWM_Channels_Value[0] = (2^PWM_RESOLUTION - 1) - mapResolution(ulValue, _writeResolution, PWM_RESOLUTION); Timer1_Compare_Unit_Occupied_by_Pin[0] = ulPin; Pin_Occupied_for_PWM[ulPin] = 1; NRF_TIMER1->EVENTS_COMPARE[0] = 0; } else if (Timer1_Compare_Unit_Occupied_by_Pin[1] == 255) { // Configure ulPin as output digitalWrite(ulPin, LOW); pinMode(ulPin, OUTPUT); if (ulValue > 0) { // Configure GPIOTE channel "gpiote_channel" to toggle the PWM pin state // Note that we can only connect one GPIOTE task to an output pin nrf_gpiote_task_config(1, ulPin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW); } GPIOTE_Channels_Occupied[ulPin] = 1; turn_On_PPI_to_GPIO_for_PWM(ulPin, 1, NRF_TIMER1, 1); PWM_Channels_Value[1] = (2^PWM_RESOLUTION - 1) - mapResolution(ulValue, _writeResolution, PWM_RESOLUTION); Timer1_Compare_Unit_Occupied_by_Pin[1] = ulPin; Pin_Occupied_for_PWM[ulPin] = 1; NRF_TIMER1->EVENTS_COMPARE[1] = 0; } else if (Timer1_Compare_Unit_Occupied_by_Pin[2] == 255) { // Configure ulPin as output digitalWrite(ulPin, LOW); pinMode(ulPin, OUTPUT); if (ulValue > 0) { // Configure GPIOTE channel "gpiote_channel" to toggle the PWM pin state // Note that we can only connect one GPIOTE task to an output pin nrf_gpiote_task_config(2, ulPin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW); } GPIOTE_Channels_Occupied[ulPin] = 2; turn_On_PPI_to_GPIO_for_PWM(ulPin, 2, NRF_TIMER1, 2); PWM_Channels_Value[2] = (2^PWM_RESOLUTION - 1) - mapResolution(ulValue, _writeResolution, PWM_RESOLUTION); Timer1_Compare_Unit_Occupied_by_Pin[2] = ulPin; Pin_Occupied_for_PWM[ulPin] = 1; NRF_TIMER1->EVENTS_COMPARE[2] = 0; } else { // All channels of Timer1 is occupied, need to use Timer2 if (!RFduinoGZLL_used && Timer2_Compare_Unit_Occupied_by_Pin[0] == 255) { // Timer2 is not used: need to initialize it // Configure ulPin as output digitalWrite(ulPin, LOW); pinMode(ulPin, OUTPUT); if (ulValue > 0) { // Configure GPIOTE channel "gpiote_channel" to toggle the PWM pin state // Note that we can only connect one GPIOTE task to an output pin nrf_gpiote_task_config(3, ulPin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW); } GPIOTE_Channels_Occupied[ulPin] = 3; NRF_TIMER2->TASKS_STOP = 1; NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer; //NRF_TIMER2->PRESCALER = 6; // Source clock frequency is divided by 2^6 = 64 NRF_TIMER2->PRESCALER = 0; // Source clock frequency is divided by 2^6 = 64 ///////////////////////////////////////// //NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_08Bit; NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit; //////////////////////////// // Clears the timer, sets it to 0 NRF_TIMER2->TASKS_CLEAR = 1; NRF_TIMER2->CC[0] = (2^PWM_RESOLUTION - 1); NRF_TIMER2->CC[3] = 0; NRF_TIMER2->EVENTS_COMPARE[0] = 0; NRF_TIMER2->EVENTS_COMPARE[3] = 0; // Interrupt setup NRF_TIMER2->INTENSET = (TIMER_INTENSET_COMPARE3_Enabled << TIMER_INTENSET_COMPARE3_Pos); attachInterrupt(TIMER2_IRQn, TIMER2_Interrupt); // Start clock NRF_TIMER2->TASKS_START = 1; turn_On_PPI_to_GPIO_for_PWM(ulPin, 3, NRF_TIMER2, 0); PWM_Channels_Value[3] = (2^PWM_RESOLUTION - 1) - mapResolution(ulValue, _writeResolution, PWM_RESOLUTION); Timer2_Compare_Unit_Occupied_by_Pin[0] = ulPin; Pin_Occupied_for_PWM[ulPin] = 1; } else { // Using all 4 TASK channels of GPIOTE, it is not possible to add another PWM channel. } } } } /* // Defaults to digital write pinMode(ulPin, OUTPUT); ulValue = mapResolution(ulValue, _writeResolution, 8); if (ulValue < 128) digitalWrite(ulPin, LOW); else digitalWrite(ulPin, HIGH); */ }
extern void pinMode( uint32_t ulPin, uint32_t ulMode ) { if ( ulPin > PINS_COUNT ) { return ; } GPIO_TypeDef *gpio_port = g_APinDescription[ulPin].pPort; uint16_t gpio_pin = g_APinDescription[ulPin].ulPin; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(g_APinDescription[ulPin].ulPeripheral,ENABLE); GPIO_InitStructure.GPIO_Pin = gpio_pin; switch ( ulMode ) { case INPUT: GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; break ; case INPUT_PULLUP: GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; break ; case INPUT_PULLDOWN: GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; break; case OUTPUT: GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; break ; case AF_OUTPUT_PUSHPULL: //Used internally for Alternate Function Output PushPull(TIM, UART, SPI etc) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; break; case AF_OUTPUT_DRAIN: //Used internally for Alternate Function Output Drain(I2C etc) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; break; case AN_INPUT: //Used internally for ADC Input GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; break; case OUTPUT_OD : //Used internally for ADC Input GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; break; #if 0 case TIMER_PWM: { uint32_t ulValue = 0; uint32_t ulChannel; if ( g_APinDescription[ulPin].ulTimerPeripheral == NULL) { // Defaults to digital write pinMode(ulPin, OUTPUT); ulValue = mapResolution(ulValue, _writeResolution, 8); if (ulValue < 128) digitalWrite(ulPin, LOW); else digitalWrite(ulPin, HIGH); return; } TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; uint16_t TIM_CCR = 0; ulValue = mapResolution(ulValue, _writeResolution, PWM_RESOLUTION); //对于PWM 模块来说 该函数直接返回ulValue. //PWM Frequency : 1000 Hz,Timer counter clk:1MHz uint16_t TIM_Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; uint16_t TIM_ARR = (uint16_t)(1000000 / PWM_FREQUENCY) - 1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(gpio_port, &GPIO_InitStructure); if (!pinEnabled[ulPin]) { // Setup PWM for this pin // AFIO clock enable RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // TIM clock enable if(g_APinDescription[ulPin].ulTimerPeripheral == TIM1) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 , ENABLE); else if(g_APinDescription[ulPin].ulTimerPeripheral == TIM2) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); } else if(g_APinDescription[ulPin].ulTimerPeripheral == TIM3) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); } else if(g_APinDescription[ulPin].ulTimerPeripheral == TIM4) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); } else if(g_APinDescription[ulPin].ulTimerPeripheral == TIM5) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); } else if(g_APinDescription[ulPin].ulTimerPeripheral == TIM8) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8 , ENABLE); // Time base configuration TIM_TimeBaseStructure.TIM_Period = TIM_ARR; TIM_TimeBaseStructure.TIM_Prescaler = TIM_Prescaler; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//0 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //for TIM1 and TIM8 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(g_APinDescription[ulPin].ulTimerPeripheral, &TIM_TimeBaseStructure); pinEnabled[ulPin] = 1; } // PWM1 Mode configuration TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_Pulse = TIM_CCR; //for TIM1 and TIM8 TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; if(g_APinDescription[ulPin].ulTimerChannel == TIM_Channel_1) { // PWM1 Mode configuration: Channel1 TIM_OC1Init(g_APinDescription[ulPin].ulTimerPeripheral, &TIM_OCInitStructure); TIM_OC1PreloadConfig(g_APinDescription[ulPin].ulTimerPeripheral, TIM_OCPreload_Enable); } else if(g_APinDescription[ulPin].ulTimerChannel == TIM_Channel_2) { // PWM1 Mode configuration: Channel2 TIM_OC2Init(g_APinDescription[ulPin].ulTimerPeripheral, &TIM_OCInitStructure); TIM_OC2PreloadConfig(g_APinDescription[ulPin].ulTimerPeripheral, TIM_OCPreload_Enable); } else if(g_APinDescription[ulPin].ulTimerChannel == TIM_Channel_3) { // PWM1 Mode configuration: Channel3 TIM_OC3Init(g_APinDescription[ulPin].ulTimerPeripheral, &TIM_OCInitStructure); TIM_OC3PreloadConfig(g_APinDescription[ulPin].ulTimerPeripheral, TIM_OCPreload_Enable); } else if(g_APinDescription[ulPin].ulTimerChannel == TIM_Channel_4) { // PWM1 Mode configuration: Channel4 TIM_OC4Init(g_APinDescription[ulPin].ulTimerPeripheral, &TIM_OCInitStructure); TIM_OC4PreloadConfig(g_APinDescription[ulPin].ulTimerPeripheral, TIM_OCPreload_Enable); } TIM_ARRPreloadConfig(g_APinDescription[ulPin].ulTimerPeripheral, ENABLE); // TIM enable counter TIM_Cmd(g_APinDescription[ulPin].ulTimerPeripheral, ENABLE); //for TIM1 and TIM8 TIM_CtrlPWMOutputs(g_APinDescription[ulPin].ulTimerPeripheral, ENABLE); } return; #endif default: break ; } GPIO_Init(gpio_port, &GPIO_InitStructure); }
// Right now, PWM output only works on the pins with // hardware support. These are defined in the appropriate // pins_*.c file. For the rest of the pins, we default // to digital output. void analogWrite(uint32_t ulPin, uint32_t ulValue) { if (ulPin >= PINS_COUNT ) { return; } if ( g_APinDescription[ulPin].ulTimerPeripheral == NULL) { // Defaults to digital write pinMode(ulPin, OUTPUT); ulValue = mapResolution(ulValue, _writeResolution, 8); if (ulValue < 128) digitalWrite(ulPin, LOW); else digitalWrite(ulPin, HIGH); return; } TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; ulValue = mapResolution(ulValue, _writeResolution, PWM_RESOLUTION); //PWM Frequency : 1000 Hz,Timer counter clk:1MHz uint16_t TIM_Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; uint16_t TIM_ARR = (uint16_t)(1000000 / PWM_FREQUENCY) - 1; uint16_t Duty_Cycle = (uint16_t)((ulValue * 100) / 255); // TIM Channel Duty Cycle(%) = (TIM_CCR / TIM_ARR + 1) * 100 uint16_t TIM_CCR = (uint16_t)((Duty_Cycle * (TIM_ARR + 1)) / 100); #if defined (STM32F40_41xxx) uint8_t GPIO_AF_TIM; #endif pinMode(ulPin, AF_OUTPUT_PUSHPULL); if (!pinEnabled[ulPin]) { // Setup PWM for this pin // AFIO clock enable #if defined(STM32F10X_HD) || defined (STM32F10X_MD) RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); #elif defined (STM32F40_41xxx) RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE); #endif // TIM clock enable if(g_APinDescription[ulPin].ulTimerPeripheral == TIM1) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 , ENABLE); #if defined (STM32F40_41xxx) GPIO_AF_TIM = GPIO_AF_TIM1; #endif } else if(g_APinDescription[ulPin].ulTimerPeripheral == TIM2) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); #if defined (STM32F40_41xxx) GPIO_AF_TIM = GPIO_AF_TIM2; #endif } else if(g_APinDescription[ulPin].ulTimerPeripheral == TIM3) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); #if defined (STM32F40_41xxx) GPIO_AF_TIM = GPIO_AF_TIM3; #endif } else if(g_APinDescription[ulPin].ulTimerPeripheral == TIM4) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); #if defined (STM32F40_41xxx) GPIO_AF_TIM = GPIO_AF_TIM4; #endif } else if(g_APinDescription[ulPin].ulTimerPeripheral == TIM5) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); #if defined (STM32F40_41xxx) GPIO_AF_TIM = GPIO_AF_TIM5; #endif } else if(g_APinDescription[ulPin].ulTimerPeripheral == TIM8) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8 , ENABLE); #if defined (STM32F40_41xxx) GPIO_AF_TIM = GPIO_AF_TIM8; #endif } #if defined (STM32F40_41xxx) uint8_t pin_source=0; uint16_t pin_temp = ulPin; while(pin_temp != 0x0001) { pin_temp = pin_temp>>1; pin_source +=1; } GPIO_PinAFConfig(g_APinDescription[ulPin].pPort, pin_source, GPIO_AF_TIM); #endif // Time base configuration TIM_TimeBaseStructure.TIM_Period = TIM_ARR; TIM_TimeBaseStructure.TIM_Prescaler = TIM_Prescaler; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//0 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //for TIM1 and TIM8 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(g_APinDescription[ulPin].ulTimerPeripheral, &TIM_TimeBaseStructure); pinEnabled[ulPin] = 1; }