├── Tutorial 11 - LCD16x2 ├── lcd16x2.c ├── lcd16x2.h └── main.c ├── Tutorial 23 - 4x4 Keypad ├── MY_Keypad4x4.c └── MY_Keypad4x4.h ├── Tutorial 24 - NRF24L01 Radio Transceiver ├── MY_NRF24.c ├── MY_NRF24.h ├── RX_main.c ├── TX_main.c ├── nRF24L01.h └── nRF24L01_Datasheet.pdf ├── Tutorial 25 - DHT22 Temperature Sensor ├── MY_DHT22.c ├── MY_DHT22.h └── main.c ├── Tutorial 26 - SPI LCD + Resistive touch ├── MY_ILI9341.c ├── MY_ILI9341.h ├── TSC2046.c ├── TSC2046.h └── main.c ├── Tutorial 27 - Motion 3-Axis Accelerometer LIS3DSH ├── MY_LIS3DSH.c ├── MY_LIS3DSH.h └── main.c ├── Tutorial 28 - I2S Audio Codec - CS43L22 ├── MY_CS43L22.c ├── MY_CS43L22.h └── main.c ├── Tutorial 29 - STM32F7 LCD and Touch ├── GUI HAL library │ ├── stm32f7xx_hal_ltdc.c │ ├── stm32f7xx_hal_ltdc.h │ ├── stm32f7xx_hal_ltdc_ex.c │ ├── stm32f7xx_hal_ltdc_ex.h │ ├── stm32f7xx_hal_sdram.c │ ├── stm32f7xx_hal_sdram.h │ ├── stm32f7xx_hal_uart.c │ ├── stm32f7xx_hal_uart.h │ ├── stm32f7xx_hal_uart_ex.h │ ├── stm32f7xx_ll_fmc.c │ └── stm32f7xx_ll_fmc.h ├── GUI files │ ├── font12.c │ ├── font16.c │ ├── font20.c │ ├── font24.c │ ├── font8.c │ ├── fonts.h │ ├── ft5336.c │ ├── ft5336.h │ ├── lcd.h │ ├── rk043fn48h.h │ ├── stm32746g_discovery.c │ ├── stm32746g_discovery.h │ ├── stm32746g_discovery_lcd.c │ ├── stm32746g_discovery_lcd.h │ ├── stm32746g_discovery_sdram.c │ ├── stm32746g_discovery_sdram.h │ ├── stm32746g_discovery_ts.c │ ├── stm32746g_discovery_ts.h │ ├── stm32f7xx_hal_conf.h │ └── ts.h └── Project Setup Steps.txt ├── Tutorial 30 - FLASH Memory ├── MY_FLASH.c └── MY_FLASH.h ├── Tutorial 32 - USB HID ├── MY_LIS3DSH.c ├── MY_LIS3DSH.h └── main.c ├── Tutorial 33 - CAN Bus ├── CAN Frame.JPG ├── CAN bus tutorial steps.txt ├── main.c └── wiring diagram.png ├── Tutorial 34 - USB MSC Flash Drive ├── USB Flash - Tutorial steps.txt └── main.c ├── Tutorial 35 - MPU6050 IMU Module ├── TJ_MPU6050.c ├── TJ_MPU6050.h └── main.c ├── Tutorial 36 - SSD1306 128x64 OLED Display ├── RJA_SSD1306.cpp └── RJA_SSD1306.h ├── Tutorial 37 - HC-SR05 Ultrasonic Sensor ├── STM32-Nucleo-F401RE-Pinout.png ├── main_method1.c └── main_method2.c ├── Tutorial 38 - Printf UART debugging └── printf perp doc.txt ├── Tutorial 40 - UART DMA └── UART_DMA_main.c ├── Tutorial 41 - SD Card + FreeRTOS ├── SDIO_RTOS_Prep.txt ├── SDcard_RTOS_tutorial.hex └── main.c ├── Tutorial 42 - LCD16x2 I2C ├── -u _printf_float ├── lcd16x2_i2c.c └── lcd16x2_i2c.h └── Tutorial 43 - WAV Player ├── Audio ├── MY_CS43L22.c ├── MY_CS43L22.h ├── audioI2S.c ├── audioI2S.h ├── wav_player.c └── wav_player.h └── main.c /Tutorial 11 - LCD16x2/lcd16x2.h: -------------------------------------------------------------------------------- 1 | /* 2 | Library: lcd16x2 - Parallel 8/4 bits 3 | Written by: Mohamed Yaqoob 4 | Date Written: 04/12/2017 5 | Updated: 26/06/2020 6 | Description: This is a library for the standard 16X2 LCD display, for the STM32 MCUs based on HAL libraries. 7 | It perfroms the basic Text/Number printing to your 16X2 LCD, in 8 bits and 4 bits modes of operation. 8 | 9 | References**: 10 | This was written based on the open source Arduino LiquidCrystal library 11 | and by referring to the DATASHEET of the LCD16X2, also with the help of 12 | the following YouTube tutorials on LCD 16X2: 13 | (1): 'RC Tractor Guy' YouTube tutorial on the following link: 14 | https://www.youtube.com/watch?v=efi2nlsvbCI 15 | (2): 'Explore Embedded' YouTube tutorial on the following link: 16 | https://www.youtube.com/watch?v=YDJISiPUdA8 17 | 18 | * Copyright (C) 2017 - M.Yaqoob - MutexEmbedded 19 | This is a free software under the GNU license, you can redistribute it and/or modify it under the terms 20 | of the GNU General Public License version 3 as published by the Free Software Foundation. 21 | 22 | This software library is shared with public for educational purposes, without WARRANTY and Author is not liable for any damages caused directly 23 | or indirectly by this software, read more about this on the GNU General Public License. 24 | */ 25 | 26 | #ifndef LCD16X2_H_ 27 | #define LCD16X2_H_ 28 | 29 | #include 30 | #include "main.h" 31 | 32 | //Floating point linker flag: -u _printf_float 33 | 34 | /** 35 | * @brief Initialise LCD on 8-bits mode 36 | * @param[in] *port_rs_e RS and EN GPIO Port (e.g. GPIOB) 37 | * @param[in] *port_0_3 D0 to D3 GPIO Port 38 | * @param[in] *port_4_7 D4 to D7 GPIO Port 39 | * @param[in] x_pin GPIO pin (e.g. GPIO_PIN_1) 40 | */ 41 | void lcd16x2_init_8bits( 42 | GPIO_TypeDef* port_rs_e, uint16_t rs_pin, uint16_t e_pin, 43 | GPIO_TypeDef* port_0_3, uint16_t d0_pin, uint16_t d1_pin, uint16_t d2_pin, uint16_t d3_pin, 44 | GPIO_TypeDef* port_4_7, uint16_t d4_pin, uint16_t d5_pin, uint16_t d6_pin, uint16_t d7_pin); 45 | 46 | /** 47 | * @brief Initialise LCD on 4-bits mode 48 | * @param[in] *port_4_7 D4 to D7 GPIO Port 49 | * @param[in] x_pin GPIO pin (e.g. GPIO_PIN_1) 50 | */ 51 | void lcd16x2_init_4bits( 52 | GPIO_TypeDef* port_rs_e, uint16_t rs_pin, uint16_t e_pin, 53 | GPIO_TypeDef* port_4_7, uint16_t d4_pin, uint16_t d5_pin, uint16_t d6_pin, uint16_t d7_pin); 54 | 55 | /** 56 | * @brief Set cursor position 57 | * @param[in] row - 0 or 1 for line1 or line2 58 | * @param[in] col - 0 - 15 (16 columns LCD) 59 | */ 60 | void lcd16x2_setCursor(uint8_t row, uint8_t col); 61 | /** 62 | * @brief Move to beginning of 1st line 63 | */ 64 | void lcd16x2_1stLine(void); 65 | /** 66 | * @brief Move to beginning of 2nd line 67 | */ 68 | void lcd16x2_2ndLine(void); 69 | 70 | /** 71 | * @brief Select LCD Number of lines mode 72 | */ 73 | void lcd16x2_twoLines(void); 74 | void lcd16x2_oneLine(void); 75 | 76 | /** 77 | * @brief Cursor ON/OFF 78 | */ 79 | void lcd16x2_cursorShow(bool state); 80 | 81 | /** 82 | * @brief Display clear 83 | */ 84 | void lcd16x2_clear(void); 85 | 86 | /** 87 | * @brief Display ON/OFF, to hide all characters, but not clear 88 | */ 89 | void lcd16x2_display(bool state); 90 | 91 | /** 92 | * @brief Shift content to right 93 | */ 94 | void lcd16x2_shiftRight(uint8_t offset); 95 | 96 | /** 97 | * @brief Shift content to left 98 | */ 99 | void lcd16x2_shiftLeft(uint8_t offset); 100 | 101 | /** 102 | * @brief Print to display any datatype (e.g. lcd16x2_printf("Value1 = %.1f", 123.45)) 103 | */ 104 | void lcd16x2_printf(const char* str, ...); 105 | 106 | #endif /* LCD16X2_H_ */ 107 | -------------------------------------------------------------------------------- /Tutorial 11 - LCD16x2/main.c: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file : main.c 5 | * @brief : Main program body 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2020 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* USER CODE END Header */ 20 | 21 | /* Includes ------------------------------------------------------------------*/ 22 | #include "main.h" 23 | 24 | /* Private includes ----------------------------------------------------------*/ 25 | /* USER CODE BEGIN Includes */ 26 | #include "lcd16x2.h" 27 | /* USER CODE END Includes */ 28 | 29 | /* Private typedef -----------------------------------------------------------*/ 30 | /* USER CODE BEGIN PTD */ 31 | 32 | /* USER CODE END PTD */ 33 | 34 | /* Private define ------------------------------------------------------------*/ 35 | /* USER CODE BEGIN PD */ 36 | /* USER CODE END PD */ 37 | 38 | /* Private macro -------------------------------------------------------------*/ 39 | /* USER CODE BEGIN PM */ 40 | 41 | /* USER CODE END PM */ 42 | 43 | /* Private variables ---------------------------------------------------------*/ 44 | 45 | /* USER CODE BEGIN PV */ 46 | 47 | /* USER CODE END PV */ 48 | 49 | /* Private function prototypes -----------------------------------------------*/ 50 | void SystemClock_Config(void); 51 | static void MX_GPIO_Init(void); 52 | /* USER CODE BEGIN PFP */ 53 | 54 | /* USER CODE END PFP */ 55 | 56 | /* Private user code ---------------------------------------------------------*/ 57 | /* USER CODE BEGIN 0 */ 58 | 59 | /* USER CODE END 0 */ 60 | 61 | /** 62 | * @brief The application entry point. 63 | * @retval int 64 | */ 65 | int main(void) 66 | { 67 | /* USER CODE BEGIN 1 */ 68 | 69 | /* USER CODE END 1 */ 70 | 71 | /* MCU Configuration--------------------------------------------------------*/ 72 | 73 | /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ 74 | HAL_Init(); 75 | 76 | /* USER CODE BEGIN Init */ 77 | 78 | /* USER CODE END Init */ 79 | 80 | /* Configure the system clock */ 81 | SystemClock_Config(); 82 | 83 | /* USER CODE BEGIN SysInit */ 84 | 85 | /* USER CODE END SysInit */ 86 | 87 | /* Initialize all configured peripherals */ 88 | MX_GPIO_Init(); 89 | /* USER CODE BEGIN 2 */ 90 | lcd16x2_init_4bits(RS_GPIO_Port, RS_Pin, E_Pin, 91 | // D0_GPIO_Port, D0_Pin, D1_Pin, D2_Pin, D3_Pin, 92 | D4_GPIO_Port, D4_Pin, D5_Pin, D6_Pin, D7_Pin); 93 | 94 | lcd16x2_printf("Hello World"); 95 | HAL_Delay(1000); 96 | /* USER CODE END 2 */ 97 | 98 | /* Infinite loop */ 99 | /* USER CODE BEGIN WHILE */ 100 | while (1) 101 | { 102 | /* USER CODE END WHILE */ 103 | 104 | /* USER CODE BEGIN 3 */ 105 | lcd16x2_1stLine(); 106 | lcd16x2_printf("Temperature 4bits"); 107 | HAL_Delay(1000); 108 | lcd16x2_2ndLine(); 109 | lcd16x2_printf("%.2f C", 25.7824); 110 | HAL_Delay(1000); 111 | lcd16x2_clear(); 112 | HAL_Delay(500); 113 | } 114 | /* USER CODE END 3 */ 115 | } 116 | 117 | /** 118 | * @brief System Clock Configuration 119 | * @retval None 120 | */ 121 | void SystemClock_Config(void) 122 | { 123 | RCC_OscInitTypeDef RCC_OscInitStruct = {0}; 124 | RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; 125 | 126 | /** Configure the main internal regulator output voltage 127 | */ 128 | __HAL_RCC_PWR_CLK_ENABLE(); 129 | __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); 130 | /** Initializes the CPU, AHB and APB busses clocks 131 | */ 132 | RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; 133 | RCC_OscInitStruct.HSEState = RCC_HSE_ON; 134 | RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; 135 | RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; 136 | RCC_OscInitStruct.PLL.PLLM = 4; 137 | RCC_OscInitStruct.PLL.PLLN = 168; 138 | RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; 139 | RCC_OscInitStruct.PLL.PLLQ = 7; 140 | if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) 141 | { 142 | Error_Handler(); 143 | } 144 | /** Initializes the CPU, AHB and APB busses clocks 145 | */ 146 | RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK 147 | |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; 148 | RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; 149 | RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; 150 | RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; 151 | RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; 152 | 153 | if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) 154 | { 155 | Error_Handler(); 156 | } 157 | } 158 | 159 | /** 160 | * @brief GPIO Initialization Function 161 | * @param None 162 | * @retval None 163 | */ 164 | static void MX_GPIO_Init(void) 165 | { 166 | GPIO_InitTypeDef GPIO_InitStruct = {0}; 167 | 168 | /* GPIO Ports Clock Enable */ 169 | __HAL_RCC_GPIOH_CLK_ENABLE(); 170 | __HAL_RCC_GPIOD_CLK_ENABLE(); 171 | __HAL_RCC_GPIOB_CLK_ENABLE(); 172 | 173 | /*Configure GPIO pin Output Level */ 174 | HAL_GPIO_WritePin(GPIOD, D0_Pin|D1_Pin|D2_Pin|D3_Pin 175 | |D4_Pin|D5_Pin|D6_Pin|D7_Pin, GPIO_PIN_RESET); 176 | 177 | /*Configure GPIO pin Output Level */ 178 | HAL_GPIO_WritePin(GPIOB, RS_Pin|E_Pin, GPIO_PIN_RESET); 179 | 180 | /*Configure GPIO pins : D0_Pin D1_Pin D2_Pin D3_Pin 181 | D4_Pin D5_Pin D6_Pin D7_Pin */ 182 | GPIO_InitStruct.Pin = D0_Pin|D1_Pin|D2_Pin|D3_Pin 183 | |D4_Pin|D5_Pin|D6_Pin|D7_Pin; 184 | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 185 | GPIO_InitStruct.Pull = GPIO_NOPULL; 186 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; 187 | HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); 188 | 189 | /*Configure GPIO pins : RS_Pin E_Pin */ 190 | GPIO_InitStruct.Pin = RS_Pin|E_Pin; 191 | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 192 | GPIO_InitStruct.Pull = GPIO_NOPULL; 193 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; 194 | HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 195 | 196 | } 197 | 198 | /* USER CODE BEGIN 4 */ 199 | 200 | /* USER CODE END 4 */ 201 | 202 | /** 203 | * @brief This function is executed in case of error occurrence. 204 | * @retval None 205 | */ 206 | void Error_Handler(void) 207 | { 208 | /* USER CODE BEGIN Error_Handler_Debug */ 209 | /* User can add his own implementation to report the HAL error return state */ 210 | 211 | /* USER CODE END Error_Handler_Debug */ 212 | } 213 | 214 | #ifdef USE_FULL_ASSERT 215 | /** 216 | * @brief Reports the name of the source file and the source line number 217 | * where the assert_param error has occurred. 218 | * @param file: pointer to the source file name 219 | * @param line: assert_param error line source number 220 | * @retval None 221 | */ 222 | void assert_failed(uint8_t *file, uint32_t line) 223 | { 224 | /* USER CODE BEGIN 6 */ 225 | /* User can add his own implementation to report the file name and line number, 226 | tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ 227 | /* USER CODE END 6 */ 228 | } 229 | #endif /* USE_FULL_ASSERT */ 230 | 231 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 232 | -------------------------------------------------------------------------------- /Tutorial 23 - 4x4 Keypad/MY_Keypad4x4.c: -------------------------------------------------------------------------------- 1 | /* 2 | Library: 4x4 Keypad drive for STM32 MCUs 3 | Written by: Mohamed Yaqoob 4 | Date written: 03/04/2018 5 | Description: The MY_Keypad4x4 library consists of the following public functions 6 | Function(1)- Keypad4x4_Init 7 | Function(2)- Keypad4x4_ReadKeypad 8 | Function(3)- Keypad4x4_GetChar 9 | */ 10 | 11 | //***** Header files *****// 12 | #include "MY_Keypad4x4.h" 13 | 14 | //***** Library variables *****// 15 | //1. Keypad pinout variable 16 | static Keypad_WiresTypeDef KeypadStruct; 17 | //2. OUT pins position, or pin number in decimal for use in colomn change function 18 | static uint8_t OutPositions[4]; 19 | // 20 | static char *Keypad_keys[16] = 21 | { 22 | "1", 23 | "2", 24 | "3", 25 | "A", 26 | "4", 27 | "5", 28 | "6", 29 | "B", 30 | "7", 31 | "8", 32 | "9", 33 | "C", 34 | "*", 35 | "0", 36 | "#", 37 | "D" 38 | }; 39 | 40 | //***** Functions definition *****// 41 | //Function(1): Set Keypad pins and ports 42 | void Keypad4x4_Init(Keypad_WiresTypeDef *KeypadWiringStruct) 43 | { 44 | //Step(1): Copy the Keypad wirings to the library 45 | KeypadStruct = *KeypadWiringStruct; 46 | //Step(2): Find the positions of the 4 OUT pins 47 | Keypad4x4_FindPins_positions(); 48 | //Step(3): Initialise all pins to set all OUT pins to RESET 49 | KeypadStruct.OUT0_Port->OTYPER |= (1UL << OutPositions[0]); 50 | KeypadStruct.OUT1_Port->OTYPER |= (1UL << OutPositions[1]); 51 | KeypadStruct.OUT2_Port->OTYPER |= (1UL << OutPositions[2]); 52 | KeypadStruct.OUT3_Port->OTYPER |= (1UL << OutPositions[3]); 53 | 54 | HAL_GPIO_WritePin(KeypadStruct.OUT0_Port, KeypadStruct.OUT0pin, GPIO_PIN_SET); 55 | HAL_GPIO_WritePin(KeypadStruct.OUT1_Port, KeypadStruct.OUT1pin, GPIO_PIN_SET); 56 | HAL_GPIO_WritePin(KeypadStruct.OUT2_Port, KeypadStruct.OUT2pin, GPIO_PIN_SET); 57 | HAL_GPIO_WritePin(KeypadStruct.OUT3_Port, KeypadStruct.OUT3pin, GPIO_PIN_SET); 58 | } 59 | //Function(2): Get pin positions for colomn change use, only for out pins 60 | static void Keypad4x4_FindPins_positions(void) 61 | { 62 | uint8_t idx=0; 63 | for(idx=0; idx<16; idx++) 64 | { 65 | if(((KeypadStruct.OUT0pin>>idx)&0x0001) == 0x0001) 66 | { 67 | OutPositions[0] = idx; 68 | } 69 | if(((KeypadStruct.OUT1pin>>idx)&0x0001) == 0x0001) 70 | { 71 | OutPositions[1] = idx; 72 | } 73 | if(((KeypadStruct.OUT2pin>>idx)&0x0001) == 0x0001) 74 | { 75 | OutPositions[2] = idx; 76 | } 77 | if(((KeypadStruct.OUT3pin>>idx)&0x0001) == 0x0001) 78 | { 79 | OutPositions[3] = idx; 80 | } 81 | } 82 | } 83 | //Function(3): Change colomn number 84 | static void Keypad4x4_ChangeColomn(uint8_t colNum_0_to_3) 85 | { 86 | if(colNum_0_to_3==0) 87 | { 88 | //Set selected colomn 89 | KeypadStruct.OUT0_Port->OTYPER &= ~(1UL << OutPositions[0]); 90 | 91 | //Make other colomns floating 92 | KeypadStruct.OUT1_Port->OTYPER |= (1UL << OutPositions[1]); 93 | KeypadStruct.OUT2_Port->OTYPER |= (1UL << OutPositions[2]); 94 | KeypadStruct.OUT3_Port->OTYPER |= (1UL << OutPositions[3]); 95 | } 96 | else if(colNum_0_to_3==1) 97 | { 98 | //Set selected colomn 99 | KeypadStruct.OUT1_Port->OTYPER &= ~(1UL << OutPositions[1]); 100 | 101 | //Make other colomns floating 102 | KeypadStruct.OUT0_Port->OTYPER |= (1UL << OutPositions[0]); 103 | KeypadStruct.OUT2_Port->OTYPER |= (1UL << OutPositions[2]); 104 | KeypadStruct.OUT3_Port->OTYPER |= (1UL << OutPositions[3]); 105 | } 106 | else if(colNum_0_to_3==2) 107 | { 108 | //Set selected colomn 109 | KeypadStruct.OUT2_Port->OTYPER &= ~(1UL << OutPositions[2]); 110 | 111 | //Make other colomns floating 112 | KeypadStruct.OUT0_Port->OTYPER |= (1UL << OutPositions[0]); 113 | KeypadStruct.OUT1_Port->OTYPER |= (1UL << OutPositions[1]); 114 | KeypadStruct.OUT3_Port->OTYPER |= (1UL << OutPositions[3]); 115 | } 116 | else if(colNum_0_to_3==3) 117 | { 118 | //Set selected colomn 119 | KeypadStruct.OUT3_Port->OTYPER &= ~(1UL << OutPositions[3]); 120 | 121 | //Make other colomns floating 122 | KeypadStruct.OUT0_Port->OTYPER |= (1UL << OutPositions[0]); 123 | KeypadStruct.OUT1_Port->OTYPER |= (1UL << OutPositions[1]); 124 | KeypadStruct.OUT2_Port->OTYPER |= (1UL << OutPositions[2]); 125 | } 126 | } 127 | 128 | //Function(4): Read active keypad button 129 | void Keypad4x4_ReadKeypad(bool keys[16]) 130 | { 131 | //Step(1): Make Col0 High and check the rows 132 | Keypad4x4_ChangeColomn(0); 133 | keys[0] = HAL_GPIO_ReadPin(KeypadStruct.IN0_Port, KeypadStruct.IN0pin); 134 | keys[4] = HAL_GPIO_ReadPin(KeypadStruct.IN1_Port, KeypadStruct.IN1pin); 135 | keys[8] = HAL_GPIO_ReadPin(KeypadStruct.IN2_Port, KeypadStruct.IN2pin); 136 | keys[12] = HAL_GPIO_ReadPin(KeypadStruct.IN3_Port, KeypadStruct.IN3pin); 137 | 138 | //Step(2): Make Col1 High and check the rows 139 | Keypad4x4_ChangeColomn(1); 140 | keys[1] = HAL_GPIO_ReadPin(KeypadStruct.IN0_Port, KeypadStruct.IN0pin); 141 | keys[5] = HAL_GPIO_ReadPin(KeypadStruct.IN1_Port, KeypadStruct.IN1pin); 142 | keys[9] = HAL_GPIO_ReadPin(KeypadStruct.IN2_Port, KeypadStruct.IN2pin); 143 | keys[13] = HAL_GPIO_ReadPin(KeypadStruct.IN3_Port, KeypadStruct.IN3pin); 144 | 145 | //Step(3): Make Col2 High and check the rows 146 | Keypad4x4_ChangeColomn(2); 147 | keys[2] = HAL_GPIO_ReadPin(KeypadStruct.IN0_Port, KeypadStruct.IN0pin); 148 | keys[6] = HAL_GPIO_ReadPin(KeypadStruct.IN1_Port, KeypadStruct.IN1pin); 149 | keys[10] = HAL_GPIO_ReadPin(KeypadStruct.IN2_Port, KeypadStruct.IN2pin); 150 | keys[14] = HAL_GPIO_ReadPin(KeypadStruct.IN3_Port, KeypadStruct.IN3pin); 151 | 152 | //Step(4): Make Col3 High and check the rows 153 | Keypad4x4_ChangeColomn(3); 154 | keys[3] = HAL_GPIO_ReadPin(KeypadStruct.IN0_Port, KeypadStruct.IN0pin); 155 | keys[7] = HAL_GPIO_ReadPin(KeypadStruct.IN1_Port, KeypadStruct.IN1pin); 156 | keys[11] = HAL_GPIO_ReadPin(KeypadStruct.IN2_Port, KeypadStruct.IN2pin); 157 | keys[15] = HAL_GPIO_ReadPin(KeypadStruct.IN3_Port, KeypadStruct.IN3pin); 158 | } 159 | //Function(5): Get character 160 | char* Keypad4x4_GetChar(uint8_t keypadSw) 161 | { 162 | return Keypad_keys[keypadSw]; 163 | } 164 | 165 | -------------------------------------------------------------------------------- /Tutorial 23 - 4x4 Keypad/MY_Keypad4x4.h: -------------------------------------------------------------------------------- 1 | /* 2 | Library: 4x4 Keypad drive for STM32 MCUs 3 | Written by: Mohamed Yaqoob 4 | Date written: 03/04/2018 5 | Description: The MY_Keypad4x4 library consists of the following public functions 6 | Function(1)- Keypad4x4_Init 7 | Function(2)- Keypad4x4_ReadKeypad 8 | Function(3)- Keypad4x4_GetChar 9 | */ 10 | 11 | //Header files 12 | #include "stm32f4xx_hal.h" 13 | #include 14 | 15 | //***** Constant variables and typedefs *****// 16 | typedef struct 17 | { 18 | GPIO_TypeDef* IN0_Port; 19 | GPIO_TypeDef* IN1_Port; 20 | GPIO_TypeDef* IN2_Port; 21 | GPIO_TypeDef* IN3_Port; 22 | GPIO_TypeDef* OUT0_Port; 23 | GPIO_TypeDef* OUT1_Port; 24 | GPIO_TypeDef* OUT2_Port; 25 | GPIO_TypeDef* OUT3_Port; 26 | 27 | uint16_t IN0pin; 28 | uint16_t IN1pin; 29 | uint16_t IN2pin; 30 | uint16_t IN3pin; 31 | uint16_t OUT0pin; 32 | uint16_t OUT1pin; 33 | uint16_t OUT2pin; 34 | uint16_t OUT3pin; 35 | }Keypad_WiresTypeDef; 36 | 37 | //List of keys as chars 38 | 39 | 40 | //***** Functions prototype *****// 41 | //Function(1): Set Keypad pins and ports 42 | void Keypad4x4_Init(Keypad_WiresTypeDef *KeypadWiringStruct); 43 | //Function(2): Get pin positions for colomn change use, only for out pins 44 | static void Keypad4x4_FindPins_positions(void); 45 | //Function(3): Change colomn number 46 | static void Keypad4x4_ChangeColomn(uint8_t colNum_0_to_3); 47 | //Function(4): Read active keypad button 48 | void Keypad4x4_ReadKeypad(bool keys[16]); 49 | //Function(5): Get character 50 | char* Keypad4x4_GetChar(uint8_t keypadSw); 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Tutorial 24 - NRF24L01 Radio Transceiver/MY_NRF24.h: -------------------------------------------------------------------------------- 1 | /* 2 | Library: NRF24L01/NRF24L01+ 3 | Written by: Mohamed Yaqoob (MYaqoobEmbedded YouTube Channel) 4 | Date Written: 10/11/2018 5 | Last modified: -/- 6 | Description: This is an STM32 device driver library for the NRF24L01 Nordic Radio transceiver, using STM HAL libraries 7 | 8 | References: This library was written based on the Arduino NRF24 Open-Source library by J. Coliz and the NRF24 datasheet 9 | - https://github.com/maniacbug/RF24 10 | - https://www.sparkfun.com/datasheets/Components/SMD/nRF24L01Pluss_Preliminary_Product_Specification_v1_0.pdf 11 | 12 | * Copyright (C) 2018 - M. Yaqoob 13 | This is a free software under the GNU license, you can redistribute it and/or modify it under the terms 14 | of the GNU General Public Licenseversion 3 as published by the Free Software Foundation. 15 | 16 | This software library is shared with puplic for educational purposes, without WARRANTY and Author is not liable for any damages caused directly 17 | or indirectly by this software, read more about this on the GNU General Public License. 18 | */ 19 | 20 | //List of header files 21 | #include "stm32f4xx_hal.h" //** Change this according to your STM32 series **// 22 | #include "nRF24L01.h" 23 | #include 24 | #include 25 | #include 26 | //1. Pinout Ports and Pin 27 | //#define nrf_CSN_PORT GPIOD 28 | //#define nrf_CSN_PIN GPIO_PIN_0 29 | 30 | //#define nrf_CE_PORT GPIOD 31 | //#define nrf_CE_PIN GPIO_PIN_1 32 | 33 | //**** TypeDefs ****// 34 | //1. Power Amplifier function, NRF24_setPALevel() 35 | typedef enum { 36 | RF24_PA_m18dB = 0, 37 | RF24_PA_m12dB, 38 | RF24_PA_m6dB, 39 | RF24_PA_0dB, 40 | RF24_PA_ERROR 41 | }rf24_pa_dbm_e ; 42 | //2. NRF24_setDataRate() input 43 | typedef enum { 44 | RF24_1MBPS = 0, 45 | RF24_2MBPS, 46 | RF24_250KBPS 47 | }rf24_datarate_e; 48 | //3. NRF24_setCRCLength() input 49 | typedef enum { 50 | RF24_CRC_DISABLED = 0, 51 | RF24_CRC_8, 52 | RF24_CRC_16 53 | }rf24_crclength_e; 54 | //4. Pipe address registers 55 | static const uint8_t NRF24_ADDR_REGS[7] = { 56 | REG_RX_ADDR_P0, 57 | REG_RX_ADDR_P1, 58 | REG_RX_ADDR_P2, 59 | REG_RX_ADDR_P3, 60 | REG_RX_ADDR_P4, 61 | REG_RX_ADDR_P5, 62 | REG_TX_ADDR 63 | }; 64 | //5. RX_PW_Px registers addresses 65 | static const uint8_t RF24_RX_PW_PIPE[6] = { 66 | REG_RX_PW_P0, 67 | REG_RX_PW_P1, 68 | REG_RX_PW_P2, 69 | REG_RX_PW_P3, 70 | REG_RX_PW_P4, 71 | REG_RX_PW_P5 72 | }; 73 | //**** Functions prototypes ****// 74 | //Microsecond delay function 75 | void NRF24_DelayMicroSeconds(uint32_t uSec); 76 | 77 | //1. Chip Select function 78 | void NRF24_csn(int mode); 79 | //2. Chip Enable 80 | void NRF24_ce(int level); 81 | //3. Read single byte from a register 82 | uint8_t NRF24_read_register(uint8_t reg); 83 | //4. Read multiple bytes register 84 | void NRF24_read_registerN(uint8_t reg, uint8_t *buf, uint8_t len); 85 | //5. Write single byte register 86 | void NRF24_write_register(uint8_t reg, uint8_t value); 87 | //6. Write multipl bytes register 88 | void NRF24_write_registerN(uint8_t reg, const uint8_t* buf, uint8_t len); 89 | //7. Write transmit payload 90 | void NRF24_write_payload(const void* buf, uint8_t len); 91 | //8. Read receive payload 92 | void NRF24_read_payload(void* buf, uint8_t len); 93 | //9. Flush Tx buffer 94 | void NRF24_flush_tx(void); 95 | //10. Flush Rx buffer 96 | void NRF24_flush_rx(void); 97 | //11. Get status register value 98 | uint8_t NRF24_get_status(void); 99 | 100 | //12. Begin function 101 | void NRF24_begin(GPIO_TypeDef *nrf24PORT, uint16_t nrfCSN_Pin, uint16_t nrfCE_Pin, SPI_HandleTypeDef nrfSPI); 102 | //13. Listen on open pipes for reading (Must call NRF24_openReadingPipe() first) 103 | void NRF24_startListening(void); 104 | //14. Stop listening (essential before any write operation) 105 | void NRF24_stopListening(void); 106 | 107 | //15. Write(Transmit data), returns true if successfully sent 108 | bool NRF24_write( const void* buf, uint8_t len ); 109 | //16. Check for available data to read 110 | bool NRF24_available(void); 111 | //17. Read received data 112 | bool NRF24_read( void* buf, uint8_t len ); 113 | //18. Open Tx pipe for writing (Cannot perform this while Listenning, has to call NRF24_stopListening) 114 | void NRF24_openWritingPipe(uint64_t address); 115 | //19. Open reading pipe 116 | void NRF24_openReadingPipe(uint8_t number, uint64_t address); 117 | //20 set transmit retries (rf24_Retries_e) and delay 118 | void NRF24_setRetries(uint8_t delay, uint8_t count); 119 | //21. Set RF channel frequency 120 | void NRF24_setChannel(uint8_t channel); 121 | //22. Set payload size 122 | void NRF24_setPayloadSize(uint8_t size); 123 | //23. Get payload size 124 | uint8_t NRF24_getPayloadSize(void); 125 | //24. Get dynamic payload size, of latest packet received 126 | uint8_t NRF24_getDynamicPayloadSize(void); 127 | //25. Enable payload on Ackknowledge packet 128 | void NRF24_enableAckPayload(void); 129 | //26. Enable dynamic payloads 130 | void NRF24_enableDynamicPayloads(void); 131 | void NRF24_disableDynamicPayloads(void); 132 | //27. Check if module is NRF24L01+ or normal module 133 | bool NRF24_isNRF_Plus(void) ; 134 | //28. Set Auto Ack for all 135 | void NRF24_setAutoAck(bool enable); 136 | //29. Set Auto Ack for certain pipe 137 | void NRF24_setAutoAckPipe( uint8_t pipe, bool enable ) ; 138 | //30. Set transmit power level 139 | void NRF24_setPALevel( rf24_pa_dbm_e level ) ; 140 | //31. Get transmit power level 141 | rf24_pa_dbm_e NRF24_getPALevel( void ) ; 142 | //32. Set data rate (250 Kbps, 1Mbps, 2Mbps) 143 | bool NRF24_setDataRate(rf24_datarate_e speed); 144 | //33. Get data rate 145 | rf24_datarate_e NRF24_getDataRate( void ); 146 | //34. Set crc length (disable, 8-bits or 16-bits) 147 | void NRF24_setCRCLength(rf24_crclength_e length); 148 | //35. Get CRC length 149 | rf24_crclength_e NRF24_getCRCLength(void); 150 | //36. Disable CRC 151 | void NRF24_disableCRC( void ) ; 152 | //37. power up 153 | void NRF24_powerUp(void) ; 154 | //38. power down 155 | void NRF24_powerDown(void); 156 | //39. Check if data are available and on which pipe (Use this for multiple rx pipes) 157 | bool NRF24_availablePipe(uint8_t* pipe_num); 158 | //40. Start write (for IRQ mode) 159 | void NRF24_startWrite( const void* buf, uint8_t len ); 160 | //41. Write acknowledge payload 161 | void NRF24_writeAckPayload(uint8_t pipe, const void* buf, uint8_t len); 162 | //42. Check if an Ack payload is available 163 | bool NRF24_isAckPayloadAvailable(void); 164 | //43. Check interrupt flags 165 | void NRF24_whatHappened(bool *tx_ok,bool *tx_fail,bool *rx_ready); 166 | //44. Test if there is a carrier on the previous listenning period (useful to check for intereference) 167 | bool NRF24_testCarrier(void); 168 | //45. Test if a signal carrier exists (=> -64dB), only for NRF24L01+ 169 | bool NRF24_testRPD(void) ; 170 | //46. Reset Status 171 | void NRF24_resetStatus(void); 172 | //47. ACTIVATE cmd 173 | void NRF24_ACTIVATE_cmd(void); 174 | //48. Get AckPayload Size 175 | uint8_t NRF24_GetAckPayloadSize(void); 176 | 177 | //********** DEBUG Functions **********// 178 | //1. Print radio settings 179 | void printRadioSettings(void); 180 | //2. Print Status 181 | void printStatusReg(void); 182 | //3. Print Config 183 | void printConfigReg(void); 184 | //4. Init Variables 185 | void nrf24_DebugUART_Init(UART_HandleTypeDef nrf24Uart); 186 | //5. FIFO Status 187 | void printFIFOstatus(void); 188 | 189 | 190 | -------------------------------------------------------------------------------- /Tutorial 24 - NRF24L01 Radio Transceiver/nRF24L01.h: -------------------------------------------------------------------------------- 1 | /* 2 | Library: NRF24L01 software library for STM32 MCUs 3 | Written by: Mohamed Yaqoob 4 | Date written: 25/10/2018 5 | Last modified: -/- 6 | Description: 7 | 8 | */ 9 | 10 | #define _BV(x) (1<<(x)) 11 | 12 | /* Memory Map */ 13 | #define REG_CONFIG 0x00 14 | #define REG_EN_AA 0x01 15 | #define REG_EN_RXADDR 0x02 16 | #define REG_SETUP_AW 0x03 17 | #define REG_SETUP_RETR 0x04 18 | #define REG_RF_CH 0x05 19 | #define REG_RF_SETUP 0x06 20 | #define REG_STATUS 0x07 21 | #define REG_OBSERVE_TX 0x08 22 | #define REG_CD 0x09 23 | #define REG_RX_ADDR_P0 0x0A 24 | #define REG_RX_ADDR_P1 0x0B 25 | #define REG_RX_ADDR_P2 0x0C 26 | #define REG_RX_ADDR_P3 0x0D 27 | #define REG_RX_ADDR_P4 0x0E 28 | #define REG_RX_ADDR_P5 0x0F 29 | #define REG_TX_ADDR 0x10 30 | #define REG_RX_PW_P0 0x11 31 | #define REG_RX_PW_P1 0x12 32 | #define REG_RX_PW_P2 0x13 33 | #define REG_RX_PW_P3 0x14 34 | #define REG_RX_PW_P4 0x15 35 | #define REG_RX_PW_P5 0x16 36 | #define REG_FIFO_STATUS 0x17 37 | #define REG_DYNPD 0x1C 38 | #define REG_FEATURE 0x1D 39 | 40 | /* Bit Mnemonics */ 41 | #define MASK_RX_DR 6 42 | #define MASK_TX_DS 5 43 | #define MASK_MAX_RT 4 44 | #define BIT_EN_CRC 3 45 | #define BIT_CRCO 2 46 | #define BIT_PWR_UP 1 47 | #define BIT_PRIM_RX 0 48 | #define BIT_ENAA_P5 5 49 | #define BIT_ENAA_P4 4 50 | #define BIT_ENAA_P3 3 51 | #define BIT_ENAA_P2 2 52 | #define BIT_ENAA_P1 1 53 | #define BIT_ENAA_P0 0 54 | #define BIT_ERX_P5 5 55 | #define BIT_ERX_P4 4 56 | #define BIT_ERX_P3 3 57 | #define BIT_ERX_P2 2 58 | #define BIT_ERX_P1 1 59 | #define BIT_ERX_P0 0 60 | #define BIT_AW 0 61 | #define BIT_ARD 4 62 | #define BIT_ARC 0 63 | #define BIT_PLL_LOCK 4 64 | #define BIT_RF_DR 3 65 | #define BIT_RF_PWR 6 66 | #define BIT_RX_DR 6 67 | #define BIT_TX_DS 5 68 | #define BIT_MAX_RT 4 69 | #define BIT_RX_P_NO 1 70 | #define BIT_TX_FULL 0 71 | #define BIT_PLOS_CNT 4 72 | #define BIT_ARC_CNT 0 73 | #define BIT_TX_REUSE 6 74 | #define BIT_FIFO_FULL 5 75 | #define BIT_TX_EMPTY 4 76 | #define BIT_RX_FULL 1 77 | #define BIT_RX_EMPTY 0 78 | #define BIT_DPL_P5 5 79 | #define BIT_DPL_P4 4 80 | #define BIT_DPL_P3 3 81 | #define BIT_DPL_P2 2 82 | #define BIT_DPL_P1 1 83 | #define BIT_DPL_P0 0 84 | #define BIT_EN_DPL 2 85 | #define BIT_EN_ACK_PAY 1 86 | #define BIT_EN_DYN_ACK 0 87 | 88 | /* Instruction Mnemonics */ 89 | #define CMD_R_REGISTER 0x00 90 | #define CMD_W_REGISTER 0x20 91 | #define CMD_REGISTER_MASK 0x1F 92 | #define CMD_ACTIVATE 0x50 93 | #define CMD_R_RX_PL_WID 0x60 94 | #define CMD_R_RX_PAYLOAD 0x61 95 | #define CMD_W_TX_PAYLOAD 0xA0 96 | #define CMD_W_ACK_PAYLOAD 0xA8 97 | #define CMD_FLUSH_TX 0xE1 98 | #define CMD_FLUSH_RX 0xE2 99 | #define CMD_REUSE_TX_PL 0xE3 100 | #define CMD_NOP 0xFF 101 | 102 | /* Non-P omissions */ 103 | #define LNA_HCURR 0 104 | 105 | /* P model memory Map */ 106 | #define REG_RPD 0x09 107 | 108 | /* P model bit Mnemonics */ 109 | #define RF_DR_LOW 5 110 | #define RF_DR_HIGH 3 111 | #define RF_PWR_LOW 1 112 | #define RF_PWR_HIGH 2 113 | 114 | -------------------------------------------------------------------------------- /Tutorial 24 - NRF24L01 Radio Transceiver/nRF24L01_Datasheet.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MYaqoobEmbedded/STM32-Tutorials/bdf2c8e7722f267b5c7e8114462c66f59203704c/Tutorial 24 - NRF24L01 Radio Transceiver/nRF24L01_Datasheet.pdf -------------------------------------------------------------------------------- /Tutorial 25 - DHT22 Temperature Sensor/MY_DHT22.c: -------------------------------------------------------------------------------- 1 | /* 2 | Library: DHT22 - AM2302 Temperature and Humidity Sensor 3 | Written by: Mohamed Yaqoob (MYaqoobEmbedded YouTube Channel) 4 | Date Written: 21/11/2018 5 | Last modified: -/- 6 | Description: This is an STM32 device driver library for the DHT22 Temperature and Humidity Sensor, using STM HAL libraries 7 | 8 | References: This library was written based on the DHT22 datasheet 9 | - https://cdn-shop.adafruit.com/datasheets/Digital+humidity+and+temperature+sensor+AM2302.pdf 10 | 11 | * Copyright (C) 2018 - M. Yaqoob 12 | This is a free software under the GNU license, you can redistribute it and/or modify it under the terms 13 | of the GNU General Public Licenseversion 3 as published by the Free Software Foundation. 14 | 15 | This software library is shared with puplic for educational purposes, without WARRANTY and Author is not liable for any damages caused directly 16 | or indirectly by this software, read more about this on the GNU General Public License. 17 | */ 18 | 19 | //Header files 20 | #include "MY_DHT22.h" 21 | 22 | //Bit fields manipulations 23 | #define bitRead(value, bit) (((value) >> (bit)) & 0x01) 24 | #define bitSet(value, bit) ((value) |= (1UL << (bit))) 25 | #define bitClear(value, bit) ((value) &= ~(1UL << (bit))) 26 | #define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) 27 | 28 | //1. One wire data line 29 | static GPIO_TypeDef* oneWire_PORT; 30 | static uint16_t oneWire_PIN; 31 | static uint8_t oneWirePin_Idx; 32 | 33 | //*** Functions prototypes ***// 34 | //OneWire Initialise 35 | void DHT22_Init(GPIO_TypeDef* DataPort, uint16_t DataPin) 36 | { 37 | oneWire_PORT = DataPort; 38 | oneWire_PIN = DataPin; 39 | for(uint8_t i=0; i<16; i++) 40 | { 41 | if(DataPin & (1 << i)) 42 | { 43 | oneWirePin_Idx = i; 44 | break; 45 | } 46 | } 47 | 48 | 49 | } 50 | //Change pin mode 51 | static void ONE_WIRE_PinMode(OnePinMode_Typedef mode) 52 | { 53 | GPIO_InitTypeDef GPIO_InitStruct; 54 | GPIO_InitStruct.Pin = oneWire_PIN; 55 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; 56 | GPIO_InitStruct.Pull = GPIO_NOPULL; 57 | 58 | if(mode == ONE_OUTPUT) 59 | { 60 | // oneWire_PORT->MODER &= ~(3UL << 2*oneWirePin_Idx); //Reset State 61 | // oneWire_PORT->MODER |= (0x01 << 2*oneWirePin_Idx); //Output Mode 62 | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 63 | } 64 | else if(mode == ONE_INPUT) 65 | { 66 | // oneWire_PORT->MODER &= ~(3UL << 2*oneWirePin_Idx); //Input Mode 67 | GPIO_InitStruct.Mode = GPIO_MODE_INPUT; 68 | } 69 | 70 | HAL_GPIO_Init(oneWire_PORT, &GPIO_InitStruct); 71 | } 72 | //One Wire pin HIGH/LOW Write 73 | static void ONE_WIRE_Pin_Write(bool state) 74 | { 75 | if(state) HAL_GPIO_WritePin(oneWire_PORT, oneWire_PIN, GPIO_PIN_SET); 76 | else HAL_GPIO_WritePin(oneWire_PORT, oneWire_PIN, GPIO_PIN_RESET); 77 | } 78 | static bool ONE_WIRE_Pin_Read(void) 79 | { 80 | return (1&HAL_GPIO_ReadPin(oneWire_PORT, oneWire_PIN)); 81 | } 82 | 83 | //Microsecond delay 84 | static void DelayMicroSeconds(uint32_t uSec) 85 | { 86 | uint32_t uSecVar = uSec; 87 | uSecVar = uSecVar* ((SystemCoreClock/1000000)/3); 88 | while(uSecVar--); 89 | } 90 | 91 | //DHT Begin function 92 | static void DHT22_StartAcquisition(void) 93 | { 94 | //Change data pin mode to OUTPUT 95 | ONE_WIRE_PinMode(ONE_OUTPUT); 96 | //Put pin LOW 97 | ONE_WIRE_Pin_Write(0); 98 | //500uSec delay 99 | DelayMicroSeconds(500); 100 | //Bring pin HIGH 101 | ONE_WIRE_Pin_Write(1); 102 | //30 uSec delay 103 | DelayMicroSeconds(30); 104 | //Set pin as input 105 | ONE_WIRE_PinMode(ONE_INPUT); 106 | } 107 | //Read 5 bytes 108 | static void DHT22_ReadRaw(uint8_t *data) 109 | { 110 | uint32_t rawBits = 0UL; 111 | uint8_t checksumBits=0; 112 | 113 | DelayMicroSeconds(40); 114 | while(!ONE_WIRE_Pin_Read()); 115 | while(ONE_WIRE_Pin_Read()); 116 | for(int8_t i=31; i>=0; i--) 117 | { 118 | while(!ONE_WIRE_Pin_Read()); 119 | DelayMicroSeconds(40); 120 | if(ONE_WIRE_Pin_Read()) 121 | { 122 | rawBits |= (1UL << i); 123 | } 124 | while(ONE_WIRE_Pin_Read()); 125 | } 126 | 127 | for(int8_t i=7; i>=0; i--) 128 | { 129 | while(!ONE_WIRE_Pin_Read()); 130 | DelayMicroSeconds(40); 131 | if(ONE_WIRE_Pin_Read()) 132 | { 133 | checksumBits |= (1UL << i); 134 | } 135 | while(ONE_WIRE_Pin_Read()); 136 | } 137 | 138 | 139 | //Copy raw data to array of bytes 140 | data[0] = (rawBits>>24)&0xFF; 141 | data[1] = (rawBits>>16)&0xFF; 142 | data[2] = (rawBits>>8)&0xFF; 143 | data[3] = (rawBits>>0)&0xFF; 144 | data[4] = (checksumBits)&0xFF; 145 | } 146 | 147 | //Get Temperature and Humidity data 148 | bool DHT22_GetTemp_Humidity(float *Temp, float *Humidity) 149 | { 150 | uint8_t dataArray[6], myChecksum; 151 | uint16_t Temp16, Humid16; 152 | //Implement Start data Aqcuisition routine 153 | DHT22_StartAcquisition(); 154 | //Aqcuire raw data 155 | DHT22_ReadRaw(dataArray); 156 | //calculate checksum 157 | myChecksum = 0; 158 | for(uint8_t k=0; k<4; k++) 159 | { 160 | myChecksum += dataArray[k]; 161 | } 162 | if(myChecksum == dataArray[4]) 163 | { 164 | Temp16 = (dataArray[2] <<8) | dataArray[3]; 165 | Humid16 = (dataArray[0] <<8) | dataArray[1]; 166 | 167 | *Temp = Temp16/10.0f; 168 | *Humidity = Humid16/10.0f; 169 | return 1; 170 | } 171 | return 0; 172 | } 173 | 174 | -------------------------------------------------------------------------------- /Tutorial 25 - DHT22 Temperature Sensor/MY_DHT22.h: -------------------------------------------------------------------------------- 1 | /* 2 | Library: DHT22 - AM2302 Temperature and Humidity Sensor 3 | Written by: Mohamed Yaqoob (MYaqoobEmbedded YouTube Channel) 4 | Date Written: 21/11/2018 5 | Last modified: -/- 6 | Description: This is an STM32 device driver library for the DHT22 Temperature and Humidity Sensor, using STM HAL libraries 7 | 8 | References: This library was written based on the DHT22 datasheet 9 | - https://cdn-shop.adafruit.com/datasheets/Digital+humidity+and+temperature+sensor+AM2302.pdf 10 | 11 | * Copyright (C) 2018 - M. Yaqoob 12 | This is a free software under the GNU license, you can redistribute it and/or modify it under the terms 13 | of the GNU General Public Licenseversion 3 as published by the Free Software Foundation. 14 | 15 | This software library is shared with puplic for educational purposes, without WARRANTY and Author is not liable for any damages caused directly 16 | or indirectly by this software, read more about this on the GNU General Public License. 17 | */ 18 | 19 | //Header files 20 | #include "stm32f4xx_hal.h" 21 | #include 22 | #include 23 | #include 24 | 25 | //Pin Mode enum 26 | typedef enum 27 | { 28 | ONE_OUTPUT = 0, 29 | ONE_INPUT, 30 | }OnePinMode_Typedef; 31 | 32 | 33 | 34 | //*** Functions prototypes ***// 35 | //OneWire Initialise 36 | void DHT22_Init(GPIO_TypeDef* DataPort, uint16_t DataPin); 37 | //Change pin mode 38 | static void ONE_WIRE_PinMode(OnePinMode_Typedef mode); 39 | //One Wire pin HIGH/LOW Write 40 | static void ONE_WIRE_Pin_Write(bool state); 41 | static bool ONE_WIRE_Pin_Read(void); 42 | //Microsecond delay 43 | static void DelayMicroSeconds(uint32_t uSec); 44 | //Begin function 45 | static void DHT22_StartAcquisition(void); 46 | //Read 5 bytes 47 | static void DHT22_ReadRaw(uint8_t *data); 48 | 49 | //Get Temperature and Humidity data 50 | bool DHT22_GetTemp_Humidity(float *Temp, float *Humidity); 51 | 52 | -------------------------------------------------------------------------------- /Tutorial 25 - DHT22 Temperature Sensor/main.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * File Name : main.c 4 | * Description : Main program body 5 | ****************************************************************************** 6 | ** This notice applies to any and all portions of this file 7 | * that are not between comment pairs USER CODE BEGIN and 8 | * USER CODE END. Other portions of this file, whether 9 | * inserted by the user or by software development tools 10 | * are owned by their respective copyright owners. 11 | * 12 | * COPYRIGHT(c) 2018 STMicroelectronics 13 | * 14 | * Redistribution and use in source and binary forms, with or without modification, 15 | * are permitted provided that the following conditions are met: 16 | * 1. Redistributions of source code must retain the above copyright notice, 17 | * this list of conditions and the following disclaimer. 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, 19 | * this list of conditions and the following disclaimer in the documentation 20 | * and/or other materials provided with the distribution. 21 | * 3. Neither the name of STMicroelectronics nor the names of its contributors 22 | * may be used to endorse or promote products derived from this software 23 | * without specific prior written permission. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 33 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | * 36 | ****************************************************************************** 37 | */ 38 | /* Includes ------------------------------------------------------------------*/ 39 | #include "main.h" 40 | #include "stm32f4xx_hal.h" 41 | 42 | /* USER CODE BEGIN Includes */ 43 | #include "MY_DHT22.h" 44 | /* USER CODE END Includes */ 45 | 46 | /* Private variables ---------------------------------------------------------*/ 47 | UART_HandleTypeDef huart2; 48 | 49 | /* USER CODE BEGIN PV */ 50 | /* Private variables ---------------------------------------------------------*/ 51 | 52 | /* USER CODE END PV */ 53 | 54 | /* Private function prototypes -----------------------------------------------*/ 55 | void SystemClock_Config(void); 56 | static void MX_GPIO_Init(void); 57 | static void MX_USART2_UART_Init(void); 58 | 59 | /* USER CODE BEGIN PFP */ 60 | /* Private function prototypes -----------------------------------------------*/ 61 | 62 | /* USER CODE END PFP */ 63 | 64 | /* USER CODE BEGIN 0 */ 65 | float TempC, Humidity; 66 | char uartData[50]; 67 | /* USER CODE END 0 */ 68 | 69 | int main(void) 70 | { 71 | 72 | /* USER CODE BEGIN 1 */ 73 | 74 | /* USER CODE END 1 */ 75 | 76 | /* MCU Configuration----------------------------------------------------------*/ 77 | 78 | /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ 79 | HAL_Init(); 80 | 81 | /* USER CODE BEGIN Init */ 82 | 83 | /* USER CODE END Init */ 84 | 85 | /* Configure the system clock */ 86 | SystemClock_Config(); 87 | 88 | /* USER CODE BEGIN SysInit */ 89 | 90 | /* USER CODE END SysInit */ 91 | 92 | /* Initialize all configured peripherals */ 93 | MX_GPIO_Init(); 94 | MX_USART2_UART_Init(); 95 | 96 | /* USER CODE BEGIN 2 */ 97 | DHT22_Init(GPIOA, GPIO_PIN_9); 98 | /* USER CODE END 2 */ 99 | 100 | /* Infinite loop */ 101 | /* USER CODE BEGIN WHILE */ 102 | while (1) 103 | { 104 | /* USER CODE END WHILE */ 105 | 106 | /* USER CODE BEGIN 3 */ 107 | if(DHT22_GetTemp_Humidity(&TempC, &Humidity) == 1) 108 | { 109 | sprintf(uartData, "\r\nTemp (C) =\t %.1f\r\nHumidity (%%) =\t %.1f%%\r\n", TempC, Humidity); 110 | HAL_UART_Transmit(&huart2, (uint8_t *)uartData, strlen(uartData), 10); 111 | } 112 | else 113 | { 114 | sprintf(uartData, "\r\nCRC Error!\r\n"); 115 | HAL_UART_Transmit(&huart2, (uint8_t *)uartData, strlen(uartData), 10); 116 | } 117 | 118 | HAL_Delay(1000); 119 | 120 | } 121 | /* USER CODE END 3 */ 122 | 123 | } 124 | 125 | /** System Clock Configuration 126 | */ 127 | void SystemClock_Config(void) 128 | { 129 | 130 | RCC_OscInitTypeDef RCC_OscInitStruct; 131 | RCC_ClkInitTypeDef RCC_ClkInitStruct; 132 | 133 | /**Configure the main internal regulator output voltage 134 | */ 135 | __HAL_RCC_PWR_CLK_ENABLE(); 136 | 137 | __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2); 138 | 139 | /**Initializes the CPU, AHB and APB busses clocks 140 | */ 141 | RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; 142 | RCC_OscInitStruct.HSIState = RCC_HSI_ON; 143 | RCC_OscInitStruct.HSICalibrationValue = 16; 144 | RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; 145 | RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; 146 | RCC_OscInitStruct.PLL.PLLM = 16; 147 | RCC_OscInitStruct.PLL.PLLN = 336; 148 | RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4; 149 | RCC_OscInitStruct.PLL.PLLQ = 7; 150 | if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) 151 | { 152 | _Error_Handler(__FILE__, __LINE__); 153 | } 154 | 155 | /**Initializes the CPU, AHB and APB busses clocks 156 | */ 157 | RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK 158 | |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; 159 | RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; 160 | RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; 161 | RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; 162 | RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; 163 | 164 | if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) 165 | { 166 | _Error_Handler(__FILE__, __LINE__); 167 | } 168 | 169 | /**Configure the Systick interrupt time 170 | */ 171 | HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); 172 | 173 | /**Configure the Systick 174 | */ 175 | HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); 176 | 177 | /* SysTick_IRQn interrupt configuration */ 178 | HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); 179 | } 180 | 181 | /* USART2 init function */ 182 | static void MX_USART2_UART_Init(void) 183 | { 184 | 185 | huart2.Instance = USART2; 186 | huart2.Init.BaudRate = 115200; 187 | huart2.Init.WordLength = UART_WORDLENGTH_8B; 188 | huart2.Init.StopBits = UART_STOPBITS_1; 189 | huart2.Init.Parity = UART_PARITY_NONE; 190 | huart2.Init.Mode = UART_MODE_TX_RX; 191 | huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; 192 | huart2.Init.OverSampling = UART_OVERSAMPLING_16; 193 | if (HAL_UART_Init(&huart2) != HAL_OK) 194 | { 195 | _Error_Handler(__FILE__, __LINE__); 196 | } 197 | 198 | } 199 | 200 | /** Configure pins as 201 | * Analog 202 | * Input 203 | * Output 204 | * EVENT_OUT 205 | * EXTI 206 | */ 207 | static void MX_GPIO_Init(void) 208 | { 209 | 210 | GPIO_InitTypeDef GPIO_InitStruct; 211 | 212 | /* GPIO Ports Clock Enable */ 213 | __HAL_RCC_GPIOC_CLK_ENABLE(); 214 | __HAL_RCC_GPIOA_CLK_ENABLE(); 215 | 216 | /*Configure GPIO pin Output Level */ 217 | HAL_GPIO_WritePin(GPIOA, LED_Pin|GPIO_PIN_9, GPIO_PIN_RESET); 218 | 219 | /*Configure GPIO pin : Button_Pin */ 220 | GPIO_InitStruct.Pin = Button_Pin; 221 | GPIO_InitStruct.Mode = GPIO_MODE_INPUT; 222 | GPIO_InitStruct.Pull = GPIO_NOPULL; 223 | HAL_GPIO_Init(Button_GPIO_Port, &GPIO_InitStruct); 224 | 225 | /*Configure GPIO pins : LED_Pin PA9 */ 226 | GPIO_InitStruct.Pin = LED_Pin|GPIO_PIN_9; 227 | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 228 | GPIO_InitStruct.Pull = GPIO_NOPULL; 229 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; 230 | HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 231 | 232 | } 233 | 234 | /* USER CODE BEGIN 4 */ 235 | 236 | /* USER CODE END 4 */ 237 | 238 | /** 239 | * @brief This function is executed in case of error occurrence. 240 | * @param None 241 | * @retval None 242 | */ 243 | void _Error_Handler(char * file, int line) 244 | { 245 | /* USER CODE BEGIN Error_Handler_Debug */ 246 | /* User can add his own implementation to report the HAL error return state */ 247 | while(1) 248 | { 249 | } 250 | /* USER CODE END Error_Handler_Debug */ 251 | } 252 | 253 | #ifdef USE_FULL_ASSERT 254 | 255 | /** 256 | * @brief Reports the name of the source file and the source line number 257 | * where the assert_param error has occurred. 258 | * @param file: pointer to the source file name 259 | * @param line: assert_param error line source number 260 | * @retval None 261 | */ 262 | void assert_failed(uint8_t* file, uint32_t line) 263 | { 264 | /* USER CODE BEGIN 6 */ 265 | /* User can add his own implementation to report the file name and line number, 266 | ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ 267 | /* USER CODE END 6 */ 268 | 269 | } 270 | 271 | #endif 272 | 273 | /** 274 | * @} 275 | */ 276 | 277 | /** 278 | * @} 279 | */ 280 | 281 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 282 | -------------------------------------------------------------------------------- /Tutorial 26 - SPI LCD + Resistive touch/MY_ILI9341.h: -------------------------------------------------------------------------------- 1 | /* 2 | Library: SPI LCD - ILI9341 3 | Written by: Mohamed Yaqoob (MYaqoobEmbedded YouTube Channel) 4 | Date Written: 09/12/2018 5 | Last modified: -/- 6 | Description: This is an STM32 device driver library for the ILI9341 SPI LCD display, using STM HAL libraries 7 | 8 | * Copyright (C) 2018 - M. Yaqoob 9 | This is a free software under the GNU license, you can redistribute it and/or modify it under the terms 10 | of the GNU General Public Licenseversion 3 as published by the Free Software Foundation. 11 | 12 | This software library is shared with puplic for educational purposes, without WARRANTY and Author is not liable for any damages caused directly 13 | or indirectly by this software, read more about this on the GNU General Public License. 14 | */ 15 | 16 | //List of includes 17 | #include 18 | //** CHANGE BASED ON STM32 CHIP F4/F7/F1...**// 19 | #include "stm32f4xx_hal.h" 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | //LCD dimensions defines 26 | #define ILI9341_WIDTH 240 27 | #define ILI9341_HEIGHT 320 28 | #define ILI9341_PIXEL_COUNT ILI9341_WIDTH * ILI9341_HEIGHT 29 | //ILI9341 LCD commands 30 | #define ILI9341_RESET 0x01 31 | #define ILI9341_SLEEP_OUT 0x11 32 | #define ILI9341_GAMMA 0x26 33 | #define ILI9341_DISPLAY_OFF 0x28 34 | #define ILI9341_DISPLAY_ON 0x29 35 | #define ILI9341_COLUMN_ADDR 0x2A 36 | #define ILI9341_PAGE_ADDR 0x2B 37 | #define ILI9341_GRAM 0x2C 38 | #define ILI9341_TEARING_OFF 0x34 39 | #define ILI9341_TEARING_ON 0x35 40 | #define ILI9341_DISPLAY_INVERSION 0xb4 41 | #define ILI9341_MAC 0x36 42 | #define ILI9341_PIXEL_FORMAT 0x3A 43 | #define ILI9341_WDB 0x51 44 | #define ILI9341_WCD 0x53 45 | #define ILI9341_RGB_INTERFACE 0xB0 46 | #define ILI9341_FRC 0xB1 47 | #define ILI9341_BPC 0xB5 48 | #define ILI9341_DFC 0xB6 49 | #define ILI9341_Entry_Mode_Set 0xB7 50 | #define ILI9341_POWER1 0xC0 51 | #define ILI9341_POWER2 0xC1 52 | #define ILI9341_VCOM1 0xC5 53 | #define ILI9341_VCOM2 0xC7 54 | #define ILI9341_POWERA 0xCB 55 | #define ILI9341_POWERB 0xCF 56 | #define ILI9341_PGAMMA 0xE0 57 | #define ILI9341_NGAMMA 0xE1 58 | #define ILI9341_DTCA 0xE8 59 | #define ILI9341_DTCB 0xEA 60 | #define ILI9341_POWER_SEQ 0xED 61 | #define ILI9341_3GAMMA_EN 0xF2 62 | #define ILI9341_INTERFACE 0xF6 63 | #define ILI9341_PRC 0xF7 64 | #define ILI9341_VERTICAL_SCROLL 0x33 65 | 66 | #define ILI9341_MEMCONTROL 0x36 67 | #define ILI9341_MADCTL_MY 0x80 68 | #define ILI9341_MADCTL_MX 0x40 69 | #define ILI9341_MADCTL_MV 0x20 70 | #define ILI9341_MADCTL_ML 0x10 71 | #define ILI9341_MADCTL_RGB 0x00 72 | #define ILI9341_MADCTL_BGR 0x08 73 | #define ILI9341_MADCTL_MH 0x04 74 | 75 | //List of colors 76 | #define COLOR_BLACK 0x0000 77 | #define COLOR_NAVY 0x000F 78 | #define COLOR_DGREEN 0x03E0 79 | #define COLOR_DCYAN 0x03EF 80 | #define COLOR_MAROON 0x7800 81 | #define COLOR_PURPLE 0x780F 82 | #define COLOR_OLIVE 0x7BE0 83 | #define COLOR_LGRAY 0xC618 84 | #define COLOR_DGRAY 0x7BEF 85 | #define COLOR_BLUE 0x001F 86 | #define COLOR_BLUE2 0x051D 87 | #define COLOR_GREEN 0x07E0 88 | #define COLOR_GREEN2 0xB723 89 | #define COLOR_GREEN3 0x8000 90 | #define COLOR_CYAN 0x07FF 91 | #define COLOR_RED 0xF800 92 | #define COLOR_MAGENTA 0xF81F 93 | #define COLOR_YELLOW 0xFFE0 94 | #define COLOR_WHITE 0xFFFF 95 | #define COLOR_ORANGE 0xFD20 96 | #define COLOR_GREENYELLOW 0xAFE5 97 | #define COLOR_BROWN 0XBC40 98 | #define COLOR_BRRED 0XFC07 99 | 100 | //Functions defines Macros 101 | #define swap(a, b) { int16_t t = a; a = b; b = t; } 102 | #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) 103 | #define min(a,b) (((a)<(b))?(a):(b)) 104 | 105 | //***** Functions prototypes *****// 106 | //1. Write Command to LCD 107 | void ILI9341_SendCommand(uint8_t com); 108 | //2. Write data to LCD 109 | void ILI9341_SendData(uint8_t data); 110 | //2.2 Write multiple/DMA 111 | void ILI9341_SendData_Multi(uint16_t Colordata, uint32_t size); 112 | 113 | 114 | //3. Set cursor position 115 | void ILI9341_SetCursorPosition(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); 116 | //4. Initialise function 117 | void ILI9341_Init(SPI_HandleTypeDef *spiLcdHandle, GPIO_TypeDef *csPORT, uint16_t csPIN, GPIO_TypeDef *dcPORT, uint16_t dcPIN, GPIO_TypeDef *resetPORT, uint16_t resetPIN); 118 | //5. Write data to a single pixel 119 | void ILI9341_DrawPixel(uint16_t x, uint16_t y, uint16_t color); //Draw single pixel to ILI9341 120 | //6. Fill the entire screen with a background color 121 | void ILI9341_Fill(uint16_t color); //Fill entire ILI9341 with color 122 | //7. Rectangle drawing functions 123 | void ILI9341_Fill_Rect(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, uint16_t color); 124 | //8. Circle drawing functions 125 | void ILI9341_drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color); 126 | static void drawCircleHelper( int16_t x0, int16_t y0, int16_t r, uint8_t cornername, uint16_t color); 127 | static void fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta, uint16_t color); 128 | void ILI9341_fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color); 129 | //9. Line drawing functions 130 | void ILI9341_drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color); 131 | void ILI9341_drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); 132 | void ILI9341_drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); 133 | //10. Triangle drawing 134 | void ILI9341_drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color); 135 | void ILI9341_fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color); 136 | //11. Text printing functions 137 | void ILI9341_drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size); 138 | void ILI9341_printText(char text[], int16_t x, int16_t y, uint16_t color, uint16_t bg, uint8_t size); 139 | //12. Image print (RGB 565, 2 bytes per pixel) 140 | void ILI9341_printImage(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint8_t *data, uint32_t size); 141 | //13. Set screen rotation 142 | void ILI9341_setRotation(uint8_t rotate); 143 | //14. Get screen rotation 144 | uint8_t ILI9341_getRotation(void); 145 | -------------------------------------------------------------------------------- /Tutorial 26 - SPI LCD + Resistive touch/TSC2046.c: -------------------------------------------------------------------------------- 1 | /* 2 | Library: Resistive touch screen controller SPI - TSC2046 3 | Written by: Mohamed Yaqoob (MYaqoobEmbedded YouTube Channel) 4 | Date Written: 09/12/2018 5 | Last modified: -/- 6 | Description: This is an STM32 device driver library for the TSC2046 resistive touch controller, using STM HAL libraries 7 | 8 | * Copyright (C) 2018 - M. Yaqoob 9 | This is a free software under the GNU license, you can redistribute it and/or modify it under the terms 10 | of the GNU General Public Licenseversion 3 as published by the Free Software Foundation. 11 | 12 | This software library is shared with puplic for educational purposes, without WARRANTY and Author is not liable for any damages caused directly 13 | or indirectly by this software, read more about this on the GNU General Public License. 14 | */ 15 | 16 | //Header files 17 | #include "TSC2046.h" 18 | 19 | //Library Private variables 20 | //1. SPI handle 21 | static SPI_HandleTypeDef tsSPIhandle; 22 | //2. Chip Select pin 23 | static GPIO_TypeDef *tsCS_GPIO; 24 | static uint16_t tsCS_PIN; 25 | //3. Touch controller command settings 26 | static uint8_t CMD_Default = 0x84; 27 | //4. Touch data 28 | static TS_TOUCH_RAW_Def myLocalTs_Def; 29 | //5. Screen Orientation 30 | static uint8_t ScreenOrientation = 0; 31 | //6. calibration variable declaration 32 | static TS_CALIBRATE_Def myTS_Calibrate; 33 | //7. recent raw touch data 34 | static TS_TOUCH_RAW_Def localRawTouch; 35 | 36 | //List of defines and typedefs 37 | #define _TS_CS_ENBALE HAL_GPIO_WritePin(tsCS_GPIO, tsCS_PIN, GPIO_PIN_RESET); 38 | #define _TS_CS_DISABLE HAL_GPIO_WritePin(tsCS_GPIO, tsCS_PIN, GPIO_PIN_SET); 39 | 40 | //Functions definitions 41 | //1. Send TSC2046 Command and wait for a response 42 | uint16_t TSC2046_SendCommand(uint8_t cmd) 43 | { 44 | uint8_t spiBuf[3] = {0,0,0}; 45 | uint16_t return16=0; 46 | 47 | _TS_CS_ENBALE; 48 | spiBuf[0] = cmd; 49 | HAL_SPI_Transmit(&tsSPIhandle, spiBuf, 1, 10); 50 | //Wait for response (3 ms) 51 | HAL_Delay(3); 52 | if(HAL_SPI_Receive(&tsSPIhandle, &spiBuf[1], 2, 10) == HAL_OK) return16 = (spiBuf[1]<<4) + (spiBuf[2]>>4); 53 | else return16 = 0; 54 | 55 | 56 | return return16; 57 | } 58 | //2. Calibrate resistive touch panel 59 | void TSC2046_Calibrate(void) 60 | { 61 | uint16_t watchVar1=0; 62 | TS_TOUCH_RAW_Def myRawTouchDef; 63 | //Get Top-Left corner calibration coordinate 64 | TSC2046_TL_point(); 65 | myTS_Calibrate.TL_X = 0; 66 | myTS_Calibrate.TL_Y = 0; 67 | myTS_Calibrate.BR_X = 0; 68 | myTS_Calibrate.BR_Y = 0; 69 | 70 | while(1) 71 | { 72 | watchVar1 = TSC2046_getRaw_Z(); 73 | if(watchVar1>50) 74 | { 75 | for(uint8_t i=0; i<10; i++) 76 | { 77 | myRawTouchDef = TSC2046_GetRawTouch(); 78 | myTS_Calibrate.TL_X += myRawTouchDef.x_touch; 79 | myTS_Calibrate.TL_Y += myRawTouchDef.y_touch; 80 | } 81 | 82 | break; 83 | } 84 | HAL_Delay(10); 85 | } 86 | HAL_Delay(1000); 87 | //Get Bottom-Right corner calibration coordinate 88 | TSC2046_BR_point(); 89 | while(1) 90 | { 91 | watchVar1 = TSC2046_getRaw_Z(); 92 | if(watchVar1>50) 93 | { 94 | for(uint8_t i=0; i<10; i++) 95 | { 96 | myRawTouchDef = TSC2046_GetRawTouch(); 97 | myTS_Calibrate.BR_X += myRawTouchDef.x_touch; 98 | myTS_Calibrate.BR_Y += myRawTouchDef.y_touch; 99 | } 100 | break; 101 | } 102 | HAL_Delay(10); 103 | } 104 | 105 | myTS_Calibrate.TL_X *=0.1; 106 | myTS_Calibrate.TL_Y *=0.1; 107 | 108 | myTS_Calibrate.BR_X *=0.1; 109 | myTS_Calibrate.BR_Y *=0.1; 110 | 111 | //1. Calculate X_Diff, Y_Diff 112 | myTS_Calibrate.Scale_X = (myTS_Calibrate.Width + 0.0f)/(myTS_Calibrate.BR_X - myTS_Calibrate.TL_X + 0.0f); 113 | myTS_Calibrate.Scale_Y = (myTS_Calibrate.Height + 0.0f)/(myTS_Calibrate.BR_Y - myTS_Calibrate.TL_Y + 0.0f); 114 | //2. Calculate Scalling () 115 | myTS_Calibrate.Bias_X = 10 - myTS_Calibrate.Scale_X*myTS_Calibrate.TL_X; 116 | myTS_Calibrate.Bias_Y = 10 - myTS_Calibrate.Scale_Y*myTS_Calibrate.TL_Y; 117 | 118 | } 119 | //3. Poll for touch status 120 | TS_TOUCH_RAW_Def TSC2046_GetRawTouch(void) 121 | { 122 | 123 | //Assign raw touch based on orientation 124 | switch (ScreenOrientation) 125 | { 126 | case 1: 127 | localRawTouch.x_touch = 4095 - TSC2046_getRaw_X(); 128 | localRawTouch.y_touch = TSC2046_getRaw_Y(); 129 | myTS_Calibrate.Width = 230; 130 | myTS_Calibrate.Height = 320; 131 | break; 132 | 133 | case 2: 134 | localRawTouch.x_touch = 4095 - TSC2046_getRaw_Y(); 135 | localRawTouch.y_touch = 4095 - TSC2046_getRaw_X(); 136 | myTS_Calibrate.Width = 320; 137 | myTS_Calibrate.Height = 240; 138 | break; 139 | 140 | case 3: 141 | localRawTouch.x_touch = TSC2046_getRaw_X(); 142 | localRawTouch.y_touch = 4095 - TSC2046_getRaw_Y(); 143 | myTS_Calibrate.Width = 230; 144 | myTS_Calibrate.Height = 320; 145 | break; 146 | 147 | case 4: 148 | localRawTouch.x_touch = TSC2046_getRaw_Y(); 149 | localRawTouch.y_touch = TSC2046_getRaw_X(); 150 | myTS_Calibrate.Width = 320; 151 | myTS_Calibrate.Height = 240; 152 | break; 153 | } 154 | 155 | return localRawTouch; 156 | } 157 | 158 | //4. Begin function 159 | bool TSC2046_Begin(SPI_HandleTypeDef *touchSPI, GPIO_TypeDef *csPort, uint16_t csPin) 160 | { 161 | //Touch Screen SPI 162 | memcpy(&tsSPIhandle, touchSPI, sizeof(*touchSPI)); 163 | //Chip-Select Port and Pin 164 | tsCS_GPIO = csPort; 165 | tsCS_PIN = csPin; 166 | //Get screen orientation 167 | ScreenOrientation = TSC2046_getOrientation(); 168 | } 169 | 170 | //5. Get raw touch data 171 | //i. get x-axis raw touch 12-bit value 172 | uint16_t TSC2046_getRaw_X(void) 173 | { 174 | return TSC2046_SendCommand(CMD_X_AXIS | CMD_Default); 175 | } 176 | //ii. get y-axis raw touch 12-bit value 177 | uint16_t TSC2046_getRaw_Y(void) 178 | { 179 | return TSC2046_SendCommand(CMD_Y_AXIS | CMD_Default); 180 | } 181 | //iii. get z-axis raw touch 12-bit value 182 | uint16_t TSC2046_getRaw_Z(void) 183 | { 184 | return TSC2046_SendCommand(CMD_Z_AXIS | CMD_Default); 185 | } 186 | 187 | //6. Print calibration points 188 | //i. Top-Left corner point 189 | void TSC2046_TL_point(void) 190 | { 191 | ILI9341_fillCircle(10, 10, 3, COLOR_RED); 192 | ILI9341_printText("Press here", 20, 30, COLOR_RED, COLOR_RED, 1); 193 | } 194 | //ii. Bottom-Right corner point 195 | void TSC2046_BR_point(void) 196 | { 197 | ILI9341_fillCircle(myTS_Calibrate.Width-10, myTS_Calibrate.Height-10, 3, COLOR_RED); 198 | ILI9341_printText("Press here", myTS_Calibrate.Width-80, myTS_Calibrate.Height-40, COLOR_RED, COLOR_RED, 1); 199 | } 200 | 201 | //7. Get orientation (from LCD driver) 202 | uint8_t TSC2046_getOrientation(void) 203 | { 204 | return ILI9341_getRotation(); 205 | } 206 | 207 | //8. Get touch sccreen data 208 | TS_TOUCH_DATA_Def TSC2046_GetTouchData(void) 209 | { 210 | TS_TOUCH_DATA_Def myTsData; 211 | uint16_t temp16x=0, temp16y=0; 212 | //Is screen pressed 213 | if(TSC2046_getRaw_Z()>50) 214 | { 215 | myTsData.isPressed = true; 216 | //Read touch data 217 | for(uint8_t i=0; i<1; i++) 218 | { 219 | localRawTouch = TSC2046_GetRawTouch(); 220 | temp16x += localRawTouch.x_touch; 221 | temp16y += localRawTouch.y_touch; 222 | } 223 | localRawTouch.x_touch = temp16x*1; 224 | localRawTouch.y_touch = temp16y*1; 225 | } 226 | else myTsData.isPressed = false; 227 | 228 | 229 | //X_Touch value 230 | myTsData.X = myTS_Calibrate.Scale_X*localRawTouch.x_touch + myTS_Calibrate.Bias_X; 231 | //Y_Touch value 232 | myTsData.Y = myTS_Calibrate.Scale_Y*localRawTouch.y_touch + myTS_Calibrate.Bias_Y; 233 | 234 | return myTsData; 235 | } 236 | 237 | -------------------------------------------------------------------------------- /Tutorial 26 - SPI LCD + Resistive touch/TSC2046.h: -------------------------------------------------------------------------------- 1 | /* 2 | Library: Resistive touch screen controller SPI - TSC2046 3 | Written by: Mohamed Yaqoob (MYaqoobEmbedded YouTube Channel) 4 | Date Written: 09/12/2018 5 | Last modified: -/- 6 | Description: This is an STM32 device driver library for the TSC2046 resistive touch controller, using STM HAL libraries 7 | 8 | * Copyright (C) 2018 - M. Yaqoob 9 | This is a free software under the GNU license, you can redistribute it and/or modify it under the terms 10 | of the GNU General Public Licenseversion 3 as published by the Free Software Foundation. 11 | 12 | This software library is shared with puplic for educational purposes, without WARRANTY and Author is not liable for any damages caused directly 13 | or indirectly by this software, read more about this on the GNU General Public License. 14 | */ 15 | 16 | //Header files 17 | //** CHANGE BASED ON STM32 CHIP F4/F7/F1...**// 18 | #include "stm32f4xx_hal.h" 19 | 20 | #include "MY_ILI9341.h" 21 | #include 22 | #include 23 | #include 24 | 25 | //List of defines 26 | //1. X-Axis measurement 27 | #define CMD_X_AXIS 0x50 28 | #define CMD_Y_AXIS 0x10 29 | #define CMD_Z_AXIS 0x30 30 | 31 | 32 | //Typedefs 33 | //1. Touch coordinates 34 | typedef struct 35 | { 36 | uint16_t x_touch; 37 | uint16_t y_touch; 38 | }TS_TOUCH_RAW_Def; 39 | 40 | //2. Calibration typedef 41 | typedef struct 42 | { 43 | uint16_t TL_X; 44 | uint16_t TL_Y; 45 | 46 | uint16_t BR_X; 47 | uint16_t BR_Y; 48 | 49 | float Scale_X; 50 | float Scale_Y; 51 | 52 | float Bias_X; 53 | float Bias_Y; 54 | 55 | uint16_t Width; 56 | uint16_t Height; 57 | }TS_CALIBRATE_Def; 58 | 59 | //3. Touch Screen Data 60 | typedef struct 61 | { 62 | bool isPressed; 63 | uint16_t X; 64 | uint16_t Y; 65 | }TS_TOUCH_DATA_Def; 66 | 67 | //Functions prototypes 68 | //1. Send TSC2046 Command and wait for a response 69 | uint16_t TSC2046_SendCommand(uint8_t cmd); 70 | //2. Calibrate resistive touch panel 71 | void TSC2046_Calibrate(void); 72 | //3. Poll for touch status 73 | TS_TOUCH_RAW_Def TSC2046_GetRawTouch(void); 74 | 75 | //4. Begin function 76 | bool TSC2046_Begin(SPI_HandleTypeDef *touchSPI, GPIO_TypeDef *csPort, uint16_t csPin); 77 | 78 | //5. Get raw touch data 79 | //i. get x-axis raw touch 12-bit value 80 | uint16_t TSC2046_getRaw_X(void); 81 | //ii. get y-axis raw touch 12-bit value 82 | uint16_t TSC2046_getRaw_Y(void); 83 | //iii. get z-axis raw touch 12-bit value 84 | uint16_t TSC2046_getRaw_Z(void); 85 | 86 | //6. Print calibration points (to LCD driver) 87 | //i. Top-Left corner point 88 | void TSC2046_TL_point(void); 89 | //ii. Bottom-Right corner point 90 | void TSC2046_BR_point(void); 91 | 92 | //7. Get orientation (from LCD driver) 93 | uint8_t TSC2046_getOrientation(void); 94 | 95 | //8. Get touch sccreen data 96 | TS_TOUCH_DATA_Def TSC2046_GetTouchData(void); 97 | 98 | -------------------------------------------------------------------------------- /Tutorial 27 - Motion 3-Axis Accelerometer LIS3DSH/MY_LIS3DSH.c: -------------------------------------------------------------------------------- 1 | /* 2 | Library: Accelerometer - LIS3DSH 3 | Written by: Mohamed Yaqoob (MYaqoobEmbedded YouTube Channel) 4 | Date Written: 12/12/2018 5 | Last modified: -/- 6 | Description: This is an STM32 device driver library for the LIS3DSH Accelerometer, using STM HAL libraries 7 | 8 | References: 9 | 1) STMicroelectronics LIS3DSH datasheet 10 | https://www.st.com/resource/en/datasheet/lis3dsh.pdf 11 | 2) ST opensource LIS3DSH accelerometer dsp drivers. 12 | 13 | * Copyright (C) 2018 - M. Yaqoob 14 | This is a free software under the GNU license, you can redistribute it and/or modify it under the terms 15 | of the GNU General Public Licenseversion 3 as published by the Free Software Foundation. 16 | 17 | This software library is shared with puplic for educational purposes, without WARRANTY and Author is not liable for any damages caused directly 18 | or indirectly by this software, read more about this on the GNU General Public License. 19 | */ 20 | 21 | //Header files 22 | #include "MY_LIS3DSH.h" 23 | 24 | //SPI Chip Select 25 | #define _LIS3DHS_CS_ENBALE HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET); 26 | #define _LIS3DHS_CS_DISABLE HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET); 27 | 28 | //Library variables 29 | //1. SPI handle 30 | static SPI_HandleTypeDef accSPI_Handle; 31 | 32 | //2. Sensitivity value 33 | static float lis3dsh_Sensitivity = LIS3DSH_SENSITIVITY_0_06G; 34 | //3. bias variables 35 | static float __X_Bias = 0.0f; 36 | static float __Y_Bias = 0.0f; 37 | static float __Z_Bias = 0.0f; 38 | //4. scaling variables 39 | static float __X_Scale = 1.0f; 40 | static float __Y_Scale = 1.0f; 41 | static float __Z_Scale = 1.0f; 42 | 43 | //Functions definitions 44 | //Private functions 45 | //1. Write IO 46 | void LIS3DSH_WriteIO(uint8_t reg, uint8_t *dataW, uint8_t size) 47 | { 48 | uint8_t spiReg = reg; 49 | //Enable CS 50 | _LIS3DHS_CS_ENBALE; 51 | //set register value 52 | HAL_SPI_Transmit(&accSPI_Handle, &spiReg, 1, 10); 53 | //Transmit data 54 | HAL_SPI_Transmit(&accSPI_Handle, dataW, size, 10); 55 | //Disable CS 56 | _LIS3DHS_CS_DISABLE; 57 | } 58 | //2. Read IO 59 | void LIS3DSH_ReadIO(uint8_t reg, uint8_t *dataR, uint8_t size) 60 | { 61 | uint8_t spiBuf[4]; 62 | spiBuf[0] = reg | 0x80; 63 | //Enable CS 64 | _LIS3DHS_CS_ENBALE; 65 | //set register value 66 | HAL_SPI_Transmit(&accSPI_Handle, spiBuf, 1, 10); 67 | //Transmit data 68 | HAL_SPI_Receive(&accSPI_Handle, spiBuf, size, 10); 69 | //Disable CS 70 | _LIS3DHS_CS_DISABLE; 71 | 72 | for(uint8_t i=0; i<(size&0x3); i++) 73 | { 74 | dataR[i] = spiBuf[i]; 75 | } 76 | } 77 | 78 | 79 | //1. Accelerometer initialise function 80 | void LIS3DSH_Init(SPI_HandleTypeDef *accSPI, LIS3DSH_InitTypeDef *accInitDef) 81 | { 82 | uint8_t spiData = 0; 83 | 84 | memcpy(&accSPI_Handle, accSPI, sizeof(*accSPI)); 85 | //** 1. Enable Axes and Output Data Rate **// 86 | //Set CTRL REG4 settings value 87 | spiData |= (accInitDef->enableAxes & 0x07); //Enable Axes 88 | spiData |= (accInitDef->dataRate & 0xF0); //Output Data Rate 89 | //Write to accelerometer 90 | LIS3DSH_WriteIO(LIS3DSH_CTRL_REG4_ADDR, &spiData, 1); 91 | 92 | //** 2. Full-Scale selection, Anti-aliasing BW, self test and 4-wire SPI **// 93 | spiData = 0; 94 | spiData |= (accInitDef->antiAliasingBW & 0xC0); //Anti-aliasing BW 95 | spiData |= (accInitDef->fullScale & 0x38); //Full-Scale 96 | //Write to accelerometer 97 | LIS3DSH_WriteIO(LIS3DSH_CTRL_REG5_ADDR, &spiData, 1); 98 | 99 | //** 3. Interrupt Configuration **// 100 | if(accInitDef->interruptEnable) 101 | { 102 | spiData = 0x88; 103 | //Write to accelerometer 104 | LIS3DSH_WriteIO(LIS3DSH_CTRL_REG3_ADDR, &spiData, 1); 105 | } 106 | 107 | //Assign sensor sensitivity (based on Full-Scale) 108 | switch(accInitDef->fullScale) 109 | { 110 | case LIS3DSH_FULLSCALE_2: 111 | lis3dsh_Sensitivity = LIS3DSH_SENSITIVITY_0_06G; 112 | break; 113 | 114 | case LIS3DSH_FULLSCALE_4: 115 | lis3dsh_Sensitivity = LIS3DSH_SENSITIVITY_0_12G; 116 | break; 117 | 118 | case LIS3DSH_FULLSCALE_6: 119 | lis3dsh_Sensitivity = LIS3DSH_SENSITIVITY_0_18G; 120 | break; 121 | 122 | case LIS3DSH_FULLSCALE_8: 123 | lis3dsh_Sensitivity = LIS3DSH_SENSITIVITY_0_24G; 124 | break; 125 | 126 | case LIS3DSH_FULLSCALE_16: 127 | lis3dsh_Sensitivity = LIS3DSH_SENSITIVITY_0_73G; 128 | break; 129 | } 130 | _LIS3DHS_CS_DISABLE; 131 | } 132 | //2. Get Accelerometer raw data 133 | LIS3DSH_DataRaw LIS3DSH_GetDataRaw(void) 134 | { 135 | uint8_t spiBuf[2]; 136 | LIS3DSH_DataRaw tempDataRaw; 137 | //Read X data 138 | LIS3DSH_ReadIO(LIS3DSH_OUT_X_L_ADDR, spiBuf, 2); 139 | tempDataRaw.x = ((spiBuf[1] << 8) + spiBuf[0]); 140 | 141 | //Read Y data 142 | LIS3DSH_ReadIO(LIS3DSH_OUT_Y_L_ADDR, spiBuf, 2); 143 | tempDataRaw.y = ((spiBuf[1] << 8) + spiBuf[0]); 144 | 145 | //Read Z data 146 | LIS3DSH_ReadIO(LIS3DSH_OUT_Z_L_ADDR, spiBuf, 2); 147 | tempDataRaw.z = ((spiBuf[1] << 8) + spiBuf[0]); 148 | 149 | return tempDataRaw; 150 | 151 | } 152 | //3. Get Accelerometer mg data 153 | LIS3DSH_DataScaled LIS3DSH_GetDataScaled(void) 154 | { 155 | //Read raw data 156 | LIS3DSH_DataRaw tempRawData = LIS3DSH_GetDataRaw();; 157 | //Scale data and return 158 | LIS3DSH_DataScaled tempScaledData; 159 | tempScaledData.x = (tempRawData.x * lis3dsh_Sensitivity * __X_Scale) + 0.0f - __X_Bias; 160 | tempScaledData.y = (tempRawData.y * lis3dsh_Sensitivity * __Y_Scale) + 0.0f - __Y_Bias; 161 | tempScaledData.z = (tempRawData.z * lis3dsh_Sensitivity * __Z_Scale) + 0.0f - __Z_Bias; 162 | 163 | return tempScaledData; 164 | } 165 | //4. Poll for Data Ready 166 | bool LIS3DSH_PollDRDY(uint32_t msTimeout) 167 | { 168 | uint8_t Acc_status; 169 | uint32_t startTick = HAL_GetTick(); 170 | do 171 | { 172 | //Read status register with a timeout 173 | LIS3DSH_ReadIO(0x27, &Acc_status, 1); 174 | if(Acc_status & 0x07)break; 175 | 176 | }while((Acc_status & 0x07)==0 && (HAL_GetTick() - startTick) < msTimeout); 177 | if(Acc_status & 0x07) 178 | { 179 | return true; 180 | } 181 | return false; 182 | 183 | } 184 | 185 | //** Calibration functions **// 186 | //1. Set X-Axis calibrate 187 | void LIS3DSH_X_calibrate(float x_min, float x_max) 188 | { 189 | __X_Bias = (x_max+x_min)/2.0f; 190 | __X_Scale = (2*1000)/(x_max - x_min); 191 | } 192 | //2. Set Y-Axis calibrate 193 | void LIS3DSH_Y_calibrate(float y_min, float y_max) 194 | { 195 | __Y_Bias = (y_max+y_min)/2.0f; 196 | __Y_Scale = (2*1000)/(y_max - y_min); 197 | } 198 | //3. Set Z-Axis calibrate 199 | void LIS3DSH_Z_calibrate(float z_min, float z_max) 200 | { 201 | __Z_Bias = (z_max+z_min)/2.0f; 202 | __Z_Scale = (2*1000)/(z_max - z_min); 203 | } 204 | 205 | -------------------------------------------------------------------------------- /Tutorial 27 - Motion 3-Axis Accelerometer LIS3DSH/MY_LIS3DSH.h: -------------------------------------------------------------------------------- 1 | /* 2 | Library: Accelerometer - LIS3DSH 3 | Written by: Mohamed Yaqoob (MYaqoobEmbedded YouTube Channel) 4 | Date Written: 12/12/2018 5 | Last modified: -/- 6 | Description: This is an STM32 device driver library for the LIS3DSH Accelerometer, using STM HAL libraries 7 | 8 | References: 9 | 1) STMicroelectronics LIS3DSH datasheet 10 | https://www.st.com/resource/en/datasheet/lis3dsh.pdf 11 | 2) ST opensource LIS3DSH accelerometer dsp drivers. 12 | 13 | * Copyright (C) 2018 - M. Yaqoob 14 | This is a free software under the GNU license, you can redistribute it and/or modify it under the terms 15 | of the GNU General Public Licenseversion 3 as published by the Free Software Foundation. 16 | 17 | This software library is shared with puplic for educational purposes, without WARRANTY and Author is not liable for any damages caused directly 18 | or indirectly by this software, read more about this on the GNU General Public License. 19 | */ 20 | 21 | //Header files 22 | #include "stm32f4xx_hal.h" 23 | #include 24 | #include 25 | 26 | //List of Defines 27 | //1. LIS3DHS registers addresses 28 | #define LIS3DSH_WHO_AM_I_ADDR 0x0F 29 | #define LIS3DSH_OFF_X_ADDR 0x10 30 | #define LIS3DSH_OFF_Y_ADDR 0x11 31 | #define LIS3DSH_OFF_Z_ADDR 0x12 32 | 33 | #define LIS3DSH_CTRL_REG4_ADDR 0x20 34 | #define LIS3DSH_CTRL_REG1_ADDR 0x21 35 | #define LIS3DSH_CTRL_REG2_ADDR 0x22 36 | #define LIS3DSH_CTRL_REG3_ADDR 0x23 37 | #define LIS3DSH_CTRL_REG5_ADDR 0x24 38 | #define LIS3DSH_CTRL_REG6_ADDR 0x25 39 | 40 | #define LIS3DSH_STATUS_ADDR 0x27 41 | 42 | #define LIS3DSH_OUT_X_L_ADDR 0x28 43 | #define LIS3DSH_OUT_X_H_ADDR 0x29 44 | #define LIS3DSH_OUT_Y_L_ADDR 0x2A 45 | #define LIS3DSH_OUT_Y_H_ADDR 0x2B 46 | #define LIS3DSH_OUT_Z_L_ADDR 0x2C 47 | #define LIS3DSH_OUT_Z_H_ADDR 0x2D 48 | 49 | 50 | //2. Data rate 51 | #define LIS3DSH_DATARATE_POWERDOWN ((uint8_t)0x00) /* Power Down Mode*/ 52 | #define LIS3DSH_DATARATE_3_125 ((uint8_t)0x10) /* 3.125 Hz Normal Mode */ 53 | #define LIS3DSH_DATARATE_6_25 ((uint8_t)0x20) /* 6.25 Hz Normal Mode */ 54 | #define LIS3DSH_DATARATE_12_5 ((uint8_t)0x30) /* 12.5 Hz Normal Mode */ 55 | #define LIS3DSH_DATARATE_25 ((uint8_t)0x40) /* 25 Hz Normal Mode */ 56 | #define LIS3DSH_DATARATE_50 ((uint8_t)0x50) /* 50 Hz Normal Mode */ 57 | #define LIS3DSH_DATARATE_100 ((uint8_t)0x60) /* 100 Hz Normal Mode */ 58 | #define LIS3DSH_DATARATE_400 ((uint8_t)0x70) /* 400 Hz Normal Mode */ 59 | #define LIS3DSH_DATARATE_800 ((uint8_t)0x80) /* 800 Hz Normal Mode */ 60 | #define LIS3DSH_DATARATE_1600 ((uint8_t)0x90) /* 1600 Hz Normal Mode */ 61 | 62 | //3. Full scale 63 | #define LIS3DSH_FULLSCALE_2 ((uint8_t)0x00) /* 2 g */ 64 | #define LIS3DSH_FULLSCALE_4 ((uint8_t)0x08) /* 4 g */ 65 | #define LIS3DSH_FULLSCALE_6 ((uint8_t)0x10) /* 6 g */ 66 | #define LIS3DSH_FULLSCALE_8 ((uint8_t)0x18) /* 8 g */ 67 | #define LIS3DSH_FULLSCALE_16 ((uint8_t)0x20) /* 16 g */ 68 | 69 | //4. Anti-Aliasing Bandwidth 70 | #define LIS3DSH_FILTER_BW_800 ((uint8_t)0x00) /* 800 Hz */ 71 | #define LIS3DSH_FILTER_BW_400 ((uint8_t)0x80) /* 400 Hz */ 72 | #define LIS3DSH_FILTER_BW_200 ((uint8_t)0x40) /* 200 Hz */ 73 | #define LIS3DSH_FILTER_BW_50 ((uint8_t)0xC0) /* 50 Hz */ 74 | 75 | //5. Enabled axis 76 | #define LIS3DSH_X_ENABLE ((uint8_t)0x01) 77 | #define LIS3DSH_Y_ENABLE ((uint8_t)0x02) 78 | #define LIS3DSH_Z_ENABLE ((uint8_t)0x04) 79 | #define LIS3DSH_XYZ_ENABLE ((uint8_t)0x07) 80 | 81 | //6. Sensitivity values (Based on Full-Scale) 82 | #define LIS3DSH_SENSITIVITY_0_06G 0.06 /* 0.06 mg/digit*/ 83 | #define LIS3DSH_SENSITIVITY_0_12G 0.12 /* 0.12 mg/digit*/ 84 | #define LIS3DSH_SENSITIVITY_0_18G 0.18 /* 0.18 mg/digit*/ 85 | #define LIS3DSH_SENSITIVITY_0_24G 0.24 /* 0.24 mg/digit*/ 86 | #define LIS3DSH_SENSITIVITY_0_73G 0.73 /* 0.73 mg/digit*/ 87 | 88 | //Typedefs 89 | //1. Accelerometer Configuration struct 90 | typedef struct 91 | { 92 | uint8_t dataRate; 93 | uint8_t fullScale; 94 | uint8_t antiAliasingBW; 95 | uint8_t enableAxes; 96 | bool interruptEnable; 97 | }LIS3DSH_InitTypeDef; 98 | 99 | //2. Accelerometer raw data 100 | typedef struct 101 | { 102 | int16_t x; 103 | int16_t y; 104 | int16_t z; 105 | }LIS3DSH_DataRaw; 106 | 107 | //3. Accelerometer mg data (scaled data) 108 | typedef struct 109 | { 110 | float x; 111 | float y; 112 | float z; 113 | }LIS3DSH_DataScaled; 114 | 115 | //Functions prototypes 116 | //Private functions 117 | //1. Write IO 118 | void LIS3DSH_WriteIO(uint8_t reg, uint8_t *dataW, uint8_t size); 119 | //2. Read IO 120 | void LIS3DSH_ReadIO(uint8_t reg, uint8_t *dataR, uint8_t size); 121 | 122 | 123 | //1. Accelerometer initialise function 124 | void LIS3DSH_Init(SPI_HandleTypeDef *accSPI, LIS3DSH_InitTypeDef *accInitDef); 125 | //2. Get Accelerometer raw data 126 | LIS3DSH_DataRaw LIS3DSH_GetDataRaw(void); 127 | //3. Get Accelerometer mg data 128 | LIS3DSH_DataScaled LIS3DSH_GetDataScaled(void); 129 | //4. Poll for Data Ready 130 | bool LIS3DSH_PollDRDY(uint32_t msTimeout); 131 | 132 | //** Calibration functions **// 133 | //1. Set X-Axis calibrate 134 | void LIS3DSH_X_calibrate(float x_min, float x_max); 135 | //2. Set Y-Axis calibrate 136 | void LIS3DSH_Y_calibrate(float y_min, float y_max); 137 | //3. Set Z-Axis calibrate 138 | void LIS3DSH_Z_calibrate(float z_min, float z_max); 139 | 140 | -------------------------------------------------------------------------------- /Tutorial 28 - I2S Audio Codec - CS43L22/MY_CS43L22.c: -------------------------------------------------------------------------------- 1 | /* 2 | Library: STM32F4 Audio Codec - CS43L22 3 | Written by: Mohamed Yaqoob (MYaqoobEmbedded YouTube Channel) 4 | Date Written: 29/01/2016 5 | Last modified: 29/12/2018 6 | Description: This is an STM32 device driver library for the CS43L22 Audio Codec, using STM HAL libraries 7 | 8 | References: 9 | 1) Cirrus Logic CS43L22 datasheet 10 | https://www.mouser.com/ds/2/76/CS43L22_F2-1142121.pdf 11 | 2) ST opensource CS43L22 Audio Codec dsp drivers. 12 | 13 | * Copyright (C) 2018 - M. Yaqoob 14 | This is a free software under the GNU license, you can redistribute it and/or modify it under the terms 15 | of the GNU General Public Licenseversion 3 as published by the Free Software Foundation. 16 | 17 | This software library is shared with puplic for educational purposes, without WARRANTY and Author is not liable for any damages caused directly 18 | or indirectly by this software, read more about this on the GNU General Public License. 19 | */ 20 | 21 | #include "stm32f4xx_hal.h" 22 | #include "MY_CS43L22.h" 23 | 24 | static uint8_t iData[2]; 25 | static I2C_HandleTypeDef i2cx; 26 | extern I2S_HandleTypeDef hi2s3; 27 | 28 | //(1): Functions definitions 29 | //-------------- Static Functions ---------------// 30 | // Function(1): Write to register 31 | static void write_register(uint8_t reg, uint8_t *data) 32 | { 33 | iData[0] = reg; 34 | iData[1] = data[0]; 35 | HAL_I2C_Master_Transmit(&i2cx, DAC_I2C_ADDR, iData, 2, 100); 36 | //HAL_I2C_Master_Transmit(&i2cx, DAC_I2C_ADDR, data, size, 100); 37 | } 38 | // Function(2): Read from register 39 | static void read_register(uint8_t reg, uint8_t *data) 40 | { 41 | iData[0] = reg; 42 | HAL_I2C_Master_Transmit(&i2cx, DAC_I2C_ADDR, iData, 1, 100); 43 | HAL_I2C_Master_Receive(&i2cx, DAC_I2C_ADDR, data, 1, 100); 44 | } 45 | 46 | //-------------- Public Functions ----------------// 47 | // Function(1): Initialisation 48 | void CS43_Init(I2C_HandleTypeDef i2c_handle, CS43_MODE outputMode) 49 | { 50 | __HAL_UNLOCK(&hi2s3); // THIS IS EXTREMELY IMPORTANT FOR I2S3 TO WORK!! 51 | __HAL_I2S_ENABLE(&hi2s3); // THIS IS EXTREMELY IMPORTANT FOR I2S3 TO WORK!! 52 | HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_SET); 53 | //(1): Get the I2C handle 54 | i2cx = i2c_handle; 55 | //(2): Power down 56 | iData[1] = 0x01; 57 | write_register(POWER_CONTROL1,iData); 58 | //(3): Enable Right and Left headphones 59 | iData[1] = (2 << 6); // PDN_HPB[0:1] = 10 (HP-B always onCon) 60 | iData[1] |= (2 << 4); // PDN_HPA[0:1] = 10 (HP-A always on) 61 | iData[1] |= (3 << 2); // PDN_SPKB[0:1] = 11 (Speaker B always off) 62 | iData[1] |= (3 << 0); // PDN_SPKA[0:1] = 11 (Speaker A always off) 63 | write_register(POWER_CONTROL2,&iData[1]); 64 | //(4): Automatic clock detection 65 | iData[1] = (1 << 7); 66 | write_register(CLOCKING_CONTROL,&iData[1]); 67 | //(5): Interface control 1 68 | read_register(INTERFACE_CONTROL1, iData); 69 | iData[1] &= (1 << 5); // Clear all bits except bit 5 which is reserved 70 | iData[1] &= ~(1 << 7); // Slave 71 | iData[1] &= ~(1 << 6); // Clock polarity: Not inverted 72 | iData[1] &= ~(1 << 4); // No DSP mode 73 | iData[1] &= ~(1 << 2); // Left justified, up to 24 bit (default) 74 | iData[1] |= (1 << 2); 75 | 76 | iData[1] |= (3 << 0); // 16-bit audio word length for I2S interface 77 | write_register(INTERFACE_CONTROL1,&iData[1]); 78 | //(6): Passthrough A settings 79 | read_register(PASSTHROUGH_A, &iData[1]); 80 | iData[1] &= 0xF0; // Bits [4-7] are reserved 81 | iData[1] |= (1 << 0); // Use AIN1A as source for passthrough 82 | write_register(PASSTHROUGH_A,&iData[1]); 83 | //(7): Passthrough B settings 84 | read_register(PASSTHROUGH_B, &iData[1]); 85 | iData[1] &= 0xF0; // Bits [4-7] are reserved 86 | iData[1] |= (1 << 0); // Use AIN1B as source for passthrough 87 | write_register(PASSTHROUGH_B,&iData[1]); 88 | //(8): Miscellaneous register settings 89 | read_register(MISCELLANEOUS_CONTRLS, &iData[1]); 90 | if(outputMode == MODE_ANALOG) 91 | { 92 | iData[1] |= (1 << 7); // Enable passthrough for AIN-A 93 | iData[1] |= (1 << 6); // Enable passthrough for AIN-B 94 | iData[1] &= ~(1 << 5); // Unmute passthrough on AIN-A 95 | iData[1] &= ~(1 << 4); // Unmute passthrough on AIN-B 96 | iData[1] &= ~(1 << 3); // Changed settings take affect immediately 97 | } 98 | else if(outputMode == MODE_I2S) 99 | { 100 | iData[1] = 0x02; 101 | } 102 | write_register(MISCELLANEOUS_CONTRLS,&iData[1]); 103 | //(9): Unmute headphone and speaker 104 | read_register(PLAYBACK_CONTROL, &iData[1]); 105 | iData[1] = 0x00; 106 | write_register(PLAYBACK_CONTROL,&iData[1]); 107 | //(10): Set volume to default (0dB) 108 | iData[1] = 0x00; 109 | write_register(PASSTHROUGH_VOLUME_A,&iData[1]); 110 | write_register(PASSTHROUGH_VOLUME_B,&iData[1]); 111 | write_register(PCM_VOLUME_A,&iData[1]); 112 | write_register(PCM_VOLUME_B,&iData[1]); 113 | } 114 | 115 | // Function(2): Enable Right and Left headphones 116 | void CS43_Enable_RightLeft(uint8_t side) 117 | { 118 | switch (side) 119 | { 120 | case 0: 121 | iData[1] = (3 << 6); // PDN_HPB[0:1] = 10 (HP-B always onCon) 122 | iData[1] |= (3 << 4); // PDN_HPA[0:1] = 10 (HP-A always on) 123 | break; 124 | case 1: 125 | iData[1] = (2 << 6); // PDN_HPB[0:1] = 10 (HP-B always onCon) 126 | iData[1] |= (3 << 4); // PDN_HPA[0:1] = 10 (HP-A always on) 127 | break; 128 | case 2: 129 | iData[1] = (3 << 6); // PDN_HPB[0:1] = 10 (HP-B always onCon) 130 | iData[1] |= (2 << 4); // PDN_HPA[0:1] = 10 (HP-A always on) 131 | break; 132 | case 3: 133 | iData[1] = (2 << 6); // PDN_HPB[0:1] = 10 (HP-B always onCon) 134 | iData[1] |= (2 << 4); // PDN_HPA[0:1] = 10 (HP-A always on) 135 | break; 136 | default: 137 | break; 138 | } 139 | iData[1] |= (3 << 2); // PDN_SPKB[0:1] = 11 (Speaker B always off) 140 | iData[1] |= (3 << 0); // PDN_SPKA[0:1] = 11 (Speaker A always off) 141 | write_register(POWER_CONTROL2,&iData[1]); 142 | } 143 | 144 | // Function(3): Set Volume Level 145 | void CS43_SetVolume(uint8_t volume) 146 | { 147 | int8_t tempVol = volume - 50; 148 | tempVol = tempVol*(127/50); 149 | uint8_t myVolume = (uint8_t )tempVol; 150 | iData[1] = myVolume; 151 | write_register(PASSTHROUGH_VOLUME_A,&iData[1]); 152 | write_register(PASSTHROUGH_VOLUME_B,&iData[1]); 153 | 154 | iData[1] = VOLUME_CONVERT_D(volume); 155 | 156 | /* Set the Master volume */ 157 | write_register(CS43L22_REG_MASTER_A_VOL,&iData[1]); 158 | write_register(CS43L22_REG_MASTER_B_VOL,&iData[1]); 159 | } 160 | 161 | // Function(4): Start the Audio DAC 162 | void CS43_Start(void) 163 | { 164 | // Write 0x99 to register 0x00. 165 | iData[1] = 0x99; 166 | write_register(CONFIG_00,&iData[1]); 167 | // Write 0x80 to register 0x47. 168 | iData[1] = 0x80; 169 | write_register(CONFIG_47,&iData[1]); 170 | // Write '1'b to bit 7 in register 0x32. 171 | read_register(CONFIG_32, &iData[1]); 172 | iData[1] |= 0x80; 173 | write_register(CONFIG_32,&iData[1]); 174 | // Write '0'b to bit 7 in register 0x32. 175 | read_register(CONFIG_32, &iData[1]); 176 | iData[1] &= ~(0x80); 177 | write_register(CONFIG_32,&iData[1]); 178 | // Write 0x00 to register 0x00. 179 | iData[1] = 0x00; 180 | write_register(CONFIG_00,&iData[1]); 181 | //Set the "Power Ctl 1" register (0x02) to 0x9E 182 | iData[1] = 0x9E; 183 | write_register(POWER_CONTROL1,&iData[1]); 184 | } 185 | 186 | void CS43_Stop(void) 187 | { 188 | iData[1] = 0x01; 189 | write_register(POWER_CONTROL1,&iData[1]); 190 | } 191 | -------------------------------------------------------------------------------- /Tutorial 28 - I2S Audio Codec - CS43L22/MY_CS43L22.h: -------------------------------------------------------------------------------- 1 | /* 2 | Library: STM32F4 Audio Codec - CS43L22 3 | Written by: Mohamed Yaqoob (MYaqoobEmbedded YouTube Channel) 4 | Date Written: 29/01/2016 5 | Last modified: 29/12/2018 6 | Description: This is an STM32 device driver library for the CS43L22 Audio Codec, using STM HAL libraries 7 | 8 | References: 9 | 1) Cirrus Logic CS43L22 datasheet 10 | https://www.mouser.com/ds/2/76/CS43L22_F2-1142121.pdf 11 | 2) ST opensource CS43L22 Audio Codec dsp drivers. 12 | 13 | * Copyright (C) 2018 - M. Yaqoob 14 | This is a free software under the GNU license, you can redistribute it and/or modify it under the terms 15 | of the GNU General Public Licenseversion 3 as published by the Free Software Foundation. 16 | 17 | This software library is shared with puplic for educational purposes, without WARRANTY and Author is not liable for any damages caused directly 18 | or indirectly by this software, read more about this on the GNU General Public License. 19 | */ 20 | 21 | //(1): Header files 22 | #include "stm32f4xx_hal.h" 23 | 24 | //(2): List of all the defines 25 | #define POWER_CONTROL1 0x02 26 | #define POWER_CONTROL2 0x04 27 | #define CLOCKING_CONTROL 0x05 28 | #define INTERFACE_CONTROL1 0x06 29 | #define INTERFACE_CONTROL2 0x07 30 | #define PASSTHROUGH_A 0x08 31 | #define PASSTHROUGH_B 0x09 32 | #define MISCELLANEOUS_CONTRLS 0x0E 33 | #define PLAYBACK_CONTROL 0x0F 34 | #define PASSTHROUGH_VOLUME_A 0x14 35 | #define PASSTHROUGH_VOLUME_B 0x15 36 | #define PCM_VOLUME_A 0x1A 37 | #define PCM_VOLUME_B 0x1B 38 | #define CONFIG_00 0x00 39 | #define CONFIG_47 0x47 40 | #define CONFIG_32 0x32 41 | 42 | #define CS43L22_REG_MASTER_A_VOL 0x20 43 | #define CS43L22_REG_MASTER_B_VOL 0x21 44 | 45 | #define DAC_I2C_ADDR 0x94 46 | 47 | #define CS43_MUTE 0x00 48 | 49 | #define CS43_RIGHT 0x01 50 | #define CS43_LEFT 0x02 51 | #define CS43_RIGHT_LEFT 0x03 52 | 53 | #define VOLUME_CONVERT_A(Volume) (((Volume) > 100)? 255:((uint8_t)(((Volume) * 255) / 100))) 54 | #define VOLUME_CONVERT_D(Volume) (((Volume) > 100)? 24:((uint8_t)((((Volume) * 48) / 100) - 24))) 55 | 56 | //1. Mode Select Enum 57 | typedef enum 58 | { 59 | MODE_I2S = 0, 60 | MODE_ANALOG, 61 | }CS43_MODE; 62 | 63 | 64 | //(3): List of the functions prototypes 65 | //------------ Static functions ------------// 66 | static void write_register(uint8_t reg, uint8_t *data); 67 | static void read_register(uint8_t reg, uint8_t *data); 68 | //------------ Public functions ------------// 69 | void CS43_Init(I2C_HandleTypeDef i2c_handle, CS43_MODE outputMode); 70 | void CS43_Enable_RightLeft(uint8_t side); 71 | void CS43_SetVolume(uint8_t volume); 72 | void CS43_Start(void); 73 | void CS43_Stop(void); 74 | -------------------------------------------------------------------------------- /Tutorial 29 - STM32F7 LCD and Touch/GUI HAL library/stm32f7xx_hal_ltdc_ex.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f7xx_hal_ltdc_ex.c 4 | * @author MCD Application Team 5 | * @brief LTDC Extension HAL module driver. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© COPYRIGHT(c) 2017 STMicroelectronics

10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 1. Redistributions of source code must retain the above copyright notice, 14 | * this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 3. Neither the name of STMicroelectronics nor the names of its contributors 19 | * may be used to endorse or promote products derived from this software 20 | * without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | ****************************************************************************** 34 | */ 35 | 36 | /* Includes ------------------------------------------------------------------*/ 37 | #include "stm32f7xx_hal.h" 38 | 39 | /** @addtogroup STM32F7xx_HAL_Driver 40 | * @{ 41 | */ 42 | /** @defgroup LTDCEx LTDCEx 43 | * @brief LTDC HAL module driver 44 | * @{ 45 | */ 46 | 47 | #ifdef HAL_LTDC_MODULE_ENABLED 48 | 49 | /* Private typedef -----------------------------------------------------------*/ 50 | /* Private define ------------------------------------------------------------*/ 51 | /* Private macro -------------------------------------------------------------*/ 52 | /* Private variables ---------------------------------------------------------*/ 53 | /* Private function prototypes -----------------------------------------------*/ 54 | /* Exported functions --------------------------------------------------------*/ 55 | 56 | /** @defgroup LTDCEx_Exported_Functions LTDC Extended Exported Functions 57 | * @{ 58 | */ 59 | 60 | /** @defgroup LTDCEx_Exported_Functions_Group1 Initialization and Configuration functions 61 | * @brief Initialization and Configuration functions 62 | * 63 | @verbatim 64 | =============================================================================== 65 | ##### Initialization and Configuration functions ##### 66 | =============================================================================== 67 | [..] This section provides functions allowing to: 68 | (+) Initialize and configure the LTDC 69 | 70 | @endverbatim 71 | * @{ 72 | */ 73 | #if defined (STM32F769xx) || defined (STM32F779xx) 74 | /** 75 | * @brief Retrieve common parameters from DSI Video mode configuration structure 76 | * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains 77 | * the configuration information for the LTDC. 78 | * @param VidCfg pointer to a DSI_VidCfgTypeDef structure that contains 79 | * the DSI video mode configuration parameters 80 | * @note The implementation of this function is taking into account the LTDC 81 | * polarities inversion as described in the current LTDC specification 82 | * @retval HAL status 83 | */ 84 | HAL_StatusTypeDef HAL_LTDC_StructInitFromVideoConfig(LTDC_HandleTypeDef* hltdc, DSI_VidCfgTypeDef *VidCfg) 85 | { 86 | /* Retrieve signal polarities from DSI */ 87 | 88 | /* The following polarity is inverted: 89 | LTDC_DEPOLARITY_AL <-> LTDC_DEPOLARITY_AH */ 90 | 91 | /* Note 1 : Code in line w/ Current LTDC specification */ 92 | hltdc->Init.DEPolarity = (VidCfg->DEPolarity == DSI_DATA_ENABLE_ACTIVE_HIGH) ? LTDC_DEPOLARITY_AL : LTDC_DEPOLARITY_AH; 93 | hltdc->Init.VSPolarity = (VidCfg->VSPolarity == DSI_VSYNC_ACTIVE_HIGH) ? LTDC_VSPOLARITY_AH : LTDC_VSPOLARITY_AL; 94 | hltdc->Init.HSPolarity = (VidCfg->HSPolarity == DSI_HSYNC_ACTIVE_HIGH) ? LTDC_HSPOLARITY_AH : LTDC_HSPOLARITY_AL; 95 | 96 | /* Note 2: Code to be used in case LTDC polarities inversion updated in the specification */ 97 | /* hltdc->Init.DEPolarity = VidCfg->DEPolarity << 29; 98 | hltdc->Init.VSPolarity = VidCfg->VSPolarity << 29; 99 | hltdc->Init.HSPolarity = VidCfg->HSPolarity << 29; */ 100 | 101 | /* Retrieve vertical timing parameters from DSI */ 102 | hltdc->Init.VerticalSync = VidCfg->VerticalSyncActive - 1; 103 | hltdc->Init.AccumulatedVBP = VidCfg->VerticalSyncActive + VidCfg->VerticalBackPorch - 1; 104 | hltdc->Init.AccumulatedActiveH = VidCfg->VerticalSyncActive + VidCfg->VerticalBackPorch + VidCfg->VerticalActive - 1; 105 | hltdc->Init.TotalHeigh = VidCfg->VerticalSyncActive + VidCfg->VerticalBackPorch + VidCfg->VerticalActive + VidCfg->VerticalFrontPorch - 1; 106 | 107 | return HAL_OK; 108 | } 109 | 110 | /** 111 | * @brief Retrieve common parameters from DSI Adapted command mode configuration structure 112 | * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains 113 | * the configuration information for the LTDC. 114 | * @param CmdCfg pointer to a DSI_CmdCfgTypeDef structure that contains 115 | * the DSI command mode configuration parameters 116 | * @note The implementation of this function is taking into account the LTDC 117 | * polarities inversion as described in the current LTDC specification 118 | * @retval HAL status 119 | */ 120 | HAL_StatusTypeDef HAL_LTDC_StructInitFromAdaptedCommandConfig(LTDC_HandleTypeDef* hltdc, DSI_CmdCfgTypeDef *CmdCfg) 121 | { 122 | /* Retrieve signal polarities from DSI */ 123 | 124 | /* The following polarities are inverted: 125 | LTDC_DEPOLARITY_AL <-> LTDC_DEPOLARITY_AH 126 | LTDC_VSPOLARITY_AL <-> LTDC_VSPOLARITY_AH 127 | LTDC_HSPOLARITY_AL <-> LTDC_HSPOLARITY_AH)*/ 128 | 129 | /* Note 1 : Code in line w/ Current LTDC specification */ 130 | hltdc->Init.DEPolarity = (CmdCfg->DEPolarity == DSI_DATA_ENABLE_ACTIVE_HIGH) ? LTDC_DEPOLARITY_AL : LTDC_DEPOLARITY_AH; 131 | hltdc->Init.VSPolarity = (CmdCfg->VSPolarity == DSI_VSYNC_ACTIVE_HIGH) ? LTDC_VSPOLARITY_AL : LTDC_VSPOLARITY_AH; 132 | hltdc->Init.HSPolarity = (CmdCfg->HSPolarity == DSI_HSYNC_ACTIVE_HIGH) ? LTDC_HSPOLARITY_AL : LTDC_HSPOLARITY_AH; 133 | 134 | /* Note 2: Code to be used in case LTDC polarities inversion updated in the specification */ 135 | /* hltdc->Init.DEPolarity = CmdCfg->DEPolarity << 29; 136 | hltdc->Init.VSPolarity = CmdCfg->VSPolarity << 29; 137 | hltdc->Init.HSPolarity = CmdCfg->HSPolarity << 29; */ 138 | 139 | return HAL_OK; 140 | } 141 | #endif /*STM32F769xx | STM32F779xx */ 142 | 143 | /** 144 | * @} 145 | */ 146 | 147 | /** 148 | * @} 149 | */ 150 | 151 | #endif /* HAL_LTCD_MODULE_ENABLED */ 152 | /** 153 | * @} 154 | */ 155 | 156 | /** 157 | * @} 158 | */ 159 | 160 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 161 | -------------------------------------------------------------------------------- /Tutorial 29 - STM32F7 LCD and Touch/GUI HAL library/stm32f7xx_hal_ltdc_ex.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f7xx_hal_ltdc_ex.h 4 | * @author MCD Application Team 5 | * @brief Header file of LTDC HAL Extension module. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© COPYRIGHT(c) 2017 STMicroelectronics

10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 1. Redistributions of source code must retain the above copyright notice, 14 | * this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 3. Neither the name of STMicroelectronics nor the names of its contributors 19 | * may be used to endorse or promote products derived from this software 20 | * without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | ****************************************************************************** 34 | */ 35 | 36 | /* Define to prevent recursive inclusion -------------------------------------*/ 37 | #ifndef __STM32F7xx_HAL_LTDC_EX_H 38 | #define __STM32F7xx_HAL_LTDC_EX_H 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | #if defined (STM32F769xx) || defined (STM32F779xx) 45 | /* Includes ------------------------------------------------------------------*/ 46 | #include "stm32f7xx_hal_def.h" 47 | #include "stm32f7xx_hal_dsi.h" 48 | 49 | /** @addtogroup STM32F7xx_HAL_Driver 50 | * @{ 51 | */ 52 | 53 | /** @addtogroup LTDCEx 54 | * @{ 55 | */ 56 | 57 | /* Exported types ------------------------------------------------------------*/ 58 | /* Exported constants --------------------------------------------------------*/ 59 | 60 | /** @defgroup LTDCEx_Exported_Constants LTDCEx Exported Constants 61 | * @{ 62 | */ 63 | 64 | /** 65 | * @} 66 | */ 67 | 68 | /* Exported macro ------------------------------------------------------------*/ 69 | /** @defgroup LTDCEx_Exported_Macros LTDC Exported Macros 70 | * @{ 71 | */ 72 | 73 | /** 74 | * @} 75 | */ 76 | 77 | /* Exported functions --------------------------------------------------------*/ 78 | /** @defgroup LTDCEx_Exported_Functions LTDC Extended Exported Functions 79 | * @{ 80 | */ 81 | HAL_StatusTypeDef HAL_LTDC_StructInitFromVideoConfig(LTDC_HandleTypeDef* hltdc, DSI_VidCfgTypeDef *VidCfg); 82 | HAL_StatusTypeDef HAL_LTDC_StructInitFromAdaptedCommandConfig(LTDC_HandleTypeDef* hltdc, DSI_CmdCfgTypeDef *CmdCfg); 83 | /** 84 | * @} 85 | */ 86 | 87 | 88 | /* Private types -------------------------------------------------------------*/ 89 | /** @defgroup LTDCEx_Private_Types LTDCEx Private Types 90 | * @{ 91 | */ 92 | 93 | /** 94 | * @} 95 | */ 96 | 97 | /* Private variables ---------------------------------------------------------*/ 98 | /** @defgroup LTDCEx_Private_Variables LTDCEx Private Variables 99 | * @{ 100 | */ 101 | 102 | /** 103 | * @} 104 | */ 105 | 106 | /* Private constants ---------------------------------------------------------*/ 107 | /** @defgroup LTDCEx_Private_Constants LTDCEx Private Constants 108 | * @{ 109 | */ 110 | 111 | /** 112 | * @} 113 | */ 114 | 115 | /* Private macros ------------------------------------------------------------*/ 116 | /** @defgroup LTDCEx_Private_Macros LTDCEx Private Macros 117 | * @{ 118 | */ 119 | 120 | /** 121 | * @} 122 | */ 123 | 124 | /* Private functions ---------------------------------------------------------*/ 125 | /** @defgroup LTDCEx_Private_Functions LTDCEx Private Functions 126 | * @{ 127 | */ 128 | 129 | /** 130 | * @} 131 | */ 132 | 133 | /** 134 | * @} 135 | */ 136 | 137 | /** 138 | * @} 139 | */ 140 | 141 | #endif /*STM32F769xx | STM32F779xx */ 142 | 143 | #ifdef __cplusplus 144 | } 145 | #endif 146 | 147 | #endif /* __STM32F7xx_HAL_LTDC_EX_H */ 148 | 149 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 150 | -------------------------------------------------------------------------------- /Tutorial 29 - STM32F7 LCD and Touch/GUI HAL library/stm32f7xx_hal_sdram.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f7xx_hal_sdram.h 4 | * @author MCD Application Team 5 | * @brief Header file of SDRAM HAL module. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© COPYRIGHT(c) 2017 STMicroelectronics

10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 1. Redistributions of source code must retain the above copyright notice, 14 | * this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 3. Neither the name of STMicroelectronics nor the names of its contributors 19 | * may be used to endorse or promote products derived from this software 20 | * without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | ****************************************************************************** 34 | */ 35 | 36 | /* Define to prevent recursive inclusion -------------------------------------*/ 37 | #ifndef __STM32F7xx_HAL_SDRAM_H 38 | #define __STM32F7xx_HAL_SDRAM_H 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | /* Includes ------------------------------------------------------------------*/ 45 | #include "stm32f7xx_ll_fmc.h" 46 | #include "stm32f7xx_hal_dma.h" 47 | 48 | /** @addtogroup STM32F7xx_HAL_Driver 49 | * @{ 50 | */ 51 | 52 | /** @addtogroup SDRAM 53 | * @{ 54 | */ 55 | 56 | /* Exported typedef ----------------------------------------------------------*/ 57 | 58 | /** @defgroup SDRAM_Exported_Types SDRAM Exported Types 59 | * @{ 60 | */ 61 | 62 | /** 63 | * @brief HAL SDRAM State structure definition 64 | */ 65 | typedef enum 66 | { 67 | HAL_SDRAM_STATE_RESET = 0x00U, /*!< SDRAM not yet initialized or disabled */ 68 | HAL_SDRAM_STATE_READY = 0x01U, /*!< SDRAM initialized and ready for use */ 69 | HAL_SDRAM_STATE_BUSY = 0x02U, /*!< SDRAM internal process is ongoing */ 70 | HAL_SDRAM_STATE_ERROR = 0x03U, /*!< SDRAM error state */ 71 | HAL_SDRAM_STATE_WRITE_PROTECTED = 0x04U, /*!< SDRAM device write protected */ 72 | HAL_SDRAM_STATE_PRECHARGED = 0x05U /*!< SDRAM device precharged */ 73 | 74 | }HAL_SDRAM_StateTypeDef; 75 | 76 | /** 77 | * @brief SDRAM handle Structure definition 78 | */ 79 | typedef struct 80 | { 81 | FMC_SDRAM_TypeDef *Instance; /*!< Register base address */ 82 | 83 | FMC_SDRAM_InitTypeDef Init; /*!< SDRAM device configuration parameters */ 84 | 85 | __IO HAL_SDRAM_StateTypeDef State; /*!< SDRAM access state */ 86 | 87 | HAL_LockTypeDef Lock; /*!< SDRAM locking object */ 88 | 89 | DMA_HandleTypeDef *hdma; /*!< Pointer DMA handler */ 90 | 91 | }SDRAM_HandleTypeDef; 92 | /** 93 | * @} 94 | */ 95 | 96 | /* Exported constants --------------------------------------------------------*/ 97 | /* Exported macro ------------------------------------------------------------*/ 98 | 99 | /** @defgroup SDRAM_Exported_Macros SDRAM Exported Macros 100 | * @{ 101 | */ 102 | 103 | /** @brief Reset SDRAM handle state 104 | * @param __HANDLE__ specifies the SDRAM handle. 105 | * @retval None 106 | */ 107 | #define __HAL_SDRAM_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SDRAM_STATE_RESET) 108 | 109 | /** 110 | * @} 111 | */ 112 | 113 | /* Exported functions --------------------------------------------------------*/ 114 | 115 | /** @addtogroup SDRAM_Exported_Functions SDRAM Exported Functions 116 | * @{ 117 | */ 118 | 119 | /** @addtogroup SDRAM_Exported_Functions_Group1 120 | * @{ 121 | */ 122 | 123 | /* Initialization/de-initialization functions *********************************/ 124 | HAL_StatusTypeDef HAL_SDRAM_Init(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_TimingTypeDef *Timing); 125 | HAL_StatusTypeDef HAL_SDRAM_DeInit(SDRAM_HandleTypeDef *hsdram); 126 | void HAL_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram); 127 | void HAL_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram); 128 | 129 | void HAL_SDRAM_IRQHandler(SDRAM_HandleTypeDef *hsdram); 130 | void HAL_SDRAM_RefreshErrorCallback(SDRAM_HandleTypeDef *hsdram); 131 | void HAL_SDRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma); 132 | void HAL_SDRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma); 133 | 134 | /** 135 | * @} 136 | */ 137 | 138 | /** @addtogroup SDRAM_Exported_Functions_Group2 139 | * @{ 140 | */ 141 | /* I/O operation functions ****************************************************/ 142 | HAL_StatusTypeDef HAL_SDRAM_Read_8b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint8_t *pDstBuffer, uint32_t BufferSize); 143 | HAL_StatusTypeDef HAL_SDRAM_Write_8b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint8_t *pSrcBuffer, uint32_t BufferSize); 144 | HAL_StatusTypeDef HAL_SDRAM_Read_16b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint16_t *pDstBuffer, uint32_t BufferSize); 145 | HAL_StatusTypeDef HAL_SDRAM_Write_16b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint16_t *pSrcBuffer, uint32_t BufferSize); 146 | HAL_StatusTypeDef HAL_SDRAM_Read_32b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize); 147 | HAL_StatusTypeDef HAL_SDRAM_Write_32b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize); 148 | 149 | HAL_StatusTypeDef HAL_SDRAM_Read_DMA(SDRAM_HandleTypeDef *hsdram, uint32_t * pAddress, uint32_t *pDstBuffer, uint32_t BufferSize); 150 | HAL_StatusTypeDef HAL_SDRAM_Write_DMA(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize); 151 | 152 | /** 153 | * @} 154 | */ 155 | 156 | /** @addtogroup SDRAM_Exported_Functions_Group3 157 | * @{ 158 | */ 159 | /* SDRAM Control functions *****************************************************/ 160 | HAL_StatusTypeDef HAL_SDRAM_WriteProtection_Enable(SDRAM_HandleTypeDef *hsdram); 161 | HAL_StatusTypeDef HAL_SDRAM_WriteProtection_Disable(SDRAM_HandleTypeDef *hsdram); 162 | HAL_StatusTypeDef HAL_SDRAM_SendCommand(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command, uint32_t Timeout); 163 | HAL_StatusTypeDef HAL_SDRAM_ProgramRefreshRate(SDRAM_HandleTypeDef *hsdram, uint32_t RefreshRate); 164 | HAL_StatusTypeDef HAL_SDRAM_SetAutoRefreshNumber(SDRAM_HandleTypeDef *hsdram, uint32_t AutoRefreshNumber); 165 | uint32_t HAL_SDRAM_GetModeStatus(SDRAM_HandleTypeDef *hsdram); 166 | 167 | /** 168 | * @} 169 | */ 170 | 171 | /** @addtogroup SDRAM_Exported_Functions_Group4 172 | * @{ 173 | */ 174 | /* SDRAM State functions ********************************************************/ 175 | HAL_SDRAM_StateTypeDef HAL_SDRAM_GetState(SDRAM_HandleTypeDef *hsdram); 176 | /** 177 | * @} 178 | */ 179 | 180 | /** 181 | * @} 182 | */ 183 | 184 | /** 185 | * @} 186 | */ 187 | 188 | /** 189 | * @} 190 | */ 191 | 192 | #ifdef __cplusplus 193 | } 194 | #endif 195 | 196 | #endif /* __STM32F7xx_HAL_SDRAM_H */ 197 | 198 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 199 | -------------------------------------------------------------------------------- /Tutorial 29 - STM32F7 LCD and Touch/GUI files/fonts.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file fonts.h 4 | * @author MCD Application Team 5 | * @version V1.0.0 6 | * @date 18-February-2014 7 | * @brief Header for fonts.c file 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT(c) 2014 STMicroelectronics

