changeset 887:17f02ac9da67 Evo_2_23

adding GNSS code
author heinrichsweikamp
date Tue, 03 Sep 2024 15:30:53 +0200
parents d398ecc7d103
children 07af9efd7c13
files Small_CPU/Inc/GNSS.h Small_CPU/Src/GNSS.c Small_CPU/Src/baseCPU2.c
diffstat 3 files changed, 514 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Small_CPU/Inc/GNSS.h	Tue Sep 03 15:30:53 2024 +0200
@@ -0,0 +1,154 @@
+ /*
+ * GNSS.h
+ *
+ *  Created on: 03.10.2020
+ *      Author: SimpleMethod
+ *
+ *Copyright 2020 SimpleMethod
+ *
+ *Permission is hereby granted, free of charge, to any person obtaining a copy of
+ *this software and associated documentation files (the "Software"), to deal in
+ *the Software without restriction, including without limitation the rights to
+ *use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ *of the Software, and to permit persons to whom the Software is furnished to do
+ *so, subject to the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be included in all
+ *copies or substantial portions of the Software.
+ *
+ *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ *THE SOFTWARE.
+ ******************************************************************************
+ */
+
+#ifndef INC_GNSS_H_
+#define INC_GNSS_H_
+
+#include "stm32f4xx_hal.h"
+
+union u_Short
+{
+	uint8_t bytes[2];
+	unsigned short uShort;
+};
+
+union i_Short
+{
+	uint8_t bytes[2];
+	signed short iShort;
+};
+
+union u_Long
+{
+	uint8_t bytes[4];
+	unsigned long uLong;
+};
+
+union i_Long
+{
+	uint8_t bytes[4];
+	signed long iLong;
+};
+
+typedef struct
+{
+	UART_HandleTypeDef *huart;
+
+	uint8_t uniqueID[4];
+	uint8_t uartWorkingBuffer[101];
+
+	unsigned short year;
+	uint8_t yearBytes[2];
+	uint8_t month;
+	uint8_t day;
+	uint8_t hour;
+	uint8_t min;
+	uint8_t sec;
+	uint8_t fixType;
+
+	signed long lon;
+	uint8_t lonBytes[4];
+	signed long lat;
+	uint8_t latBytes[4];
+	float fLon;
+	float fLat;
+
+	signed long height;
+	signed long hMSL;
+	uint8_t hMSLBytes[4];
+	unsigned long hAcc;
+	unsigned long vAcc;
+
+	signed long gSpeed;
+	uint8_t gSpeedBytes[4];
+	signed long headMot;
+
+}GNSS_StateHandle;
+
+GNSS_StateHandle GNSS_Handle;
+
+
+enum GNSSMode{Portable=0, Stationary=1, Pedestrian=2, Automotiv=3, Airbone1G=5, Airbone2G=6,Airbone4G=7,Wirst=8,Bike=9};
+
+static const uint8_t configUBX[]={0xB5,0x62,0x06,0x00,0x14,0x00,0x01,0x00,0x00,0x00,0xD0,0x08,0x00,0x00,0x80,0x25,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x9A,0x79};
+
+static const uint8_t setNMEA410[]={0xB5,0x62,0x06,0x17,0x14,0x00,0x00,0x41,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x75,0x57};
+
+//Activation of navigation system: Galileo, Glonass, GPS, SBAS, IMES
+static const uint8_t setGNSS[]={0xB5,0x62,0x06,0x3E,0x24,0x00,0x00,0x00,0x20,0x04,0x00,0x08,0x10,0x00,0x01,0x00,0x01,0x01,0x01,0x01,0x03,0x00,0x01,0x00,0x01,0x01,0x02,0x04,0x08,0x00,0x01,0x00,0x01,0x01,0x06,0x08,0x0E,0x00,0x01,0x00,0x01,0x01,0xDF,0xFB};
+
+static const uint8_t getDeviceID[]={0xB5,0x62,0x27,0x03,0x00,0x00,0x2A,0xA5};
+
+static const uint8_t getNavigatorData[]={0xB5,0x62,0x01,0x21,0x00,0x00,0x22,0x67};
+
+static const uint8_t getPOSLLHData[]={0xB5,0x62,0x01,0x02,0x00,0x00,0x03,0x0A};
+
+static const uint8_t getPVTData[]={0xB5,0x62,0x01,0x07,0x00,0x00,0x08,0x19};
+
+static const uint8_t setPortableMode[]={0xB5,0x62,0x06,0x24,0x24,0x00,0xFF,0xFF,0x00,0x03,0x00,0x00,0x00,0x00,0x10,0x27,0x00,0x00,0x05,0x00,0xFA,0x00,0xFA,0x00,0x64,0x00,0x5E,0x01,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x3C};
+
+static const uint8_t setStationaryMode[]={0xB5,0x62,0x06,0x24,0x24,0x00,0xFF,0xFF,0x02,0x03,0x00,0x00,0x00,0x00,0x10,0x27,0x00,0x00,0x05,0x00,0xFA,0x00,0xFA,0x00,0x64,0x00,0x5E,0x01,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80};
+
+static const uint8_t setPedestrianMode[]={0xB5,0x62,0x06,0x24,0x24,0x00,0xFF,0xFF,0x03,0x03,0x00,0x00,0x00,0x00,0x10,0x27,0x00,0x00,0x05,0x00,0xFA,0x00,0xFA,0x00,0x64,0x00,0x5E,0x01,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0xA2};
+
+static const uint8_t setAutomotiveMode[]={0xB5,0x62,0x06,0x24,0x24,0x00,0xFF,0xFF,0x04,0x03,0x00,0x00,0x00,0x00,0x10,0x27,0x00,0x00,0x05,0x00,0xFA,0x00,0xFA,0x00,0x64,0x00,0x5E,0x01,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0xC4};
+
+//static const uint8_t setSeaMode[]={0xB5,0x62,0x06,0x24,0x24,0x00,0xFF,0xFF,0x05,0x03,0x00,0x00,0x00,0x00,0x10,0x27,0x00,0x00,0x05,0x00,0xFA,0x00,0xFA,0x00,0x64,0x00,0x5E,0x01,0x00,0x3C,0x00,0x00,0x,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x83,0xE6};
+
+static const uint8_t setAirbone1GMode[]={0xB5,0x62,0x06,0x24,0x24,0x00,0xFF,0xFF,0x06,0x03,0x00,0x00,0x00,0x00,0x10,0x27,0x00,0x00,0x05,0x00,0xFA,0x00,0xFA,0x00,0x64,0x00,0x5E,0x01,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,0x08};
+
+static const uint8_t setAirbone2GMode[]={0xB5,0x62,0x06,0x24,0x24,0x00,0xFF,0xFF,0x07,0x03,0x00,0x00,0x00,0x00,0x10,0x27,0x00,0x00,0x05,0x00,0xFA,0x00,0xFA,0x00,0x64,0x00,0x5E,0x01,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x85,0x2A};
+
+static const uint8_t setAirbone4GMode[]={0xB5,0x62,0x06,0x24,0x24,0x00,0xFF,0xFF,0x08,0x03,0x00,0x00,0x00,0x00,0x10,0x27,0x00,0x00,0x05,0x00,0xFA,0x00,0xFA,0x00,0x64,0x00,0x5E,0x01,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x86,0x4C};
+
+static const uint8_t setWirstMode[]={0xB5,0x62,0x06,0x24,0x24,0x00,0xFF,0xFF,0x09,0x03,0x00,0x00,0x00,0x00,0x10,0x27,0x00,0x00,0x05,0x00,0xFA,0x00,0xFA,0x00,0x64,0x00,0x5E,0x01,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x87,0x6E};
+
+static const uint8_t setBikeMode[]={0xB5,0x62,0x06,0x24,0x24,0x00,0xFF,0xFF,0x0A,0x03,0x00,0x00,0x00,0x00,0x10,0x27,0x00,0x00,0x05,0x00,0xFA,0x00,0xFA,0x00,0x64,0x00,0x5E,0x01,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x90};
+
+static const uint8_t setPortableType[]={};
+void GNSS_Init(GNSS_StateHandle *GNSS, UART_HandleTypeDef *huart);
+void GNSS_LoadConfig(GNSS_StateHandle *GNSS);
+void GNSS_ParseBuffer(GNSS_StateHandle *GNSS);
+
+void GNSS_GetUniqID(GNSS_StateHandle *GNSS);
+void GNSS_ParseUniqID(GNSS_StateHandle *GNSS);
+
+void GNSS_GetNavigatorData(GNSS_StateHandle *GNSS);
+void GNSS_ParseNavigatorData(GNSS_StateHandle *GNSS);
+
+void GNSS_GetPOSLLHData(GNSS_StateHandle *GNSS);
+void GNSS_ParsePOSLLHData(GNSS_StateHandle *GNSS);
+
+void GNSS_GetPVTData(GNSS_StateHandle *GNSS);
+void GNSS_ParsePVTData(GNSS_StateHandle *GNSS);
+
+void GNSS_SetMode(GNSS_StateHandle *GNSS, short gnssMode);
+#endif /* INC_GNSS_H_ */
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Small_CPU/Src/GNSS.c	Tue Sep 03 15:30:53 2024 +0200
@@ -0,0 +1,311 @@
+/*
+ * GNSS.c
+ *
+ *  Created on: 03.10.2020
+ *      Author: SimpleMethod
+ *
+ *Copyright 2020 SimpleMethod
+ *
+ *Permission is hereby granted, free of charge, to any person obtaining a copy of
+ *this software and associated documentation files (the "Software"), to deal in
+ *the Software without restriction, including without limitation the rights to
+ *use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ *of the Software, and to permit persons to whom the Software is furnished to do
+ *so, subject to the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be included in all
+ *copies or substantial portions of the Software.
+ *
+ *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ *THE SOFTWARE.
+ ******************************************************************************
+ */
+
+#include "GNSS.h"
+
+union u_Short uShort;
+union i_Short iShort;
+union u_Long uLong;
+union i_Long iLong;
+
+/*!
+ * Structure initialization.
+ * @param GNSS Pointer to main GNSS structure.
+ * @param huart Pointer to uart handle.
+ */
+void GNSS_Init(GNSS_StateHandle *GNSS, UART_HandleTypeDef *huart) {
+	GNSS->huart = huart;
+	GNSS->year = 0;
+	GNSS->month = 0;
+	GNSS->day = 0;
+	GNSS->hour = 0;
+	GNSS->min = 0;
+	GNSS->sec = 0;
+	GNSS->fixType = 0;
+	GNSS->lon = 0;
+	GNSS->lat = 0;
+	GNSS->height = 0;
+	GNSS->hMSL = 0;
+	GNSS->hAcc = 0;
+	GNSS->vAcc = 0;
+	GNSS->gSpeed = 0;
+	GNSS->headMot = 0;
+}
+
+/*!
+ * Searching for a header in data buffer and matching class and message ID to buffer data.
+ * @param GNSS Pointer to main GNSS structure.
+ */
+void GNSS_ParseBuffer(GNSS_StateHandle *GNSS) {
+
+	for (int var = 0; var <= 100; ++var) {
+		if (GNSS->uartWorkingBuffer[var] == 0xB5
+				&& GNSS->uartWorkingBuffer[var + 1] == 0x62) {
+			if (GNSS->uartWorkingBuffer[var + 2] == 0x27
+					&& GNSS->uartWorkingBuffer[var + 3] == 0x03) { //Look at: 32.19.1.1 u-blox 8 Receiver description
+				GNSS_ParseUniqID(GNSS);
+			} else if (GNSS->uartWorkingBuffer[var + 2] == 0x01
+					&& GNSS->uartWorkingBuffer[var + 3] == 0x21) { //Look at: 32.17.14.1 u-blox 8 Receiver description
+				GNSS_ParseNavigatorData(GNSS);
+			} else if (GNSS->uartWorkingBuffer[var + 2] == 0x01
+					&& GNSS->uartWorkingBuffer[var + 3] == 0x07) { //ook at: 32.17.30.1 u-blox 8 Receiver description
+				GNSS_ParsePVTData(GNSS);
+			} else if (GNSS->uartWorkingBuffer[var + 2] == 0x01
+					&& GNSS->uartWorkingBuffer[var + 3] == 0x02) { // Look at: 32.17.15.1 u-blox 8 Receiver description
+				GNSS_ParsePOSLLHData(GNSS);
+			}
+		}
+	}
+}
+
+/*!
+ * Make request for unique chip ID data.
+ * @param GNSS Pointer to main GNSS structure.
+ */
+void GNSS_GetUniqID(GNSS_StateHandle *GNSS) {
+	HAL_UART_Transmit_DMA(GNSS->huart, getDeviceID,
+			sizeof(getDeviceID) / sizeof(uint8_t));
+	HAL_UART_Receive_IT(GNSS->huart, GNSS_Handle.uartWorkingBuffer, 17);
+}
+
+/*!
+ * Make request for UTC time solution data.
+ * @param GNSS Pointer to main GNSS structure.
+ */
+void GNSS_GetNavigatorData(GNSS_StateHandle *GNSS) {
+	HAL_UART_Transmit_DMA(GNSS->huart, getNavigatorData,
+			sizeof(getNavigatorData) / sizeof(uint8_t));
+	HAL_UART_Receive_IT(GNSS->huart, GNSS_Handle.uartWorkingBuffer, 28);
+}
+
+/*!
+ * Make request for geodetic position solution data.
+ * @param GNSS Pointer to main GNSS structure.
+ */
+void GNSS_GetPOSLLHData(GNSS_StateHandle *GNSS) {
+	HAL_UART_Transmit_DMA(GNSS->huart, getPOSLLHData,
+			sizeof(getPOSLLHData) / sizeof(uint8_t));
+	HAL_UART_Receive_IT(GNSS->huart, GNSS_Handle.uartWorkingBuffer, 36);
+}
+
+/*!
+ * Make request for navigation position velocity time solution data.
+ * @param GNSS Pointer to main GNSS structure.
+ */
+void GNSS_GetPVTData(GNSS_StateHandle *GNSS) {
+	HAL_UART_Transmit_DMA(GNSS->huart, getPVTData,
+			sizeof(getPVTData) / sizeof(uint8_t));
+	HAL_UART_Receive_IT(GNSS->huart, GNSS_Handle.uartWorkingBuffer, 100);
+}
+
+/*!
+ * Parse data to unique chip ID standard.
+ * Look at: 32.19.1.1 u-blox 8 Receiver description
+ * @param GNSS Pointer to main GNSS structure.
+ */
+void GNSS_ParseUniqID(GNSS_StateHandle *GNSS) {
+	for (int var = 0; var < 5; ++var) {
+		GNSS->uniqueID[var] = GNSS_Handle.uartWorkingBuffer[10 + var];
+	}
+}
+
+/*!
+ * Changing the GNSS mode.
+ * Look at: 32.10.19 u-blox 8 Receiver description
+ */
+void GNSS_SetMode(GNSS_StateHandle *GNSS, short gnssMode) {
+	if (gnssMode == 0) {
+		HAL_UART_Transmit_DMA(GNSS->huart, setPortableMode,sizeof(setPortableMode) / sizeof(uint8_t));
+	} else if (gnssMode == 1) {
+		HAL_UART_Transmit_DMA(GNSS->huart, setStationaryMode,sizeof(setStationaryMode) / sizeof(uint8_t));
+	} else if (gnssMode == 2) {
+		HAL_UART_Transmit_DMA(GNSS->huart, setPedestrianMode,sizeof(setPedestrianMode) / sizeof(uint8_t));
+	} else if (gnssMode == 3) {
+		HAL_UART_Transmit_DMA(GNSS->huart, setAutomotiveMode,sizeof(setAutomotiveMode) / sizeof(uint8_t));
+	} else if (gnssMode == 4) {
+		HAL_UART_Transmit_DMA(GNSS->huart, setAutomotiveMode,sizeof(setAutomotiveMode) / sizeof(uint8_t));
+	} else if (gnssMode == 5) {
+		HAL_UART_Transmit_DMA(GNSS->huart, setAirbone1GMode,sizeof(setAirbone1GMode) / sizeof(uint8_t));
+	} else if (gnssMode == 6) {
+		HAL_UART_Transmit_DMA(GNSS->huart, setAirbone2GMode,sizeof(setAirbone2GMode) / sizeof(uint8_t));
+	} else if (gnssMode == 7) {
+		HAL_UART_Transmit_DMA(GNSS->huart, setAirbone4GMode,sizeof(setAirbone4GMode) / sizeof(uint8_t));
+	} else if (gnssMode == 8) {
+		HAL_UART_Transmit_DMA(GNSS->huart, setWirstMode,sizeof(setWirstMode) / sizeof(uint8_t));
+	} else if (gnssMode == 9) {
+		HAL_UART_Transmit_DMA(GNSS->huart, setBikeMode,sizeof(setBikeMode) / sizeof(uint8_t));
+	}
+}
+/*!
+ * Parse data to navigation position velocity time solution standard.
+ * Look at: 32.17.15.1 u-blox 8 Receiver description.
+ * @param GNSS Pointer to main GNSS structure.
+ */
+void GNSS_ParsePVTData(GNSS_StateHandle *GNSS) {
+	uShort.bytes[0] = GNSS_Handle.uartWorkingBuffer[10];
+	GNSS->yearBytes[0]=GNSS_Handle.uartWorkingBuffer[10];
+	uShort.bytes[1] = GNSS_Handle.uartWorkingBuffer[11];
+	GNSS->yearBytes[1]=GNSS_Handle.uartWorkingBuffer[11];
+	GNSS->year = uShort.uShort;
+	GNSS->month = GNSS_Handle.uartWorkingBuffer[12];
+	GNSS->day = GNSS_Handle.uartWorkingBuffer[13];
+	GNSS->hour = GNSS_Handle.uartWorkingBuffer[14];
+	GNSS->min = GNSS_Handle.uartWorkingBuffer[15];
+	GNSS->sec = GNSS_Handle.uartWorkingBuffer[16];
+	GNSS->fixType = GNSS_Handle.uartWorkingBuffer[26];
+
+	for (int var = 0; var < 4; ++var) {
+		iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 30];
+		GNSS->lonBytes[var]= GNSS_Handle.uartWorkingBuffer[var + 30];
+	}
+	GNSS->lon = iLong.iLong;
+	GNSS->fLon=(float)iLong.iLong/10000000.0;
+	for (int var = 0; var < 4; ++var) {
+		iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 34];
+		GNSS->latBytes[var]=GNSS_Handle.uartWorkingBuffer[var + 34];
+	}
+	GNSS->lat = iLong.iLong;
+	GNSS->fLat=(float)iLong.iLong/10000000.0;
+	for (int var = 0; var < 4; ++var) {
+		iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 38];
+	}
+	GNSS->height = iLong.iLong;
+
+	for (int var = 0; var < 4; ++var) {
+		iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 42];
+		GNSS->hMSLBytes[var] = GNSS_Handle.uartWorkingBuffer[var + 42];
+	}
+	GNSS->hMSL = iLong.iLong;
+
+	for (int var = 0; var < 4; ++var) {
+		uLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 46];
+	}
+	GNSS->hAcc = uLong.uLong;
+
+	for (int var = 0; var < 4; ++var) {
+		uLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 50];
+	}
+	GNSS->vAcc = uLong.uLong;
+
+	for (int var = 0; var < 4; ++var) {
+		iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 66];
+		GNSS->gSpeedBytes[var] = GNSS_Handle.uartWorkingBuffer[var + 66];
+	}
+	GNSS->gSpeed = iLong.iLong;
+
+	for (int var = 0; var < 4; ++var) {
+		iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 70];
+	}
+	GNSS->headMot = iLong.iLong * 1e-5; // todo I'm not sure this good options.
+}
+
+/*!
+ * Parse data to UTC time solution standard.
+ * Look at: 32.17.30.1 u-blox 8 Receiver description.
+ * @param GNSS Pointer to main GNSS structure.
+ */
+void GNSS_ParseNavigatorData(GNSS_StateHandle *GNSS) {
+	uShort.bytes[0] = GNSS_Handle.uartWorkingBuffer[18];
+	uShort.bytes[1] = GNSS_Handle.uartWorkingBuffer[19];
+	GNSS->year = uShort.uShort;
+	GNSS->month = GNSS_Handle.uartWorkingBuffer[20];
+	GNSS->day = GNSS_Handle.uartWorkingBuffer[21];
+	GNSS->hour = GNSS_Handle.uartWorkingBuffer[22];
+	GNSS->min = GNSS_Handle.uartWorkingBuffer[23];
+	GNSS->sec = GNSS_Handle.uartWorkingBuffer[24];
+}
+
+/*!
+ * Parse data to geodetic position solution standard.
+ * Look at: 32.17.14.1 u-blox 8 Receiver description.
+ * @param GNSS Pointer to main GNSS structure.
+ */
+void GNSS_ParsePOSLLHData(GNSS_StateHandle *GNSS) {
+	for (int var = 0; var < 4; ++var) {
+		iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 10];
+	}
+	GNSS->lon = iLong.iLong;
+	GNSS->fLon=(float)iLong.iLong/10000000.0;
+
+	for (int var = 0; var < 4; ++var) {
+		iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 14];
+	}
+	GNSS->lat = iLong.iLong;
+	GNSS->fLat=(float)iLong.iLong/10000000.0;
+
+	for (int var = 0; var < 4; ++var) {
+		iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 18];
+	}
+	GNSS->height = iLong.iLong;
+
+	for (int var = 0; var < 4; ++var) {
+		iLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 22];
+	}
+	GNSS->hMSL = iLong.iLong;
+
+	for (int var = 0; var < 4; ++var) {
+		uLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 26];
+	}
+	GNSS->hAcc = uLong.uLong;
+
+	for (int var = 0; var < 4; ++var) {
+		uLong.bytes[var] = GNSS_Handle.uartWorkingBuffer[var + 30];
+	}
+	GNSS->vAcc = uLong.uLong;
+}
+
+/*!
+ *  Sends the basic configuration: Activation of the UBX standard, change of NMEA version to 4.10 and turn on of the Galileo system.
+ * @param GNSS Pointer to main GNSS structure.
+ */
+void GNSS_LoadConfig(GNSS_StateHandle *GNSS) {
+	HAL_UART_Transmit_DMA(GNSS->huart, configUBX,
+			sizeof(configUBX) / sizeof(uint8_t));
+	HAL_Delay(250);
+	HAL_UART_Transmit_DMA(GNSS->huart, setNMEA410,
+			sizeof(setNMEA410) / sizeof(uint8_t));
+	HAL_Delay(250);
+	HAL_UART_Transmit_DMA(GNSS->huart, setGNSS,
+			sizeof(setGNSS) / sizeof(uint8_t));
+	HAL_Delay(250);
+}
+
+
+
+/*!
+ *  Creates a checksum based on UBX standard.
+ * @param class Class value from UBX doc.
+ * @param messageID MessageID value from UBX doc.
+ * @param dataLength Data length value from UBX doc.
+ * @param payload Just payload.
+ * @return  Returns checksum.
+ */
+uint8_t GNSS_Checksum(uint8_t class, uint8_t messageID, uint8_t dataLength,uint8_t *payload) {
+//todo: Look at 32.4 UBX Checksum
+	return 0;
+}
--- a/Small_CPU/Src/baseCPU2.c	Sun Sep 01 21:38:06 2024 +0200
+++ b/Small_CPU/Src/baseCPU2.c	Tue Sep 03 15:30:53 2024 +0200
@@ -216,6 +216,8 @@
 #define LED_CONTROL_PIN_RED        		GPIO_PIN_2		/* PortA */
 #define LED_CONTROL_PIN_GREEN      		GPIO_PIN_1		/* PortA */
 #define MAINCPU_CONTROL_PIN				GPIO_PIN_0		/* PortC */
+#define	GPS_POWER_CONTROL_PIN			GPIO_PIN_15		/* PortB */
+#define	GPS_BCKP_CONTROL_PIN			GPIO_PIN_14		/* PortB */
 
 /* Private macro -------------------------------------------------------------*/
 
@@ -237,6 +239,10 @@
 static void GPIO_LED_GREEN_ON(void);
 static void GPIO_VIBRATION_OFF(void);
 static void GPIO_VIBRATION_ON(void);
+static void GPIO_GPS_OFF(void);
+static void GPIO_GPS_ON(void);
+static void GPIO_GPS_BCKP_OFF(void);
+static void GPIO_GPS_BCKP_ON(void);
 
 #ifdef DEBUG_I2C_LINES
 void GPIO_test_I2C_lines(void);
@@ -413,6 +419,8 @@
 				HAL_Delay(100);
 				GPIO_LED_RED_OFF();
 				GPIO_VIBRATION_OFF();
+				GPIO_GPS_ON();
+				GPIO_GPS_BCKP_ON();
 			}
 			SPI_synchronize_with_Master();
 			MX_DMA_Init();
@@ -476,25 +484,13 @@
 			break;
 
 		case MODE_SLEEP:
-			/*
-			 sleep_prepare();
-			 scheduleSleepMode_test();
-			 */
-			/*
-			 GPIO_Power_MainCPU_OFF();
-			 EXTI_Test_Button_DeInit();
-			 EXTI_Wakeup_Button_Init();
-			 NOT_USED_AT_THE_MOMENT_scheduleSleepMode();
-			 */
-
 			externalInterface_SwitchUART(EXT_INTERFACE_UART_OFF);
 			externalInterface_SwitchPower33(false);
 			if (hasExternalClock())
 				SystemClock_Config_HSI();
