text: /* USER CODE BEGIN Header */
  /* USER CODE END Header */
  /* Includes ------------------------------------------------------------------*/
  #include "main.h"
  
  
  void SystemClock_Config(void);
  static void MX_GPIO_Init(void);
  static void MX_SPI1_Init(void);
  static void MX_TIM1_Init(void);
  static void MX_I2C1_Init(void);
  /* USER CODE BEGIN PFP */
  
  /* USER CODE END PFP */
  
  /* Private user code ---------------------------------------------------------*/
  /* USER CODE BEGIN 0 */
  #include "../lib/Nokia5110_LCD.h"
  #include "../lib/Encoder/RotaryEncoder.h"
  #include "../lib/DS1307/DS1307.h"
  
  
  int main(void) {
  
      LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
      LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
  
      NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
  
      SystemClock_Config();
  
      MX_GPIO_Init();
      MX_SPI1_Init();
      MX_TIM1_Init();
      MX_I2C1_Init();
  
  
      initN5110(SPI1);
      I2C i2C = initI2C(I2C1, I2C_ADDRESSING_MODE_7BIT, 10);    // set low timeout for faster search
      printStringN5110("Searching...");
  
      int i;
      I2CStatus status;
      for (i = 0; i < 255; i++) { // search available module
          status = isDeviceReady(&i2C, i);
          if (status == I2C_OK) { // module is found
              break;
          }
      }
  
      clearN5110();
      if (status == I2C_OK) {
          printStringN5110("Module found!");
          goToXYN5110(0, 1);
          printfStringN5110("Address: 0x%.2X", i);
      } else {
          printStringN5110("Not found!");
      }
  
  
      while (1) {
      }
  }
  
  /* USER CODE END 0 */
  
  /**
    * @brief  The application entry point.
    * @retval int
    */
  
  /**
    * @brief System Clock Configuration
    * @retval None
    */
  void SystemClock_Config(void) {
      LL_FLASH_SetLatency(LL_FLASH_LATENCY_2);
      while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_2) {
      }
      LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE2);
      LL_RCC_HSI_SetCalibTrimming(16);
      LL_RCC_HSI_Enable();
  
      /* Wait till HSI is ready */
      while (LL_RCC_HSI_IsReady() != 1) {
  
      }
      LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, LL_RCC_PLLM_DIV_16, 336, LL_RCC_PLLP_DIV_4);
      LL_RCC_PLL_Enable();
  
      /* Wait till PLL is ready */
      while (LL_RCC_PLL_IsReady() != 1) {
  
      }
      LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
      LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
      LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
      LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
  
      /* Wait till System clock is ready */
      while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) {
  
      }
      LL_Init1msTick(84000000);
      LL_SetSystemCoreClock(84000000);
      LL_RCC_SetTIMPrescaler(LL_RCC_TIM_PRESCALER_TWICE);
  }
  
  /**
    * @brief I2C1 Initialization Function
    * @param None
    * @retval None
    */
  static void MX_I2C1_Init(void) {
  
      /* USER CODE BEGIN I2C1_Init 0 */
  
      /* USER CODE END I2C1_Init 0 */
  
      LL_I2C_InitTypeDef I2C_InitStruct = {0};
  
      LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
  
      LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB);
      /**I2C1 GPIO Configuration
      PB6   ------> I2C1_SCL
      PB7   ------> I2C1_SDA
      */
      GPIO_InitStruct.Pin = LL_GPIO_PIN_6 | LL_GPIO_PIN_7;
      GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
      GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
      GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
      GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
      GPIO_InitStruct.Alternate = LL_GPIO_AF_4;
      LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  
      /* Peripheral clock enable */
      LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
  
      /* USER CODE BEGIN I2C1_Init 1 */
  //    LL_I2C_EnableReset(I2C1);
  //    LL_mDelay(10);
  //    LL_I2C_DisableReset(I2C1);
  //    LL_mDelay(10);
      /* USER CODE END I2C1_Init 1 */
      /** I2C Initialization
      */
      LL_I2C_DisableOwnAddress2(I2C1);
      LL_I2C_DisableGeneralCall(I2C1);
      LL_I2C_EnableClockStretching(I2C1);
      I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;
      I2C_InitStruct.ClockSpeed = 100000;
      I2C_InitStruct.DutyCycle = LL_I2C_DUTYCYCLE_2;
      I2C_InitStruct.OwnAddress1 = 0;
      I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;
      I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
      LL_I2C_Init(I2C1, &I2C_InitStruct);
      LL_I2C_SetOwnAddress2(I2C1, 0);
      /* USER CODE BEGIN I2C1_Init 2 */
  
      /* USER CODE END I2C1_Init 2 */
  
  }
  
  /**
    * @brief SPI1 Initialization Function
    * @param None
    * @retval None
    */
  static void MX_SPI1_Init(void) {
  
      /* USER CODE BEGIN SPI1_Init 0 */
  
      /* USER CODE END SPI1_Init 0 */
  
      LL_SPI_InitTypeDef SPI_InitStruct = {0};
  
      LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
  
      /* Peripheral clock enable */
      LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1);
  
      LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);
      /**SPI1 GPIO Configuration
      PA5   ------> SPI1_SCK
      PA6   ------> SPI1_MISO
      PA7   ------> SPI1_MOSI
      */
      GPIO_InitStruct.Pin = LL_GPIO_PIN_5 | LL_GPIO_PIN_6 | LL_GPIO_PIN_7;
      GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
      GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
      GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
      GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
      GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
      LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  
      /* USER CODE BEGIN SPI1_Init 1 */
  
      /* USER CODE END SPI1_Init 1 */
      /* SPI1 parameter configuration*/
      SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX;
      SPI_InitStruct.Mode = LL_SPI_MODE_MASTER;
      SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT;
      SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW;
      SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE;
      SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;
      SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8;
      SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;
      SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
      SPI_InitStruct.CRCPoly = 10;
      LL_SPI_Init(SPI1, &SPI_InitStruct);
      LL_SPI_SetStandard(SPI1, LL_SPI_PROTOCOL_MOTOROLA);
      /* USER CODE BEGIN SPI1_Init 2 */
  
      /* USER CODE END SPI1_Init 2 */
  
  }
  
  /**
    * @brief TIM1 Initialization Function
    * @param None
    * @retval None
    */
  static void MX_TIM1_Init(void) {
  
      /* USER CODE BEGIN TIM1_Init 0 */
  
      /* USER CODE END TIM1_Init 0 */
  
      LL_TIM_InitTypeDef TIM_InitStruct = {0};
  
      LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
  
      /* Peripheral clock enable */
      LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
  
      LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);
      /**TIM1 GPIO Configuration
      PA8   ------> TIM1_CH1
      PA9   ------> TIM1_CH2
      */
      GPIO_InitStruct.Pin = LL_GPIO_PIN_8 | LL_GPIO_PIN_9;
      GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
      GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
      GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
      GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
      GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
      LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  
      /* USER CODE BEGIN TIM1_Init 1 */
  
      /* USER CODE END TIM1_Init 1 */
      LL_TIM_SetEncoderMode(TIM1, LL_TIM_ENCODERMODE_X2_TI1);
      LL_TIM_IC_SetActiveInput(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_DIRECTTI);
      LL_TIM_IC_SetPrescaler(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1);
      LL_TIM_IC_SetFilter(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV1);
      LL_TIM_IC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_RISING);
      LL_TIM_IC_SetActiveInput(TIM1, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_DIRECTTI);
      LL_TIM_IC_SetPrescaler(TIM1, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1);
      LL_TIM_IC_SetFilter(TIM1, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1);
      LL_TIM_IC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_RISING);
      TIM_InitStruct.Prescaler = 0;
      TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
      TIM_InitStruct.Autoreload = 65535;
      TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
      TIM_InitStruct.RepetitionCounter = 0;
      LL_TIM_Init(TIM1, &TIM_InitStruct);
      LL_TIM_DisableARRPreload(TIM1);
      LL_TIM_SetTriggerOutput(TIM1, LL_TIM_TRGO_RESET);
      LL_TIM_DisableMasterSlaveMode(TIM1);
      /* USER CODE BEGIN TIM1_Init 2 */
  
      /* USER CODE END TIM1_Init 2 */
  
  }
  
  /**
    * @brief GPIO Initialization Function
    * @param None
    * @retval None
    */
  static void MX_GPIO_Init(void) {
      LL_EXTI_InitTypeDef EXTI_InitStruct = {0};
      LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
  
      /* GPIO Ports Clock Enable */
      LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC);
      LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);
      LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB);
  
      /**/
      LL_GPIO_ResetOutputPin(GPIOC, N5110_RESET_Pin | N5110_DC_Pin);
  
      /**/
      LL_GPIO_ResetOutputPin(CHIP_SELECT_GPIO_Port, CHIP_SELECT_Pin);
  
      /**/
      LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTC, LL_SYSCFG_EXTI_LINE13);
  
      /**/
      EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_13;
      EXTI_InitStruct.LineCommand = ENABLE;
      EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
      EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_FALLING;
      LL_EXTI_Init(&EXTI_InitStruct);
  
      /**/
      LL_GPIO_SetPinPull(B1_GPIO_Port, B1_Pin, LL_GPIO_PULL_NO);
  
      /**/
      LL_GPIO_SetPinMode(B1_GPIO_Port, B1_Pin, LL_GPIO_MODE_INPUT);
  
      /**/
      GPIO_InitStruct.Pin = N5110_RESET_Pin | N5110_DC_Pin;
      GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
      GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
      GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
      GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
      LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  
      /**/
      GPIO_InitStruct.Pin = CHIP_SELECT_Pin;
      GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
      GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_MEDIUM;
      GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
      GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
      LL_GPIO_Init(CHIP_SELECT_GPIO_Port, &GPIO_InitStruct);
  
      /**/
      GPIO_InitStruct.Pin = ENCODER_BUTTON_Pin;
      GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
      GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
      LL_GPIO_Init(ENCODER_BUTTON_GPIO_Port, &GPIO_InitStruct);
  
  }
  
  /* USER CODE BEGIN 4 */
  
  /* USER CODE END 4 */
  
  /**
    * @brief  This function is executed in case of error occurrence.
    * @retval None
    */
  void Error_Handler(void) {
      /* USER CODE BEGIN Error_Handler_Debug */
      /* User can add his own implementation to report the HAL error return state */
      __disable_irq();
      while (1) {
      }
      /* USER CODE END Error_Handler_Debug */
  }
  
  #ifdef  USE_FULL_ASSERT
  /**
    * @brief  Reports the name of the source file and the source line number
    *         where the assert_param error has occurred.
    * @param  file: pointer to the source file name
    * @param  line: assert_param error line source number
    * @retval None
    */
  void assert_failed(uint8_t *file, uint32_t line)
  {
    /* USER CODE BEGIN 6 */
    /* User can add his own implementation to report the file name and line number,
       ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* USER CODE END 6 */
  }
  #endif /* USE_FULL_ASSERT */
  
  /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  