diff --git a/GPS/NEO-M9N-00BDDriver.cpp b/GPS/NEO-M9N-00BDDriver.cpp new file mode 100644 index 0000000..e121536 --- /dev/null +++ b/GPS/NEO-M9N-00BDDriver.cpp @@ -0,0 +1,354 @@ + +#include "NEO-M9N-00BDriver.hpp" + +NEOM9N00B::NEOM9N00B(){ + +} + +bool NEOM9N00B::Init(SPI_HandleTypeDef* hspi, GPIO_TypeDef* csPort, uint16_t csPin){ + _hspi = hspi; + _csPort = csPort; + _csPin = csPin; + csHigh(); + if (!valSetLType(static_cast(CFG_SPI_ENABLE), 1)) return false; // CFG-SPI-ENABLED = true + if (!valSetLType(static_cast(CFG_SPIINPROT_UBX), 1)) return false; // CFG-SPIINPROT-UBX = true set this just for config + if (!valSetLType(static_cast(CFG_SPIOUTPROT_UBX), 1)) return false; // CFG-SPIOUTPROT-UBX = true set this just for config + if (!valSetLType(static_cast(CFG_SPIOUTPROT_NMEA), 1)) return false; // CFG-SPIOUTPROT-NMEA = true + if (!valSetLType(static_cast(CFG_SPIINPROT_NMEA), 0)) return false; // CFG-SPIINPROT-NMEA = false, unless you need NMEA input + if(!valSetU1Type(static_cast(CFG_MSGOUT_NMEA_ID_GGA_SPI, 1)) return false; //CFG_MSGOUT_NMEA_ID_GGA_SPI = 1 sets output rate to 1(testing for now) + return true; + + +} + +bool NEOM9N00B::valSetLType(uint32_t keyId, uint8_t value){ + + uint8_t msg[] ={ + 0xB5, 0x62, // sync + 0x06, 0x8A, // UBX-CFG-VALSET + 0x09, 0x00, // payload length = 9 + 0x00, // version + 0x01, // layers: RAM + 0x00, 0x00, // reserved + static_cast( keyId & 0xFF), //copy first byte + static_cast((keyId >> 8) & 0xFF), //copy second byte + static_cast((keyId >> 16) & 0xFF), //copy third byte + static_cast((keyId >> 24) & 0xFF), // copy fourth byte + + value, //L value (either a 1 or a 0) + + 0x00, 0x00 //placeholders for checksum + }; + + uint8_t ckA = 0, ckB = 0; + + // Checksum over CLASS, ID, LENGTH, PAYLOAD + computeUBXChecksum(&msg[2], sizeof(msg) - 4, ckA, ckB); //message - 4 since we dont want first 2 bytes and last 2 bytes reserved for checksum + + //set checksum + msg[sizeof(msg) - 2] = ckA; + msg[sizeof(msg) - 1] = ckB; + + csLow(); + HAL_SPI_Transmit(_hspi, msg, sizeof(msg), HAL_MAX_DELAY); + csHigh(); + + return waitForAck(0x06, 0x8A, 1000); + + +} + +bool NEOM9N00B::valSetU1Type(uint32 keyId, uint8_t value){ + uint8_t msg[] ={ + 0xB5, 0x62, // sync + 0x06, 0x8A, // UBX-CFG-VALSET + 0x09, 0x00, // payload length = 9 + 0x00, // version + 0x01, // layers: RAM + 0x00, 0x00, // reserved + static_cast( keyId & 0xFF), //copy first byte + static_cast((keyId >> 8) & 0xFF), //copy second byte + static_cast((keyId >> 16) & 0xFF), //copy third byte + static_cast((keyId >> 24) & 0xFF), // copy fourth byte + + value, //U1 value (unsigned 1 byte integer) + + 0x00, 0x00 //placeholders for checksum + }; + + uint8_t ckA = 0, ckB = 0; + + // Checksum over CLASS, ID, LENGTH, PAYLOAD + computeUBXChecksum(&msg[2], sizeof(msg) - 4, ckA, ckB); //message - 4 since we dont want first 2 bytes and last 2 bytes reserved for checksum + + //set checksum + msg[sizeof(msg) - 2] = ckA; + msg[sizeof(msg) - 1] = ckB; + + csLow(); + HAL_SPI_Transmit(_hspi, msg, sizeof(msg), HAL_MAX_DELAY); + csHigh(); + + return waitForAck(0x06, 0x8A, 1000); + +} + +void NEOM9N00B::computeUBXChecksum(const uint8_t* data, uint16_t len, uint8_t& ckA, uint8_t& ckB) +{ + ckA = 0; + ckB = 0; + + for (uint16_t i = 0; i < len; i++) { + ckA = ckA + data[i]; + ckB = ckB + ckA; + } +} + +bool NEOM9N00B::waitForAck(uint8_t expectedClass, uint8_t expectedId, uint32_t timeoutMs=1000){ + uint32_t start = HAL_GetTick(); + uint8_t txDummy[32]; + uint8_t rxBuf[32]; + + memset(txDummy, 0xFF, sizeof(txDummy)); + + while ((HAL_GetTick() - start) < timeoutMs) { + csLow(); + HAL_SPI_TransmitReceive(_hspi, txDummy, rxBuf, sizeof(rxBuf), 1000); + csHigh(); + + for (uint8_t i = 0; i <= sizeof(rxBuf) - 10; i++) { + // Look for UBX sync chars + if (rxBuf[i] == 0xB5 && rxBuf[i + 1] == 0x62) { + uint8_t msgClass = rxBuf[i + 2]; + uint8_t msgId = rxBuf[i + 3]; + uint16_t length = rxBuf[i + 4] | (rxBuf[i + 5] << 8); + + // ACK/NAK messages have class 0x05 and length 2 + if (msgClass == 0x05 && length == 2) { + uint8_t ackedClass = rxBuf[i + 6]; + uint8_t ackedId = rxBuf[i + 7]; + + // ACK-ACK + if (msgId == 0x01 && + ackedClass == expectedClass && + ackedId == expectedId) { + return true; + } + + // ACK-NAK + if (msgId == 0x00 && + ackedClass == expectedClass && + ackedId == expectedId) { + return false; + } + } + } + } + } + return false; + +} + +bool NEOM9N00B::readBytes(uint8_t* rxBuf, uint16_t len) +{ + uint8_t txDummy[64]; + + if (len > sizeof(txDummy)) { + return false; + } + + memset(txDummy, 0xFF, len); + + csLow(); + HAL_StatusTypeDef status = HAL_SPI_TransmitReceive(_hspi, txDummy, rxBuf, len, HAL_MAX_DELAY); + csHigh(); + + return (status == HAL_OK); +} + +bool NEOM9N00B::collectNMEALine(char* lineBuf){ + + uint8_t rx[32]; //make rx buffer to recieve bytes from SPI + + /* + * idx and collecting must be static because NMEA messages may not be completed in one SPI transaction. + * The function keeps track of whether the NMEA string is still being collected or not. + * Once the String is full which could be over multiple function calls, this function will return + * a true flag which can trigger a break in the loop calling this function. That true flag will be triggered + * when the end of the message has been reached. + */ + + static uint16_t idx = 0 + static bool collecting = false + + //read the bytes from spi, return false if HAL status flag has error + if(!readBytes(rx, sizeof(rx))){ + return false; + } + + + //iterate through bytes from rx buf to create message + for(uint16_t i = 0; i < sizeof(rx); i++){ + char c = static_cast(rx[i]); + + //if collecting is false, function must have either not been previously collecting or + //the collection of a previous message has finished + if(!collecting){ + // Therefore if collection is false we are looking for a new NMEA message to start + // so we check if the char we are receiving is the start indicator or not + if(c == '$'){ + idx = 0; + collecting = true; + lineBuf[idx++] = c; + } + } + //If we are collecting, that means we clocked bytes from SPI that are the start or part of a message. + //This means we can simply append the characters to the line buffer until we reach an end indicator + //or a we reach NMEA message greater than the max length without a terminator (NMEA message is corrupt). + else{ + if(idx < NMEA_MAX_LENGTH - 1){ + lineBuf[idx++] = c; + } + else{ + collecting = false; + idx = 0; + return false; + } + //Add null terminator if we hit an end indicator, indicates end of NMEA message; return true. + if(c == '\n'){ + lineBuf[idx] = '\0' + collecting = false; + idx = 0; + return true + } + } + } + //return false if we do not have a full NMEA message yet + return false + +} + +bool NEOM9N00B::getGGALine(char* lineBuf){ + //collects the NMEALine until notified of terminator + while (true) { + if (collectNMEALine(lineBuf) { + if (strncmp(lineBuf, "$GPGGA", 6) == 0 || + strncmp(lineBuf, "$GNGGA", 6) == 0) { + return true; + } + } + } +} + +void NEOM9N00B::ParseGpsData(GpsData* data) +{ + + char* gps_item = &data->buffer_[0]; + uint8_t item_len = 0; + uint8_t counter = 0; + uint8_t done = 0; + char direction = 0; + + do + { + item_len = 0; + //Iterate through the message, stop every time there is a comma + for (uint8_t i = 0; i < NMEA_MAX_LENGTH + 1; i++) { + if (gps_item[i] == ',') { + gps_item[i] = 0; + item_len = i; + break; + } + //if hit null terminator break loop, exit function + else if (gps_item[i] == 0) { + item_len = i; + done = 1; + break; + } + } + + //skips gps item if it is null terminator + if (gps_item[0] != 0) { + //based on the counts of the commas, you can determing the data being accessed + //this case switch based off the comma parses the data to its respective data type + switch (counter) + { + case 1: + data->time_ = (uint32_t)(atof(gps_item) * 100); + break; + + case 2: + { + double latitude = atof(gps_item); // DDMM.MMMMMM + data->latitude_.degrees_ = (int32_t)(latitude / 100); + data->latitude_.minutes_ = (int32_t)((latitude - data->latitude_.degrees_ * 100) * 100000); + break; + } + + case 3: + direction = *gps_item; + if (direction == 'S') { + data->latitude_.degrees_ *= -1; + data->latitude_.minutes_ *= -1; + } + break; + + case 4: + { + double longitude = atof(gps_item); // DDDMM.MMMMMM + data->longitude_.degrees_ = (int32_t)(longitude / 100); + data->longitude_.minutes_ = (int32_t)((longitude - data->longitude_.degrees_ * 100) * 100000); + break; + } + + case 5: + direction = *gps_item; + if (direction == 'W') { + data->longitude_.degrees_ *= -1; + data->longitude_.minutes_ *= -1; + } + break; + + case 9: + data->antennaAltitude_.altitude_ = (int32_t)(atof(gps_item) * 10); + break; + + case 10: + data->antennaAltitude_.unit_ = *gps_item; + break; + + case 11: + data->geoidAltitude_.altitude_ = (int32_t)(atof(gps_item) * 10); + break; + + case 12: + data->geoidAltitude_.unit_ = *gps_item; + break; + + default: + break; + } + } + + //increment the comma counter and set the gps_item pointer past the comma just read + counter++; + gps_item = &gps_item[item_len + 1]; + + } while (done == 0); + + //set total altitude and antenna altitude + + data->totalAltitude_.altitude_ = + data->antennaAltitude_.altitude_ - data->geoidAltitude_.altitude_; + data->totalAltitude_.unit_ = data->antennaAltitude_.unit_; + +} + +void NEOM9N00B::csHigh(){ + HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_SET); +} + +void NEOM9N00B::csLow(){ + HAL_GPIO_WritePin(_csPort, _csPin, GPIO_PIN_RESET); +} + diff --git a/GPS/NEO-M9N-00BDriver.hpp b/GPS/NEO-M9N-00BDriver.hpp new file mode 100644 index 0000000..b5d0dfb --- /dev/null +++ b/GPS/NEO-M9N-00BDriver.hpp @@ -0,0 +1,76 @@ + +#ifndef NEOM9N00B_HPP +#define NEOM9N00B_HPP + + +#define CFG_SPI_CPOL 0x10640002 //KeyID to Configure Clock Polarity +#define CFG_SPI_CPHASE 0x10640003 //KeyID Command to Configure Clock Phase +#define CFG_SPI_ENABLE 0x10640006 //KeyID to enable SPI + +#define CFG_SPIOUTPROT_NMEA 0x107a0002 //KeyID to indicate if NMEA is output on SPI +#define CFG_SPIINPROT_NMEA 0x10790002 //KeyID to indicate if NMEA is input on SPI +#define CFG_SPIINPROT_UBX 0x10790001 //KeyID to indicate if UBX is input on SPI +#define CFG_SPIOUTPROT_UBX 0x107a0001 //KeyID to indicate if UBX is output on SPI + +#define CFG_MSGOUT_NMEA_ID_GGA_SPI 0x209100be //KeyID to specify output rate of GGA on SPI + +#define NMEA_MAX_LENGTH 82 //Max length for NMEA message including start and end characters + +typedef struct +{ + int32_t degrees_; + int32_t minutes_; +} LatLongType; + +typedef struct +{ + int32_t altitude_; + char unit_; +} AltitudeType; + +typedef struct +{ + char buffer_ [NMEA_MAX_LENGTH]; + uint32_t time_; + LatLongType latitude_; + LatLongType longitude_; + AltitudeType antennaAltitude_; + AltitudeType geoidAltitude_; + AltitudeType totalAltitude_; +} GpsData; + + +enum class NEOM9N00B_Status{ + OK = 0 + +}; + +class NEOM9N00B{ + + +public: + + NEOM9N00B(); + + NEOM9N00B_Status Init(SPI_HandleTypeDef* hspi, GPIO_TypeDef* csPort, uint16_t csPin); + +private: + bool valSetLType(uint32_t keyID, uint8_t value) + bool valSetU1Type(uint32_t keyID, uint8_t value) + + bool computeUBXChecksum(const uint8_t* data, uint16_t len, uint8_t& ckA, uint8_t& ckB); + bool waitForAck(uint8_t expectedClass, uint8_t expectedId, uint32_t timeoutMs); + bool collectNMEALine(char* lineBuf) + bool readBytes(uint8_t* rxBuf, uint16_t len) + bool getGGALine(char* lineBuf) + + void csHigh(); + void csLow(); + + + SPI_HandleTypeDef* _hspi; + uint16_t _csPin; + GPIO_TypeDef* _csPort; + + +} diff --git a/MX66L1G45GMI/H743VIT6TemplateRepository.ioc b/MX66L1G45GMI/H743VIT6TemplateRepository.ioc new file mode 100644 index 0000000..2084328 --- /dev/null +++ b/MX66L1G45GMI/H743VIT6TemplateRepository.ioc @@ -0,0 +1,288 @@ +#MicroXplorer Configuration settings - do not modify +CAD.formats= +CAD.pinconfig= +CAD.provider= +FREERTOS.IPParameters=Tasks01,configTOTAL_HEAP_SIZE,configMINIMAL_STACK_SIZE,configUSE_TIMERS,configUSE_NEWLIB_REENTRANT +FREERTOS.Tasks01=defaultTask,0,192,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL +FREERTOS.configMINIMAL_STACK_SIZE=192 +FREERTOS.configTOTAL_HEAP_SIZE=64000 +FREERTOS.configUSE_NEWLIB_REENTRANT=1 +FREERTOS.configUSE_TIMERS=1 +File.Version=6 +KeepUserPlacement=false +Mcu.CPN=STM32H743VIT6 +Mcu.Family=STM32H7 +Mcu.IP0=CORTEX_M7 +Mcu.IP1=CRC +Mcu.IP10=UART7 +Mcu.IP11=USART3 +Mcu.IP2=FREERTOS +Mcu.IP3=NVIC +Mcu.IP4=RCC +Mcu.IP5=SPI1 +Mcu.IP6=SPI2 +Mcu.IP7=SPI3 +Mcu.IP8=SPI4 +Mcu.IP9=SYS +Mcu.IPNb=12 +Mcu.Name=STM32H743VITx +Mcu.Package=LQFP100 +Mcu.Pin0=PE5 +Mcu.Pin1=PE6 +Mcu.Pin10=PA6 +Mcu.Pin11=PA7 +Mcu.Pin12=PC5 +Mcu.Pin13=PE7 +Mcu.Pin14=PE8 +Mcu.Pin15=PE12 +Mcu.Pin16=PB10 +Mcu.Pin17=PB11 +Mcu.Pin18=PA9 +Mcu.Pin19=PA15 (JTDI) +Mcu.Pin2=PC13 +Mcu.Pin20=PC10 +Mcu.Pin21=PC11 +Mcu.Pin22=PC12 +Mcu.Pin23=PD0 +Mcu.Pin24=VP_CRC_VS_CRC +Mcu.Pin25=VP_FREERTOS_VS_CMSIS_V1 +Mcu.Pin26=VP_SYS_VS_tim2 +Mcu.Pin3=PC1 +Mcu.Pin4=PC2_C +Mcu.Pin5=PA0 +Mcu.Pin6=PA2 +Mcu.Pin7=PA3 +Mcu.Pin8=PA4 +Mcu.Pin9=PA5 +Mcu.PinsNb=27 +Mcu.ThirdPartyNb=0 +Mcu.UserConstants= +Mcu.UserName=STM32H743VITx +MxCube.Version=6.9.2 +MxDb.Version=DB.6.0.92 +NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC.ForceEnableDMAVector=true +NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false\:false +NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 +NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false +NVIC.SavedPendsvIrqHandlerGenerated=true +NVIC.SavedSvcallIrqHandlerGenerated=true +NVIC.SavedSystickIrqHandlerGenerated=true +NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:true\:false +NVIC.TIM2_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:true\:true +NVIC.TimeBase=TIM2_IRQn +NVIC.TimeBaseIP=TIM2 +NVIC.USART3_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true +NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +PA0.GPIOParameters=GPIO_Label +PA0.GPIO_Label=BARO11_CS +PA0.Locked=true +PA0.Signal=GPIO_Output +PA15\ (JTDI).GPIOParameters=GPIO_Label +PA15\ (JTDI).GPIO_Label=IMU16_INT +PA15\ (JTDI).Locked=true +PA15\ (JTDI).Signal=GPIO_Input +PA2.GPIOParameters=GPIO_Label +PA2.GPIO_Label=MAG_CS +PA2.Locked=true +PA2.Signal=GPIO_Output +PA3.GPIOParameters=GPIO_Label +PA3.GPIO_Label=MAG_INT +PA3.Locked=true +PA3.Signal=GPIO_Input +PA4.GPIOParameters=GPIO_Label +PA4.GPIO_Label=IMU32_INT +PA4.Locked=true +PA4.Signal=GPIO_Input +PA5.Locked=true +PA5.Mode=Full_Duplex_Master +PA5.Signal=SPI1_SCK +PA6.Locked=true +PA6.Mode=Full_Duplex_Master +PA6.Signal=SPI1_MISO +PA7.Locked=true +PA7.Mode=Full_Duplex_Master +PA7.Signal=SPI1_MOSI +PA9.Locked=true +PA9.Mode=Full_Duplex_Master +PA9.Signal=SPI2_SCK +PB10.Mode=Asynchronous +PB10.Signal=USART3_TX +PB11.Mode=Asynchronous +PB11.Signal=USART3_RX +PC1.Locked=true +PC1.Mode=Full_Duplex_Master +PC1.Signal=SPI2_MOSI +PC10.Locked=true +PC10.Mode=Full_Duplex_Master +PC10.Signal=SPI3_SCK +PC11.Locked=true +PC11.Mode=Full_Duplex_Master +PC11.Signal=SPI3_MISO +PC12.Locked=true +PC12.Mode=Full_Duplex_Master +PC12.Signal=SPI3_MOSI +PC13.GPIOParameters=GPIO_Label +PC13.GPIO_Label=BARO07_CS +PC13.Locked=true +PC13.Signal=GPIO_Output +PC2_C.Locked=true +PC2_C.Mode=Full_Duplex_Master +PC2_C.Signal=SPI2_MISO +PC5.GPIOParameters=GPIO_Label +PC5.GPIO_Label=IMU32_CS +PC5.Locked=true +PC5.Signal=GPIO_Output +PD0.GPIOParameters=GPIO_Label +PD0.GPIO_Label=IMU16_CS +PD0.Locked=true +PD0.Signal=GPIO_Output +PE12.Locked=true +PE12.Mode=Full_Duplex_Master +PE12.Signal=SPI4_SCK +PE5.Mode=Full_Duplex_Master +PE5.Signal=SPI4_MISO +PE6.Locked=true +PE6.Mode=Full_Duplex_Master +PE6.Signal=SPI4_MOSI +PE7.Locked=true +PE7.Mode=Asynchronous +PE7.Signal=UART7_RX +PE8.Locked=true +PE8.Mode=Asynchronous +PE8.Signal=UART7_TX +PinOutPanel.RotationAngle=0 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=false +ProjectManager.CompilerLinker=GCC +ProjectManager.CompilerOptimize=6 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=false +ProjectManager.CustomerFirmwarePackage= +ProjectManager.DefaultFWLocation=true +ProjectManager.DeletePrevious=true +ProjectManager.DeviceId=STM32H743VITx +ProjectManager.FirmwarePackage=STM32Cube FW_H7 V1.11.2 +ProjectManager.FreePins=false +ProjectManager.HalAssertFull=false +ProjectManager.HeapSize=0x200 +ProjectManager.KeepUserCode=true +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=1 +ProjectManager.MainLocation=Core/Src +ProjectManager.NoMain=false +ProjectManager.PreviousToolchain= +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=H743VIT6TemplateRepository.ioc +ProjectManager.ProjectName=H743VIT6TemplateRepository +ProjectManager.ProjectStructure= +ProjectManager.RegisterCallBack= +ProjectManager.StackSize=0x400 +ProjectManager.TargetToolchain=STM32CubeIDE +ProjectManager.ToolChainLocation= +ProjectManager.UAScriptAfterPath= +ProjectManager.UAScriptBeforePath= +ProjectManager.UnderRoot=true +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_CRC_Init-CRC-false-HAL-true,4-MX_USART3_UART_Init-USART3-false-LL-true,5-MX_SPI1_Init-SPI1-false-HAL-true,6-MX_SPI2_Init-SPI2-false-HAL-true,7-MX_SPI3_Init-SPI3-false-HAL-true,8-MX_SPI4_Init-SPI4-false-HAL-true,9-MX_UART7_Init-UART7-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true +RCC.ADCFreq_Value=129000000 +RCC.AHB12Freq_Value=64000000 +RCC.AHB4Freq_Value=64000000 +RCC.APB1Freq_Value=32000000 +RCC.APB2Freq_Value=64000000 +RCC.APB3Freq_Value=64000000 +RCC.APB4Freq_Value=64000000 +RCC.AXIClockFreq_Value=64000000 +RCC.CECFreq_Value=32000 +RCC.CKPERFreq_Value=64000000 +RCC.CortexFreq_Value=64000000 +RCC.CpuClockFreq_Value=64000000 +RCC.D1CPREFreq_Value=64000000 +RCC.D2PPRE1=RCC_APB1_DIV2 +RCC.DFSDMACLkFreq_Value=129000000 +RCC.DFSDMFreq_Value=64000000 +RCC.DIVP1Freq_Value=129000000 +RCC.DIVP2Freq_Value=129000000 +RCC.DIVP3Freq_Value=129000000 +RCC.DIVQ1Freq_Value=129000000 +RCC.DIVQ2Freq_Value=129000000 +RCC.DIVQ3Freq_Value=129000000 +RCC.DIVR1Freq_Value=129000000 +RCC.DIVR2Freq_Value=129000000 +RCC.DIVR3Freq_Value=129000000 +RCC.FDCANFreq_Value=129000000 +RCC.FMCFreq_Value=64000000 +RCC.FamilyName=M +RCC.HCLK3ClockFreq_Value=64000000 +RCC.HCLKFreq_Value=64000000 +RCC.HRTIMFreq_Value=64000000 +RCC.I2C123Freq_Value=32000000 +RCC.I2C4Freq_Value=64000000 +RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,D2PPRE1,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HRTIMFreq_Value,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI23Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value +RCC.LPTIM1Freq_Value=32000000 +RCC.LPTIM2Freq_Value=64000000 +RCC.LPTIM345Freq_Value=64000000 +RCC.LPUART1Freq_Value=64000000 +RCC.LTDCFreq_Value=129000000 +RCC.MCO1PinFreq_Value=64000000 +RCC.MCO2PinFreq_Value=64000000 +RCC.QSPIFreq_Value=64000000 +RCC.RNGFreq_Value=48000000 +RCC.RTCFreq_Value=32000 +RCC.SAI1Freq_Value=129000000 +RCC.SAI23Freq_Value=129000000 +RCC.SAI4AFreq_Value=129000000 +RCC.SAI4BFreq_Value=129000000 +RCC.SDMMCFreq_Value=129000000 +RCC.SPDIFRXFreq_Value=129000000 +RCC.SPI123Freq_Value=129000000 +RCC.SPI45Freq_Value=64000000 +RCC.SPI6Freq_Value=64000000 +RCC.SWPMI1Freq_Value=32000000 +RCC.SYSCLKFreq_VALUE=64000000 +RCC.Tim1OutputFreq_Value=64000000 +RCC.Tim2OutputFreq_Value=64000000 +RCC.TraceFreq_Value=64000000 +RCC.USART16Freq_Value=64000000 +RCC.USART234578Freq_Value=32000000 +RCC.USBFreq_Value=129000000 +RCC.VCO1OutputFreq_Value=258000000 +RCC.VCO2OutputFreq_Value=258000000 +RCC.VCO3OutputFreq_Value=258000000 +RCC.VCOInput1Freq_Value=2000000 +RCC.VCOInput2Freq_Value=2000000 +RCC.VCOInput3Freq_Value=2000000 +SPI1.CalculateBaudRate=64.5 MBits/s +SPI1.Direction=SPI_DIRECTION_2LINES +SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate +SPI1.Mode=SPI_MODE_MASTER +SPI1.VirtualType=VM_MASTER +SPI2.CalculateBaudRate=64.5 MBits/s +SPI2.Direction=SPI_DIRECTION_2LINES +SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate +SPI2.Mode=SPI_MODE_MASTER +SPI2.VirtualType=VM_MASTER +SPI3.CalculateBaudRate=64.5 MBits/s +SPI3.Direction=SPI_DIRECTION_2LINES +SPI3.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate +SPI3.Mode=SPI_MODE_MASTER +SPI3.VirtualType=VM_MASTER +SPI4.CalculateBaudRate=32.0 MBits/s +SPI4.Direction=SPI_DIRECTION_2LINES +SPI4.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate +SPI4.Mode=SPI_MODE_MASTER +SPI4.VirtualType=VM_MASTER +USART3.IPParameters=VirtualMode-Asynchronous +USART3.VirtualMode-Asynchronous=VM_ASYNC +VP_CRC_VS_CRC.Mode=CRC_Activate +VP_CRC_VS_CRC.Signal=CRC_VS_CRC +VP_FREERTOS_VS_CMSIS_V1.Mode=CMSIS_V1 +VP_FREERTOS_VS_CMSIS_V1.Signal=FREERTOS_VS_CMSIS_V1 +VP_SYS_VS_tim2.Mode=TIM2 +VP_SYS_VS_tim2.Signal=SYS_VS_tim2 +board=custom +rtos.0.ip=FREERTOS +isbadioc=false