+			GPIO_LEDs_VIBRATION_Init();
 			sleep_prepare();
 
-			GPIO_LEDs_VIBRATION_Init();
-
 			scheduleSleepMode();
 			if (hasExternalClock())
 				SystemClock_Config_HSE();
@@ -597,7 +593,7 @@
 
 	__PWR_CLK_ENABLE(); // is identical to __HAL_RCC_PWR_CLK_ENABLE();
 
-	__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
+	__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 
 	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; //|RCC_OSCILLATORTYPE_LSE;
 	RCC_OscInitStruct.HSEState = RCC_HSE_ON;
@@ -640,7 +636,7 @@
 	/* The voltage scaling allows optimizing the power consumption when the device is
 	 clocked below the maximum system frequency, to update the voltage scaling value
 	 regarding system frequency refer to product datasheet.  */
-	__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
+	__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 
 	/* Enable HSI Oscillator and activate PLL with HSI as source */
 	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
@@ -664,44 +660,7 @@
 	RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 	HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
 }
-/*	
- RCC_OscInitTypeDef RCC_OscInitStruct;
- RCC_ClkInitTypeDef RCC_ClkInitStruct;
- 
- __HAL_RCC_PWR_CLK_ENABLE();
 
- //__PWR_CLK_ENABLE();
-
- __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
-
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSE;
- RCC_OscInitStruct.LSEState = RCC_LSE_ON;
- RCC_OscInitStruct.HSIState = RCC_HSI_ON;
- RCC_OscInitStruct.HSICalibrationValue = 16;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
- RCC_OscInitStruct.PLL.PLLM = 16;
- RCC_OscInitStruct.PLL.PLLN = 320;
- RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
- RCC_OscInitStruct.PLL.PLLQ = 4;
- HAL_RCC_OscConfig(&RCC_OscInitStruct);
-
- RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1;
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
- HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
- }
-
- static void RtcClock_Config(void)
- {
- RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
- PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
- PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
- HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
- }
- */
 
 /**
  * @brief  Configures system clock after wake-up from STOP: enable HSI, PLL
@@ -816,6 +775,20 @@
 	GPIO_InitStructure.Pull = GPIO_PULLDOWN;
 	GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
 	HAL_GPIO_Init( GPIOA, &GPIO_InitStructure);
+
+	__GPIOB_CLK_ENABLE();
+	GPIO_InitStructure.Pin = GPS_POWER_CONTROL_PIN;
+	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
+	GPIO_InitStructure.Pull = GPIO_PULLUP;
+	GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
+	HAL_GPIO_Init( GPIOB, &GPIO_InitStructure);
+
+	GPIO_InitStructure.Pin = GPS_BCKP_CONTROL_PIN;
+	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
+	GPIO_InitStructure.Pull = GPIO_PULLDOWN;
+	GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
+	HAL_GPIO_Init( GPIOB, &GPIO_InitStructure);
+
 }
 
 void GPIO_new_DEBUG_Init(void) {
@@ -886,6 +859,22 @@
 	HAL_GPIO_WritePin( GPIOA, VIBRATION_CONTROL_PIN, GPIO_PIN_RESET);
 }
 
+static void GPIO_GPS_ON(void) {
+	HAL_GPIO_WritePin( GPIOB, GPS_POWER_CONTROL_PIN, GPIO_PIN_RESET);
+}
+
+static void GPIO_GPS_OFF(void) {
+	HAL_GPIO_WritePin( GPIOB, GPS_POWER_CONTROL_PIN, GPIO_PIN_SET);
+}
+
+static void GPIO_GPS_BCKP_ON(void) {
+	HAL_GPIO_WritePin( GPIOB, GPS_BCKP_CONTROL_PIN, GPIO_PIN_SET);
+}
+
+static void GPIO_GPS_BCKP_OFF(void) {
+	HAL_GPIO_WritePin( GPIOB, GPS_BCKP_CONTROL_PIN, GPIO_PIN_RESET);
+}
+
 
 /**
  * @brief  Configures EXTI Line0 (connected to PA0 + PA1 pin) in interrupt mode
@@ -966,22 +955,22 @@
 	__HAL_RCC_GPIOH_CLK_ENABLE();
 
 	GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
-	GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+	GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
 	GPIO_InitStruct.Pull = GPIO_NOPULL;
 	GPIO_InitStruct.Pin = GPIO_PIN_All;
 	HAL_GPIO_Init( GPIOH, &GPIO_InitStruct);
 #ifdef DEBUGMODE
 	GPIO_InitStruct.Pin = GPIO_PIN_All ^ ( GPIO_PIN_3 | GPIO_PIN_8 | GPIO_PIN_9); /* debug */
 #endif
