/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2024 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include // Definitions for BT8xx co processor command buffer #define FT_DL_SIZE (8*1024) // 8kibiByte Speicher in RAM_DL für die Displayliste #define BT_CMD_FIFO_SIZE (4*1024) // 4kibiByte Speicher in RAM_CMD #define BT_CMD_SIZE (4) // 4 byte pro Befehl // RAM-Speicherbereiche #define RAM_G 0x000000 #define RAM_DL 0x300000 #define RAM_REG 0x302000 #define RAM_CMD 0x308000 #define RAM_FLASH 0x800000 // Graphics primitve #define BITMAPS 0x01 #define POINTS 0x02 #define LINES 0x03 #define LINE_STRIP 0x04 #define EDGE_STRIP_R 0x05 #define EDGE_STRIP_L 0x06 #define EDGE_STRIP_A 0x07 #define EDGE_STRIP_B 0x08 #define RECTS 0x09 // Graphics Engine Registers - FT81x Series Programmers Guide Section 3.1 // Addresses defined as offsets from the base address called RAM_REG and located at 0x302000 // Discussion: Defining this way leads to an additional add operation in code that can be avoided by defining // these addresses as 32 bit values, but this is easily paid for in clarity and coorelation to documentation. // Further, you can add defines together in code and allow the precompiler to do the add operation (as here). #define REG_CSPREAD 0x68 #define REG_DITHER 0x60 #define REG_DLSWAP 0x54 #define REG_HCYCLE 0x2C #define REG_HOFFSET 0x30 #define REG_HSIZE 0x34 #define REG_HSYNC0 0x38 #define REG_HSYNC1 0x3C #define REG_OUTBITS 0x5C #define REG_PCLK 0x70 #define REG_PCLK_POL 0x6C #define REG_PLAY 0x8C #define REG_PLAYBACK_FORMAT 0xC4 #define REG_PLAYBACK_FREQ 0xC0 #define REG_PLAYBACK_LENGTH 0xB8 #define REG_PLAYBACK_LOOP 0xC8 #define REG_PLAYBACK_PLAY 0xCC #define REG_PLAYBACK_READPTR 0xBC #define REG_PLAYBACK_START 0xB4 #define REG_PWM_DUTY 0xD4 #define REG_ROTATE 0x58 #define REG_SOUND 0x88 #define REG_SWIZZLE 0x64 #define REG_TAG 0x7C #define REG_TAG_X 0x74 #define REG_TAG_Y 0x78 #define REG_VCYCLE 0x40 #define REG_VOFFSET 0x44 #define REG_VOL_SOUND 0x84 #define REG_VOL_PB 0x80 #define REG_VSYNC0 0x4C #define REG_VSYNC1 0x50 #define REG_VSIZE 0x48 /*NOCH NICHT ÜBERPRÜFTE REGISTER // Touch Screen Engine Registers - FT81x Series Programmers Guide Section 3.3 // Addresses defined as offsets from the base address called RAM_REG and located at 0x302000 #define REG_TOUCH_CONFIG 0x168 #define REG_TOUCH_TRANSFORM_A 0x150 #define REG_TOUCH_TRANSFORM_B 0x154 #define REG_TOUCH_TRANSFORM_C 0x158 #define REG_TOUCH_TRANSFORM_D 0x15C #define REG_TOUCH_TRANSFORM_E 0x160 #define REG_TOUCH_TRANSFORM_F 0x164 // Resistive Touch Engine Registers - FT81x Series Programmers Guide Section 3.3.3 - Document confused // Addresses defined as offsets from the base address called RAM_REG and located at 0x302000 #define REG_TOUCH_ADC_MODE 0x108 #define REG_TOUCH_CHARGE 0x10C #define REG_TOUCH_DIRECT_XY 0x18C #define REG_TOUCH_DIRECT_Z1Z2 0x190 #define REG_TOUCH_MODE 0x104 #define REG_TOUCH_OVERSAMPLE 0x114 #define REG_TOUCH_RAW_XY 0x11C #define REG_TOUCH_RZ 0x120 #define REG_TOUCH_RZTHRESH 0x118 #define REG_TOUCH_SCREEN_XY 0x124 #define REG_TOUCH_SETTLE 0x110 #define REG_TOUCH_TAG 0x12C #define REG_TOUCH_TAG_XY 0x128 // Capacitive Touch Engine Registers - FT81x Series Programmers Guide Section 3.3.4 // Addresses defined as offsets from the base address called RAM_REG and located at 0x302000 #define REG_CTOUCH_MODE 0x104 #define REG_CTOUCH_EXTEND 0x108 #define REG_CTOUCH_RAW_XY 0x11C #define REG_CTOUCH_TOUCH_XY 0x124 #define REG_CTOUCH_TOUCH1_XY 0x11C #define REG_CTOUCH_TOUCH2_XY 0x18C #define REG_CTOUCH_TOUCH3_XY 0x190 #define REG_CTOUCH_TOUCH4_X 0x16C #define REG_CTOUCH_TOUCH4_Y 0x120 #define REG_CTOUCH_TAG 0x12C #define REG_CTOUCH_TAG1 0x134 #define REG_CTOUCH_TAG2 0x13C #define REG_CTOUCH_TAG3 0x144 #define REG_CTOUCH_TAG4 0x14C #define REG_CTOUCH_TAG_XY 0x128 #define REG_CTOUCH_TAG1_XY 0x130 #define REG_CTOUCH_TAG2_XY 0x138 #define REG_CTOUCH_TAG3_XY 0x140 #define REG_CTOUCH_TAG4_XY 0x148 */ // Miscellaneous Registers - FT81x Series Programmers Guide Section 3.6 - Document inspecific about base address // Addresses assumed to be defined as offsets from the base address called RAM_REG and located at 0x302000 #define REG_CPURESET 0x20 #define REG_PWM_HZ 0xD0 #define REG_INT_MASK 0xB0 #define REG_INT_EN 0xAC #define REG_INT_FLAGS 0xA8 #define REG_GPIO 0x94 #define REG_GPIO_DIR 0x90 #define REG_GPIOX 0x9C #define REG_GPIOX_DIR 0x98 #define REG_FREQUENCY 0x0C #define REG_CLOCK 0x08 #define REG_FRAMES 0x04 #define REG_ID 0x00 #define REG_TRIM 0x180 #define REG_SPI_WIDTH 0x188 // Co-processor Engine Registers - FT81x Series Programmers Guide Section 3.4 // Addresses defined as offsets from the base address called RAM_REG and located at 0x302000 #define REG_CMD_DL 0x100 #define REG_CMD_READ 0xF8 #define REG_CMDB_SPACE 0x574 #define REG_CMDB_WRITE 0x578 #define REG_COPRO_PATCH_PTR 0x7162 #define REG_CMD_WRITE 0xFC //Alphabetdefines #define T 84 #define E 69 #define X 88 /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ SPI_HandleTypeDef hspi2; /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_SPI2_Init(void); /* USER CODE BEGIN PFP */ /*Variablendeklaration -------------------------------------------------------*/ int aufwr32_disp = 0; uint32_t aktadress = 0; uint16_t FifoWriteLocation = 0; //Speicherstrukturen welche zur Konstruktion des zu sendenden Arrays benutzt werden uint8_t vierByte[4]; uint8_t dreiByte[3]; uint8_t zweiByte[2]; uint8_t einByte[1]; uint8_t send[7]; uint8_t send2[5]; uint8_t send3[4]; /*Funktiondeklaration --------------------------------------------------------*/ void SSenable(void){ //SlaveSelectPin LOW setzen HAL_GPIO_WritePin(SlaveSelect_GPIO_Port, SlaveSelect_Pin, GPIO_PIN_RESET); } void SSdisable(void){ //SlaveSelectPin HIG setzne HAL_GPIO_WritePin(SlaveSelect_GPIO_Port, SlaveSelect_Pin, GPIO_PIN_SET); } void clear_send_array(void){ //send3 array auf 0 setzen send3[0]=0x00; send3[1]=0x00; send3[2]=0x00; send3[3]=0x00; } void clear_vierByte_array(void){ //vierByte array auf 0 setzen vierByte[0]=0x00; vierByte[1]=0x00; vierByte[2]=0x00; vierByte[3]=0x00; } void HostCommand(char comand[], uint8_t data){ /*uint8_t data wird nur bei Befehlen PINDRIVE und PIN_DA_STATE verwendet, * wenn keiner dieser zwei Befehle verwendet wird soll "data" beim Funktionsaufrauf * Wert 0x00 zugeweisen werden*/ if (strcmp(comand,"ACTIVE" )==0){ dreiByte[0]=0x00; dreiByte[1]=0x00; dreiByte[2]=0x00; } else if (strcmp(comand, "STANDBY")==0){ dreiByte[0]=0x41; dreiByte[1]=0x00; dreiByte[2]=0x00; } else if (strcmp(comand, "SLEEP")==0){ dreiByte[0]=0x42; dreiByte[1]=0x00; dreiByte[2]=0x00; } else if (strcmp(comand, "PWRDOWN")==0){ dreiByte[0]=0x43; dreiByte[1]=0x00; dreiByte[2]=0x00; } else if (strcmp(comand, "CLKEXT")==0){ dreiByte[0]=0x44; dreiByte[1]=0x00; dreiByte[2]=0x00; } else if (strcmp(comand, "CLKINT")==0){ dreiByte[0]=0x48; dreiByte[1]=0x00; dreiByte[2]=0x00; } else if (strcmp(comand, "CLKSEL")==0){ dreiByte[0]=0x61; dreiByte[1]=data; dreiByte[2]=0x00; } else if (strcmp(comand, "RST_PULSE")==0){ dreiByte[0]=0x68; dreiByte[1]=0x00; dreiByte[2]=0x00; } else if (strcmp(comand, "PINDRIVE")==0){ dreiByte[0]=0x70; dreiByte[1]=data; dreiByte[2]=0x00; } else if (strcmp(comand, "PIN_DA_STATE")==0){ dreiByte[0]=0x71; dreiByte[1]=data; dreiByte[2]=0x00; } SSenable(); HAL_Delay(1); HAL_SPI_Transmit(&hspi2, dreiByte, 3, HAL_MAX_DELAY); HAL_Delay(1); SSdisable(); } /*Allgemeiner Aufbau Schreibbefehl: * 10xx xxxx xxxx xxxx xxxx xxxx Datenbyte1 [Datenbyte2 Datenbyte3 Datenbyte4] * 1AddrByte 2AddrByte 3AddrByte * * Das erste Adressbyte muss mit 10 angeführt werden*/ void wr32(uint32_t address, uint32_t DatenFolge){ //Aufruf von wr32 über "RAM_Speicherbereich+Registername" Registername nicht als char notwendig /*Schreibt vier Byte*/ dreiByte[0]=0xB0; dreiByte[1]=(address >> 8)&0xFF; dreiByte[2]=address&0xFF; clear_vierByte_array(); vierByte[0]=(DatenFolge>>24)&0xFF; vierByte[1]=(DatenFolge>>16)&0xFF; vierByte[2]=(DatenFolge>>8)&0xFF; vierByte[3]=DatenFolge&0xFF; send[0]=dreiByte[0]; send[1]=dreiByte[1]; send[2]=dreiByte[2]; send[3]=vierByte[0]; send[4]=vierByte[1]; send[5]=vierByte[2]; send[6]=vierByte[3]; SSenable(); HAL_Delay(1); HAL_SPI_Transmit(&hspi2, send, 7, HAL_MAX_DELAY); HAL_Delay(1); SSdisable(); } void wr16(uint32_t address, uint8_t byte0, uint8_t byte1){ //Aufruf von wr16 über "RAM_Speicherbereich+Registername" Registername nicht als char notwendig /*Schreibt zwei Byte in der Reihenfolge: byte0, byte1*/ dreiByte[0]=0xB0; dreiByte[1]=(address >> 8)&0xFF; dreiByte[2]=address&0xFF; send2[0]=dreiByte[0]; send2[1]=dreiByte[1]; send2[2]=dreiByte[2]; send2[3]=byte0; send2[4]=byte1; SSenable(); HAL_Delay(1); HAL_SPI_Transmit(&hspi2, send2, 5, HAL_MAX_DELAY); HAL_Delay(1); SSdisable(); } void wr8(uint32_t address, uint8_t byte0){ //Aufruf von wr8 über "RAM_Speicherbereich+Registername" Registername nicht als char notwendig /*Schreibt ein Byte in der Reihenfolge: byte0*/ dreiByte[0]=0xB0; dreiByte[1]=(address >> 8)&0xFF; dreiByte[2]=address&0xFF; send3[0]=dreiByte[0]; send3[1]=dreiByte[1]; send3[2]=dreiByte[2]; send3[3]=byte0; SSenable(); HAL_Delay(1); HAL_SPI_Transmit(&hspi2, send3, 4, HAL_MAX_DELAY); HAL_Delay(1); SSdisable(); } /*Allgemeiner Aufbaur Lese-Befehl * 00xx xxxx xxxx xxxx xxxx xxxx 0000 0000 Lesebyte1 Lesebyte2 * 1AddrByte 2AddrByte 3AddrByte DummyByte * * Die Addressbytes werden vom Master gesendet. * Das erste Adressbyte muss mit 00 angeführt werden*/ uint16_t rd16 (uint32_t address){ /*liest zwei Byte*/ clear_send_array(); dreiByte[0]=0x30; dreiByte[1]=(address >> 8)&0xFF; dreiByte[2]=address&0xFF; send3[0]=dreiByte[0]; send3[1]=dreiByte[1]; send3[2]=dreiByte[2]; send3[3]=0x00; //Dummybyte wird gesendet bevor Lesedaten empfangen werden SSenable(); HAL_Delay(1); HAL_SPI_Transmit(&hspi2, send3, 4, HAL_MAX_DELAY); //senden von Addresse und Dummybyte HAL_SPI_Receive(&hspi2, zweiByte, 2, HAL_MAX_DELAY); HAL_Delay(1); SSdisable(); uint16_t erg16 = (zweiByte[0]<<8) | zweiByte[1]; return erg16; } uint8_t rd8 (uint32_t address){ /*liest ein Byte*/ clear_send_array(); dreiByte[0]=0x30; dreiByte[1]=(address >> 8)&0xFF; dreiByte[2]=address&0xFF; send3[0]=dreiByte[0]; send3[1]=dreiByte[1]; send3[2]=dreiByte[2]; send3[3]=0x00; //Dummybyte wird gesendet bevor Lesedaten empfangen werden SSenable(); HAL_Delay(1); HAL_SPI_Transmit(&hspi2, send3, 4,HAL_MAX_DELAY); //senden von Addresse und Dummybyte HAL_SPI_Receive(&hspi2, einByte, 1, HAL_MAX_DELAY); HAL_Delay(1); SSdisable(); uint8_t erg8 = einByte[0]; return erg8; } /*Grafikfunktionen---------------------------------------------------------------------*/ /*CLEAR-Funktionen---------------------------------------------------------------------------------------------------------------------------*/ uint32_t CLEAR(uint8_t byte0, uint8_t byte1, uint8_t byte2){ //Bit 0: clear tag Buffer: if Bit is 1 means set to reset Value: Reset Value festgelegt durch Befehl CLEAR_TAG //Bit 1: clear stencil Buffer: if Bit is 1 means set to reset value: Reset value festgelegt durch den Befehl CLEAR_STENCIL //Bit2: clear color Buffer: if Bit is 1 means set to reset value: Reset value festtgelegt durch den Befehl CLEAR_COLOR_RGB clear_vierByte_array(); vierByte[0]=0x26; vierByte[1]=0x00; vierByte[2]=0x00; vierByte[3]=((byte0<<2)|(byte1<<1)|(byte2))&0xFF; uint32_t zusammen = (vierByte[0]<<24) | (vierByte[1]<<16) | vierByte[2]<<8 | vierByte[3]; return zusammen; } uint32_t CLEAR_COLOR_RGB(uint8_t red, uint8_t green, uint8_t blue){ //legt die Werte für Rot, Grün und Blau fest wenn der color buffer ist geleert clear_vierByte_array(); vierByte[0]=0x02; vierByte[1]=red; vierByte[2]=blue; vierByte[3]=green; uint32_t zusammen = (vierByte[0]<<24) | (vierByte[1]<<16) | (vierByte[2]<<8) | vierByte[3]; return zusammen; } void CLEAR_STENCIL(uint8_t byte0){ //legt Wert nach dem stencil-Buffer geleert wurde fest clear_vierByte_array(); vierByte[0]=0x11; vierByte[1]=0x00; vierByte[2]=0x00; vierByte[3]=byte0; //wr32_displaylist(RAM_DL + FifoWriteLocation,vierByte); } void CLEAR_TAG(uint8_t byte0){ //legt Wert fest nach dem tag-buffer geleert wurde fest clear_vierByte_array(); vierByte[0]=0x12; vierByte[1]=0x00; vierByte[2]=0x00; vierByte[3]=byte0; //wr32_displaylist(RAM_DL + FifoWriteLocation,vierByte); } /*Display-Funktionen---------------------------------------------------------------------------------------------------------------------------*/ uint32_t DISPLAY(void){ //zeigt das Ende der Displayliste an //alle Befefehle danach werden ignoriert clear_vierByte_array(); vierByte[0]=0x00; vierByte[1]=0x00; vierByte[2]=0x00; vierByte[3]=0x00; uint32_t zusammen = (vierByte[0]<<24) | (vierByte[1]<<16) | vierByte[2]<<8 | vierByte[3]; return zusammen; } uint32_t VERTEX2II(unsigned short x, unsigned short y, short handle, int buchstabe){ uint32_t zusammen=(0x2<<30) | (x<<21) | (y<<12) | (handle<<7) | buchstabe; clear_vierByte_array(); vierByte[0]=(zusammen>>24)&0xff; vierByte[1]=(zusammen>>16)&0xff; vierByte[2]=(zusammen>>8)&0xff; vierByte[3]=zusammen&0xff; return zusammen; } void END(void){ clear_vierByte_array(); vierByte[0]=0x21; vierByte[1]=0x00; vierByte[2]=0x00; vierByte[3]=0x00; //wr32_displaylist(RAM_DL + FifoWriteLocation,vierByte); } void DispInit(void){ HostCommand("ACTIVE", 0x00); //send host command "ACTIVE" to wake up => überprüft HostCommand("RST_PULSE", 0x00); //send host command "RST_PULSE" to reset => überprüft while(0x7C != rd8(RAM_REG+REG_ID)); while(0x0000 != rd16(RAM_REG+REG_CPURESET)); //check if EVE is in working status wr32(RAM_REG + REG_FREQUENCY, 0x03938700); //configure system clock to 60 MHz => überprüft /* Configure display registers*/ wr16(RAM_REG+REG_HCYCLE, 0x03, 0xA0); wr16(RAM_REG+REG_HOFFSET, 0x00, 0x58); wr16(RAM_REG+REG_HSYNC0, 0x00, 0x00); wr16(RAM_REG+REG_HSYNC1, 0x00, 0x30); wr16(RAM_REG+REG_VCYCLE, 0x02, 0x0D); wr16(RAM_REG+REG_VOFFSET, 0x00, 0x20); wr16(RAM_REG+REG_VSYNC0, 0x00, 0x00); wr16(RAM_REG+REG_VSYNC1, 0x00, 0x03); wr8(RAM_REG+REG_SWIZZLE, 0x00); wr8(RAM_REG+REG_PCLK_POL, 0x01); wr8(RAM_REG+REG_CSPREAD, 0x00); wr16(RAM_REG+REG_HSIZE, 0x03, 0x20); wr16(RAM_REG+REG_VSIZE, 0x01, 0xE0); /*write first display list to display memory RAM_DL*/ wr32(RAM_DL + 0, CLEAR_COLOR_RGB(0,0,0)); wr32(RAM_DL + 4, CLEAR(1,1,1)); wr32(RAM_DL + 8, DISPLAY()); wr8(REG_DLSWAP,0x02); /*Enable backlight of display panel*/ wr8(RAM_REG + REG_GPIO_DIR, 0xff); wr8(RAM_REG + REG_GPIO, 0xff); wr8(RAM_REG + REG_PCLK, 0x02); //Configure the PCLK divisor to 2, i.e. PCLK = System CLK/2 => überprüft } /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_SPI2_Init(); SSdisable(); DispInit(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Configure the main internal regulator output voltage */ __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } } /** * @brief SPI2 Initialization Function * @param None * @retval None */ static void MX_SPI2_Init(void) { /* USER CODE BEGIN SPI2_Init 0 */ /* USER CODE END SPI2_Init 0 */ /* USER CODE BEGIN SPI2_Init 1 */ /* USER CODE END SPI2_Init 1 */ /* SPI2 parameter configuration*/ hspi2.Instance = SPI2; hspi2.Init.Mode = SPI_MODE_MASTER; hspi2.Init.Direction = SPI_DIRECTION_2LINES; hspi2.Init.DataSize = SPI_DATASIZE_8BIT; hspi2.Init.CLKPolarity = SPI_POLARITY_LOW; hspi2.Init.CLKPhase = SPI_PHASE_1EDGE; hspi2.Init.NSS = SPI_NSS_SOFT; hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi2.Init.TIMode = SPI_TIMODE_DISABLE; hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi2.Init.CRCPolynomial = 10; if (HAL_SPI_Init(&hspi2) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN SPI2_Init 2 */ /* USER CODE END SPI2_Init 2 */ } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* USER CODE BEGIN MX_GPIO_Init_1 */ /* USER CODE END MX_GPIO_Init_1 */ /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(SlaveSelect_GPIO_Port, SlaveSelect_Pin, GPIO_PIN_RESET); /*Configure GPIO pin : SlaveSelect_Pin */ GPIO_InitStruct.Pin = SlaveSelect_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(SlaveSelect_GPIO_Port, &GPIO_InitStruct); /* USER CODE BEGIN MX_GPIO_Init_2 */ /* USER CODE END MX_GPIO_Init_2 */ } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ __disable_irq(); while (1) { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */