UART done
This commit is contained in:
parent
f979a89e5f
commit
582dd2b5b7
5 changed files with 164 additions and 84 deletions
|
@ -23,4 +23,5 @@ int MyGPIO_Read ( GPIO_TypeDef * GPIO , char GPIO_Pin ) ; // renvoie 0 ou autre
|
|||
void MyGPIO_Set ( GPIO_TypeDef * GPIO , char GPIO_Pin ) ;
|
||||
void MyGPIO_Reset ( GPIO_TypeDef * GPIO , char GPIO_Pin ) ;
|
||||
void MyGPIO_Toggle ( GPIO_TypeDef * GPIO , char GPIO_Pin ) ;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,35 +2,47 @@
|
|||
|
||||
|
||||
//---------------------FONCTION D'INITIALISATION-----------------//
|
||||
void MyGPIO_Init ( MyGPIO_Struct_TypeDef * GPIOStructPtr){
|
||||
void MyGPIO_Init ( MyGPIO_Struct_TypeDef * GPIOStructPtr )
|
||||
{
|
||||
|
||||
//INITIALISATION DE LA CLOCK CORRESPONDANT AU GPIO A, B ou C
|
||||
if (GPIOStructPtr->GPIO == GPIOA) {
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
|
||||
} else if (GPIOStructPtr->GPIO == GPIOB) {
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
|
||||
} else if (GPIOStructPtr->GPIO == GPIOC) {
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
|
||||
} else if (GPIOStructPtr->GPIO == GPIOD) {
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPDEN;
|
||||
/* Activation of the GPIO port specific clock */
|
||||
if (GPIOStructPtr->GPIO == GPIOA)
|
||||
{
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
|
||||
}
|
||||
else if (GPIOStructPtr->GPIO == GPIOB)
|
||||
{
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
|
||||
}
|
||||
else if (GPIOStructPtr->GPIO == GPIOC)
|
||||
{
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
|
||||
}
|
||||
else if (GPIOStructPtr->GPIO == GPIOD)
|
||||
{
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPDEN;
|
||||
}
|
||||
|
||||
|
||||
/* Reset, and then configuration writing of the selected GPIO Pin */
|
||||
if(GPIOStructPtr->GPIO_Pin <= 8)
|
||||
{
|
||||
GPIOStructPtr->GPIO->CRL &= ~0xF<<(4*(GPIOStructPtr->GPIO_Pin));
|
||||
GPIOStructPtr->GPIO->CRL |= (GPIOStructPtr->GPIO_Conf)<<(4*(GPIOStructPtr->GPIO_Pin));
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIOStructPtr->GPIO->CRH &= ~0xF<<(4*((GPIOStructPtr->GPIO_Pin)%8));
|
||||
GPIOStructPtr->GPIO->CRH |= (GPIOStructPtr->GPIO_Conf)<<(4*((GPIOStructPtr->GPIO_Pin)%8));
|
||||
}
|
||||
|
||||
//CONFIGURATION DE LA PIN UTILISEE (voir table20 p9.1)
|
||||
if(GPIOStructPtr->GPIO_Pin < 8){
|
||||
GPIOStructPtr->GPIO->CRL &= ~(0xF << (4 * GPIOStructPtr->GPIO_Pin));
|
||||
GPIOStructPtr->GPIO->CRL |= (GPIOStructPtr->GPIO_Conf << (4 * GPIOStructPtr->GPIO_Pin));
|
||||
if(GPIOStructPtr->GPIO_Conf == (char)In_PullDown)
|
||||
{
|
||||
GPIOStructPtr->GPIO->ODR &= ~(0x1<<(GPIOStructPtr->GPIO_Pin));
|
||||
}
|
||||
else {
|
||||
GPIOStructPtr->GPIO->CRH &= ~(0xF << (4 * GPIOStructPtr->GPIO_Pin - 8));
|
||||
GPIOStructPtr->GPIO->CRH |= (GPIOStructPtr->GPIO_Conf << (4 * GPIOStructPtr->GPIO_Pin - 8));
|
||||
}
|
||||
|
||||
//CONFIGURATION DE L'ODR EN ENTREE (pull up et down uniquement)
|
||||
if(GPIOStructPtr->GPIO_Conf == In_PullUp){
|
||||
GPIOStructPtr->GPIO->ODR = 0x1;
|
||||
}
|
||||
else if(GPIOStructPtr->GPIO_Conf == In_PullDown){
|
||||
GPIOStructPtr->GPIO->ODR = 0x0;
|
||||
else if(GPIOStructPtr->GPIO_Conf == (char)In_PullUp)
|
||||
{
|
||||
GPIOStructPtr->GPIO->ODR |= 0x1<<(GPIOStructPtr->GPIO_Pin);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,3 +74,4 @@ void MyGPIO_Reset ( GPIO_TypeDef * GPIO , char GPIO_Pin ){
|
|||
void MyGPIO_Toggle ( GPIO_TypeDef * GPIO , char GPIO_Pin ){
|
||||
GPIO->ODR ^= (1 << GPIO_Pin);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,10 @@ void UART_init(MyUART_Struct_Typedef * UART)
|
|||
{
|
||||
if(UART->UART ==USART1)
|
||||
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
|
||||
if(UART->UART ==USART2)
|
||||
RCC->APB2ENR |= RCC_APB1ENR_USART2EN;
|
||||
if(UART->UART ==USART3)
|
||||
RCC->APB2ENR |= RCC_APB1ENR_USART3EN;
|
||||
else if(UART->UART ==USART2)
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
|
||||
else if(UART->UART ==USART3)
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
|
||||
|
||||
|
||||
RCC->APB2ENR |= RCC_APB2ENR_USART1EN; // Validation horloge USART1
|
||||
|
@ -28,9 +28,9 @@ void UART_init(MyUART_Struct_Typedef * UART)
|
|||
|
||||
void UART_send(char data)
|
||||
{
|
||||
while(!(USART1->SR & USART_SR_TXE)){} //Attendre l'autorisation de transmission
|
||||
while(!(USART1->SR & USART_SR_TXE) | !(USART2->SR & USART_SR_TXE)){} //Attendre l'autorisation de transmission
|
||||
USART1->DR |= data;
|
||||
while(!(USART1->SR & USART_SR_TC)){} //Attendre la fin de transmission
|
||||
while(!(USART1->SR & USART_SR_TC) | !(USART2->SR & USART_SR_TC)){} //Attendre la fin de transmission
|
||||
}
|
||||
|
||||
char UART_read(char data, MyUART_Struct_Typedef * UART)
|
||||
|
@ -84,3 +84,24 @@ void USART3_IRQHandler(void)
|
|||
USART3->SR &= ~USART_SR_TC; // effacer le bit de transmission terminée
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void UART_interruption (MyUART_Struct_Typedef * UART)
|
||||
{
|
||||
UART->UART->CR1 |= USART_CR1_RXNEIE;
|
||||
|
||||
if (UART->UART==USART1)
|
||||
{
|
||||
NVIC->ISER[1] |= (1<<(USART1_IRQn-32));
|
||||
}
|
||||
if (UART->UART==USART2)
|
||||
{
|
||||
NVIC->ISER[1] |= (1<<(USART2_IRQn-32));
|
||||
}
|
||||
if (UART->UART==USART3)
|
||||
{
|
||||
NVIC->ISER[1] |= (1<<(USART3_IRQn-32));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
<OPTFL>
|
||||
<tvExp>1</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<IsCurrentTarget>0</IsCurrentTarget>
|
||||
<IsCurrentTarget>1</IsCurrentTarget>
|
||||
</OPTFL>
|
||||
<CpuCode>18</CpuCode>
|
||||
<DebugOpt>
|
||||
|
@ -125,7 +125,7 @@
|
|||
<SetRegEntry>
|
||||
<Number>0</Number>
|
||||
<Key>DLGDARM</Key>
|
||||
<Name>(1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(100=-1,-1,-1,-1,0)(110=-1,-1,-1,-1,0)(111=-1,-1,-1,-1,0)(1011=-1,-1,-1,-1,0)(180=-1,-1,-1,-1,0)(120=297,604,718,1031,0)(121=-1,-1,-1,-1,0)(122=546,289,967,716,0)(123=-1,-1,-1,-1,0)(140=-1,-1,-1,-1,0)(240=-1,-1,-1,-1,0)(190=-1,-1,-1,-1,0)(200=-1,-1,-1,-1,0)(170=-1,-1,-1,-1,0)(130=911,135,1505,886,0)(131=997,343,1591,1094,0)(132=-1,-1,-1,-1,0)(133=-1,-1,-1,-1,0)(160=930,345,1378,759,1)(161=1383,268,1831,682,0)(162=-1,-1,-1,-1,0)(210=-1,-1,-1,-1,0)(211=-1,-1,-1,-1,0)(220=-1,-1,-1,-1,0)(221=-1,-1,-1,-1,0)(230=-1,-1,-1,-1,0)(234=-1,-1,-1,-1,0)(231=-1,-1,-1,-1,0)(232=-1,-1,-1,-1,0)(233=-1,-1,-1,-1,0)(150=-1,-1,-1,-1,0)(151=-1,-1,-1,-1,0)</Name>
|
||||
<Name>(1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(100=-1,-1,-1,-1,0)(110=-1,-1,-1,-1,0)(111=-1,-1,-1,-1,0)(1011=-1,-1,-1,-1,0)(180=-1,-1,-1,-1,0)(120=865,485,1286,912,1)(121=-1,-1,-1,-1,0)(122=546,289,967,716,0)(123=-1,-1,-1,-1,0)(140=-1,-1,-1,-1,0)(240=-1,-1,-1,-1,0)(190=-1,-1,-1,-1,0)(200=-1,-1,-1,-1,0)(170=-1,-1,-1,-1,0)(130=911,135,1505,886,0)(131=997,343,1591,1094,0)(132=-1,-1,-1,-1,0)(133=-1,-1,-1,-1,0)(160=1131,175,1579,589,1)(161=1383,268,1831,682,0)(162=-1,-1,-1,-1,0)(210=-1,-1,-1,-1,0)(211=-1,-1,-1,-1,0)(220=-1,-1,-1,-1,0)(221=-1,-1,-1,-1,0)(230=-1,-1,-1,-1,0)(234=-1,-1,-1,-1,0)(231=-1,-1,-1,-1,0)(232=-1,-1,-1,-1,0)(233=-1,-1,-1,-1,0)(150=-1,-1,-1,-1,0)(151=-1,-1,-1,-1,0)</Name>
|
||||
</SetRegEntry>
|
||||
<SetRegEntry>
|
||||
<Number>0</Number>
|
||||
|
@ -143,7 +143,72 @@
|
|||
<Name>-U -O206 -S8 -C0 -P00 -N00("") -D00(00000000) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F10x_128.FLM -FS08000000 -FL020000 -FP0($$Device:STM32F103RB$Flash\STM32F10x_128.FLM)</Name>
|
||||
</SetRegEntry>
|
||||
</TargetDriverDllRegistry>
|
||||
<Breakpoint/>
|
||||
<Breakpoint>
|
||||
<Bp>
|
||||
<Number>0</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>30</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>0</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
<HtxType>0</HtxType>
|
||||
<ManyObjects>0</ManyObjects>
|
||||
<SizeOfObject>0</SizeOfObject>
|
||||
<BreakByAccess>0</BreakByAccess>
|
||||
<BreakIfRCount>0</BreakIfRCount>
|
||||
<Filename>.\Sources\Main.c</Filename>
|
||||
<ExecCommand></ExecCommand>
|
||||
<Expression></Expression>
|
||||
</Bp>
|
||||
<Bp>
|
||||
<Number>1</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>30</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>134219668</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
<HtxType>0</HtxType>
|
||||
<ManyObjects>0</ManyObjects>
|
||||
<SizeOfObject>0</SizeOfObject>
|
||||
<BreakByAccess>0</BreakByAccess>
|
||||
<BreakIfRCount>1</BreakIfRCount>
|
||||
<Filename>U:\INSA\Microcontrôleur\Projet_Voilier_grp\Voilier\GPIO_Test\Sources\Main.c</Filename>
|
||||
<ExecCommand></ExecCommand>
|
||||
<Expression>\\GPIO_Test\Sources/Main.c\30</Expression>
|
||||
</Bp>
|
||||
<Bp>
|
||||
<Number>2</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>70</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>134219784</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
<HtxType>0</HtxType>
|
||||
<ManyObjects>0</ManyObjects>
|
||||
<SizeOfObject>0</SizeOfObject>
|
||||
<BreakByAccess>0</BreakByAccess>
|
||||
<BreakIfRCount>1</BreakIfRCount>
|
||||
<Filename>U:\INSA\Microcontrôleur\Projet_Voilier_grp\Voilier\GPIO_Test\Sources\Main.c</Filename>
|
||||
<ExecCommand></ExecCommand>
|
||||
<Expression>\\GPIO_Test\Sources/Main.c\70</Expression>
|
||||
</Bp>
|
||||
<Bp>
|
||||
<Number>3</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>71</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>0</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
<HtxType>0</HtxType>
|
||||
<ManyObjects>0</ManyObjects>
|
||||
<SizeOfObject>0</SizeOfObject>
|
||||
<BreakByAccess>0</BreakByAccess>
|
||||
<BreakIfRCount>0</BreakIfRCount>
|
||||
<Filename>.\Sources\Main.c</Filename>
|
||||
<ExecCommand></ExecCommand>
|
||||
<Expression></Expression>
|
||||
</Bp>
|
||||
</Breakpoint>
|
||||
<Tracepoint>
|
||||
<THDelay>0</THDelay>
|
||||
</Tracepoint>
|
||||
|
@ -152,7 +217,7 @@
|
|||
<periodic>1</periodic>
|
||||
<aLwin>0</aLwin>
|
||||
<aCover>0</aCover>
|
||||
<aSer1>0</aSer1>
|
||||
<aSer1>1</aSer1>
|
||||
<aSer2>0</aSer2>
|
||||
<aPa>0</aPa>
|
||||
<viewmode>1</viewmode>
|
||||
|
@ -257,7 +322,7 @@
|
|||
<OPTFL>
|
||||
<tvExp>1</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<IsCurrentTarget>1</IsCurrentTarget>
|
||||
<IsCurrentTarget>0</IsCurrentTarget>
|
||||
</OPTFL>
|
||||
<CpuCode>18</CpuCode>
|
||||
<DebugOpt>
|
||||
|
@ -330,40 +395,7 @@
|
|||
<Name>-U -O206 -S8 -C0 -P00 -N00("") -D00(00000000) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F10x_128.FLM -FS08000000 -FL020000 -FP0($$Device:STM32F103RB$Flash\STM32F10x_128.FLM)</Name>
|
||||
</SetRegEntry>
|
||||
</TargetDriverDllRegistry>
|
||||
<Breakpoint>
|
||||
<Bp>
|
||||
<Number>0</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>62</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>134218958</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
<HtxType>0</HtxType>
|
||||
<ManyObjects>0</ManyObjects>
|
||||
<SizeOfObject>0</SizeOfObject>
|
||||
<BreakByAccess>0</BreakByAccess>
|
||||
<BreakIfRCount>1</BreakIfRCount>
|
||||
<Filename>U:\INSA\Microcontrôleur\Projet_Voilier_grp\Voilier\GPIO_Test\Sources\Main.c</Filename>
|
||||
<ExecCommand></ExecCommand>
|
||||
<Expression>\\GPIO_Test\Sources/Main.c\62</Expression>
|
||||
</Bp>
|
||||
<Bp>
|
||||
<Number>1</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>53</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>0</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
<HtxType>0</HtxType>
|
||||
<ManyObjects>0</ManyObjects>
|
||||
<SizeOfObject>0</SizeOfObject>
|
||||
<BreakByAccess>0</BreakByAccess>
|
||||
<BreakIfRCount>0</BreakIfRCount>
|
||||
<Filename>.\Sources\Main.c</Filename>
|
||||
<ExecCommand></ExecCommand>
|
||||
<Expression></Expression>
|
||||
</Bp>
|
||||
</Breakpoint>
|
||||
<Breakpoint/>
|
||||
<Tracepoint>
|
||||
<THDelay>0</THDelay>
|
||||
</Tracepoint>
|
||||
|
@ -372,7 +404,7 @@
|
|||
<periodic>1</periodic>
|
||||
<aLwin>0</aLwin>
|
||||
<aCover>0</aCover>
|
||||
<aSer1>0</aSer1>
|
||||
<aSer1>1</aSer1>
|
||||
<aSer2>0</aSer2>
|
||||
<aPa>0</aPa>
|
||||
<viewmode>1</viewmode>
|
||||
|
@ -426,7 +458,7 @@
|
|||
<GroupNumber>1</GroupNumber>
|
||||
<FileNumber>1</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExp>1</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\Drivers\Sources\Driver_GPIO.c</PathWithFileName>
|
||||
|
@ -438,7 +470,7 @@
|
|||
<GroupNumber>1</GroupNumber>
|
||||
<FileNumber>2</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>1</tvExp>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\Drivers\Sources\Driver_Timer.c</PathWithFileName>
|
||||
|
@ -450,7 +482,7 @@
|
|||
<GroupNumber>1</GroupNumber>
|
||||
<FileNumber>3</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>1</tvExp>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\Drivers\Sources\Driver_UART.c</PathWithFileName>
|
||||
|
@ -470,7 +502,7 @@
|
|||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>4</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>1</tvExp>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>.\Sources\Main.c</PathWithFileName>
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
#include "Driver_Timer.h"
|
||||
#include "Driver_UART.h"
|
||||
|
||||
char data[] = "Hello World";
|
||||
int i = 0;
|
||||
int len = sizeof(data) - 1; // -1 pour ne pas envoyer le caractère nul
|
||||
char data[] = "Hello World";
|
||||
int i = 0;
|
||||
int len = sizeof(data) - 1; // -1 pour ne pas envoyer le caractère nul
|
||||
|
||||
int main (void){
|
||||
//Déclaration d'une LED et d'un BP par structure GPIO
|
||||
|
@ -14,10 +14,22 @@ int main (void){
|
|||
//Déclaration d'un Timer 500 ms
|
||||
MyTimer_Struct_TypeDef TIM500ms;
|
||||
|
||||
//Déclaration de l'UART
|
||||
MyUART_Struct_Typedef * UART;
|
||||
UART->UART=USART1;
|
||||
UART->baudrate=9600;
|
||||
//Déclaration de l'UART /
|
||||
MyUART_Struct_Typedef UART1 = {USART1,9600};
|
||||
MyUART_Struct_Typedef UART2 = {USART2,9600};
|
||||
|
||||
//UART2
|
||||
//MyGPIO_Struct_TypeDef PA2 = {GPIOA,2,AltOut_Ppull};
|
||||
//MyGPIO_Struct_TypeDef PA3 = {GPIOA,3,In_PullUp};
|
||||
//UART1
|
||||
MyGPIO_Struct_TypeDef PA9 = {GPIOA,9,AltOut_Ppull};
|
||||
MyGPIO_Struct_TypeDef PA10 = {GPIOA,10,In_Floating};
|
||||
|
||||
|
||||
//MyGPIO_Init (&PA2);
|
||||
//MyGPIO_Init (&PA3);
|
||||
MyGPIO_Init (&PA9);
|
||||
MyGPIO_Init (&PA10);
|
||||
|
||||
//Config LED PA5
|
||||
LED.GPIO_Conf = Out_Ppull;
|
||||
|
@ -50,7 +62,8 @@ int main (void){
|
|||
|
||||
|
||||
|
||||
UART_init(UART);
|
||||
UART_init(&UART1);
|
||||
UART_init(&UART2);
|
||||
|
||||
//NVIC_EnableIRQ(USART1_IRQn);// Activer les interruptions
|
||||
|
||||
|
@ -59,7 +72,7 @@ int main (void){
|
|||
UART_send(data[i]);
|
||||
}
|
||||
|
||||
UART_read(data[i], UART);
|
||||
UART_read(data[i], &UART1);
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue