SHARE
TWEET

Untitled

a guest Feb 23rd, 2019 75 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* USER CODE BEGIN Header */
  2. /**
  3.  ******************************************************************************
  4.  * @file           : main.c
  5.  * @brief          : Main program body
  6.  ******************************************************************************
  7.  ** This notice applies to any and all portions of this file
  8.  * that are not between comment pairs USER CODE BEGIN and
  9.  * USER CODE END. Other portions of this file, whether
  10.  * inserted by the user or by software development tools
  11.  * are owned by their respective copyright owners.
  12.  *
  13.  * COPYRIGHT(c) 2019 STMicroelectronics
  14.  *
  15.  * Redistribution and use in source and binary forms, with or without modification,
  16.  * are permitted provided that the following conditions are met:
  17.  *   1. Redistributions of source code must retain the above copyright notice,
  18.  *      this list of conditions and the following disclaimer.
  19.  *   2. Redistributions in binary form must reproduce the above copyright notice,
  20.  *      this list of conditions and the following disclaimer in the documentation
  21.  *      and/or other materials provided with the distribution.
  22.  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  23.  *      may be used to endorse or promote products derived from this software
  24.  *      without specific prior written permission.
  25.  *
  26.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  27.  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  29.  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  30.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  32.  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  33.  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  34.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  35.  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36.  *
  37.  ******************************************************************************
  38.  */
  39. /* USER CODE END Header */
  40.  
  41. /* Includes ------------------------------------------------------------------*/
  42. #include "main.h"
  43.  
  44. /* Private includes ----------------------------------------------------------*/
  45. /* USER CODE BEGIN Includes */
  46. #include <string.h>
  47. #include <stdlib.h>
  48. #include <stdarg.h>
  49. /* USER CODE END Includes */
  50.  
  51. /* Private typedef -----------------------------------------------------------*/
  52. /* USER CODE BEGIN PTD */
  53.  
  54. /* USER CODE END PTD */
  55.  
  56. /* Private define ------------------------------------------------------------*/
  57. /* USER CODE BEGIN PD */
  58. #define BUF_SIZE 256
  59. #define BUF_DATA_SIZE 512
  60.  
  61. /* USER CODE END PD */
  62.  
  63. /* Private macro -------------------------------------------------------------*/
  64. /* USER CODE BEGIN PM */
  65.  
  66. /* USER CODE END PM */
  67.  
  68. /* Private variables ---------------------------------------------------------*/
  69. ADC_HandleTypeDef hadc1;
  70. DMA_HandleTypeDef hdma_adc1;
  71. UART_HandleTypeDef huart2;
  72.  
  73. /* USER CODE BEGIN PV */
  74. volatile uint16_t Buf_Data[BUF_DATA_SIZE];
  75. volatile uint16_t Data_Samples[BUF_DATA_SIZE];
  76. volatile uint8_t Busy = 0;
  77.  
  78. volatile uint8_t Buf_Rx[BUF_SIZE];
  79. volatile uint8_t Buf_Tx[BUF_SIZE];
  80. volatile uint8_t Busy_Rx = 0, Empty_Rx = 0, Busy_Tx = 0, Empty_Tx = 0;
  81. volatile uint8_t temp = 0;
  82. volatile uint8_t endFrameDetected = 0;
  83.  
  84. uint16_t peak_max = 0;
  85. uint16_t peak_min = 4095;
  86. uint16_t zero_offset = 0;
  87.  
  88. volatile uint8_t tryb;
  89. volatile uint8_t pomiar;
  90. volatile uint8_t tick;
  91. volatile uint8_t dataIndex;
  92.  
  93. volatile float voltage;
  94. volatile float avg;
  95.  
  96. struct ring_buffer *buffer;
  97. /* USER CODE END PV */
  98.  
  99. /* Private function prototypes -----------------------------------------------*/
  100. void SystemClock_Config(void);
  101. static void MX_GPIO_Init(void);
  102. static void MX_DMA_Init(void);
  103. static void MX_USART2_UART_Init(void);
  104. static void MX_ADC1_Init(void);
  105.  
  106. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
  107.     if (huart->Instance == USART2) {
  108.         Empty_Rx++;
  109.         if (Buf_Rx[Empty_Rx - 1] == ';') {
  110.             endFrameDetected = 1;
  111.         }
  112.         if (Empty_Rx >= BUF_SIZE) {
  113.             Empty_Rx = 0;
  114.         }
  115.     }
  116.     HAL_UART_Receive_IT(&huart2, &Buf_Rx[Empty_Rx], 1);
  117. }
  118.  
  119. void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
  120.     if (huart->Instance == USART2) {
  121.         if (Busy_Tx != Empty_Tx) {
  122.             temp = Buf_Tx[Busy_Tx];
  123.             Busy_Tx++;
  124.             if (Busy_Tx >= BUF_SIZE) {
  125.                 Busy_Tx = 0;
  126.             }
  127.             HAL_UART_Transmit_IT(&huart2, &temp, 1);
  128.         }
  129.     }
  130. }
  131.  
  132. void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *hadc1) {
  133.     for (uint8_t i = 0; i < 16; i++) {
  134.         uint32_t suma = 0;
  135.         for (uint8_t j = 0; j < 16; j++) {
  136.             suma += Buf_Data[(16 * i) + j];
  137.         }
  138.         Data_Samples[Busy] = suma / 16;
  139.         Busy++;
  140.         if (Busy >= BUF_DATA_SIZE) {
  141.             Busy = 0;
  142.         }
  143.     }
  144. }
  145.  
  146. void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc1) {
  147.     for (uint8_t i = 0; i < 16; i++) {
  148.         uint32_t suma = 0;
  149.         for (uint8_t j = 0; j < 16; j++) {
  150.             suma += Buf_Data[(16 * i) + j + 256];
  151.         }
  152.         Data_Samples[Busy] = suma / 16;
  153.         Busy++;
  154.         if (Busy >= BUF_DATA_SIZE) {
  155.             Busy = 0;
  156.         }
  157.     }
  158. }
  159.  
  160. void obliczeniaDC() {
  161.     uint8_t data[20];
  162.     for (uint16_t i = 0; i < 512; i++) {
  163.         voltage = Data_Samples[i] * 3.3f / 4095.0f;
  164.         avg += voltage;
  165.     }
  166.     avg /= 256;
  167.  
  168.     sprintf(data, "ADC = %.3fV", avg);
  169.     tick = 0;
  170.     frame_send(data, 12);
  171.     avg = 0;
  172.  
  173. }
  174.  
  175. void obliczeniaAC() {
  176.     uint8_t data[20];
  177.     uint16_t values[255];
  178.     for (uint16_t i = 0; i < 512; i++) {
  179.         if (peak_max < Data_Samples[i]) {
  180.             peak_max = Data_Samples[i];
  181.         }
  182.         if (peak_min > Data_Samples[i]) {
  183.             peak_min = Data_Samples[i];
  184.         }
  185.     }
  186.     zero_offset = peak_max - peak_min;
  187.  
  188.     voltage = peak_max * 3.3f / 4095.0f;
  189.     avg = voltage / sqrt(2);
  190.  
  191.     for (uint16_t i = 0; i < 512; i++) {
  192.         sprintf(data, "ADC = %.3fV", avg);
  193.         tick = 0;
  194.         frame_send(data, 12);
  195.         avg = 0;
  196.     }
  197. }
  198. /* USER CODE BEGIN PFP */
  199. /* USER CODE END PFP */
  200.  
  201. /* Private user code ---------------------------------------------------------*/
  202. /* USER CODE BEGIN 0 */
  203. unsigned char crc8(unsigned char poly, unsigned char* data, int size) {
  204.     unsigned char crc = 0x00;
  205.     int bit;
  206.  
  207.     while (size--) {
  208.         crc ^= *data++;
  209.         for (bit = 0; bit < 8; bit++) {
  210.             if (crc & 0x80) {
  211.                 crc = (crc << 1) ^ poly;
  212.             } else {
  213.                 crc <<= 1;
  214.             }
  215.         }
  216.     }
  217.     return crc;
  218. }
  219.  
  220. void frame_decoder() {
  221.     char frame_buffer[255];
  222.     char frame[127];
  223.     char frame_escape[127];
  224.     uint8_t i = 0;
  225.     while (Busy_Rx != Empty_Rx) {
  226.         frame_buffer[i++] = Buf_Rx[Busy_Rx++];
  227.         if (Busy_Rx >= BUF_SIZE) {
  228.             Busy_Rx = 0;
  229.         }
  230.     }
  231.  
  232. // poczatek ramki
  233.     uint8_t k = 0;
  234.     uint8_t startDetected = 0;
  235.     for (uint8_t j = 0; j < i; j++) {
  236.         if (frame_buffer[j] == ':') { // szukam znaku startu ramki
  237.             startDetected = 1;
  238.             k = 0;
  239.         } else if (startDetected == 1) {
  240.             frame[k++] = frame_buffer[j];
  241.         }
  242.     }
  243.     if (startDetected != 0) {
  244.         //deescapowanie ramki
  245.         uint8_t m = 0;
  246.         uint8_t escapeFlag = 0;
  247.         for (uint8_t l = 0; l < k; l++) {
  248.             if (frame[l] == 0x3F) {
  249.                 escapeFlag = 1;
  250.             } else if (escapeFlag == 0) {
  251.                 frame_escape[m++] = frame[l];
  252.             } else {
  253.                 escapeFlag = 0;
  254.                 frame_escape[m++] = frame[l] ^ 0x20;
  255.             }
  256.         }
  257.  
  258.         // sprawdzam czy ramka nie jest za mała i za duża
  259.         if (m > 2 && m < 126) {
  260.             uint8_t checksum = frame_escape[m - 2]; // sume kontrolna nalezy sprawdzac, ale w celach debugu nie sprawdzam
  261.             execute_command(frame_escape, m - 2);
  262.         }
  263.     }
  264. }
  265.  
  266. void frame_send(uint8_t *senddata, uint8_t length) {
  267.     uint8_t frame[128];
  268.     uint8_t i;
  269.     for (i = 0; i < length; i++) {
  270.         if (i > 127) {
  271.             length = 127;
  272.             break; // jesli podamy za duzo danych to wysle tylko poczatek
  273.         }
  274.         frame[i] = senddata[i];
  275.     }
  276.     frame[length] = crc8(0xAA, frame, length); //crc
  277.  
  278.     uint8_t frame_escape[128];
  279.     uint8_t m = 1;
  280.     frame_escape[0] = ':';
  281.     for (uint8_t l = 0; l < length + 1; l++) {
  282.         if (frame[l] == 0x3A || frame[l] == 0x3B || frame[l] == 0x3F) {
  283.             frame_escape[m++] = 0x3F;
  284.             frame_escape[m++] = frame[l] ^ 0x20;
  285.         } else {
  286.             frame_escape[m++] = frame[l];
  287.         }
  288.     }
  289.  
  290.     frame_escape[m] = ';';
  291.     uint8_t idx = Empty_Tx;
  292.     for (int i = 0; i < m + 1; i++) {
  293.         Buf_Tx[idx] = frame_escape[i];
  294.         idx++;
  295.         if (idx > 255) {
  296.             idx = 0;
  297.         }
  298.     }
  299.     __disable_irq();
  300.  
  301.     if (Busy_Tx == Empty_Tx
  302.             && __HAL_UART_GET_FLAG(&huart2, UART_FLAG_TXE) == SET) {
  303.         Empty_Tx = idx;
  304.         temp = Buf_Tx[Busy_Tx];
  305.         Busy_Tx++;
  306.         if (Busy_Tx > 255) {
  307.             Busy_Tx = 0;
  308.         }
  309.         HAL_UART_Transmit_IT(&huart2, &temp, 1);
  310.     } else {
  311.         Empty_Tx = idx;
  312.     }
  313.     __enable_irq();
  314. }
  315.  
  316. void execute_command(char *data_in, uint8_t length) {
  317.     if (strncmp("pomiardc", data_in, length) == 0) {
  318.         tryb = 0;
  319.         pomiar = 1;
  320.         frame_send("OK", 2);
  321.     } else if (strncmp("pomiarpeak", data_in, length) == 0) {
  322.         tryb = 1;
  323.         pomiar = 1;
  324.         frame_send("OK", 2);
  325.     } else if (strncmp("pomiarrms", data_in, length) == 0) {
  326.         tryb = 2;
  327.         pomiar = 1;
  328.         frame_send("OK", 2);
  329.     } else if (strncmp("stop", data_in, length) == 0) {
  330.         pomiar = 0;
  331.         frame_send("stopped", 7);
  332.     } else {
  333.         frame_send("unknown command", 15);
  334.     }
  335. }
  336.  
  337. /* USER CODE END 0 */
  338.  
  339. /**
  340.  * @brief  The application entry point.
  341.  * @retval int
  342.  */
  343. int main(void) {
  344.     /* USER CODE BEGIN 1 */
  345.     /* USER CODE END 1 */
  346.  
  347.     /* MCU Configuration--------------------------------------------------------*/
  348.  
  349.     /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  350.     HAL_Init();
  351.  
  352.     /* USER CODE BEGIN Init */
  353.  
  354.     /* USER CODE END Init */
  355.  
  356.     /* Configure the system clock */
  357.     SystemClock_Config();
  358.  
  359.     /* USER CODE BEGIN SysInit */
  360.  
  361.     /* USER CODE END SysInit */
  362.  
  363.     /* Initialize all configured peripherals */
  364.     MX_GPIO_Init();
  365.     MX_DMA_Init();
  366.     MX_USART2_UART_Init();
  367.     MX_ADC1_Init();
  368.  
  369.     /* USER CODE BEGIN 2 */
  370.     HAL_ADC_Start_DMA(&hadc1, (uint16_t*) Buf_Data, 512);
  371.     HAL_UART_Receive_IT(&huart2, &Buf_Rx[Empty_Rx], 1);
  372.     /* USER CODE END 2 */
  373.  
  374.     /* Infinite loop */
  375.     /* USER CODE BEGIN WHILE */
  376.     while (1) {
  377.  
  378.         /* USER CODE END WHILE */
  379.         if (endFrameDetected) {
  380.             endFrameDetected = 0;
  381.             frame_decoder();
  382.         }
  383.         if (tick == 1) {
  384.             if (tryb == 0) {
  385.                 obliczeniaDC();
  386.             } else if (tryb == 1) {
  387.                 obliczeniaAC();
  388.             }
  389.             tick = 0;
  390.         }
  391.         /* USER CODE BEGIN 3 */
  392.     }
  393.     /* USER CODE END 3 */
  394. }
  395.  
  396. /**
  397.  * @brief System Clock Configuration
  398.  * @retval None
  399.  */
  400. void SystemClock_Config(void) {
  401.     RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };
  402.     RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };
  403.     RCC_PeriphCLKInitTypeDef PeriphClkInit = { 0 };
  404.  
  405.     /**Initializes the CPU, AHB and APB busses clocks
  406.      */
  407.     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  408.     RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  409.     RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  410.     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  411.     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
  412.         Error_Handler();
  413.     }
  414.     /**Initializes the CPU, AHB and APB busses clocks
  415.      */
  416.     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
  417.             | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  418.     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  419.     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  420.     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  421.     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  422.  
  423.     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) {
  424.         Error_Handler();
  425.     }
  426.     PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  427.     PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV2;
  428.     if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
  429.         Error_Handler();
  430.     }
  431. }
  432.  
  433. /**
  434.  * @brief ADC1 Initialization Function
  435.  * @param None
  436.  * @retval None
  437.  */
  438. static void MX_ADC1_Init(void) {
  439.  
  440.     /* USER CODE BEGIN ADC1_Init 0 */
  441.  
  442.     /* USER CODE END ADC1_Init 0 */
  443.  
  444.     ADC_ChannelConfTypeDef sConfig = { 0 };
  445.  
  446.     /* USER CODE BEGIN ADC1_Init 1 */
  447.  
  448.     /* USER CODE END ADC1_Init 1 */
  449.     /**Common config
  450.      */
  451.     hadc1.Instance = ADC1;
  452.     hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  453.     hadc1.Init.ContinuousConvMode = ENABLE;
  454.     hadc1.Init.DiscontinuousConvMode = DISABLE;
  455.     hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  456.     hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  457.     hadc1.Init.NbrOfConversion = 1;
  458.     if (HAL_ADC_Init(&hadc1) != HAL_OK) {
  459.         Error_Handler();
  460.     }
  461.     /**Configure Regular Channel
  462.      */
  463.     sConfig.Channel = ADC_CHANNEL_0;
  464.     sConfig.Rank = ADC_REGULAR_RANK_1;
  465.     sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
  466.     if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
  467.         Error_Handler();
  468.     }
  469.     /* USER CODE BEGIN ADC1_Init 2 */
  470.  
  471.     /* USER CODE END ADC1_Init 2 */
  472.  
  473. }
  474.  
  475. /**
  476.  * @brief USART2 Initialization Function
  477.  * @param None
  478.  * @retval None
  479.  */
  480. static void MX_USART2_UART_Init(void) {
  481.  
  482.     /* USER CODE BEGIN USART2_Init 0 */
  483.  
  484.     /* USER CODE END USART2_Init 0 */
  485.  
  486.     /* USER CODE BEGIN USART2_Init 1 */
  487.  
  488.     /* USER CODE END USART2_Init 1 */
  489.     huart2.Instance = USART2;
  490.     huart2.Init.BaudRate = 9600;
  491.     huart2.Init.WordLength = UART_WORDLENGTH_8B;
  492.     huart2.Init.StopBits = UART_STOPBITS_1;
  493.     huart2.Init.Parity = UART_PARITY_NONE;
  494.     huart2.Init.Mode = UART_MODE_TX_RX;
  495.     huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  496.     huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  497.     if (HAL_UART_Init(&huart2) != HAL_OK) {
  498.         Error_Handler();
  499.     }
  500.     /* USER CODE BEGIN USART2_Init 2 */
  501.  
  502.     /* USER CODE END USART2_Init 2 */
  503.  
  504. }
  505.  
  506. /**
  507.  * Enable DMA controller clock
  508.  */
  509. static void MX_DMA_Init(void) {
  510.     /* DMA controller clock enable */
  511.     __HAL_RCC_DMA1_CLK_ENABLE()
  512.     ;
  513.  
  514.     /* DMA interrupt init */
  515.     /* DMA1_Channel1_IRQn interrupt configuration */
  516.     HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
  517.     HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
  518.  
  519. }
  520.  
  521. /**
  522.  * @brief GPIO Initialization Function
  523.  * @param None
  524.  * @retval None
  525.  */
  526. static void MX_GPIO_Init(void) {
  527.     GPIO_InitTypeDef GPIO_InitStruct = { 0 };
  528.  
  529.     /* GPIO Ports Clock Enable */
  530.     __HAL_RCC_GPIOA_CLK_ENABLE()
  531.     ;
  532.  
  533.     /*Configure GPIO pin Output Level */
  534.     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
  535.  
  536.     /*Configure GPIO pin : PA5 */
  537.     GPIO_InitStruct.Pin = GPIO_PIN_5;
  538.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  539.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  540.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  541.     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  542.  
  543. }
  544.  
  545. /* USER CODE BEGIN 4 */
  546.  
  547. /* USER CODE END 4 */
  548.  
  549. /**
  550.  * @brief  This function is executed in case of error occurrence.
  551.  * @retval None
  552.  */
  553. void Error_Handler(void) {
  554.     /* USER CODE BEGIN Error_Handler_Debug */
  555.     /* User can add his own implementation to report the HAL error return state */
  556.  
  557.     /* USER CODE END Error_Handler_Debug */
  558. }
  559.  
  560. #ifdef  USE_FULL_ASSERT
  561. /**
  562.  * @brief  Reports the name of the source file and the source line number
  563.  *         where the assert_param error has occurred.
  564.  * @param  file: pointer to the source file name
  565.  * @param  line: assert_param error line source number
  566.  * @retval None
  567.  */
  568. void assert_failed(uint8_t *file, uint32_t line)
  569. {
  570.     /* USER CODE BEGIN 6 */
  571.     /* User can add his own implementation to report the file name and line number,
  572.      tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  573.     /* USER CODE END 6 */
  574. }
  575. #endif /* USE_FULL_ASSERT */
  576.  
  577. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top