12 | * 13 | * Redistribution and use in source and binary forms, with or without modification, 14 | * are permitted provided that the following conditions are met: 15 | * 1. Redistributions of source code must retain the above copyright notice, 16 | * this list of conditions and the following disclaimer. 17 | * 2. Redistributions in binary form must reproduce the above copyright notice, 18 | * this list of conditions and the following disclaimer in the documentation 19 | * and/or other materials provided with the distribution. 20 | * 3. Neither the name of STMicroelectronics nor the names of its contributors 21 | * may be used to endorse or promote products derived from this software 22 | * without specific prior written permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 32 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | * 35 | ****************************************************************************** 36 | */ 37 | 38 | /* Define to prevent recursive inclusion -------------------------------------*/ 39 | #ifndef __FONTS_H 40 | #define __FONTS_H 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | /* Includes ------------------------------------------------------------------*/ 47 | #include 48 | 49 | /** @addtogroup Utilities 50 | * @{ 51 | */ 52 | 53 | /** @addtogroup STM32_EVAL 54 | * @{ 55 | */ 56 | 57 | /** @addtogroup Common 58 | * @{ 59 | */ 60 | 61 | /** @addtogroup FONTS 62 | * @{ 63 | */ 64 | 65 | /** @defgroup FONTS_Exported_Types 66 | * @{ 67 | */ 68 | typedef struct _tFont 69 | { 70 | const uint8_t *table; 71 | uint16_t Width; 72 | uint16_t Height; 73 | 74 | } sFONT; 75 | 76 | extern sFONT Font24; 77 | extern sFONT Font20; 78 | extern sFONT Font16; 79 | extern sFONT Font12; 80 | extern sFONT Font8; 81 | /** 82 | * @} 83 | */ 84 | 85 | /** @defgroup FONTS_Exported_Constants 86 | * @{ 87 | */ 88 | #define LINE(x) ((x) * (((sFONT *)BSP_LCD_GetFont())->Height)) 89 | 90 | /** 91 | * @} 92 | */ 93 | 94 | /** @defgroup FONTS_Exported_Macros 95 | * @{ 96 | */ 97 | /** 98 | * @} 99 | */ 100 | 101 | /** @defgroup FONTS_Exported_Functions 102 | * @{ 103 | */ 104 | /** 105 | * @} 106 | */ 107 | 108 | #ifdef __cplusplus 109 | } 110 | #endif 111 | 112 | #endif /* __FONTS_H */ 113 | 114 | /** 115 | * @} 116 | */ 117 | 118 | /** 119 | * @} 120 | */ 121 | 122 | /** 123 | * @} 124 | */ 125 | 126 | /** 127 | * @} 128 | */ 129 | 130 | /** 131 | * @} 132 | */ 133 | 134 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 135 | -------------------------------------------------------------------------------- /Tutorial 29 - STM32F7 LCD and Touch/GUI files/lcd.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file lcd.h 4 | * @author MCD Application Team 5 | * @version V4.0.1 6 | * @date 21-July-2015 7 | * @brief This file contains all the functions prototypes for the LCD driver. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT(c) 2015 STMicroelectronics

12 | * 13 | * Redistribution and use in source and binary forms, with or without modification, 14 | * are permitted provided that the following conditions are met: 15 | * 1. Redistributions of source code must retain the above copyright notice, 16 | * this list of conditions and the following disclaimer. 17 | * 2. Redistributions in binary form must reproduce the above copyright notice, 18 | * this list of conditions and the following disclaimer in the documentation 19 | * and/or other materials provided with the distribution. 20 | * 3. Neither the name of STMicroelectronics nor the names of its contributors 21 | * may be used to endorse or promote products derived from this software 22 | * without specific prior written permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 32 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | * 35 | ****************************************************************************** 36 | */ 37 | 38 | /* Define to prevent recursive inclusion -------------------------------------*/ 39 | #ifndef __LCD_H 40 | #define __LCD_H 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | /* Includes ------------------------------------------------------------------*/ 47 | #include 48 | 49 | /** @addtogroup BSP 50 | * @{ 51 | */ 52 | 53 | /** @addtogroup Components 54 | * @{ 55 | */ 56 | 57 | /** @addtogroup LCD 58 | * @{ 59 | */ 60 | 61 | /** @defgroup LCD_Exported_Types 62 | * @{ 63 | */ 64 | 65 | /** @defgroup LCD_Driver_structure LCD Driver structure 66 | * @{ 67 | */ 68 | typedef struct 69 | { 70 | void (*Init)(void); 71 | uint16_t (*ReadID)(void); 72 | void (*DisplayOn)(void); 73 | void (*DisplayOff)(void); 74 | void (*SetCursor)(uint16_t, uint16_t); 75 | void (*WritePixel)(uint16_t, uint16_t, uint16_t); 76 | uint16_t (*ReadPixel)(uint16_t, uint16_t); 77 | 78 | /* Optimized operation */ 79 | void (*SetDisplayWindow)(uint16_t, uint16_t, uint16_t, uint16_t); 80 | void (*DrawHLine)(uint16_t, uint16_t, uint16_t, uint16_t); 81 | void (*DrawVLine)(uint16_t, uint16_t, uint16_t, uint16_t); 82 | 83 | uint16_t (*GetLcdPixelWidth)(void); 84 | uint16_t (*GetLcdPixelHeight)(void); 85 | void (*DrawBitmap)(uint16_t, uint16_t, uint8_t*); 86 | void (*DrawRGBImage)(uint16_t, uint16_t, uint16_t, uint16_t, uint8_t*); 87 | }LCD_DrvTypeDef; 88 | /** 89 | * @} 90 | */ 91 | 92 | /** 93 | * @} 94 | */ 95 | 96 | /** 97 | * @} 98 | */ 99 | 100 | /** 101 | * @} 102 | */ 103 | 104 | /** 105 | * @} 106 | */ 107 | 108 | #ifdef __cplusplus 109 | } 110 | #endif 111 | 112 | #endif /* __LCD_H */ 113 | 114 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 115 | -------------------------------------------------------------------------------- /Tutorial 29 - STM32F7 LCD and Touch/GUI files/rk043fn48h.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file rk043fn48h.h 4 | * @author MCD Application Team 5 | * @brief This file contains all the constants parameters for the RK043FN48H-CT672B 6 | * LCD component. 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | *

© COPYRIGHT(c) 2015 STMicroelectronics

11 | * 12 | * Redistribution and use in source and binary forms, with or without modification, 13 | * are permitted provided that the following conditions are met: 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 3. Neither the name of STMicroelectronics nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software 21 | * without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | ****************************************************************************** 35 | */ 36 | 37 | /* Define to prevent recursive inclusion -------------------------------------*/ 38 | #ifndef __RK043FN48H_H 39 | #define __RK043FN48H_H 40 | 41 | #ifdef __cplusplus 42 | extern "C" { 43 | #endif 44 | 45 | /* Includes ------------------------------------------------------------------*/ 46 | 47 | /** @addtogroup BSP 48 | * @{ 49 | */ 50 | 51 | /** @addtogroup Components 52 | * @{ 53 | */ 54 | 55 | /** @addtogroup rk043fn48h 56 | * @{ 57 | */ 58 | 59 | /** @defgroup RK043FN48H_Exported_Types 60 | * @{ 61 | */ 62 | 63 | /** 64 | * @} 65 | */ 66 | 67 | /** @defgroup RK043FN48H_Exported_Constants 68 | * @{ 69 | */ 70 | 71 | /** 72 | * @brief RK043FN48H Size 73 | */ 74 | #define RK043FN48H_WIDTH ((uint16_t)480) /* LCD PIXEL WIDTH */ 75 | #define RK043FN48H_HEIGHT ((uint16_t)272) /* LCD PIXEL HEIGHT */ 76 | 77 | /** 78 | * @brief RK043FN48H Timing 79 | */ 80 | #define RK043FN48H_HSYNC ((uint16_t)41) /* Horizontal synchronization */ 81 | #define RK043FN48H_HBP ((uint16_t)13) /* Horizontal back porch */ 82 | #define RK043FN48H_HFP ((uint16_t)32) /* Horizontal front porch */ 83 | #define RK043FN48H_VSYNC ((uint16_t)10) /* Vertical synchronization */ 84 | #define RK043FN48H_VBP ((uint16_t)2) /* Vertical back porch */ 85 | #define RK043FN48H_VFP ((uint16_t)2) /* Vertical front porch */ 86 | 87 | /** 88 | * @brief RK043FN48H frequency divider 89 | */ 90 | #define RK043FN48H_FREQUENCY_DIVIDER 5 /* LCD Frequency divider */ 91 | /** 92 | * @} 93 | */ 94 | 95 | /** @defgroup RK043FN48H_Exported_Functions 96 | * @{ 97 | */ 98 | 99 | /** 100 | * @} 101 | */ 102 | #ifdef __cplusplus 103 | } 104 | #endif 105 | 106 | #endif /* __RK043FN48H_H */ 107 | /** 108 | * @} 109 | */ 110 | 111 | /** 112 | * @} 113 | */ 114 | 115 | /** 116 | * @} 117 | */ 118 | 119 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 120 | -------------------------------------------------------------------------------- /Tutorial 29 - STM32F7 LCD and Touch/GUI files/stm32746g_discovery_sdram.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32746g_discovery_sdram.h 4 | * @author MCD Application Team 5 | * @brief This file contains the common defines and functions prototypes for 6 | * the stm32746g_discovery_sdram.c driver. 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | *

© COPYRIGHT(c) 2016 STMicroelectronics

11 | * 12 | * Redistribution and use in source and binary forms, with or without modification, 13 | * are permitted provided that the following conditions are met: 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 3. Neither the name of STMicroelectronics nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software 21 | * without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | ****************************************************************************** 35 | */ 36 | 37 | /* Define to prevent recursive inclusion -------------------------------------*/ 38 | #ifndef __STM32746G_DISCOVERY_SDRAM_H 39 | #define __STM32746G_DISCOVERY_SDRAM_H 40 | 41 | #ifdef __cplusplus 42 | extern "C" { 43 | #endif 44 | 45 | /* Includes ------------------------------------------------------------------*/ 46 | #include "stm32f7xx_hal.h" 47 | #include "stdint.h" 48 | #include "stm32f7xx_hal_sdram.h" 49 | 50 | /** @addtogroup BSP 51 | * @{ 52 | */ 53 | 54 | /** @addtogroup STM32746G_DISCOVERY 55 | * @{ 56 | */ 57 | 58 | /** @addtogroup STM32746G_DISCOVERY_SDRAM 59 | * @{ 60 | */ 61 | 62 | /** @defgroup STM32746G_DISCOVERY_SDRAM_Exported_Types STM32746G_DISCOVERY_SDRAM Exported Types 63 | * @{ 64 | */ 65 | 66 | /** 67 | * @brief SDRAM status structure definition 68 | */ 69 | #define SDRAM_OK ((uint8_t)0x00) 70 | #define SDRAM_ERROR ((uint8_t)0x01) 71 | 72 | /** @defgroup STM32746G_DISCOVERY_SDRAM_Exported_Constants STM32746G_DISCOVERY_SDRAM Exported Constants 73 | * @{ 74 | */ 75 | #define SDRAM_DEVICE_ADDR ((uint32_t)0xC0000000) 76 | #define SDRAM_DEVICE_SIZE ((uint32_t)0x800000) /* SDRAM device size in MBytes */ 77 | 78 | /* #define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_8 */ 79 | #define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_16 80 | 81 | #define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_2 82 | /* #define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_3 */ 83 | 84 | #define REFRESH_COUNT ((uint32_t)0x0603) /* SDRAM refresh counter (100Mhz SD clock) */ 85 | 86 | #define SDRAM_TIMEOUT ((uint32_t)0xFFFF) 87 | 88 | /* DMA definitions for SDRAM DMA transfer */ 89 | #define __DMAx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE 90 | #define __DMAx_CLK_DISABLE __HAL_RCC_DMA2_CLK_DISABLE 91 | #define SDRAM_DMAx_CHANNEL DMA_CHANNEL_0 92 | #define SDRAM_DMAx_STREAM DMA2_Stream0 93 | #define SDRAM_DMAx_IRQn DMA2_Stream0_IRQn 94 | #define BSP_SDRAM_DMA_IRQHandler DMA2_Stream0_IRQHandler 95 | /** 96 | * @} 97 | */ 98 | 99 | /** 100 | * @brief FMC SDRAM Mode definition register defines 101 | */ 102 | #define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000) 103 | #define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001) 104 | #define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002) 105 | #define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004) 106 | #define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000) 107 | #define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008) 108 | #define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020) 109 | #define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030) 110 | #define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000) 111 | #define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000) 112 | #define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200) 113 | /** 114 | * @} 115 | */ 116 | 117 | /** @defgroup STM32746G_DISCOVERY_SDRAM_Exported_Macro STM32746G_DISCOVERY_SDRAM Exported Macro 118 | * @{ 119 | */ 120 | /** 121 | * @} 122 | */ 123 | 124 | /** @addtogroup STM32746G_DISCOVERY_SDRAM_Exported_Functions 125 | * @{ 126 | */ 127 | uint8_t BSP_SDRAM_Init(void); 128 | uint8_t BSP_SDRAM_DeInit(void); 129 | void BSP_SDRAM_Initialization_sequence(uint32_t RefreshCount); 130 | uint8_t BSP_SDRAM_ReadData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize); 131 | uint8_t BSP_SDRAM_ReadData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize); 132 | uint8_t BSP_SDRAM_WriteData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize); 133 | uint8_t BSP_SDRAM_WriteData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize); 134 | uint8_t BSP_SDRAM_Sendcmd(FMC_SDRAM_CommandTypeDef *SdramCmd); 135 | 136 | /* These functions can be modified in case the current settings (e.g. DMA stream) 137 | need to be changed for specific application needs */ 138 | void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram, void *Params); 139 | void BSP_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram, void *Params); 140 | 141 | 142 | /** 143 | * @} 144 | */ 145 | 146 | /** 147 | * @} 148 | */ 149 | 150 | /** 151 | * @} 152 | */ 153 | 154 | /** 155 | * @} 156 | */ 157 | 158 | #ifdef __cplusplus 159 | } 160 | #endif 161 | 162 | #endif /* __STM32746G_DISCOVERY_SDRAM_H */ 163 | 164 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 165 | -------------------------------------------------------------------------------- /Tutorial 29 - STM32F7 LCD and Touch/GUI files/stm32746g_discovery_ts.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32746g_discovery_ts.h 4 | * @author MCD Application Team 5 | * @brief This file contains the common defines and functions prototypes for 6 | * the stm32746g_discovery_ts.c driver. 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | *

© COPYRIGHT(c) 2016 STMicroelectronics

11 | * 12 | * Redistribution and use in source and binary forms, with or without modification, 13 | * are permitted provided that the following conditions are met: 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 3. Neither the name of STMicroelectronics nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software 21 | * without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | ****************************************************************************** 35 | */ 36 | 37 | /* Define to prevent recursive inclusion -------------------------------------*/ 38 | #ifndef __STM32746G_DISCOVERY_TS_H 39 | #define __STM32746G_DISCOVERY_TS_H 40 | 41 | #ifdef __cplusplus 42 | extern "C" { 43 | #endif 44 | 45 | /* Includes ------------------------------------------------------------------*/ 46 | #include "stm32746g_discovery.h" 47 | /* Include touch screen FT5336 component Driver */ 48 | #include "ft5336.h" 49 | 50 | /** @addtogroup BSP 51 | * @{ 52 | */ 53 | 54 | /** @addtogroup STM32746G_DISCOVERY 55 | * @{ 56 | */ 57 | 58 | /** @addtogroup STM32746G_DISCOVERY_TS 59 | * @{ 60 | */ 61 | 62 | /** @defgroup STM32746G_DISCOVERY_TS_Exported_Constants STM32746G_DISCOVERY_TS Exported Constants 63 | * @{ 64 | */ 65 | 66 | /** @brief With FT5336 : maximum 5 touches detected simultaneously 67 | */ 68 | #define TS_MAX_NB_TOUCH ((uint32_t) FT5336_MAX_DETECTABLE_TOUCH) 69 | 70 | #define TS_NO_IRQ_PENDING ((uint8_t) 0) 71 | #define TS_IRQ_PENDING ((uint8_t) 1) 72 | 73 | #define TS_SWAP_NONE ((uint8_t) 0x01) 74 | #define TS_SWAP_X ((uint8_t) 0x02) 75 | #define TS_SWAP_Y ((uint8_t) 0x04) 76 | #define TS_SWAP_XY ((uint8_t) 0x08) 77 | 78 | /** 79 | * @} 80 | */ 81 | 82 | /** @defgroup STM32746G_DISCOVERY_TS_Exported_Types STM32746G_DISCOVERY_TS Exported Types 83 | * @{ 84 | */ 85 | /** 86 | * @brief TS_StateTypeDef 87 | * Define TS State structure 88 | */ 89 | typedef struct 90 | { 91 | uint8_t touchDetected; /*!< Total number of active touches detected at last scan */ 92 | uint16_t touchX[TS_MAX_NB_TOUCH]; /*!< Touch X[0], X[1] coordinates on 12 bits */ 93 | uint16_t touchY[TS_MAX_NB_TOUCH]; /*!< Touch Y[0], Y[1] coordinates on 12 bits */ 94 | 95 | #if (TS_MULTI_TOUCH_SUPPORTED == 1) 96 | uint8_t touchWeight[TS_MAX_NB_TOUCH]; /*!< Touch_Weight[0], Touch_Weight[1] : weight property of touches */ 97 | uint8_t touchEventId[TS_MAX_NB_TOUCH]; /*!< Touch_EventId[0], Touch_EventId[1] : take value of type @ref TS_TouchEventTypeDef */ 98 | uint8_t touchArea[TS_MAX_NB_TOUCH]; /*!< Touch_Area[0], Touch_Area[1] : touch area of each touch */ 99 | uint32_t gestureId; /*!< type of gesture detected : take value of type @ref TS_GestureIdTypeDef */ 100 | #endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */ 101 | 102 | } TS_StateTypeDef; 103 | 104 | /** 105 | * @} 106 | */ 107 | 108 | /** @defgroup STM32746G_DISCOVERY_TS_Exported_Constants STM32746G_DISCOVERY_TS Exported Constants 109 | * @{ 110 | */ 111 | 112 | typedef enum 113 | { 114 | TS_OK = 0x00, /*!< Touch Ok */ 115 | TS_ERROR = 0x01, /*!< Touch Error */ 116 | TS_TIMEOUT = 0x02, /*!< Touch Timeout */ 117 | TS_DEVICE_NOT_FOUND = 0x03 /*!< Touchscreen device not found */ 118 | }TS_StatusTypeDef; 119 | 120 | /** 121 | * @brief TS_GestureIdTypeDef 122 | * Define Possible managed gesture identification values returned by touch screen 123 | * driver. 124 | */ 125 | typedef enum 126 | { 127 | GEST_ID_NO_GESTURE = 0x00, /*!< Gesture not defined / recognized */ 128 | GEST_ID_MOVE_UP = 0x01, /*!< Gesture Move Up */ 129 | GEST_ID_MOVE_RIGHT = 0x02, /*!< Gesture Move Right */ 130 | GEST_ID_MOVE_DOWN = 0x03, /*!< Gesture Move Down */ 131 | GEST_ID_MOVE_LEFT = 0x04, /*!< Gesture Move Left */ 132 | GEST_ID_ZOOM_IN = 0x05, /*!< Gesture Zoom In */ 133 | GEST_ID_ZOOM_OUT = 0x06, /*!< Gesture Zoom Out */ 134 | GEST_ID_NB_MAX = 0x07 /*!< max number of gesture id */ 135 | 136 | } TS_GestureIdTypeDef; 137 | 138 | /** 139 | * @brief TS_TouchEventTypeDef 140 | * Define Possible touch events kind as returned values 141 | * by touch screen IC Driver. 142 | */ 143 | typedef enum 144 | { 145 | TOUCH_EVENT_NO_EVT = 0x00, /*!< Touch Event : undetermined */ 146 | TOUCH_EVENT_PRESS_DOWN = 0x01, /*!< Touch Event Press Down */ 147 | TOUCH_EVENT_LIFT_UP = 0x02, /*!< Touch Event Lift Up */ 148 | TOUCH_EVENT_CONTACT = 0x03, /*!< Touch Event Contact */ 149 | TOUCH_EVENT_NB_MAX = 0x04 /*!< max number of touch events kind */ 150 | 151 | } TS_TouchEventTypeDef; 152 | /** 153 | * @} 154 | */ 155 | 156 | /** @defgroup STM32746G_DISCOVERY_TS_Imported_Variables STM32746G_DISCOVERY_TS Imported Variables 157 | * @{ 158 | */ 159 | /** 160 | * @brief Table for touchscreen event information display on LCD : 161 | * table indexed on enum @ref TS_TouchEventTypeDef information 162 | */ 163 | extern char * ts_event_string_tab[TOUCH_EVENT_NB_MAX]; 164 | 165 | /** 166 | * @brief Table for touchscreen gesture Id information display on LCD : table indexed 167 | * on enum @ref TS_GestureIdTypeDef information 168 | */ 169 | extern char * ts_gesture_id_string_tab[GEST_ID_NB_MAX]; 170 | /** 171 | * @} 172 | */ 173 | 174 | /** @addtogroup STM32746G_DISCOVERY_TS_Exported_Functions 175 | * @{ 176 | */ 177 | uint8_t BSP_TS_Init(uint16_t ts_SizeX, uint16_t ts_SizeY); 178 | uint8_t BSP_TS_DeInit(void); 179 | uint8_t BSP_TS_GetState(TS_StateTypeDef *TS_State); 180 | 181 | #if (TS_MULTI_TOUCH_SUPPORTED == 1) 182 | uint8_t BSP_TS_Get_GestureId(TS_StateTypeDef *TS_State); 183 | #endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */ 184 | 185 | uint8_t BSP_TS_ITConfig(void); 186 | uint8_t BSP_TS_ITGetStatus(void); 187 | void BSP_TS_ITClear(void); 188 | uint8_t BSP_TS_ResetTouchData(TS_StateTypeDef *TS_State); 189 | /** 190 | * @} 191 | */ 192 | 193 | /** 194 | * @} 195 | */ 196 | 197 | /** 198 | * @} 199 | */ 200 | 201 | /** 202 | * @} 203 | */ 204 | 205 | 206 | #ifdef __cplusplus 207 | } 208 | #endif 209 | 210 | #endif /* __STM32746G_DISCOVERY_TS_H */ 211 | 212 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 213 | -------------------------------------------------------------------------------- /Tutorial 29 - STM32F7 LCD and Touch/GUI files/ts.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file ts.h 4 | * @author MCD Application Team 5 | * @version V4.0.1 6 | * @date 21-July-2015 7 | * @brief This file contains all the functions prototypes for the Touch Screen driver. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT(c) 2015 STMicroelectronics

