mirror of
https://github.com/modelec/odo_STM32.git
synced 2026-01-18 16:27:25 +01:00
tests
This commit is contained in:
File diff suppressed because one or more lines are too long
2
.settings/com.st.stm32cube.ide.mcu.sfrview.prefs
Normal file
2
.settings/com.st.stm32cube.ide.mcu.sfrview.prefs
Normal file
@@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
sfrviewstate={"fFavorites"\:{"fLists"\:{}},"fProperties"\:{"fNodeProperties"\:{}}}
|
||||
@@ -5,7 +5,7 @@
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="1020268094863512062" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="-1068160135481153484" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
@@ -16,7 +16,7 @@
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="1020268094863512062" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="-1068160135481153484" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
#define HAL_MODULE_ENABLED
|
||||
|
||||
#define HAL_ADC_MODULE_ENABLED
|
||||
/*#define HAL_ADC_MODULE_ENABLED */
|
||||
/*#define HAL_COMP_MODULE_ENABLED */
|
||||
/*#define HAL_CORDIC_MODULE_ENABLED */
|
||||
/*#define HAL_CRC_MODULE_ENABLED */
|
||||
|
||||
219
Core/Src/main.c
219
Core/Src/main.c
@@ -44,25 +44,21 @@ void ModelecOdometryLoop(void* pid, void* pidG, void* pidD);
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
ADC_HandleTypeDef hadc2;
|
||||
|
||||
TIM_HandleTypeDef htim1;
|
||||
TIM_HandleTypeDef htim2;
|
||||
TIM_HandleTypeDef htim3;
|
||||
TIM_HandleTypeDef htim8;
|
||||
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
int counter1=0;
|
||||
int counter2=0;
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
void SystemClock_Config(void);
|
||||
static void MX_GPIO_Init(void);
|
||||
static void MX_ADC2_Init(void);
|
||||
static void MX_TIM2_Init(void);
|
||||
static void MX_TIM1_Init(void);
|
||||
static void MX_TIM3_Init(void);
|
||||
static void MX_TIM8_Init(void);
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
@@ -102,16 +98,14 @@ int main(void)
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
MX_GPIO_Init();
|
||||
MX_ADC2_Init();
|
||||
MX_TIM2_Init();
|
||||
MX_TIM1_Init();
|
||||
MX_TIM3_Init();
|
||||
MX_TIM8_Init();
|
||||
MX_USB_Device_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
|
||||
HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_1); // IN1A
|
||||
HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_2); // IN2A
|
||||
// HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_1); // IN1A
|
||||
//HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_2); // IN2A
|
||||
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // IN1B
|
||||
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2); // IN2B
|
||||
HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);
|
||||
@@ -132,6 +126,8 @@ int main(void)
|
||||
CDC_Transmit_FS((uint8_t*)test, strlen(test));
|
||||
while (1)
|
||||
{
|
||||
counter2 = __HAL_TIM_GET_COUNTER(&htim2);
|
||||
counter1 = __HAL_TIM_GET_COUNTER(&htim3);
|
||||
ModelecOdometryLoop(pid, pidG, pidD);
|
||||
/* USER CODE END WHILE */
|
||||
|
||||
@@ -181,65 +177,6 @@ void SystemClock_Config(void)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ADC2 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_ADC2_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN ADC2_Init 0 */
|
||||
|
||||
/* USER CODE END ADC2_Init 0 */
|
||||
|
||||
ADC_ChannelConfTypeDef sConfig = {0};
|
||||
|
||||
/* USER CODE BEGIN ADC2_Init 1 */
|
||||
|
||||
/* USER CODE END ADC2_Init 1 */
|
||||
|
||||
/** Common config
|
||||
*/
|
||||
hadc2.Instance = ADC2;
|
||||
hadc2.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
|
||||
hadc2.Init.Resolution = ADC_RESOLUTION_12B;
|
||||
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
|
||||
hadc2.Init.GainCompensation = 0;
|
||||
hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
|
||||
hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
|
||||
hadc2.Init.LowPowerAutoWait = DISABLE;
|
||||
hadc2.Init.ContinuousConvMode = DISABLE;
|
||||
hadc2.Init.NbrOfConversion = 1;
|
||||
hadc2.Init.DiscontinuousConvMode = DISABLE;
|
||||
hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
|
||||
hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
|
||||
hadc2.Init.DMAContinuousRequests = DISABLE;
|
||||
hadc2.Init.Overrun = ADC_OVR_DATA_PRESERVED;
|
||||
hadc2.Init.OversamplingMode = DISABLE;
|
||||
if (HAL_ADC_Init(&hadc2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Regular Channel
|
||||
*/
|
||||
sConfig.Channel = ADC_CHANNEL_3;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_1;
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
|
||||
sConfig.SingleDiff = ADC_DIFFERENTIAL_ENDED;
|
||||
sConfig.OffsetNumber = ADC_OFFSET_NONE;
|
||||
sConfig.Offset = 0;
|
||||
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN ADC2_Init 2 */
|
||||
|
||||
/* USER CODE END ADC2_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM1 Initialization Function
|
||||
* @param None
|
||||
@@ -347,10 +284,10 @@ static void MX_TIM2_Init(void)
|
||||
htim2.Instance = TIM2;
|
||||
htim2.Init.Prescaler = 0;
|
||||
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim2.Init.Period = 4294967295;
|
||||
htim2.Init.Period = 65535;
|
||||
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
sConfig.EncoderMode = TIM_ENCODERMODE_TI1;
|
||||
sConfig.EncoderMode = TIM_ENCODERMODE_TI12;
|
||||
sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
|
||||
sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
|
||||
sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
|
||||
@@ -399,7 +336,7 @@ static void MX_TIM3_Init(void)
|
||||
htim3.Init.Period = 65535;
|
||||
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
sConfig.EncoderMode = TIM_ENCODERMODE_TI1;
|
||||
sConfig.EncoderMode = TIM_ENCODERMODE_TI12;
|
||||
sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
|
||||
sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
|
||||
sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
|
||||
@@ -424,82 +361,6 @@ static void MX_TIM3_Init(void)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM8 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_TIM8_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN TIM8_Init 0 */
|
||||
|
||||
/* USER CODE END TIM8_Init 0 */
|
||||
|
||||
TIM_MasterConfigTypeDef sMasterConfig = {0};
|
||||
TIM_OC_InitTypeDef sConfigOC = {0};
|
||||
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
|
||||
|
||||
/* USER CODE BEGIN TIM8_Init 1 */
|
||||
|
||||
/* USER CODE END TIM8_Init 1 */
|
||||
htim8.Instance = TIM8;
|
||||
htim8.Init.Prescaler = 0;
|
||||
htim8.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim8.Init.Period = 630;
|
||||
htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim8.Init.RepetitionCounter = 0;
|
||||
htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
|
||||
if (HAL_TIM_PWM_Init(&htim8) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||
sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
|
||||
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||
if (HAL_TIMEx_MasterConfigSynchronization(&htim8, &sMasterConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.OCMode = TIM_OCMODE_PWM1;
|
||||
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_PWM_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
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.BreakAFMode = TIM_BREAK_AFMODE_INPUT;
|
||||
sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
|
||||
sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
|
||||
sBreakDeadTimeConfig.Break2Filter = 0;
|
||||
sBreakDeadTimeConfig.Break2AFMode = TIM_BREAK_AFMODE_INPUT;
|
||||
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
|
||||
if (HAL_TIMEx_ConfigBreakDeadTime(&htim8, &sBreakDeadTimeConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN TIM8_Init 2 */
|
||||
|
||||
/* USER CODE END TIM8_Init 2 */
|
||||
HAL_TIM_MspPostInit(&htim8);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GPIO Initialization Function
|
||||
* @param None
|
||||
@@ -507,74 +368,14 @@ static void MX_TIM8_Init(void)
|
||||
*/
|
||||
static void MX_GPIO_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
/* USER CODE BEGIN MX_GPIO_Init_1 */
|
||||
/* USER CODE END MX_GPIO_Init_1 */
|
||||
|
||||
/* GPIO Ports Clock Enable */
|
||||
__HAL_RCC_GPIOF_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pins : PA2 PA3 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF12_LPUART1;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : PA5 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_5;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF15_EVENTOUT;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : PB0 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_0;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : PA10 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_10;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : PA15 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_15;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : PB5 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_5;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF15_EVENTOUT;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : PB7 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_7;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN MX_GPIO_Init_2 */
|
||||
/* USER CODE END MX_GPIO_Init_2 */
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ void ModelecOdometryUpdate() {
|
||||
|
||||
char msg[128];
|
||||
sprintf(msg, " Update current position : X: %.3f m, Y: %.3f m, Theta: %.3f rad\r\n", x, y, theta);
|
||||
//CDC_Transmit_FS((uint8_t*) msg, strlen(msg));
|
||||
CDC_Transmit_FS((uint8_t*) msg, strlen(msg));
|
||||
float dt = 0.01f; // 10 ms
|
||||
|
||||
// Calcul des vitesses des roues
|
||||
@@ -193,6 +193,7 @@ void ModelecOdometryLoop(void* pid, void* pidG, void* pidD) {
|
||||
//On met à jour toutes les 10ms
|
||||
if (isDelayPassed(10)) {
|
||||
ModelecOdometryUpdate();
|
||||
/*
|
||||
HAL_Delay(1000);
|
||||
Point currentPoint(x, y,theta, StatePoint::INTERMEDIAIRE);
|
||||
Point targetPoint(0.20, 0.20,0, StatePoint::FINAL);
|
||||
@@ -205,6 +206,7 @@ void ModelecOdometryLoop(void* pid, void* pidG, void* pidD) {
|
||||
determinationCoefPosition(currentPoint,targetPoint, *pidPosition, *pidVitesseG, *pidVitesseD);
|
||||
HAL_Delay(1000);
|
||||
motor.update();
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
/* USER CODE END 0 */
|
||||
|
||||
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
|
||||
/**
|
||||
/**
|
||||
* Initializes the Global MSP.
|
||||
*/
|
||||
void HAL_MspInit(void)
|
||||
@@ -83,81 +83,6 @@ void HAL_MspInit(void)
|
||||
/* USER CODE END MspInit 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ADC MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param hadc: ADC handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
|
||||
if(hadc->Instance==ADC2)
|
||||
{
|
||||
/* USER CODE BEGIN ADC2_MspInit 0 */
|
||||
|
||||
/* USER CODE END ADC2_MspInit 0 */
|
||||
|
||||
/** Initializes the peripherals clocks
|
||||
*/
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC12;
|
||||
PeriphClkInit.Adc12ClockSelection = RCC_ADC12CLKSOURCE_SYSCLK;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_ADC12_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**ADC2 GPIO Configuration
|
||||
PA6 ------> ADC2_IN3
|
||||
PA7 ------> ADC2_IN4
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN ADC2_MspInit 1 */
|
||||
|
||||
/* USER CODE END ADC2_MspInit 1 */
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ADC MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param hadc: ADC handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
if(hadc->Instance==ADC2)
|
||||
{
|
||||
/* USER CODE BEGIN ADC2_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END ADC2_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_ADC12_CLK_DISABLE();
|
||||
|
||||
/**ADC2 GPIO Configuration
|
||||
PA6 ------> ADC2_IN3
|
||||
PA7 ------> ADC2_IN4
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_6|GPIO_PIN_7);
|
||||
|
||||
/* USER CODE BEGIN ADC2_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END ADC2_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM_Base MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
@@ -205,8 +130,8 @@ void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef* htim_encoder)
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
@@ -230,15 +155,15 @@ void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef* htim_encoder)
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_4;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_4;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
@@ -249,29 +174,6 @@ void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef* htim_encoder)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM_PWM MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param htim_pwm: TIM_PWM handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* htim_pwm)
|
||||
{
|
||||
if(htim_pwm->Instance==TIM8)
|
||||
{
|
||||
/* USER CODE BEGIN TIM8_MspInit 0 */
|
||||
|
||||
/* USER CODE END TIM8_MspInit 0 */
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_TIM8_CLK_ENABLE();
|
||||
/* USER CODE BEGIN TIM8_MspInit 1 */
|
||||
|
||||
/* USER CODE END TIM8_MspInit 1 */
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
@@ -280,6 +182,7 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
|
||||
/* USER CODE BEGIN TIM1_MspPostInit 0 */
|
||||
|
||||
/* USER CODE END TIM1_MspPostInit 0 */
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**TIM1 GPIO Configuration
|
||||
PA8 ------> TIM1_CH1
|
||||
@@ -296,35 +199,6 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
|
||||
|
||||
/* USER CODE END TIM1_MspPostInit 1 */
|
||||
}
|
||||
else if(htim->Instance==TIM8)
|
||||
{
|
||||
/* USER CODE BEGIN TIM8_MspPostInit 0 */
|
||||
|
||||
/* USER CODE END TIM8_MspPostInit 0 */
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
/**TIM8 GPIO Configuration
|
||||
PB6 ------> TIM8_CH1
|
||||
PB8-BOOT0 ------> TIM8_CH2
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_6;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF5_TIM8;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_8;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF10_TIM8;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN TIM8_MspPostInit 1 */
|
||||
|
||||
/* USER CODE END TIM8_MspPostInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
@@ -398,28 +272,6 @@ void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef* htim_encoder)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM_PWM MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param htim_pwm: TIM_PWM handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef* htim_pwm)
|
||||
{
|
||||
if(htim_pwm->Instance==TIM8)
|
||||
{
|
||||
/* USER CODE BEGIN TIM8_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END TIM8_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_TIM8_CLK_DISABLE();
|
||||
/* USER CODE BEGIN TIM8_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END TIM8_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
133
pcb_odo.ioc
133
pcb_odo.ioc
@@ -1,12 +1,4 @@
|
||||
#MicroXplorer Configuration settings - do not modify
|
||||
ADC2.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_3
|
||||
ADC2.CommonPathInternal=null|null|null|null
|
||||
ADC2.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,NbrOfConversionFlag,SingleDiff-0\#ChannelRegularConversion,CommonPathInternal
|
||||
ADC2.NbrOfConversionFlag=1
|
||||
ADC2.OffsetNumber-0\#ChannelRegularConversion=ADC_OFFSET_NONE
|
||||
ADC2.Rank-0\#ChannelRegularConversion=1
|
||||
ADC2.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_2CYCLES_5
|
||||
ADC2.SingleDiff-0\#ChannelRegularConversion=ADC_DIFFERENTIAL_ENDED
|
||||
CAD.formats=
|
||||
CAD.pinconfig=
|
||||
CAD.provider=
|
||||
@@ -15,47 +7,31 @@ GPIO.groupedBy=Group By Peripherals
|
||||
KeepUserPlacement=false
|
||||
Mcu.CPN=STM32G491KEU6
|
||||
Mcu.Family=STM32G4
|
||||
Mcu.IP0=ADC2
|
||||
Mcu.IP1=NVIC
|
||||
Mcu.IP2=RCC
|
||||
Mcu.IP3=SYS
|
||||
Mcu.IP4=TIM1
|
||||
Mcu.IP5=TIM2
|
||||
Mcu.IP6=TIM3
|
||||
Mcu.IP7=TIM8
|
||||
Mcu.IP8=USB
|
||||
Mcu.IP9=USB_DEVICE
|
||||
Mcu.IPNb=10
|
||||
Mcu.IP0=NVIC
|
||||
Mcu.IP1=RCC
|
||||
Mcu.IP2=SYS
|
||||
Mcu.IP3=TIM1
|
||||
Mcu.IP4=TIM2
|
||||
Mcu.IP5=TIM3
|
||||
Mcu.IP6=USB
|
||||
Mcu.IP7=USB_DEVICE
|
||||
Mcu.IPNb=8
|
||||
Mcu.Name=STM32G491K(C-E)Ux
|
||||
Mcu.Package=UFQFPN32
|
||||
Mcu.Pin0=PA0
|
||||
Mcu.Pin1=PA1
|
||||
Mcu.Pin10=PA9
|
||||
Mcu.Pin11=PA10
|
||||
Mcu.Pin12=PA11
|
||||
Mcu.Pin13=PA12
|
||||
Mcu.Pin14=PA13
|
||||
Mcu.Pin15=PA14
|
||||
Mcu.Pin16=PA15
|
||||
Mcu.Pin17=PB3
|
||||
Mcu.Pin18=PB4
|
||||
Mcu.Pin19=PB5
|
||||
Mcu.Pin2=PA2
|
||||
Mcu.Pin20=PB6
|
||||
Mcu.Pin21=PB7
|
||||
Mcu.Pin22=PB8-BOOT0
|
||||
Mcu.Pin23=VP_SYS_VS_Systick
|
||||
Mcu.Pin24=VP_SYS_VS_DBSignals
|
||||
Mcu.Pin25=VP_TIM1_VS_ClockSourceINT
|
||||
Mcu.Pin26=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
|
||||
Mcu.Pin3=PA3
|
||||
Mcu.Pin4=PA4
|
||||
Mcu.Pin5=PA5
|
||||
Mcu.Pin6=PA6
|
||||
Mcu.Pin7=PA7
|
||||
Mcu.Pin8=PB0
|
||||
Mcu.Pin9=PA8
|
||||
Mcu.PinsNb=27
|
||||
Mcu.Pin0=PF0-OSC_IN
|
||||
Mcu.Pin1=PA0
|
||||
Mcu.Pin10=VP_SYS_VS_DBSignals
|
||||
Mcu.Pin11=VP_TIM1_VS_ClockSourceINT
|
||||
Mcu.Pin12=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
|
||||
Mcu.Pin2=PA1
|
||||
Mcu.Pin3=PA4
|
||||
Mcu.Pin4=PA8
|
||||
Mcu.Pin5=PA9
|
||||
Mcu.Pin6=PA11
|
||||
Mcu.Pin7=PA12
|
||||
Mcu.Pin8=PB4
|
||||
Mcu.Pin9=VP_SYS_VS_Systick
|
||||
Mcu.PinsNb=13
|
||||
Mcu.ThirdPartyNb=0
|
||||
Mcu.UserConstants=
|
||||
Mcu.UserName=STM32G491KEUx
|
||||
@@ -73,54 +49,37 @@ NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false
|
||||
NVIC.USB_LP_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
|
||||
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||
PA0.GPIOParameters=GPIO_Speed,GPIO_PuPd
|
||||
PA0.GPIO_PuPd=GPIO_PULLUP
|
||||
PA0.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||
PA0.Locked=true
|
||||
PA0.Signal=S_TIM2_CH1
|
||||
PA1.GPIOParameters=GPIO_ModeDefaultPP,GPIO_Speed,GPIO_PuPd
|
||||
PA1.GPIO_ModeDefaultPP=GPIO_MODE_AF_PP
|
||||
PA1.GPIO_PuPd=GPIO_PULLUP
|
||||
PA1.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||
PA1.Locked=true
|
||||
PA1.Signal=S_TIM2_CH2
|
||||
PA10.Locked=true
|
||||
PA10.Signal=GPIO_Output
|
||||
PA11.Mode=Device
|
||||
PA11.Signal=USB_DM
|
||||
PA12.Mode=Device
|
||||
PA12.Signal=USB_DP
|
||||
PA13.Locked=true
|
||||
PA13.Signal=SYS_JTMS-SWDIO
|
||||
PA14.Locked=true
|
||||
PA14.Signal=SYS_JTCK-SWCLK
|
||||
PA15.Locked=true
|
||||
PA15.Signal=I2C1_SCL
|
||||
PA2.Locked=true
|
||||
PA2.Signal=LPUART1_TX
|
||||
PA3.Locked=true
|
||||
PA3.Signal=LPUART1_RX
|
||||
PA4.GPIOParameters=GPIO_Speed,GPIO_PuPd
|
||||
PA4.GPIO_PuPd=GPIO_PULLUP
|
||||
PA4.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||
PA4.Locked=true
|
||||
PA4.Signal=S_TIM3_CH2
|
||||
PA5.Locked=true
|
||||
PA5.Signal=EVENTOUT
|
||||
PA6.Locked=true
|
||||
PA6.Mode=IN3-Differential
|
||||
PA6.Signal=ADC2_IN3
|
||||
PA7.Locked=true
|
||||
PA7.Mode=IN3-Differential
|
||||
PA7.Signal=ADC2_IN4
|
||||
PA8.Locked=true
|
||||
PA8.Signal=S_TIM1_CH1
|
||||
PA9.Locked=true
|
||||
PA9.Signal=S_TIM1_CH2
|
||||
PB0.Locked=true
|
||||
PB0.Signal=GPIO_Output
|
||||
PB3.Locked=true
|
||||
PB3.Signal=SYS_JTDO-SWO
|
||||
PB4.GPIOParameters=GPIO_Speed,GPIO_PuPd
|
||||
PB4.GPIO_PuPd=GPIO_PULLUP
|
||||
PB4.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||
PB4.Locked=true
|
||||
PB4.Signal=S_TIM3_CH1
|
||||
PB5.Locked=true
|
||||
PB5.Signal=EVENTOUT
|
||||
PB6.Locked=true
|
||||
PB6.Signal=S_TIM8_CH1
|
||||
PB7.Locked=true
|
||||
PB7.Signal=I2C1_SDA
|
||||
PB8-BOOT0.Locked=true
|
||||
PB8-BOOT0.Signal=S_TIM8_CH2
|
||||
PF0-OSC_IN.Mode=HSE-External-Clock-Source
|
||||
PF0-OSC_IN.Signal=RCC_OSC_IN
|
||||
PinOutPanel.RotationAngle=0
|
||||
ProjectManager.AskForMigrate=true
|
||||
ProjectManager.BackupPrevious=false
|
||||
@@ -153,7 +112,7 @@ ProjectManager.ToolChainLocation=
|
||||
ProjectManager.UAScriptAfterPath=
|
||||
ProjectManager.UAScriptBeforePath=
|
||||
ProjectManager.UnderRoot=true
|
||||
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_ADC2_Init-ADC2-false-HAL-true,4-MX_TIM2_Init-TIM2-false-HAL-true,5-MX_TIM1_Init-TIM1-false-HAL-true,6-MX_TIM3_Init-TIM3-false-HAL-true,7-MX_TIM8_Init-TIM8-false-HAL-true,8-MX_USB_Device_Init-USB_DEVICE-false-HAL-false
|
||||
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_TIM2_Init-TIM2-false-HAL-true,4-MX_TIM1_Init-TIM1-false-HAL-true,5-MX_TIM3_Init-TIM3-false-HAL-true,6-MX_USB_Device_Init-USB_DEVICE-false-HAL-false
|
||||
RCC.AHBFreq_Value=16000000
|
||||
RCC.APB1Freq_Value=16000000
|
||||
RCC.APB1TimFreq_Value=16000000
|
||||
@@ -204,20 +163,16 @@ SH.S_TIM3_CH1.0=TIM3_CH1,Encoder_Interface
|
||||
SH.S_TIM3_CH1.ConfNb=1
|
||||
SH.S_TIM3_CH2.0=TIM3_CH2,Encoder_Interface
|
||||
SH.S_TIM3_CH2.ConfNb=1
|
||||
SH.S_TIM8_CH1.0=TIM8_CH1,PWM Generation1 CH1
|
||||
SH.S_TIM8_CH1.ConfNb=1
|
||||
SH.S_TIM8_CH2.0=TIM8_CH2,PWM Generation2 CH2
|
||||
SH.S_TIM8_CH2.ConfNb=1
|
||||
TIM1.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE
|
||||
TIM1.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
|
||||
TIM1.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
|
||||
TIM1.IPParameters=Channel-PWM Generation1 CH1,Channel-PWM Generation2 CH2,PeriodNoDither,AutoReloadPreload
|
||||
TIM1.PeriodNoDither=630
|
||||
TIM8.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE
|
||||
TIM8.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
|
||||
TIM8.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
|
||||
TIM8.IPParameters=Channel-PWM Generation2 CH2,PeriodNoDither,AutoReloadPreload,Channel-PWM Generation1 CH1
|
||||
TIM8.PeriodNoDither=630
|
||||
TIM2.EncoderMode=TIM_ENCODERMODE_TI12
|
||||
TIM2.IPParameters=PeriodNoDither,EncoderMode
|
||||
TIM2.PeriodNoDither=65535
|
||||
TIM3.EncoderMode=TIM_ENCODERMODE_TI12
|
||||
TIM3.IPParameters=EncoderMode
|
||||
USB_DEVICE.CLASS_NAME_FS=CDC
|
||||
USB_DEVICE.IPParameters=VirtualMode,VirtualModeFS,CLASS_NAME_FS
|
||||
USB_DEVICE.VirtualMode=Cdc
|
||||
|
||||
14
usb-cbc.py
Normal file
14
usb-cbc.py
Normal file
@@ -0,0 +1,14 @@
|
||||
import serial
|
||||
|
||||
SERIAL_PORT = 'COM8' # Change selon ton port
|
||||
BAUDRATE = 115200 # Peu importe ici, c’est USB, mais ça évite des bugs parfois
|
||||
|
||||
try:
|
||||
with serial.Serial(SERIAL_PORT, BAUDRATE, timeout=1) as ser:
|
||||
print(f"Écoute sur {SERIAL_PORT}...")
|
||||
while True:
|
||||
line = ser.readline().decode(errors='ignore').strip()
|
||||
if line:
|
||||
print(f"[STM32] {line}")
|
||||
except serial.SerialException as e:
|
||||
print(f"Erreur : {e}")
|
||||
Reference in New Issue
Block a user