+
+	GPIO_InitStruct.Pin = GPIO_PIN_All ^ (GPS_POWER_CONTROL_PIN | GPS_BCKP_CONTROL_PIN);
 	HAL_GPIO_Init( GPIOB, &GPIO_InitStruct);
 
-	GPIO_InitStruct.Pin =
-			GPIO_PIN_All
-					^ ( MAINCPU_CONTROL_PIN | CHARGE_OUT_PIN | CHARGE_IN_PIN | EXT33V_CONTROL_PIN | LED_CONTROL_PIN_RED | LED_CONTROL_PIN_GREEN); /* power off & charger in & charge out & OSC32 & ext33Volt */
+	GPIO_InitStruct.Pin =  GPIO_PIN_All ^ ( MAINCPU_CONTROL_PIN | CHARGE_OUT_PIN | EXT33V_CONTROL_PIN); /* power off & charger in & charge out & OSC32 & ext33Volt */
 
 	HAL_GPIO_Init( GPIOC, &GPIO_InitStruct);
 
-	GPIO_InitStruct.Pin = GPIO_PIN_All ^ ( GPIO_PIN_0);
+	GPIO_InitStruct.Pin = GPIO_PIN_All ^ ( GPIO_PIN_0 | VIBRATION_CONTROL_PIN | LED_CONTROL_PIN_RED | LED_CONTROL_PIN_GREEN);
 #ifdef DEBUGMODE
 	GPIO_InitStruct.Pin = GPIO_PIN_All ^ ( GPIO_PIN_0 | GPIO_PIN_13 | GPIO_PIN_14); /* wake up button & debug */
 #endif
@@ -993,6 +982,9 @@
 	GPIO_Power_MainCPU_OFF();
 	GPIO_LED_GREEN_OFF();
 	GPIO_LED_RED_OFF();
+	GPIO_VIBRATION_OFF();
+	GPIO_GPS_BCKP_ON();			// mH : costs 100µA in sleep - beware
+	GPIO_GPS_OFF();
 
 
 #ifndef DEBUGMODE