12 | * 13 | * Redistribution and use in source and binary forms, with or without modification, 14 | * are permitted provided that the following conditions are met: 15 | * 1. Redistributions of source code must retain the above copyright notice, 16 | * this list of conditions and the following disclaimer. 17 | * 2. Redistributions in binary form must reproduce the above copyright notice, 18 | * this list of conditions and the following disclaimer in the documentation 19 | * and/or other materials provided with the distribution. 20 | * 3. Neither the name of STMicroelectronics nor the names of its contributors 21 | * may be used to endorse or promote products derived from this software 22 | * without specific prior written permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 32 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | * 35 | ****************************************************************************** 36 | */ 37 | 38 | /* Define to prevent recursive inclusion -------------------------------------*/ 39 | #ifndef __TS_H 40 | #define __TS_H 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | /* Includes ------------------------------------------------------------------*/ 47 | #include 48 | 49 | /** @addtogroup BSP 50 | * @{ 51 | */ 52 | 53 | /** @addtogroup Components 54 | * @{ 55 | */ 56 | 57 | /** @addtogroup TS 58 | * @{ 59 | */ 60 | 61 | /** @defgroup TS_Exported_Types 62 | * @{ 63 | */ 64 | 65 | /** @defgroup TS_Driver_structure Touch Sensor Driver structure 66 | * @{ 67 | */ 68 | typedef struct 69 | { 70 | void (*Init)(uint16_t); 71 | uint16_t (*ReadID)(uint16_t); 72 | void (*Reset)(uint16_t); 73 | void (*Start)(uint16_t); 74 | uint8_t (*DetectTouch)(uint16_t); 75 | void (*GetXY)(uint16_t, uint16_t*, uint16_t*); 76 | void (*EnableIT)(uint16_t); 77 | void (*ClearIT)(uint16_t); 78 | uint8_t (*GetITStatus)(uint16_t); 79 | void (*DisableIT)(uint16_t); 80 | }TS_DrvTypeDef; 81 | /** 82 | * @} 83 | */ 84 | 85 | /** 86 | * @} 87 | */ 88 | 89 | /** 90 | * @} 91 | */ 92 | 93 | /** 94 | * @} 95 | */ 96 | 97 | /** 98 | * @} 99 | */ 100 | 101 | #ifdef __cplusplus 102 | } 103 | #endif 104 | 105 | #endif /* __TS_H */ 106 | 107 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 108 | -------------------------------------------------------------------------------- /Tutorial 29 - STM32F7 LCD and Touch/Project Setup Steps.txt: -------------------------------------------------------------------------------- 1 | 1. CubeMX Configurations: 2 | - Enable the LED on PI0 3 | - Enable CRC 4 | - Enable DMA2D 5 | - Enable RCC 6 | - Set Clock Source to External and 200 MHz System Clock speed 7 | 8 | 2. Copy HAL h and c files specific for LTDC and SDRAM 9 | 10 | 3. Copy GUI Files folder to your newly generated project 11 | 12 | 4. Add paths and Source folder location and compile. 13 | 14 | 5. Do the following 15 | 16 | *main.h includes* 17 | #include "stm32f7xx_hal.h" 18 | 19 | #include "stm32746g_discovery.h" 20 | #include "stm32746g_discovery_sdram.h" 21 | #include "stm32746g_discovery_ts.h" 22 | #include "stm32746g_discovery_lcd.h" 23 | 24 | Step(6): Uncomment the following into the stm32f7xx_hal_conf.h: 25 | -------------------------------- 26 | #define HAL_SDRAM_MODULE_ENABLED 27 | #define HAL_LTDC_MODULE_ENABLED 28 | #define HAL_UART_MODULE_ENABLED 29 | 30 | 31 | Step(7): Modify STM32F7xx_it.c to include the following: 32 | ----------------------------- 33 | extern LTDC_HandleTypeDef hLtdcHandler; 34 | 35 | /* USER CODE BEGIN 1 */ 36 | void LTDC_IRQHandler(void) 37 | { 38 | HAL_LTDC_IRQHandler(&hLtdcHandler); 39 | } 40 | /* USER CODE END 1 */ 41 | 42 | Step(8): Main initialization 43 | ---------------------------- 44 | /* USER CODE BEGIN 0 */ 45 | TS_StateTypeDef ts; 46 | 47 | char xTouchStr[10]; 48 | /* USER CODE END 0 */ 49 | 50 | /* USER CODE BEGIN 1 */ 51 | /* Enable the CPU Cache */ 52 | /* Enable I-Cache */ 53 | SCB_EnableICache(); 54 | /* Enable D-Cache */ 55 | SCB_EnableDCache(); 56 | 57 | /* USER CODE END 1 */ 58 | 59 | BSP_SDRAM_Init(); /* Initializes the SDRAM device */ 60 | __HAL_RCC_CRC_CLK_ENABLE(); /* Enable the CRC Module */ 61 | 62 | BSP_TS_Init(480, 272); 63 | 64 | BSP_LCD_Init(); 65 | BSP_LCD_LayerDefaultInit(0, LCD_FB_START_ADDRESS); 66 | BSP_LCD_DisplayOn(); 67 | 68 | BSP_LCD_SelectLayer(0); 69 | BSP_LCD_Clear(LCD_COLOR_BLUE); 70 | 71 | 72 | BSP_LCD_DisplayStringAt(20, 20, (uint8_t *)"Hello!", LEFT_MODE); 73 | 74 | Step(9): While 1 main 75 | ------------------------- 76 | BSP_TS_GetState(&ts); 77 | sprintf(xTouchStr, "X: %3d", ts.touchX[0]); 78 | BSP_LCD_DisplayStringAt(20, 20, (uint8_t *)xTouchStr, LEFT_MODE); 79 | 80 | sprintf(xTouchStr, "Y: %3d", ts.touchY[0]); 81 | BSP_LCD_DisplayStringAt(20, 60, (uint8_t *)xTouchStr, LEFT_MODE); 82 | HAL_Delay(50); 83 | 84 | 85 | -------------------------------------------------------------------------------- /Tutorial 30 - FLASH Memory/MY_FLASH.c: -------------------------------------------------------------------------------- 1 | /* 2 | Library: STM32F40x Internal FLASH read/write 3 | Written by: Mohamed Yaqoob (MYaqoobEmbedded YouTube Channel) 4 | Last modified: 15/03/2019 5 | 6 | Description: 7 | MY_FLASH library implements the following basic functionalities 8 | - Set sectos address 9 | - Flash Sector Erase 10 | - Flash Write 11 | - Flash Read 12 | 13 | * Copyright (C) 2019 - M. Yaqoob 14 | This is a free software under the GNU license, you can redistribute it and/or modify it under the terms 15 | of the GNU General Public Licenseversion 3 as published by the Free Software Foundation. 16 | 17 | This software library is shared with puplic for educational purposes, without WARRANTY and Author is not liable for any damages caused directly 18 | or indirectly by this software, read more about this on the GNU General Public License. 19 | */ 20 | 21 | #include "MY_FLASH.h" 22 | 23 | //Private variables 24 | //1. sector start address 25 | static uint32_t MY_SectorAddrs; 26 | static uint8_t MY_SectorNum; 27 | 28 | //functions definitions 29 | //1. Erase Sector 30 | static void MY_FLASH_EraseSector(void) 31 | { 32 | HAL_FLASH_Unlock(); 33 | //Erase the required Flash sector 34 | FLASH_Erase_Sector(MY_SectorNum, FLASH_VOLTAGE_RANGE_3); 35 | HAL_FLASH_Lock(); 36 | } 37 | 38 | //2. Set Sector Adress 39 | void MY_FLASH_SetSectorAddrs(uint8_t sector, uint32_t addrs) 40 | { 41 | MY_SectorNum = sector; 42 | MY_SectorAddrs = addrs; 43 | } 44 | 45 | //3. Write Flash 46 | void MY_FLASH_WriteN(uint32_t idx, void *wrBuf, uint32_t Nsize, DataTypeDef dataType) 47 | { 48 | uint32_t flashAddress = MY_SectorAddrs + idx; 49 | 50 | //Erase sector before write 51 | MY_FLASH_EraseSector(); 52 | 53 | //Unlock Flash 54 | HAL_FLASH_Unlock(); 55 | //Write to Flash 56 | switch(dataType) 57 | { 58 | case DATA_TYPE_8: 59 | for(uint32_t i=0; ienableAxes & 0x07); //Enable Axes 88 | spiData |= (accInitDef->dataRate & 0xF0); //Output Data Rate 89 | //Write to accelerometer 90 | LIS3DSH_WriteIO(LIS3DSH_CTRL_REG4_ADDR, &spiData, 1); 91 | 92 | //** 2. Full-Scale selection, Anti-aliasing BW, self test and 4-wire SPI **// 93 | spiData = 0; 94 | spiData |= (accInitDef->antiAliasingBW & 0xC0); //Anti-aliasing BW 95 | spiData |= (accInitDef->fullScale & 0x38); //Full-Scale 96 | //Write to accelerometer 97 | LIS3DSH_WriteIO(LIS3DSH_CTRL_REG5_ADDR, &spiData, 1); 98 | 99 | //** 3. Interrupt Configuration **// 100 | if(accInitDef->interruptEnable) 101 | { 102 | spiData = 0x88; 103 | //Write to accelerometer 104 | LIS3DSH_WriteIO(LIS3DSH_CTRL_REG3_ADDR, &spiData, 1); 105 | } 106 | 107 | //Assign sensor sensitivity (based on Full-Scale) 108 | switch(accInitDef->fullScale) 109 | { 110 | case LIS3DSH_FULLSCALE_2: 111 | lis3dsh_Sensitivity = LIS3DSH_SENSITIVITY_0_06G; 112 | break; 113 | 114 | case LIS3DSH_FULLSCALE_4: 115 | lis3dsh_Sensitivity = LIS3DSH_SENSITIVITY_0_12G; 116 | break; 117 | 118 | case LIS3DSH_FULLSCALE_6: 119 | lis3dsh_Sensitivity = LIS3DSH_SENSITIVITY_0_18G; 120 | break; 121 | 122 | case LIS3DSH_FULLSCALE_8: 123 | lis3dsh_Sensitivity = LIS3DSH_SENSITIVITY_0_24G; 124 | break; 125 | 126 | case LIS3DSH_FULLSCALE_16: 127 | lis3dsh_Sensitivity = LIS3DSH_SENSITIVITY_0_73G; 128 | break; 129 | } 130 | _LIS3DHS_CS_DISABLE; 131 | } 132 | //2. Get Accelerometer raw data 133 | LIS3DSH_DataRaw LIS3DSH_GetDataRaw(void) 134 | { 135 | uint8_t spiBuf[2]; 136 | LIS3DSH_DataRaw tempDataRaw; 137 | //Read X data 138 | LIS3DSH_ReadIO(LIS3DSH_OUT_X_L_ADDR, spiBuf, 2); 139 | tempDataRaw.x = ((spiBuf[1] << 8) + spiBuf[0]); 140 | 141 | //Read Y data 142 | LIS3DSH_ReadIO(LIS3DSH_OUT_Y_L_ADDR, spiBuf, 2); 143 | tempDataRaw.y = ((spiBuf[1] << 8) + spiBuf[0]); 144 | 145 | //Read Z data 146 | LIS3DSH_ReadIO(LIS3DSH_OUT_Z_L_ADDR, spiBuf, 2); 147 | tempDataRaw.z = ((spiBuf[1] << 8) + spiBuf[0]); 148 | 149 | return tempDataRaw; 150 | 151 | } 152 | //3. Get Accelerometer mg data 153 | LIS3DSH_DataScaled LIS3DSH_GetDataScaled(void) 154 | { 155 | //Read raw data 156 | LIS3DSH_DataRaw tempRawData = LIS3DSH_GetDataRaw();; 157 | //Scale data and return 158 | LIS3DSH_DataScaled tempScaledData; 159 | tempScaledData.x = (tempRawData.x * lis3dsh_Sensitivity * __X_Scale) + 0.0f - __X_Bias; 160 | tempScaledData.y = (tempRawData.y * lis3dsh_Sensitivity * __Y_Scale) + 0.0f - __Y_Bias; 161 | tempScaledData.z = (tempRawData.z * lis3dsh_Sensitivity * __Z_Scale) + 0.0f - __Z_Bias; 162 | 163 | return tempScaledData; 164 | } 165 | //4. Poll for Data Ready 166 | bool LIS3DSH_PollDRDY(uint32_t msTimeout) 167 | { 168 | uint8_t Acc_status; 169 | uint32_t startTick = HAL_GetTick(); 170 | do 171 | { 172 | //Read status register with a timeout 173 | LIS3DSH_ReadIO(0x27, &Acc_status, 1); 174 | if(Acc_status & 0x07)break; 175 | 176 | }while((Acc_status & 0x07)==0 && (HAL_GetTick() - startTick) < msTimeout); 177 | if(Acc_status & 0x07) 178 | { 179 | return true; 180 | } 181 | return false; 182 | 183 | } 184 | 185 | //** Calibration functions **// 186 | //1. Set X-Axis calibrate 187 | void LIS3DSH_X_calibrate(float x_min, float x_max) 188 | { 189 | __X_Bias = (x_max+x_min)/2.0f; 190 | __X_Scale = (2*1000)/(x_max - x_min); 191 | } 192 | //2. Set Y-Axis calibrate 193 | void LIS3DSH_Y_calibrate(float y_min, float y_max) 194 | { 195 | __Y_Bias = (y_max+y_min)/2.0f; 196 | __Y_Scale = (2*1000)/(y_max - y_min); 197 | } 198 | //3. Set Z-Axis calibrate 199 | void LIS3DSH_Z_calibrate(float z_min, float z_max) 200 | { 201 | __Z_Bias = (z_max+z_min)/2.0f; 202 | __Z_Scale = (2*1000)/(z_max - z_min); 203 | } 204 | 205 | -------------------------------------------------------------------------------- /Tutorial 32 - USB HID/MY_LIS3DSH.h: -------------------------------------------------------------------------------- 1 | /* 2 | Library: Accelerometer - LIS3DSH 3 | Written by: Mohamed Yaqoob (MYaqoobEmbedded YouTube Channel) 4 | Date Written: 12/12/2018 5 | Last modified: -/- 6 | Description: This is an STM32 device driver library for the LIS3DSH Accelerometer, using STM HAL libraries 7 | 8 | References: 9 | 1) STMicroelectronics LIS3DSH datasheet 10 | https://www.st.com/resource/en/datasheet/lis3dsh.pdf 11 | 2) ST opensource LIS3DSH accelerometer dsp drivers. 12 | 13 | * Copyright (C) 2018 - M. Yaqoob 14 | This is a free software under the GNU license, you can redistribute it and/or modify it under the terms 15 | of the GNU General Public Licenseversion 3 as published by the Free Software Foundation. 16 | 17 | This software library is shared with puplic for educational purposes, without WARRANTY and Author is not liable for any damages caused directly 18 | or indirectly by this software, read more about this on the GNU General Public License. 19 | */ 20 | 21 | //Header files 22 | #include "stm32f4xx_hal.h" 23 | #include 24 | #include 25 | 26 | //List of Defines 27 | //1. LIS3DHS registers addresses 28 | #define LIS3DSH_WHO_AM_I_ADDR 0x0F 29 | #define LIS3DSH_OFF_X_ADDR 0x10 30 | #define LIS3DSH_OFF_Y_ADDR 0x11 31 | #define LIS3DSH_OFF_Z_ADDR 0x12 32 | 33 | #define LIS3DSH_CTRL_REG4_ADDR 0x20 34 | #define LIS3DSH_CTRL_REG1_ADDR 0x21 35 | #define LIS3DSH_CTRL_REG2_ADDR 0x22 36 | #define LIS3DSH_CTRL_REG3_ADDR 0x23 37 | #define LIS3DSH_CTRL_REG5_ADDR 0x24 38 | #define LIS3DSH_CTRL_REG6_ADDR 0x25 39 | 40 | #define LIS3DSH_STATUS_ADDR 0x27 41 | 42 | #define LIS3DSH_OUT_X_L_ADDR 0x28 43 | #define LIS3DSH_OUT_X_H_ADDR 0x29 44 | #define LIS3DSH_OUT_Y_L_ADDR 0x2A 45 | #define LIS3DSH_OUT_Y_H_ADDR 0x2B 46 | #define LIS3DSH_OUT_Z_L_ADDR 0x2C 47 | #define LIS3DSH_OUT_Z_H_ADDR 0x2D 48 | 49 | 50 | //2. Data rate 51 | #define LIS3DSH_DATARATE_POWERDOWN ((uint8_t)0x00) /* Power Down Mode*/ 52 | #define LIS3DSH_DATARATE_3_125 ((uint8_t)0x10) /* 3.125 Hz Normal Mode */ 53 | #define LIS3DSH_DATARATE_6_25 ((uint8_t)0x20) /* 6.25 Hz Normal Mode */ 54 | #define LIS3DSH_DATARATE_12_5 ((uint8_t)0x30) /* 12.5 Hz Normal Mode */ 55 | #define LIS3DSH_DATARATE_25 ((uint8_t)0x40) /* 25 Hz Normal Mode */ 56 | #define LIS3DSH_DATARATE_50 ((uint8_t)0x50) /* 50 Hz Normal Mode */ 57 | #define LIS3DSH_DATARATE_100 ((uint8_t)0x60) /* 100 Hz Normal Mode */ 58 | #define LIS3DSH_DATARATE_400 ((uint8_t)0x70) /* 400 Hz Normal Mode */ 59 | #define LIS3DSH_DATARATE_800 ((uint8_t)0x80) /* 800 Hz Normal Mode */ 60 | #define LIS3DSH_DATARATE_1600 ((uint8_t)0x90) /* 1600 Hz Normal Mode */ 61 | 62 | //3. Full scale 63 | #define LIS3DSH_FULLSCALE_2 ((uint8_t)0x00) /* 2 g */ 64 | #define LIS3DSH_FULLSCALE_4 ((uint8_t)0x08) /* 4 g */ 65 | #define LIS3DSH_FULLSCALE_6 ((uint8_t)0x10) /* 6 g */ 66 | #define LIS3DSH_FULLSCALE_8 ((uint8_t)0x18) /* 8 g */ 67 | #define LIS3DSH_FULLSCALE_16 ((uint8_t)0x20) /* 16 g */ 68 | 69 | //4. Anti-Aliasing Bandwidth 70 | #define LIS3DSH_FILTER_BW_800 ((uint8_t)0x00) /* 800 Hz */ 71 | #define LIS3DSH_FILTER_BW_400 ((uint8_t)0x80) /* 400 Hz */ 72 | #define LIS3DSH_FILTER_BW_200 ((uint8_t)0x40) /* 200 Hz */ 73 | #define LIS3DSH_FILTER_BW_50 ((uint8_t)0xC0) /* 50 Hz */ 74 | 75 | //5. Enabled axis 76 | #define LIS3DSH_X_ENABLE ((uint8_t)0x01) 77 | #define LIS3DSH_Y_ENABLE ((uint8_t)0x02) 78 | #define LIS3DSH_Z_ENABLE ((uint8_t)0x04) 79 | #define LIS3DSH_XYZ_ENABLE ((uint8_t)0x07) 80 | 81 | //6. Sensitivity values (Based on Full-Scale) 82 | #define LIS3DSH_SENSITIVITY_0_06G 0.06 /* 0.06 mg/digit*/ 83 | #define LIS3DSH_SENSITIVITY_0_12G 0.12 /* 0.12 mg/digit*/ 84 | #define LIS3DSH_SENSITIVITY_0_18G 0.18 /* 0.18 mg/digit*/ 85 | #define LIS3DSH_SENSITIVITY_0_24G 0.24 /* 0.24 mg/digit*/ 86 | #define LIS3DSH_SENSITIVITY_0_73G 0.73 /* 0.73 mg/digit*/ 87 | 88 | //Typedefs 89 | //1. Accelerometer Configuration struct 90 | typedef struct 91 | { 92 | uint8_t dataRate; 93 | uint8_t fullScale; 94 | uint8_t antiAliasingBW; 95 | uint8_t enableAxes; 96 | bool interruptEnable; 97 | }LIS3DSH_InitTypeDef; 98 | 99 | //2. Accelerometer raw data 100 | typedef struct 101 | { 102 | int16_t x; 103 | int16_t y; 104 | int16_t z; 105 | }LIS3DSH_DataRaw; 106 | 107 | //3. Accelerometer mg data (scaled data) 108 | typedef struct 109 | { 110 | float x; 111 | float y; 112 | float z; 113 | }LIS3DSH_DataScaled; 114 | 115 | //Functions prototypes 116 | //Private functions 117 | //1. Write IO 118 | void LIS3DSH_WriteIO(uint8_t reg, uint8_t *dataW, uint8_t size); 119 | //2. Read IO 120 | void LIS3DSH_ReadIO(uint8_t reg, uint8_t *dataR, uint8_t size); 121 | 122 | 123 | //1. Accelerometer initialise function 124 | void LIS3DSH_Init(SPI_HandleTypeDef *accSPI, LIS3DSH_InitTypeDef *accInitDef); 125 | //2. Get Accelerometer raw data 126 | LIS3DSH_DataRaw LIS3DSH_GetDataRaw(void); 127 | //3. Get Accelerometer mg data 128 | LIS3DSH_DataScaled LIS3DSH_GetDataScaled(void); 129 | //4. Poll for Data Ready 130 | bool LIS3DSH_PollDRDY(uint32_t msTimeout); 131 | 132 | //** Calibration functions **// 133 | //1. Set X-Axis calibrate 134 | void LIS3DSH_X_calibrate(float x_min, float x_max); 135 | //2. Set Y-Axis calibrate 136 | void LIS3DSH_Y_calibrate(float y_min, float y_max); 137 | //3. Set Z-Axis calibrate 138 | void LIS3DSH_Z_calibrate(float z_min, float z_max); 139 | 140 | -------------------------------------------------------------------------------- /Tutorial 33 - CAN Bus/CAN Frame.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MYaqoobEmbedded/STM32-Tutorials/bdf2c8e7722f267b5c7e8114462c66f59203704c/Tutorial 33 - CAN Bus/CAN Frame.JPG -------------------------------------------------------------------------------- /Tutorial 33 - CAN Bus/CAN bus tutorial steps.txt: -------------------------------------------------------------------------------- 1 | Step(1): CubeMX set up 2 | - Enable CAN and map to PB8 and PB9 pins 3 | - Enable CAN Rx interrupt 4 | ================================ 5 | 6 | Step(2): Declare Tx and Rx message typedef 7 | static CanTxMsgTypeDef myTxMessage; 8 | static CanRxMsgTypeDef myRxMessage; 9 | 10 | static void MX_CAN1_Init(void) 11 | { 12 | 13 | hcan1.Instance = CAN1; 14 | 15 | hcan1.pTxMsg = &myTxMessage; 16 | hcan1.pRxMsg = &myRxMessage; 17 | 18 | hcan1.Init.Prescaler = 16; 19 | hcan1.Init.Mode = CAN_MODE_NORMAL; 20 | ================================= 21 | 22 | Step(3): Can Filter config function 23 | static void CAN_FilterConfig(void) 24 | { 25 | CAN_FilterConfTypeDef sFilterConfig; 26 | sFilterConfig.FilterNumber = 0; 27 | sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; 28 | sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; 29 | sFilterConfig.FilterIdHigh = 0x000 <<5; 30 | sFilterConfig.FilterIdLow = 0x0000; 31 | sFilterConfig.FilterMaskIdHigh = 0x0000; //0xFFE0 32 | sFilterConfig.FilterMaskIdLow = 0x0000; 33 | sFilterConfig.FilterFIFOAssignment = 0; 34 | sFilterConfig.FilterActivation = ENABLE; 35 | sFilterConfig.BankNumber = 14; 36 | 37 | if(HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK) 38 | { 39 | /* Filter configuration Error */ 40 | Error_Handler(); 41 | } 42 | } 43 | ================================= 44 | 45 | Step(4): LED Switch function 46 | void LED_Switch(uint8_t led) 47 | { 48 | /* Turn off all LEDs */ 49 | HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET); 50 | HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_RESET); 51 | HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_RESET); 52 | HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_RESET); 53 | 54 | switch(led) 55 | { 56 | case(1): 57 | HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET); 58 | break; 59 | 60 | case(2): 61 | HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_SET); 62 | break; 63 | 64 | case(3): 65 | HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET); 66 | break; 67 | 68 | case(4): 69 | HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET); 70 | break; 71 | 72 | default: 73 | break; 74 | } 75 | } 76 | ================================= 77 | 78 | Step(5): Main Initialise functions call 79 | //CAN filter config 80 | CAN_FilterConfig(); 81 | 82 | //Start CAN IT receive 83 | if(HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0) != HAL_OK) 84 | { 85 | Error_Handler(); 86 | } 87 | 88 | //Set transmission CAN paramters 89 | hcan1.pTxMsg->StdId = 0x321; 90 | hcan1.pTxMsg->RTR = CAN_RTR_DATA; 91 | hcan1.pTxMsg->IDE = CAN_ID_STD; 92 | hcan1.pTxMsg->DLC = 2; 93 | ================================= 94 | 95 | Step(6): Transmit CAN data 96 | if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET) 97 | { 98 | if(dataVar == 0x4) dataVar = 0x00; 99 | LED_Switch(++dataVar); 100 | //Set data to be transmitted 101 | hcan1.pTxMsg->Data[0] = dataVar; 102 | hcan1.pTxMsg->Data[1] = 0x12; 103 | //Transmit data via CAN 104 | if(HAL_CAN_Transmit(&hcan1, 10) != HAL_OK) 105 | { 106 | Error_Handler(); 107 | } 108 | HAL_Delay(300); 109 | } 110 | 111 | ================================= 112 | 113 | Step(7): CAN receive callback 114 | void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* CanHandle) 115 | { 116 | if (CanHandle->pRxMsg->StdId == 0x321) 117 | { 118 | dataVar = CanHandle->pRxMsg->Data[0]; 119 | LED_Switch(dataVar); 120 | } 121 | 122 | /* Receive */ 123 | if(HAL_CAN_Receive_IT(CanHandle, CAN_FIFO0) != HAL_OK) 124 | { 125 | /* Reception Error */ 126 | Error_Handler(); 127 | } 128 | } 129 | ================================= 130 | 131 | Step(8): Demonstrate Own and Remote ID 132 | //Own ID 133 | uint16_t canOwnDeviceID = 0x456; //0x456 134 | //Away ID 135 | uint16_t canRemoteDeviceID = 0x123; //0x123 136 | ================================= 137 | 138 | Step(9): Filter test 139 | sFilterConfig.FilterIdHigh = 0x123 <<5; 140 | sFilterConfig.FilterIdLow = 0x0000; 141 | sFilterConfig.FilterMaskIdHigh = 0xFFE0; //0xFFE0 142 | ================================== 143 | 144 | 145 | -------------------------------------------------------------------------------- /Tutorial 33 - CAN Bus/wiring diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MYaqoobEmbedded/STM32-Tutorials/bdf2c8e7722f267b5c7e8114462c66f59203704c/Tutorial 33 - CAN Bus/wiring diagram.png -------------------------------------------------------------------------------- /Tutorial 34 - USB MSC Flash Drive/USB Flash - Tutorial steps.txt: -------------------------------------------------------------------------------- 1 | Step(1): CubeMX setup 2 | - Enable LEDs and Button 3 | - Enable USB_OTG_FS as Host only + VBUS 4 | - USB Host as Mass Storage Host Class 5 | - FatFS middleware select = USB Disk 6 | - Enable HSE RCC 7 | - Enable PC0 pin and set to OUTPUT (Power Switch enable for USB supply) 8 | - MAX_SS = 4096 (FATFS Configuration parameters) 9 | ======================================================== 10 | 11 | Step(2): Flash Drive connected/disconnected indicator 12 | - open usb_host.c and use this in main 13 | extern ApplicationTypeDef Appli_state; 14 | 15 | - USB application states (LED ON when USB Flash Drive is connected) 16 | /* USER CODE BEGIN 3 */ 17 | switch(Appli_state) 18 | { 19 | case APPLICATION_READY: 20 | break; 21 | 22 | case APPLICATION_IDLE: 23 | break; 24 | 25 | case APPLICATION_DISCONNECT: 26 | HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET); 27 | break; 28 | 29 | case APPLICATION_START: 30 | HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET); 31 | break; 32 | 33 | default: 34 | break; 35 | } 36 | ======================================================= 37 | Step(3): Mount SD Card code 38 | 39 | - Add FATFS variable 40 | //FatFS variable 41 | FATFS myUsbFatFS; 42 | 43 | - open fatfs.c files and add USB logical path drive as extern in main 44 | extern char USBH_Path[4]; 45 | 46 | - Software mount of USB Flash Drive 47 | case APPLICATION_START: 48 | /* Register the file system object to the FatFs module */ 49 | if(f_mount(&myUsbFatFS, (TCHAR const*)USBH_Path, 0) != FR_OK) 50 | { 51 | /* FatFs Initialization Error */ 52 | Error_Handler(); 53 | } 54 | else 55 | { 56 | HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET); 57 | } 58 | break; 59 | ======================================================= 60 | 61 | Step(4): Add File IO Variables 62 | //File IO Variables 63 | FIL myFile; 64 | FRESULT res; 65 | UINT byteswritten, bytesread; 66 | char rwtext[100]; 67 | ======================================================= 68 | 69 | Step(5): File write function 70 | - Include string and boolean header files 71 | //String library 72 | #include 73 | #include 74 | 75 | - Test Write function body 76 | //1. USB test Write function 77 | bool UsbTest_Write(void) 78 | { 79 | //Open/Create file for Writing 80 | if(f_open(&myFile, "TEST.TXT", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) 81 | { 82 | return 0; //error 83 | } 84 | else 85 | { 86 | //Set text string to write to file 87 | sprintf(rwtext, "Hello world from Mohamed Yaqoob!"); 88 | //write to file 89 | res = f_write(&myFile, (uint8_t *)rwtext, strlen(rwtext), &byteswritten); 90 | if((byteswritten == 0) || (res != FR_OK)) 91 | { 92 | return 0; //error 93 | } 94 | } 95 | 96 | //Close file 97 | f_close(&myFile); 98 | return 1; //success 99 | } 100 | 101 | - Call write function in the main when button is pressed 102 | case APPLICATION_READY: 103 | if(HAL_GPIO_ReadPin(Button_GPIO_Port, Button_Pin) == GPIO_PIN_SET) 104 | { 105 | if(UsbTest_Write()) HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin); 106 | else HAL_GPIO_TogglePin(LED3_GPIO_Port, LED3_Pin); 107 | HAL_Delay(1000); 108 | } 109 | ======================================================= 110 | 111 | Step(6): File read function 112 | 113 | //2. USB test Read function 114 | bool UsbTest_Read(void) 115 | { 116 | //Open file for Reading 117 | if(f_open(&myFile, "TEST.TXT", FA_READ) != FR_OK) 118 | { 119 | return 0; //error 120 | } 121 | else 122 | { 123 | //Read text from files until NULL 124 | for(uint8_t i=0; i<100; i++) 125 | { 126 | res = f_read(&myFile, (uint8_t*)&rwtext[i], 1, &bytesread); 127 | if(rwtext[i] == 0x00) 128 | { 129 | bytesread = i; 130 | break; 131 | } 132 | } 133 | //Reading error handling 134 | if(bytesread==0) return 0; 135 | } 136 | 137 | //Close file 138 | f_close(&myFile); 139 | return 1; //success 140 | } 141 | 142 | - Call read file function in the main 143 | case APPLICATION_READY: 144 | if(HAL_GPIO_ReadPin(Button_GPIO_Port, Button_Pin) == GPIO_PIN_SET) 145 | { 146 | if(UsbTest_Read()) HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin); 147 | else HAL_GPIO_TogglePin(LED3_GPIO_Port, LED3_Pin); 148 | HAL_Delay(1000); 149 | } 150 | -------------------------------------------------------------------------------- /Tutorial 35 - MPU6050 IMU Module/TJ_MPU6050.c: -------------------------------------------------------------------------------- 1 | /* 2 | library name: MPU6050 6 axis module 3 | written by: T.Jaber 4 | Date Written: 25 Mar 2019 5 | Last Modified: 20 April 2019 by Mohamed Yaqoob 6 | Description: MPU6050 Module Basic Functions Device Driver library that use HAL libraries. 7 | References: 8 | - MPU6050 Registers map: https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf 9 | - Jeff Rowberg MPU6050 library: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050 10 | 11 | * Copyright (C) 2019 - T. Jaber 12 | This is a free software under the GNU license, you can redistribute it and/or modify it under the terms 13 | of the GNU General Public Licenseversion 3 as published by the Free Software Foundation. 14 | 15 | This software library is shared with puplic for educational purposes, without WARRANTY and Author is not liable for any damages caused directly 16 | or indirectly by this software, read more about this on the GNU General Public License. 17 | 18 | */ 19 | 20 | //Header files 21 | #include "TJ_MPU6050.h" 22 | 23 | //Library Variable 24 | //1- I2C Handle 25 | static I2C_HandleTypeDef i2cHandler; 26 | //2- Accel & Gyro Scaling Factor 27 | static float accelScalingFactor, gyroScalingFactor; 28 | //3- Bias varaibles 29 | static float A_X_Bias = 0.0f; 30 | static float A_Y_Bias = 0.0f; 31 | static float A_Z_Bias = 0.0f; 32 | 33 | static int16_t GyroRW[3]; 34 | 35 | //Fucntion Definitions 36 | //1- i2c Handler 37 | void MPU6050_Init(I2C_HandleTypeDef *I2Chnd) 38 | { 39 | //Copy I2C CubeMX handle to local library 40 | memcpy(&i2cHandler, I2Chnd, sizeof(*I2Chnd)); 41 | } 42 | 43 | //2- i2c Read 44 | void I2C_Read(uint8_t ADDR, uint8_t *i2cBif, uint8_t NofData) 45 | { 46 | uint8_t i2cBuf[2]; 47 | uint8_t MPUADDR; 48 | //Need to Shift address to make it proper to i2c operation 49 | MPUADDR = (MPU_ADDR<<1); 50 | i2cBuf[0] = ADDR; 51 | HAL_I2C_Master_Transmit(&i2cHandler, MPUADDR, i2cBuf, 1, 10); 52 | HAL_I2C_Master_Receive(&i2cHandler, MPUADDR, i2cBif, NofData, 100); 53 | } 54 | 55 | //3- i2c Write 56 | void I2C_Write8(uint8_t ADDR, uint8_t data) 57 | { 58 | uint8_t i2cData[2]; 59 | i2cData[0] = ADDR; 60 | i2cData[1] = data; 61 | uint8_t MPUADDR = (MPU_ADDR<<1); 62 | HAL_I2C_Master_Transmit(&i2cHandler, MPUADDR, i2cData, 2,100); 63 | } 64 | 65 | //4- MPU6050 Initialaztion Configuration 66 | void MPU6050_Config(MPU_ConfigTypeDef *config) 67 | { 68 | uint8_t Buffer = 0; 69 | //Clock Source 70 | //Reset Device 71 | I2C_Write8(PWR_MAGT_1_REG, 0x80); 72 | HAL_Delay(100); 73 | Buffer = config ->ClockSource & 0x07; //change the 7th bits of register 74 | Buffer |= (config ->Sleep_Mode_Bit << 6) &0x40; // change only the 7th bit in the register 75 | I2C_Write8(PWR_MAGT_1_REG, Buffer); 76 | HAL_Delay(100); // should wait 10ms after changeing the clock setting. 77 | 78 | //Set the Digital Low Pass Filter 79 | Buffer = 0; 80 | Buffer = config->CONFIG_DLPF & 0x07; 81 | I2C_Write8(CONFIG_REG, Buffer); 82 | 83 | //Select the Gyroscope Full Scale Range 84 | Buffer = 0; 85 | Buffer = (config->Gyro_Full_Scale << 3) & 0x18; 86 | I2C_Write8(GYRO_CONFIG_REG, Buffer); 87 | 88 | //Select the Accelerometer Full Scale Range 89 | Buffer = 0; 90 | Buffer = (config->Accel_Full_Scale << 3) & 0x18; 91 | I2C_Write8(ACCEL_CONFIG_REG, Buffer); 92 | //Set SRD To Default 93 | MPU6050_Set_SMPRT_DIV(0x04); 94 | 95 | 96 | //Accelerometer Scaling Factor, Set the Accelerometer and Gyroscope Scaling Factor 97 | switch (config->Accel_Full_Scale) 98 | { 99 | case AFS_SEL_2g: 100 | accelScalingFactor = (2000.0f/32768.0f); 101 | break; 102 | 103 | case AFS_SEL_4g: 104 | accelScalingFactor = (4000.0f/32768.0f); 105 | break; 106 | 107 | case AFS_SEL_8g: 108 | accelScalingFactor = (8000.0f/32768.0f); 109 | break; 110 | 111 | case AFS_SEL_16g: 112 | accelScalingFactor = (16000.0f/32768.0f); 113 | break; 114 | 115 | default: 116 | break; 117 | } 118 | //Gyroscope Scaling Factor 119 | switch (config->Gyro_Full_Scale) 120 | { 121 | case FS_SEL_250: 122 | gyroScalingFactor = 250.0f/32768.0f; 123 | break; 124 | 125 | case FS_SEL_500: 126 | gyroScalingFactor = 500.0f/32768.0f; 127 | break; 128 | 129 | case FS_SEL_1000: 130 | gyroScalingFactor = 1000.0f/32768.0f; 131 | break; 132 | 133 | case FS_SEL_2000: 134 | gyroScalingFactor = 2000.0f/32768.0f; 135 | break; 136 | 137 | default: 138 | break; 139 | } 140 | 141 | } 142 | 143 | //5- Get Sample Rate Divider 144 | uint8_t MPU6050_Get_SMPRT_DIV(void) 145 | { 146 | uint8_t Buffer = 0; 147 | 148 | I2C_Read(SMPLRT_DIV_REG, &Buffer, 1); 149 | return Buffer; 150 | } 151 | 152 | //6- Set Sample Rate Divider 153 | void MPU6050_Set_SMPRT_DIV(uint8_t SMPRTvalue) 154 | { 155 | I2C_Write8(SMPLRT_DIV_REG, SMPRTvalue); 156 | } 157 | 158 | //7- Get External Frame Sync. 159 | uint8_t MPU6050_Get_FSYNC(void) 160 | { 161 | uint8_t Buffer = 0; 162 | 163 | I2C_Read(CONFIG_REG, &Buffer, 1); 164 | Buffer &= 0x38; 165 | return (Buffer>>3); 166 | } 167 | 168 | //8- Set External Frame Sync. 169 | void MPU6050_Set_FSYNC(enum EXT_SYNC_SET_ENUM ext_Sync) 170 | { 171 | uint8_t Buffer = 0; 172 | I2C_Read(CONFIG_REG, &Buffer,1); 173 | Buffer &= ~0x38; 174 | 175 | Buffer |= (ext_Sync <<3); 176 | I2C_Write8(CONFIG_REG, Buffer); 177 | 178 | } 179 | 180 | //9- Get Accel Raw Data 181 | void MPU6050_Get_Accel_RawData(RawData_Def *rawDef) 182 | { 183 | uint8_t i2cBuf[2]; 184 | uint8_t AcceArr[6], GyroArr[6]; 185 | 186 | I2C_Read(INT_STATUS_REG, &i2cBuf[1],1); 187 | if((i2cBuf[1]&&0x01)) 188 | { 189 | I2C_Read(ACCEL_XOUT_H_REG, AcceArr,6); 190 | 191 | //Accel Raw Data 192 | rawDef->x = ((AcceArr[0]<<8) + AcceArr[1]); // x-Axis 193 | rawDef->y = ((AcceArr[2]<<8) + AcceArr[3]); // y-Axis 194 | rawDef->z = ((AcceArr[4]<<8) + AcceArr[5]); // z-Axis 195 | //Gyro Raw Data 196 | I2C_Read(GYRO_XOUT_H_REG, GyroArr,6); 197 | GyroRW[0] = ((GyroArr[0]<<8) + GyroArr[1]); 198 | GyroRW[1] = (GyroArr[2]<<8) + GyroArr[3]; 199 | GyroRW[2] = ((GyroArr[4]<<8) + GyroArr[5]); 200 | } 201 | } 202 | 203 | //10- Get Accel scaled data (g unit of gravity, 1g = 9.81m/s2) 204 | void MPU6050_Get_Accel_Scale(ScaledData_Def *scaledDef) 205 | { 206 | 207 | RawData_Def AccelRData; 208 | MPU6050_Get_Accel_RawData(&AccelRData); 209 | 210 | //Accel Scale data 211 | scaledDef->x = ((AccelRData.x+0.0f)*accelScalingFactor); 212 | scaledDef->y = ((AccelRData.y+0.0f)*accelScalingFactor); 213 | scaledDef->z = ((AccelRData.z+0.0f)*accelScalingFactor); 214 | } 215 | 216 | //11- Get Accel calibrated data 217 | void MPU6050_Get_Accel_Cali(ScaledData_Def *CaliDef) 218 | { 219 | ScaledData_Def AccelScaled; 220 | MPU6050_Get_Accel_Scale(&AccelScaled); 221 | 222 | //Accel Scale data 223 | CaliDef->x = (AccelScaled.x) - A_X_Bias; // x-Axis 224 | CaliDef->y = (AccelScaled.y) - A_Y_Bias;// y-Axis 225 | CaliDef->z = (AccelScaled.z) - A_Z_Bias;// z-Axis 226 | } 227 | //12- Get Gyro Raw Data 228 | void MPU6050_Get_Gyro_RawData(RawData_Def *rawDef) 229 | { 230 | 231 | //Accel Raw Data 232 | rawDef->x = GyroRW[0]; 233 | rawDef->y = GyroRW[1]; 234 | rawDef->z = GyroRW[2]; 235 | 236 | } 237 | 238 | //13- Get Gyro scaled data 239 | void MPU6050_Get_Gyro_Scale(ScaledData_Def *scaledDef) 240 | { 241 | RawData_Def myGyroRaw; 242 | MPU6050_Get_Gyro_RawData(&myGyroRaw); 243 | 244 | //Gyro Scale data 245 | scaledDef->x = (myGyroRaw.x)*gyroScalingFactor; // x-Axis 246 | scaledDef->y = (myGyroRaw.y)*gyroScalingFactor; // y-Axis 247 | scaledDef->z = (myGyroRaw.z)*gyroScalingFactor; // z-Axis 248 | } 249 | 250 | //14- Accel Calibration 251 | void _Accel_Cali(float x_min, float x_max, float y_min, float y_max, float z_min, float z_max) 252 | { 253 | //1* X-Axis calibrate 254 | A_X_Bias = (x_max + x_min)/2.0f; 255 | 256 | //2* Y-Axis calibrate 257 | A_Y_Bias = (y_max + y_min)/2.0f; 258 | 259 | //3* Z-Axis calibrate 260 | A_Z_Bias = (z_max + z_min)/2.0f; 261 | } 262 | -------------------------------------------------------------------------------- /Tutorial 35 - MPU6050 IMU Module/TJ_MPU6050.h: -------------------------------------------------------------------------------- 1 | /* 2 | library name: MPU6050 6 axis module 3 | written by: T.Jaber 4 | Date Written: 25 Mar 2019 5 | Last Modified: 20 April 2019 by Mohamed Yaqoob 6 | Description: MPU6050 Module Basic Functions Device Driver library that use HAL libraries. 7 | References: 8 | - MPU6050 Registers map: https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf 9 | - Jeff Rowberg MPU6050 library: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050 10 | 11 | * Copyright (C) 2019 - T. Jaber 12 | This is a free software under the GNU license, you can redistribute it and/or modify it under the terms 13 | of the GNU General Public Licenseversion 3 as published by the Free Software Foundation. 14 | 15 | This software library is shared with puplic for educational purposes, without WARRANTY and Author is not liable for any damages caused directly 16 | or indirectly by this software, read more about this on the GNU General Public License. 17 | 18 | */ 19 | 20 | //Header Files 21 | #include "stm32f4xx_hal.h" //dpending on your board 22 | #include 23 | #include //Boolean 24 | #include //Pow() 25 | 26 | //Define Registers 27 | #define WHO_AM_I_REG 0x75 28 | #define MPU_ADDR 0x68 29 | #define PWR_MAGT_1_REG 0x6B 30 | #define CONFIG_REG 0x1A 31 | #define GYRO_CONFIG_REG 0x1B 32 | #define ACCEL_CONFIG_REG 0x1C 33 | #define SMPLRT_DIV_REG 0x19 34 | #define INT_STATUS_REG 0x3A 35 | #define ACCEL_XOUT_H_REG 0x3B 36 | #define TEMP_OUT_H_REG 0x41 37 | #define GYRO_XOUT_H_REG 0x43 38 | #define FIFO_EN_REG 0x23 39 | #define INT_ENABLE_REG 0x38 40 | #define I2CMACO_REG 0x23 41 | #define USER_CNT_REG 0x6A 42 | #define FIFO_COUNTH_REG 0x72 43 | #define FIFO_R_W_REG 0x74 44 | 45 | //TypeDefs and Enums 46 | //1- MPU Configuration 47 | typedef struct 48 | { 49 | uint8_t ClockSource; 50 | uint8_t Gyro_Full_Scale; 51 | uint8_t Accel_Full_Scale; 52 | uint8_t CONFIG_DLPF; 53 | bool Sleep_Mode_Bit; 54 | 55 | }MPU_ConfigTypeDef; 56 | //2- Clock Source ENUM 57 | enum PM_CLKSEL_ENUM 58 | { 59 | Internal_8MHz = 0x00, 60 | X_Axis_Ref = 0x01, 61 | Y_Axis_Ref = 0x02, 62 | Z_Axis_Ref = 0x03, 63 | Ext_32_768KHz = 0x04, 64 | Ext_19_2MHz = 0x05, 65 | TIM_GENT_INREST = 0x07 66 | }; 67 | //3- Gyro Full Scale Range ENUM (deg/sec) 68 | enum gyro_FullScale_ENUM 69 | { 70 | FS_SEL_250 = 0x00, 71 | FS_SEL_500 = 0x01, 72 | FS_SEL_1000 = 0x02, 73 | FS_SEL_2000 = 0x03 74 | }; 75 | //4- Accelerometer Full Scale Range ENUM (1g = 9.81m/s2) 76 | enum accel_FullScale_ENUM 77 | { 78 | AFS_SEL_2g = 0x00, 79 | AFS_SEL_4g, 80 | AFS_SEL_8g, 81 | AFS_SEL_16g 82 | }; 83 | //5- Digital Low Pass Filter ENUM 84 | enum DLPF_CFG_ENUM 85 | { 86 | DLPF_260A_256G_Hz = 0x00, 87 | DLPF_184A_188G_Hz = 0x01, 88 | DLPF_94A_98G_Hz = 0x02, 89 | DLPF_44A_42G_Hz = 0x03, 90 | DLPF_21A_20G_Hz = 0x04, 91 | DLPF_10_Hz = 0x05, 92 | DLPF_5_Hz = 0x06 93 | }; 94 | //6- e external Frame Synchronization ENUM 95 | enum EXT_SYNC_SET_ENUM 96 | { 97 | input_Disable = 0x00, 98 | TEMP_OUT_L = 0x01, 99 | GYRO_XOUT_L = 0x02, 100 | GYRO_YOUT_L = 0x03, 101 | GYRO_ZOUT_L = 0x04, 102 | ACCEL_XOUT_L = 0x05, 103 | ACCEL_YOUT_L = 0x06, 104 | ACCEL_ZOUT_L = 0x07 105 | }; 106 | 107 | //7. Raw data typedef 108 | typedef struct 109 | { 110 | int16_t x; 111 | int16_t y; 112 | int16_t z; 113 | }RawData_Def; 114 | 115 | //8. Scaled data typedef 116 | typedef struct 117 | { 118 | float x; 119 | float y; 120 | float z; 121 | }ScaledData_Def; 122 | 123 | 124 | //Function Prototype 125 | //1- i2c Handler 126 | void MPU6050_Init(I2C_HandleTypeDef *I2Chnd); 127 | //2- i2c Read 128 | void I2C_Read(uint8_t ADDR, uint8_t *i2cBuf, uint8_t NofData); 129 | //3- i2c Write 8 Bit 130 | void I2C_Write8(uint8_t ADDR, uint8_t data); 131 | //4- MPU6050 Initialaztion Configuration 132 | void MPU6050_Config(MPU_ConfigTypeDef *config); 133 | //5- Get Sample Rate Divider 134 | uint8_t MPU6050_Get_SMPRT_DIV(void); 135 | //6- Set Sample Rate Divider 136 | void MPU6050_Set_SMPRT_DIV(uint8_t SMPRTvalue); 137 | //7- External Frame Sync. 138 | uint8_t MPU6050_Get_FSYNC(void); 139 | //8- Set External Frame Sync. 140 | void MPU6050_Set_FSYNC(enum EXT_SYNC_SET_ENUM ext_Sync); 141 | //9- Get Accel Raw Data 142 | void MPU6050_Get_Accel_RawData(RawData_Def *rawDef);//************ 143 | //10- Get Accel scaled data 144 | void MPU6050_Get_Accel_Scale(ScaledData_Def *scaledDef);//*********** 145 | //11- Get Accel calibrated data 146 | void MPU6050_Get_Accel_Cali(ScaledData_Def *CaliDef); 147 | //12- Get Gyro Raw Data 148 | void MPU6050_Get_Gyro_RawData(RawData_Def *rawDef); 149 | //13- Get Gyro scaled data 150 | void MPU6050_Get_Gyro_Scale(ScaledData_Def *scaledDef); 151 | //14- Accel Calibration 152 | void _Accel_Cali(float x_min, float x_max, float y_min, float y_max, float z_min, float z_max); 153 | -------------------------------------------------------------------------------- /Tutorial 37 - HC-SR05 Ultrasonic Sensor/STM32-Nucleo-F401RE-Pinout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MYaqoobEmbedded/STM32-Tutorials/bdf2c8e7722f267b5c7e8114462c66f59203704c/Tutorial 37 - HC-SR05 Ultrasonic Sensor/STM32-Nucleo-F401RE-Pinout.png -------------------------------------------------------------------------------- /Tutorial 38 - Printf UART debugging/printf perp doc.txt: -------------------------------------------------------------------------------- 1 | Part1: Keil 2 | -------------- 3 | Step(1): Generate normal CubeMX project 4 | Step(2): Add the following on top of main 5 | /* Private typedef -----------------------------------------------------------*/ 6 | /* USER CODE BEGIN PTD */ 7 | #ifdef __GNUC__ 8 | /* With GCC, small printf (option LD Linker->Libraries->Small printf 9 | set to 'Yes') calls __io_putchar() */ 10 | #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) 11 | #else 12 | #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) 13 | #endif /* __GNUC__ */ 14 | /* USER CODE END PTD */ 15 | 16 | Step(3): Add body definition of PUTCHAR_PROTOTYPE 17 | PUTCHAR_PROTOTYPE 18 | { 19 | /* Place your implementation of fputc here */ 20 | /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */ 21 | HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF); 22 | 23 | return ch; 24 | } 25 | 26 | Step(4): Add stdio header (to use printf) 27 | #include 28 | 29 | Step(5): Test printing hello world 30 | printf("Hello world\r\n"); 31 | 32 | Step(6): Test printing integer 33 | Step(7): Test printing float 34 | 35 | Part2: for GNU compiler (SW4STM32), need to add the following flag 36 | -------------------- 37 | Open your SW4STM32, go to: project -> properties > C/C+ build > Settings > MCU GCC Linker > Miscellaneous > Linker flags: add this flag: -u _printf_float 38 | -------------------------------------------------------------------------------- /Tutorial 41 - SD Card + FreeRTOS/SDIO_RTOS_Prep.txt: -------------------------------------------------------------------------------- 1 | //1. Header files 2 | #include //printf 3 | #include // 4 | 5 | //2. Printf 6 | #ifdef __GNUC__ 7 | /* With GCC, small printf (option LD Linker->Libraries->Small printf 8 | set to 'Yes') calls __io_putchar() */ 9 | #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) 10 | #else 11 | #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) 12 | #endif /* __GNUC__ */ 13 | 14 | PUTCHAR_PROTOTYPE 15 | { 16 | /* Place your implementation of fputc here */ 17 | /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */ 18 | HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF); 19 | 20 | return ch; 21 | } 22 | 23 | //3. fatfs.c extern variables 24 | extern char SDPath[4]; /* SD logical drive path */ 25 | extern FATFS SDFatFS; /* File system object for SD logical drive */ 26 | extern FIL SDFile; /* File object for SD */ 27 | 28 | //4. FILE I/O variables 29 | FRESULT res; /* FatFs function common result code */ 30 | uint32_t byteswritten, bytesread; /* File write/read counts */ 31 | uint8_t wtext[] = "Hello from Mohamed :), xx"; /* File write buffer */ 32 | uint8_t rtext[100]; /* File read buffer */ 33 | 34 | //5. File Operations 35 | if(f_mount(&SDFatFS, (TCHAR const*)SDPath, 0) != FR_OK) 36 | { 37 | //Error 38 | printf("Error Mounting SD Card\r\n"); 39 | } 40 | //OK 41 | else printf("SD Card mounted successfully!\r\n"); 42 | HAL_Delay(200); 43 | 44 | //Open file for writing (Create) 45 | if(f_open(&SDFile, "F7FILE2.TXT", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) 46 | { 47 | //Error 48 | printf("Error openning file\r\n"); 49 | } 50 | else 51 | { 52 | printf("File Openned Successfully!\r\n"); 53 | 54 | //Write to the text file 55 | res = f_write(&SDFile, wtext, strlen((char *)wtext), (void *)&byteswritten); 56 | if((byteswritten == 0) || (res != FR_OK)) 57 | { 58 | printf("Failed to write file!\r\n"); 59 | } 60 | else printf("File written successfully\r\n"); 61 | 62 | f_close(&SDFile); 63 | 64 | //Test read file 65 | f_open(&SDFile, "F7FILE2.TXT", FA_READ); 66 | memset(rtext,0,sizeof(rtext)); 67 | res = f_read(&SDFile, rtext, sizeof(rtext), (UINT*)&bytesread); 68 | if((bytesread == 0) || (res != FR_OK)) 69 | { 70 | printf("Failed to read file!\r\n"); 71 | } 72 | else 73 | { 74 | printf("File read successfully\r\n"); 75 | printf("File content: %s\r\n", (char *)rtext); 76 | } 77 | f_close(&SDFile); 78 | } 79 | f_mount(&SDFatFS, (TCHAR const*)NULL, 0); 80 | -------------------------------------------------------------------------------- /Tutorial 42 - LCD16x2 I2C/-u _printf_float: -------------------------------------------------------------------------------- 1 | -u_printf_float -------------------------------------------------------------------------------- /Tutorial 42 - LCD16x2 I2C/lcd16x2_i2c.c: -------------------------------------------------------------------------------- 1 | /* 2 | * lcd16x2_i2c.c 3 | * 4 | * Created on: Mar 28, 2020 5 | * Author: Mohamed Yaqoob 6 | */ 7 | 8 | #include "lcd16x2_i2c.h" 9 | #include 10 | #include 11 | #include 12 | 13 | /* LCD Commands */ 14 | #define LCD_CLEARDISPLAY 0x01 15 | #define LCD_RETURNHOME 0x02 16 | #define LCD_ENTRYMODESET 0x04 17 | #define LCD_DISPLAYCONTROL 0x08 18 | #define LCD_CURSORSHIFT 0x10 19 | #define LCD_FUNCTIONSET 0x20 20 | #define LCD_SETCGRAMADDR 0x40 21 | #define LCD_SETDDRAMADDR 0x80 22 | 23 | /* Commands bitfields */ 24 | //1) Entry mode Bitfields 25 | #define LCD_ENTRY_SH 0x01 26 | #define LCD_ENTRY_ID 0x02 27 | //2) Display control 28 | #define LCD_DISPLAY_B 0x01 29 | #define LCD_DISPLAY_C 0x02 30 | #define LCD_DISPLAY_D 0x04 31 | //3) Shift control 32 | #define LCD_SHIFT_RL 0x04 33 | #define LCD_SHIFT_SC 0x08 34 | //4) Function set control 35 | #define LCD_FUNCTION_F 0x04 36 | #define LCD_FUNCTION_N 0x08 37 | #define LCD_FUNCTION_DL 0x10 38 | 39 | /* I2C Control bits */ 40 | #define LCD_RS (1 << 0) 41 | #define LCD_RW (1 << 1) 42 | #define LCD_EN (1 << 2) 43 | #define LCD_BK_LIGHT (1 << 3) 44 | 45 | /* Library variables */ 46 | static I2C_HandleTypeDef* lcd16x2_i2cHandle; 47 | static uint8_t LCD_I2C_SLAVE_ADDRESS=0; 48 | #define LCD_I2C_SLAVE_ADDRESS_0 0x4E 49 | #define LCD_I2C_SLAVE_ADDRESS_1 0x7E 50 | 51 | /* Private functions */ 52 | static void lcd16x2_i2c_sendCommand(uint8_t command) 53 | { 54 | const uint8_t command_0_3 = (0xF0 & (command<<4)); 55 | const uint8_t command_4_7 = (0xF0 & command); 56 | uint8_t i2cData[4] = 57 | { 58 | command_4_7 | LCD_EN | LCD_BK_LIGHT, 59 | command_4_7 | LCD_BK_LIGHT, 60 | command_0_3 | LCD_EN | LCD_BK_LIGHT, 61 | command_0_3 | LCD_BK_LIGHT, 62 | }; 63 | HAL_I2C_Master_Transmit(lcd16x2_i2cHandle, LCD_I2C_SLAVE_ADDRESS, i2cData, 4, 200); 64 | } 65 | 66 | static void lcd16x2_i2c_sendData(uint8_t data) 67 | { 68 | const uint8_t data_0_3 = (0xF0 & (data<<4)); 69 | const uint8_t data_4_7 = (0xF0 & data); 70 | uint8_t i2cData[4] = 71 | { 72 | data_4_7 | LCD_EN | LCD_BK_LIGHT | LCD_RS, 73 | data_4_7 | LCD_BK_LIGHT | LCD_RS, 74 | data_0_3 | LCD_EN | LCD_BK_LIGHT | LCD_RS, 75 | data_0_3 | LCD_BK_LIGHT | LCD_RS, 76 | }; 77 | HAL_I2C_Master_Transmit(lcd16x2_i2cHandle, LCD_I2C_SLAVE_ADDRESS, i2cData, 4, 200); 78 | } 79 | 80 | 81 | /** 82 | * @brief Initialise LCD16x2 83 | * @param[in] *pI2cHandle - pointer to HAL I2C handle 84 | */ 85 | bool lcd16x2_i2c_init(I2C_HandleTypeDef *pI2cHandle) 86 | { 87 | HAL_Delay(50); 88 | lcd16x2_i2cHandle = pI2cHandle; 89 | if(HAL_I2C_IsDeviceReady(lcd16x2_i2cHandle, LCD_I2C_SLAVE_ADDRESS_0, 5, 500) != HAL_OK) 90 | { 91 | if(HAL_I2C_IsDeviceReady(lcd16x2_i2cHandle, LCD_I2C_SLAVE_ADDRESS_1, 5, 500) != HAL_OK) 92 | { 93 | return false; 94 | } 95 | else 96 | { 97 | LCD_I2C_SLAVE_ADDRESS = LCD_I2C_SLAVE_ADDRESS_1; 98 | } 99 | } 100 | else 101 | { 102 | LCD_I2C_SLAVE_ADDRESS = LCD_I2C_SLAVE_ADDRESS_0; 103 | } 104 | //Initialise LCD for 4-bit operation 105 | //1. Wait at least 15ms 106 | HAL_Delay(45); 107 | //2. Attentions sequence 108 | lcd16x2_i2c_sendCommand(0x30); 109 | HAL_Delay(5); 110 | lcd16x2_i2c_sendCommand(0x30); 111 | HAL_Delay(1); 112 | lcd16x2_i2c_sendCommand(0x30); 113 | HAL_Delay(8); 114 | lcd16x2_i2c_sendCommand(0x20); 115 | HAL_Delay(8); 116 | 117 | lcd16x2_i2c_sendCommand(LCD_FUNCTIONSET | LCD_FUNCTION_N); 118 | HAL_Delay(1); 119 | lcd16x2_i2c_sendCommand(LCD_DISPLAYCONTROL); 120 | HAL_Delay(1); 121 | lcd16x2_i2c_sendCommand(LCD_CLEARDISPLAY); 122 | HAL_Delay(3); 123 | lcd16x2_i2c_sendCommand(0x04 | LCD_ENTRY_ID); 124 | HAL_Delay(1); 125 | lcd16x2_i2c_sendCommand(LCD_DISPLAYCONTROL | LCD_DISPLAY_D); 126 | HAL_Delay(3); 127 | 128 | return true; 129 | } 130 | 131 | /** 132 | * @brief Set cursor position 133 | * @param[in] row - 0 or 1 for line1 or line2 134 | * @param[in] col - 0 - 15 (16 columns LCD) 135 | */ 136 | void lcd16x2_i2c_setCursor(uint8_t row, uint8_t col) 137 | { 138 | uint8_t maskData; 139 | maskData = (col)&0x0F; 140 | if(row==0) 141 | { 142 | maskData |= (0x80); 143 | lcd16x2_i2c_sendCommand(maskData); 144 | } 145 | else 146 | { 147 | maskData |= (0xc0); 148 | lcd16x2_i2c_sendCommand(maskData); 149 | } 150 | } 151 | 152 | /** 153 | * @brief Move to beginning of 1st line 154 | */ 155 | void lcd16x2_i2c_1stLine(void) 156 | { 157 | lcd16x2_i2c_setCursor(0,0); 158 | } 159 | /** 160 | * @brief Move to beginning of 2nd line 161 | */ 162 | void lcd16x2_i2c_2ndLine(void) 163 | { 164 | lcd16x2_i2c_setCursor(1,0); 165 | } 166 | 167 | /** 168 | * @brief Select LCD Number of lines mode 169 | */ 170 | void lcd16x2_i2c_TwoLines(void) 171 | { 172 | lcd16x2_i2c_sendCommand(LCD_FUNCTIONSET | LCD_FUNCTION_N); 173 | } 174 | void lcd16x2_i2c_OneLine(void) 175 | { 176 | lcd16x2_i2c_sendCommand(LCD_FUNCTIONSET); 177 | } 178 | 179 | /** 180 | * @brief Cursor ON/OFF 181 | */ 182 | void lcd16x2_i2c_cursorShow(bool state) 183 | { 184 | if(state) 185 | { 186 | lcd16x2_i2c_sendCommand(LCD_DISPLAYCONTROL | LCD_DISPLAY_B | LCD_DISPLAY_C | LCD_DISPLAY_D); 187 | } 188 | else 189 | { 190 | lcd16x2_i2c_sendCommand(LCD_DISPLAYCONTROL | LCD_DISPLAY_D); 191 | } 192 | } 193 | 194 | /** 195 | * @brief Display clear 196 | */ 197 | void lcd16x2_i2c_clear(void) 198 | { 199 | lcd16x2_i2c_sendCommand(LCD_CLEARDISPLAY); 200 | HAL_Delay(3); 201 | } 202 | 203 | /** 204 | * @brief Display ON/OFF, to hide all characters, but not clear 205 | */ 206 | void lcd16x2_i2c_display(bool state) 207 | { 208 | if(state) 209 | { 210 | lcd16x2_i2c_sendCommand(LCD_DISPLAYCONTROL | LCD_DISPLAY_B | LCD_DISPLAY_C | LCD_DISPLAY_D); 211 | } 212 | else 213 | { 214 | lcd16x2_i2c_sendCommand(LCD_DISPLAYCONTROL | LCD_DISPLAY_B | LCD_DISPLAY_C); 215 | } 216 | } 217 | 218 | /** 219 | * @brief Shift content to right 220 | */ 221 | void lcd16x2_i2c_shiftRight(uint8_t offset) 222 | { 223 | for(uint8_t i=0; i 13 | 14 | /* Function prototypes */ 15 | /** 16 | * @brief Initialise LCD16x2 17 | * @param[in] *pI2cHandle - pointer to HAL I2C handle 18 | */ 19 | bool lcd16x2_i2c_init(I2C_HandleTypeDef *pI2cHandle); 20 | 21 | /** 22 | * @brief Set cursor position 23 | * @param[in] row - 0 or 1 for line1 or line2 24 | * @param[in] col - 0 - 15 (16 columns LCD) 25 | */ 26 | void lcd16x2_i2c_setCursor(uint8_t row, uint8_t col); 27 | /** 28 | * @brief Move to beginning of 1st line 29 | */ 30 | void lcd16x2_i2c_1stLine(void); 31 | /** 32 | * @brief Move to beginning of 2nd line 33 | */ 34 | void lcd16x2_i2c_2ndLine(void); 35 | 36 | /** 37 | * @brief Select LCD Number of lines mode 38 | */ 39 | void lcd16x2_i2c_TwoLines(void); 40 | void lcd16x2_i2c_OneLine(void); 41 | 42 | /** 43 | * @brief Cursor ON/OFF 44 | */ 45 | void lcd16x2_i2c_cursorShow(bool state); 46 | 47 | /** 48 | * @brief Display clear 49 | */ 50 | void lcd16x2_i2c_clear(void); 51 | 52 | /** 53 | * @brief Display ON/OFF, to hide all characters, but not cl/* 54 | * lcd16x2_i2c.c 55 | * 56 | * Created on: Mar 28, 2020 57 | * Author: Mohamed Yaqoob 58 | */ 59 | 60 | #include "lcd16x2_i2c.h" 61 | #include 62 | #include 63 | #include 64 | 65 | /* LCD Commands */ 66 | #define LCD_CLEARDISPLAY 0x01 67 | #define LCD_RETURNHOME 0x02 68 | #define LCD_ENTRYMODESET 0x04 69 | #define LCD_DISPLAYCONTROL 0x08 70 | #define LCD_CURSORSHIFT 0x10 71 | #define LCD_FUNCTIONSET 0x20 72 | #define LCD_SETCGRAMADDR 0x40 73 | #define LCD_SETDDRAMADDR 0x80 74 | 75 | /* Commands bitfields */ 76 | //1) Entry mode Bitfields 77 | #define LCD_ENTRY_SH 0x01 78 | #define LCD_ENTRY_ID 0x02 79 | //2) Display control 80 | #define LCD_DISPLAY_B 0x01 81 | #define LCD_DISPLAY_C 0x02 82 | #define LCD_DISPLAY_D 0x04 83 | //3) Shift control 84 | #define LCD_SHIFT_RL 0x04 85 | #define LCD_SHIFT_SC 0x08 86 | //4) Function set control 87 | #define LCD_FUNCTION_F 0x04 88 | #define LCD_FUNCTION_N 0x08 89 | #define LCD_FUNCTION_DL 0x10 90 | 91 | /* I2C Control bits */ 92 | #define LCD_RS (1 << 0) 93 | #define LCD_RW (1 << 1) 94 | #define LCD_EN (1 << 2) 95 | #define LCD_BK_LIGHT (1 << 3) 96 | 97 | /* Library variables */ 98 | static I2C_HandleTypeDef* lcd16x2_i2cHandle; 99 | static uint8_t LCD_I2C_SLAVE_ADDRESS=0; 100 | #define LCD_I2C_SLAVE_ADDRESS_0 0x4E 101 | #define LCD_I2C_SLAVE_ADDRESS_1 0x7E 102 | 103 | /* Private functions */ 104 | static void lcd16x2_i2c_sendCommand(uint8_t command) 105 | { 106 | const uint8_t command_0_3 = (0xF0 & (command<<4)); 107 | const uint8_t command_4_7 = (0xF0 & command); 108 | uint8_t i2cData[4] = 109 | { 110 | command_4_7 | LCD_EN | LCD_BK_LIGHT, 111 | command_4_7 | LCD_BK_LIGHT, 112 | command_0_3 | LCD_EN | LCD_BK_LIGHT, 113 | command_0_3 | LCD_BK_LIGHT, 114 | }; 115 | HAL_I2C_Master_Transmit(lcd16x2_i2cHandle, LCD_I2C_SLAVE_ADDRESS, i2cData, 4, 200); 116 | } 117 | 118 | static void lcd16x2_i2c_sendData(uint8_t data) 119 | { 120 | const uint8_t data_0_3 = (0xF0 & (data<<4)); 121 | const uint8_t data_4_7 = (0xF0 & data); 122 | uint8_t i2cData[4] = 123 | { 124 | data_4_7 | LCD_EN | LCD_BK_LIGHT | LCD_RS, 125 | data_4_7 | LCD_BK_LIGHT | LCD_RS, 126 | data_0_3 | LCD_EN | LCD_BK_LIGHT | LCD_RS, 127 | data_0_3 | LCD_BK_LIGHT | LCD_RS, 128 | }; 129 | HAL_I2C_Master_Transmit(lcd16x2_i2cHandle, LCD_I2C_SLAVE_ADDRESS, i2cData, 4, 200); 130 | } 131 | 132 | 133 | /** 134 | * @brief Initialise LCD16x2 135 | * @param[in] *pI2cHandle - pointer to HAL I2C handle 136 | */ 137 | bool lcd16x2_i2c_init(I2C_HandleTypeDef *pI2cHandle) 138 | { 139 | HAL_Delay(50); 140 | lcd16x2_i2cHandle = pI2cHandle; 141 | if(HAL_I2C_IsDeviceReady(lcd16x2_i2cHandle, LCD_I2C_SLAVE_ADDRESS_0, 5, 500) != HAL_OK) 142 | { 143 | if(HAL_I2C_IsDeviceReady(lcd16x2_i2cHandle, LCD_I2C_SLAVE_ADDRESS_1, 5, 500) != HAL_OK) 144 | { 145 | return false; 146 | } 147 | else 148 | { 149 | LCD_I2C_SLAVE_ADDRESS = LCD_I2C_SLAVE_ADDRESS_1; 150 | } 151 | } 152 | else 153 | { 154 | LCD_I2C_SLAVE_ADDRESS = LCD_I2C_SLAVE_ADDRESS_0; 155 | } 156 | //Initialise LCD for 4-bit operation 157 | //1. Wait at least 15ms 158 | HAL_Delay(45); 159 | //2. Attentions sequence 160 | lcd16x2_i2c_sendCommand(0x30); 161 | HAL_Delay(5); 162 | lcd16x2_i2c_sendCommand(0x30); 163 | HAL_Delay(1); 164 | lcd16x2_i2c_sendCommand(0x30); 165 | HAL_Delay(8); 166 | lcd16x2_i2c_sendCommand(0x20); 167 | HAL_Delay(8); 168 | 169 | lcd16x2_i2c_sendCommand(LCD_FUNCTIONSET | LCD_FUNCTION_N); 170 | HAL_Delay(1); 171 | lcd16x2_i2c_sendCommand(LCD_DISPLAYCONTROL); 172 | HAL_Delay(1); 173 | lcd16x2_i2c_sendCommand(LCD_CLEARDISPLAY); 174 | HAL_Delay(3); 175 | lcd16x2_i2c_sendCommand(0x04 | LCD_ENTRY_ID); 176 | HAL_Delay(1); 177 | lcd16x2_i2c_sendCommand(LCD_DISPLAYCONTROL | LCD_DISPLAY_D); 178 | HAL_Delay(3); 179 | 180 | return true; 181 | } 182 | 183 | /** 184 | * @brief Set cursor position 185 | * @param[in] row - 0 or 1 for line1 or line2 186 | * @param[in] col - 0 - 15 (16 columns LCD) 187 | */ 188 | void lcd16x2_i2c_setCursor(uint8_t row, uint8_t col) 189 | { 190 | uint8_t maskData; 191 | maskData = (col)&0x0F; 192 | if(row==0) 193 | { 194 | maskData |= (0x80); 195 | lcd16x2_i2c_sendCommand(maskData); 196 | } 197 | else 198 | { 199 | maskData |= (0xc0); 200 | lcd16x2_i2c_sendCommand(maskData); 201 | } 202 | } 203 | 204 | /** 205 | * @brief Move to beginning of 1st line 206 | */ 207 | void lcd16x2_i2c_1stLine(void) 208 | { 209 | lcd16x2_i2c_setCursor(0,0); 210 | } 211 | /** 212 | * @brief Move to beginning of 2nd line 213 | */ 214 | void lcd16x2_i2c_2ndLine(void) 215 | { 216 | lcd16x2_i2c_setCursor(1,0); 217 | } 218 | 219 | /** 220 | * @brief Select LCD Number of lines mode 221 | */ 222 | void lcd16x2_i2c_TwoLines(void) 223 | { 224 | lcd16x2_i2c_sendCommand(LCD_FUNCTIONSET | LCD_FUNCTION_N); 225 | } 226 | void lcd16x2_i2c_OneLine(void) 227 | { 228 | lcd16x2_i2c_sendCommand(LCD_FUNCTIONSET); 229 | } 230 | 231 | /** 232 | * @brief Cursor ON/OFF 233 | */ 234 | void lcd16x2_i2c_cursorShow(bool state) 235 | { 236 | if(state) 237 | { 238 | lcd16x2_i2c_sendCommand(LCD_DISPLAYCONTROL | LCD_DISPLAY_B | LCD_DISPLAY_C | LCD_DISPLAY_D); 239 | } 240 | else 241 | { 242 | lcd16x2_i2c_sendCommand(LCD_DISPLAYCONTROL | LCD_DISPLAY_D); 243 | } 244 | } 245 | 246 | /** 247 | * @brief Display clear 248 | */ 249 | void lcd16x2_i2c_clear(void) 250 | { 251 | lcd16x2_i2c_sendCommand(LCD_CLEARDISPLAY); 252 | HAL_Delay(3); 253 | } 254 | 255 | /** 256 | * @brief Display ON/OFF, to hide all characters, but not clear 257 | */ 258 | void lcd16x2_i2c_display(bool state) 259 | { 260 | if(state) 261 | { 262 | lcd16x2_i2c_sendCommand(LCD_DISPLAYCONTROL | LCD_DISPLAY_B | LCD_DISPLAY_C | LCD_DISPLAY_D); 263 | } 264 | else 265 | { 266 | lcd16x2_i2c_sendCommand(LCD_DISPLAYCONTROL | LCD_DISPLAY_B | LCD_DISPLAY_C); 267 | } 268 | } 269 | 270 | /** 271 | * @brief Shift content to right 272 | */ 273 | void lcd16x2_i2c_shiftRight(uint8_t offset) 274 | { 275 | for(uint8_t i=0; i= 231 && (volume) <=255)? (volume-231) : (volume+25)) 57 | 58 | //1. Mode Select Enum 59 | typedef enum 60 | { 61 | MODE_I2S = 0, 62 | MODE_ANALOG, 63 | }CS43_MODE; 64 | 65 | 66 | //(3): List of the functions prototypes 67 | void CS43_Init(I2C_HandleTypeDef i2c_handle, CS43_MODE outputMode); 68 | void CS43_Enable_RightLeft(uint8_t side); 69 | void CS43_SetVolume(uint8_t volume); 70 | void CS43_SetMute(bool mute); 71 | void CS43_Start(void); 72 | void CS43_Stop(void); 73 | -------------------------------------------------------------------------------- /Tutorial 43 - WAV Player/Audio/audioI2S.c: -------------------------------------------------------------------------------- 1 | /* 2 | * audioI2S.c 3 | * 4 | * Created on: 17 Apr 2020 5 | * Author: Mohamed Yaqoob 6 | */ 7 | 8 | #include "audioI2S.h" 9 | #include "MY_CS43L22.h" 10 | #include "stm32f4xx_hal.h" 11 | 12 | //I2S PLL parameters for different I2S Sampling Frequency 13 | const uint32_t I2SFreq[8] = {8000, 11025, 16000, 22050, 32000, 44100, 48000, 96000}; 14 | const uint32_t I2SPLLN[8] = {256, 429, 213, 429, 426, 271, 258, 344}; 15 | const uint32_t I2SPLLR[8] = {5, 4, 4, 4, 4, 6, 3, 1}; 16 | 17 | static I2S_HandleTypeDef *hAudioI2S; 18 | 19 | //Static functions 20 | 21 | /** 22 | * @brief I2S Clock Config 23 | */ 24 | static void audioI2S_pllClockConfig(uint32_t audioFreq) 25 | { 26 | RCC_PeriphCLKInitTypeDef rccclkinit; 27 | uint8_t index = 0, freqindex = 0xFF; 28 | 29 | for(index = 0; index < 8; index++) 30 | { 31 | if(I2SFreq[index] == audioFreq) 32 | { 33 | freqindex = index; 34 | } 35 | } 36 | /* Enable PLLI2S clock */ 37 | HAL_RCCEx_GetPeriphCLKConfig(&rccclkinit); 38 | /* PLLI2S_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */ 39 | if ((freqindex & 0x7) == 0) 40 | { 41 | /* I2S clock config 42 | PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLM) 43 | I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ 44 | rccclkinit.PeriphClockSelection = RCC_PERIPHCLK_I2S; 45 | rccclkinit.PLLI2S.PLLI2SN = I2SPLLN[freqindex]; 46 | rccclkinit.PLLI2S.PLLI2SR = I2SPLLR[freqindex]; 47 | HAL_RCCEx_PeriphCLKConfig(&rccclkinit); 48 | } 49 | else 50 | { 51 | /* I2S clock config 52 | PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLM) 53 | I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ 54 | rccclkinit.PeriphClockSelection = RCC_PERIPHCLK_I2S; 55 | rccclkinit.PLLI2S.PLLI2SN = 258; 56 | rccclkinit.PLLI2S.PLLI2SR = 3; 57 | HAL_RCCEx_PeriphCLKConfig(&rccclkinit); 58 | } 59 | } 60 | 61 | /** 62 | * @brief update I2S peripheral with selected Sampling Frequency 63 | */ 64 | static bool I2S3_freqUpdate(uint32_t AudioFreq) 65 | { 66 | /* Initialize the hAudioOutI2s Instance parameter */ 67 | hAudioI2S->Instance = SPI3; 68 | 69 | /* Disable I2S block */ 70 | __HAL_I2S_DISABLE(hAudioI2S); 71 | 72 | /* I2S3 peripheral configuration */ 73 | hAudioI2S->Init.AudioFreq = AudioFreq; 74 | hAudioI2S->Init.ClockSource = I2S_CLOCK_PLL; 75 | hAudioI2S->Init.CPOL = I2S_CPOL_LOW; 76 | hAudioI2S->Init.DataFormat = I2S_DATAFORMAT_16B; 77 | hAudioI2S->Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE; 78 | hAudioI2S->Init.Mode = I2S_MODE_MASTER_TX; 79 | hAudioI2S->Init.Standard = I2S_STANDARD_PHILIPS; 80 | /* Initialize the I2S peripheral with the structure above */ 81 | if(HAL_I2S_Init(hAudioI2S) != HAL_OK) 82 | { 83 | return false; 84 | } 85 | else 86 | { 87 | return true; 88 | } 89 | } 90 | 91 | /** 92 | * @brief set I2S HAL handle 93 | */ 94 | void audioI2S_setHandle(I2S_HandleTypeDef *pI2Shandle) 95 | { 96 | hAudioI2S = pI2Shandle; 97 | } 98 | 99 | /* I2S Audio library function definitions */ 100 | /** 101 | * @brief Initialises I2S Audio settings 102 | * @param audioFreq - WAV file Audio sampling rate (44.1KHz, 48KHz, ...) 103 | * @param volume - CS43L22 Codec volume settings (0 - 100) 104 | * @retval state - true: Successfully, false: Failed 105 | */ 106 | bool audioI2S_init(uint32_t audioFreq) 107 | { 108 | //Update PLL Clock Frequency setting 109 | audioI2S_pllClockConfig(audioFreq); 110 | //Update I2S peripheral sampling frequency 111 | I2S3_freqUpdate(audioFreq); 112 | return true; 113 | } 114 | 115 | /** 116 | * @brief Starts Playing Audio from buffer 117 | */ 118 | bool audioI2S_play(uint16_t* pDataBuf, uint32_t len) 119 | { 120 | //Start Codec 121 | CS43_Start(); 122 | //Start I2S DMA transfer 123 | HAL_I2S_Transmit_DMA(hAudioI2S, pDataBuf, DMA_MAX(len/AUDIODATA_SIZE)); 124 | return true; 125 | } 126 | 127 | /** 128 | * @brief Change I2S DMA Buffer pointer 129 | */ 130 | bool audioI2S_changeBuffer(uint16_t* pDataBuf, uint32_t len) 131 | { 132 | HAL_I2S_Transmit_DMA(hAudioI2S, pDataBuf, DMA_MAX(len)); 133 | return true; 134 | } 135 | 136 | /** 137 | * @brief Pause audio out 138 | */ 139 | void audioI2S_pause(void) 140 | { 141 | CS43_Stop(); 142 | HAL_I2S_DMAPause(hAudioI2S); 143 | } 144 | 145 | /** 146 | * @brief Resume audio out 147 | */ 148 | void audioI2S_resume(void) 149 | { 150 | CS43_Start(); 151 | HAL_I2S_DMAResume(hAudioI2S); 152 | } 153 | 154 | /** 155 | * @brief Set Volume 156 | */ 157 | void audioI2S_setVolume(uint8_t volume) 158 | { 159 | CS43_SetVolume(volume); 160 | } 161 | 162 | /** 163 | * @brief Stop audio 164 | */ 165 | void audioI2S_stop(void) 166 | { 167 | CS43_Stop(); 168 | HAL_I2S_DMAStop(hAudioI2S); 169 | } 170 | 171 | /** 172 | * @brief Half/Full transfer Audio callback for buffer management 173 | */ 174 | __weak void audioI2S_halfTransfer_Callback(void) 175 | { 176 | 177 | } 178 | __weak void audioI2S_fullTransfer_Callback(void) 179 | { 180 | 181 | } 182 | 183 | void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s) 184 | { 185 | if(hi2s->Instance == SPI3) 186 | { 187 | audioI2S_fullTransfer_Callback(); 188 | } 189 | } 190 | 191 | void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s) 192 | { 193 | if(hi2s->Instance == SPI3) 194 | { 195 | audioI2S_halfTransfer_Callback(); 196 | } 197 | } 198 | 199 | -------------------------------------------------------------------------------- /Tutorial 43 - WAV Player/Audio/audioI2S.h: -------------------------------------------------------------------------------- 1 | /* 2 | * audioI2S.h 3 | * 4 | * Created on: 17 Apr 2020 5 | * Author: Mohamed Yaqoob 6 | */ 7 | 8 | #ifndef AUDIOI2S_H_ 9 | #define AUDIOI2S_H_ 10 | 11 | #include "stm32f4xx_hal.h" 12 | #include "stdbool.h" 13 | 14 | //Audio library defines 15 | #define DMA_MAX_SZE 0xFFFF 16 | #define DMA_MAX(_X_) (((_X_) <= DMA_MAX_SZE)? (_X_):DMA_MAX_SZE) 17 | #define AUDIODATA_SIZE 2 /* 16-bits audio data size */ 18 | 19 | /* I2S Audio library function prototypes */ 20 | 21 | /** 22 | * @brief set I2S HAL handle 23 | */ 24 | void audioI2S_setHandle(I2S_HandleTypeDef *pI2Shandle); 25 | 26 | /** 27 | * @brief Initialises I2S Audio settings 28 | * @param audioFreq - WAV file Audio sampling rate (44.1KHz, 48KHz, ...) 29 | * @param volume - CS43L22 Codec volume settings (0 - 100) 30 | * @retval state - true: Successfully, false: Failed 31 | */ 32 | bool audioI2S_init(uint32_t audioFreq); 33 | 34 | /** 35 | * @brief Starts Playing Audio from buffer 36 | */ 37 | bool audioI2S_play(uint16_t* pDataBuf, uint32_t len); 38 | 39 | /** 40 | * @brief Change I2S DMA Buffer pointer 41 | */ 42 | bool audioI2S_changeBuffer(uint16_t* pDataBuf, uint32_t len); 43 | 44 | /** 45 | * @brief Pause audio out 46 | */ 47 | void audioI2S_pause(void); 48 | 49 | /** 50 | * @brief Resume audio out 51 | */ 52 | void audioI2S_resume(void); 53 | 54 | /** 55 | * @brief Set Volume 56 | */ 57 | void audioI2S_setVolume(uint8_t volume); 58 | 59 | /** 60 | * @brief Stop audio 61 | */ 62 | void audioI2S_stop(void); 63 | 64 | /** 65 | * @brief Half/Full transfer Audio callback for buffer management 66 | */ 67 | void audioI2S_halfTransfer_Callback(void); 68 | void audioI2S_fullTransfer_Callback(void); 69 | 70 | 71 | #endif /* AUDIOI2S_H_ */ 72 | -------------------------------------------------------------------------------- /Tutorial 43 - WAV Player/Audio/wav_player.c: -------------------------------------------------------------------------------- 1 | /* 2 | * wav_player.c 3 | * 4 | * Created on: 17 Apr 2020 5 | * Author: Mohamed Yaqoob 6 | */ 7 | 8 | #include "wav_player.h" 9 | #include "audioI2S.h" 10 | #include "fatfs.h" 11 | 12 | //WAV File System variables 13 | static FIL wavFile; 14 | 15 | //WAV Audio Buffer 16 | static uint32_t fileLength; 17 | #define AUDIO_BUFFER_SIZE 4096*1 18 | static uint8_t audioBuffer[AUDIO_BUFFER_SIZE]; 19 | static __IO uint32_t audioRemainSize = 0; 20 | 21 | //WAV Player 22 | static uint32_t samplingFreq; 23 | static UINT playerReadBytes = 0; 24 | static bool isFinished=0; 25 | //WAV Player process states 26 | typedef enum 27 | { 28 | PLAYER_CONTROL_Idle=0, 29 | PLAYER_CONTROL_HalfBuffer, 30 | PLAYER_CONTROL_FullBuffer, 31 | PLAYER_CONTROL_EndOfFile, 32 | }PLAYER_CONTROL_e; 33 | static volatile PLAYER_CONTROL_e playerControlSM = PLAYER_CONTROL_Idle; 34 | 35 | static void wavPlayer_reset(void) 36 | { 37 | audioRemainSize = 0; 38 | playerReadBytes = 0; 39 | } 40 | 41 | /** 42 | * @brief Select WAV file to play 43 | * @retval returns true when file is found in USB Drive 44 | */ 45 | bool wavPlayer_fileSelect(const char* filePath) 46 | { 47 | WAV_HeaderTypeDef wavHeader; 48 | UINT readBytes = 0; 49 | //Open WAV file 50 | if(f_open(&wavFile, filePath, FA_READ) != FR_OK) 51 | { 52 | return false; 53 | } 54 | //Read WAV file Header 55 | f_read(&wavFile, &wavHeader, sizeof(wavHeader), &readBytes); 56 | //Get audio data size 57 | fileLength = wavHeader.FileSize; 58 | //Play the WAV file with frequency specified in header 59 | samplingFreq = wavHeader.SampleRate; 60 | return true; 61 | } 62 | 63 | /** 64 | * @brief WAV File Play 65 | */ 66 | void wavPlayer_play(void) 67 | { 68 | isFinished = false; 69 | //Initialise I2S Audio Sampling settings 70 | audioI2S_init(samplingFreq); 71 | //Read Audio data from USB Disk 72 | f_lseek(&wavFile, 0); 73 | f_read (&wavFile, &audioBuffer[0], AUDIO_BUFFER_SIZE, &playerReadBytes); 74 | audioRemainSize = fileLength - playerReadBytes; 75 | //Start playing the WAV 76 | audioI2S_play((uint16_t *)&audioBuffer[0], AUDIO_BUFFER_SIZE); 77 | } 78 | 79 | /** 80 | * @brief Process WAV 81 | */ 82 | void wavPlayer_process(void) 83 | { 84 | switch(playerControlSM) 85 | { 86 | case PLAYER_CONTROL_Idle: 87 | break; 88 | 89 | case PLAYER_CONTROL_HalfBuffer: 90 | playerReadBytes = 0; 91 | playerControlSM = PLAYER_CONTROL_Idle; 92 | f_read (&wavFile, &audioBuffer[0], AUDIO_BUFFER_SIZE/2, &playerReadBytes); 93 | if(audioRemainSize > (AUDIO_BUFFER_SIZE / 2)) 94 | { 95 | audioRemainSize -= playerReadBytes; 96 | } 97 | else 98 | { 99 | audioRemainSize = 0; 100 | playerControlSM = PLAYER_CONTROL_EndOfFile; 101 | } 102 | break; 103 | 104 | case PLAYER_CONTROL_FullBuffer: 105 | playerReadBytes = 0; 106 | playerControlSM = PLAYER_CONTROL_Idle; 107 | f_read (&wavFile, &audioBuffer[AUDIO_BUFFER_SIZE/2], AUDIO_BUFFER_SIZE/2, &playerReadBytes); 108 | if(audioRemainSize > (AUDIO_BUFFER_SIZE / 2)) 109 | { 110 | audioRemainSize -= playerReadBytes; 111 | } 112 | else 113 | { 114 | audioRemainSize = 0; 115 | playerControlSM = PLAYER_CONTROL_EndOfFile; 116 | } 117 | break; 118 | 119 | case PLAYER_CONTROL_EndOfFile: 120 | f_close(&wavFile); 121 | wavPlayer_reset(); 122 | isFinished = true; 123 | playerControlSM = PLAYER_CONTROL_Idle; 124 | break; 125 | } 126 | } 127 | 128 | /** 129 | * @brief WAV stop 130 | */ 131 | void wavPlayer_stop(void) 132 | { 133 | audioI2S_stop(); 134 | isFinished = true; 135 | } 136 | 137 | /** 138 | * @brief WAV pause/resume 139 | */ 140 | void wavPlayer_pause(void) 141 | { 142 | audioI2S_pause(); 143 | } 144 | void wavPlayer_resume(void) 145 | { 146 | audioI2S_resume(); 147 | } 148 | 149 | /** 150 | * @brief isEndofFile reached 151 | */ 152 | bool wavPlayer_isFinished(void) 153 | { 154 | return isFinished; 155 | } 156 | 157 | /** 158 | * @brief Half/Full transfer Audio callback for buffer management 159 | */ 160 | void audioI2S_halfTransfer_Callback(void) 161 | { 162 | playerControlSM = PLAYER_CONTROL_HalfBuffer; 163 | } 164 | void audioI2S_fullTransfer_Callback(void) 165 | { 166 | playerControlSM = PLAYER_CONTROL_FullBuffer; 167 | // audioI2S_changeBuffer((uint16_t*)&audioBuffer[0], AUDIO_BUFFER_SIZE / 2); 168 | } 169 | 170 | -------------------------------------------------------------------------------- /Tutorial 43 - WAV Player/Audio/wav_player.h: -------------------------------------------------------------------------------- 1 | /* 2 | * wav_player.h 3 | * 4 | * Created on: 17 Apr 2020 5 | * Author: Mohamed Yaqoob 6 | */ 7 | 8 | #ifndef WAV_PLAYER_H_ 9 | #define WAV_PLAYER_H_ 10 | 11 | #include 12 | #include 13 | 14 | //Audio buffer state 15 | typedef enum 16 | { 17 | BUFFER_OFFSET_NONE = 0, 18 | BUFFER_OFFSET_HALF, 19 | BUFFER_OFFSET_FULL, 20 | }BUFFER_StateTypeDef; 21 | 22 | typedef enum 23 | { 24 | PLAY_Idle=0, 25 | PLAY_Pause, 26 | PLAY_Resume, 27 | }PLAY_State_e; 28 | 29 | typedef struct 30 | { 31 | uint32_t ChunkID; /* 0 */ 32 | uint32_t FileSize; /* 4 */ 33 | uint32_t FileFormat; /* 8 */ 34 | uint32_t SubChunk1ID; /* 12 */ 35 | uint32_t SubChunk1Size; /* 16*/ 36 | uint16_t AudioFormat; /* 20 */ 37 | uint16_t NbrChannels; /* 22 */ 38 | uint32_t SampleRate; /* 24 */ 39 | 40 | uint32_t ByteRate; /* 28 */ 41 | uint16_t BlockAlign; /* 32 */ 42 | uint16_t BitPerSample; /* 34 */ 43 | uint32_t SubChunk2ID; /* 36 */ 44 | uint32_t SubChunk2Size; /* 40 */ 45 | 46 | }WAV_HeaderTypeDef; 47 | 48 | /** 49 | * @brief Select WAV file to play 50 | * @retval returns true when file is found in USB Drive 51 | */ 52 | bool wavPlayer_fileSelect(const char* filePath); 53 | 54 | /** 55 | * @brief WAV File Play 56 | */ 57 | void wavPlayer_play(void); 58 | 59 | /** 60 | * @brief WAV stop 61 | */ 62 | void wavPlayer_stop(void); 63 | 64 | /** 65 | * @brief Process WAV 66 | */ 67 | void wavPlayer_process(void); 68 | 69 | /** 70 | * @brief isEndofFile reached 71 | */ 72 | bool wavPlayer_isFinished(void); 73 | 74 | /** 75 | * @brief WAV pause/resume 76 | */ 77 | void wavPlayer_pause(void); 78 | void wavPlayer_resume(void); 79 | 80 | #endif /* WAV_PLAYER_H_ */ 81 | --------------------------------------------------------------------------------