2019-09-22 07:25 PM
Hi,
I am working with stm32mp157-dk2.
Arduino connector CN16-pin5 is giving 5v.
How can I switch on/off this pin in my M4 program ?
I couldn't find a solution or example, could you please help me ?
Solved! Go to Solution.
2019-09-22 11:44 PM
This pin is tied to 5V_VIN (VBUS supply from USB Type-C connector CN6) thru a 0ohm resistor. No way to switch off by SW.
This 5V is present on all Arduino.
On STM32MP157-DK2, in case of conflict with your Arduino shield, you could disconnect it permanently by removing R165 (visible on PCB close the the 5V CN16 pin).
2019-09-22 11:44 PM
This pin is tied to 5V_VIN (VBUS supply from USB Type-C connector CN6) thru a 0ohm resistor. No way to switch off by SW.
This 5V is present on all Arduino.
On STM32MP157-DK2, in case of conflict with your Arduino shield, you could disconnect it permanently by removing R165 (visible on PCB close the the 5V CN16 pin).
2019-09-23 01:40 AM
thank you. I dont use Arduino shield. I just want to control a 5v ventilator with m4 program on dk2 board. (just switching on / off)
I think I should use gpio connectors. There are two gpio pins that give 5v supply.
2019-09-23 02:03 AM
Altough GPIOs could sustain 5V, they are limited in power to about 20mA (with 1.3V output, which mean only 3.7V remain on the load), so you probably can't control a fan power in that way. You must add a transistor or similar power control.
To control FAN, you could better make use of a PWM fan (e.g. most fan used in computers) which could be supplied from 5V or 12V directly whereas the PWM pin could be handled directly by a timer output in 3.3V from STM32MP1 to control fan speed from 0 to 100%.
Alternatively, if intermediate speeds are not required, a simple GPIO on the fan PWM pin could control from 0 or 100% (i.e. OFF/ON).
2019-09-23 04:18 AM
thanks for detailed answer
2019-09-23 05:32 AM
I havent done yet any project including PWM control. Is there any referance code or example written for m4 (dk2) that I can refer ?
2019-09-23 05:55 AM
Examples are no need to be DK2 specific. You probably find some just googling "STM32 PWM".
First you need to configure your timer in PWM mode at the needed frequency (usually 25kHz for PC PWM fan) on the pin you want the output control. This is mostly done under STM32CubeMx.
Then in your code, once init you have to use the HAL_TIM_PWM_Start() and __HAL_TIM_SET_COMPARE() to change the duty cycle.
Note that as PWM fan also provide a tachometer output, you could also monitor the fan speed using another timer input.
see also: STM32MP1-WDG_TIMERS-General_Purpose_Timer_GPTIM.pdf
2019-09-25 06:48 PM
Yes, I will use 4-pin pwm fan. I will use TIM1 for pwm output and TIM8 as rpm (tacho) input.
In CubeMX Pinout& Configuration menu there are three options for the channel1 of TIM8 as rpm input:
Which one should I select ?
What kind of calculation should I do after reading this channel of TIM8 in order to find RPM (tacho) ?
tnx
2019-09-26 02:02 AM
I'm not specialist of timers, but I have used 'input capture triggered by TRC' in the past for that purpose on an STM32L432.
Count TIM1 is gated for 1second by TIM15.
Then, RPM = 60/2 * __HAL_TIM_GET_COMPARE(&htim1,TIM_CHANNEL_1). Notice the /2 as the FAN here generate two pulses per rotation.
Here is some code of timer init for RPM measurement, as example as it likely need to be adapted to STM32MP1.
There is maybe better and/or more precise way to measure the frequency on RPM pin, but this one is fair enough.
Note that you should enable pull-up on TIMx_ETR pin connected to FAN output (which is open drain).
MX_TIM16_Init();
MX_TIM15_Init();
/* TIM1 is counting on TACHometer pulses gated for 1sec by TIM15 */
HAL_TIM_IC_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_OC_Start(&htim15, TIM_CHANNEL_1);
/* TIM1 init function */
static void MX_TIM1_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_SlaveConfigTypeDef sSlaveConfig;
TIM_MasterConfigTypeDef sMasterConfig;
TIM_IC_InitTypeDef sConfigIC;
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 0xffff;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_ETRMODE2;
sClockSourceConfig.ClockPolarity = TIM_CLOCKPOLARITY_NONINVERTED;
sClockSourceConfig.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1;
sClockSourceConfig.ClockFilter = 0;
if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
if (HAL_TIM_IC_Init(&htim1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;
sSlaveConfig.InputTrigger = TIM_TS_ITR0;
if (HAL_TIM_SlaveConfigSynchronization(&htim1, &sSlaveConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_TRC;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* TIM15 init function */
static void MX_TIM15_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;
TIM_OC_InitTypeDef sConfigOC;
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;
htim15.Instance = TIM15;
htim15.Init.Prescaler = (HAL_RCC_GetPCLK2Freq()/10000)-1;
htim15.Init.CounterMode = TIM_COUNTERMODE_UP;
htim15.Init.Period = 9999;
htim15.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim15.Init.RepetitionCounter = 0;
if (HAL_TIM_Base_Init(&htim15) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim15, &sClockSourceConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
if (HAL_TIM_OC_Init(&htim15) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim15, &sMasterConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sConfigOC.OCMode = TIM_OCMODE_TIMING;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if (HAL_TIM_OC_ConfigChannel(&htim15, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.BreakFilter = 0;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim15, &sBreakDeadTimeConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}