2
0

2 Commity cfa8715ef4 ... 0dda453a7b

Autor SHA1 Správa Dátum
  Juraj Ďuďák 0dda453a7b doplnok 2 1 mesiac pred
  Juraj Ďuďák f64f93b624 doplnok 1 mesiac pred
5 zmenil súbory, kde vykonal 269 pridanie a 82 odobranie
  1. 75 11
      README.md
  2. 1 0
      inc/HAL_STM32_config.h
  3. 24 0
      inc/HAL_impl.h
  4. 8 71
      src/DMP_ICM20948.cpp
  5. 161 0
      src/HAL_impl.c

+ 75 - 11
README.md

@@ -1,7 +1,72 @@
 # DMP-ICM20948
+Knižnica je odvodená z knižnice https://github.com/isouriadakis/Arduino_ICM20948_DMP_Full-Function
 
+Vlastnosti
+- port pre STM32 
+- Rozhranie I2C, SPI
+- Obsahuje originál FW pre čip ICM20948 
+- Výstup sú surové dáta alebo spracované cez DMP
+
+## Opis rozhrania
+Pre implementáciu na STM32 je potrtebné skontrolovať súbory:
+- HAL_STM32_Config.h 
+  - konštanta USE_SPI definuje rozhranie, ktoré bude použité pre low-level komunikáciu
+  - tento súbor je závislý na konfigurácii hlavnej aplikácie `main.h`, v ktorom sú definované piny pre SPI rozhranie. Pimny musia byť pomenované nasledovne:
+    - SPI_CS
+  - tento súbor je závislý na *hal* konfigurácii `stm32l0xx_hal.h` 
+- HAL_impl.c
+  - obsahuje implementáciu low-level komunikácie cez I2C/SPI
+
+## Vzorový kód
 ```c
 // app.cpp
+#include "app.h"
+
+extern SPI_HandleTypeDef hspi1;
+extern UART_HandleTypeDef huart1;
+
+volatile uint8_t tx_ready = 1;
+
+void tx_done(UART_HandleTypeDef *h)
+{
+	tx_ready = 1;
+}
+
+void run_icm20948_quat6_controller(DMP_ICM20948 *icm20948, uint8_t inEuler)
+{
+    float quat_w, quat_x, quat_y, quat_z;
+    float roll, pitch, yaw;
+    char sensor_string_buff[128];
+    uint8_t byte_angles[128];
+    float float_angles[3] = {0,0,0};
+    if (inEuler)
+    {
+        if (icm20948->euler6DataIsReady())
+        {
+
+            if (tx_ready == 1){
+            	icm20948->readEuler6Data(&roll, &pitch, &yaw);
+            	float_angles[0] = roll;
+            	float_angles[1] = pitch;
+            	float_angles[2] = yaw;
+            	memcpy(byte_angles, float_angles, sizeof(float_angles));
+            	tx_ready = 0;
+                uint8_t ok = HAL_UART_Transmit_DMA(&huart1, byte_angles, 3*sizeof(float));
+                if(ok == HAL_OK){
+            	   HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
+                }
+           }
+        }
+    }
+    else
+    {
+        if (icm20948->quat6DataIsReady())
+        {
+            icm20948->readQuat6Data(&quat_w, &quat_x, &quat_y, &quat_z);
+        }
+    }
+
+}
 
 void app() {
 
@@ -18,19 +83,20 @@ void app() {
 	  .enable_quaternion9 = false,         // Enables quaternion 9DOF output
 	  .enable_har = false,                 // Enables activity recognition
 	  .enable_steps = false,               // Enables step counter
-	  .gyroscope_frequency = 1,           // Max frequency = 225, min frequency = 1
-	  .accelerometer_frequency = 1,       // Max frequency = 225, min frequency = 1
-	  .magnetometer_frequency = 1,        // Max frequency = 70, min frequency = 1
-	  .gravity_frequency = 1,             // Max frequency = 225, min frequency = 1
-	  .linearAcceleration_frequency = 1,  // Max frequency = 225, min frequency = 1
-	  .quaternion6_frequency = 50,        // Max frequency = 225, min frequency = 50
+	  .gyroscope_frequency = 225,           // Max frequency = 225, min frequency = 1
+	  .accelerometer_frequency = 225,       // Max frequency = 225, min frequency = 1
+	  .magnetometer_frequency = 70,        // Max frequency = 70, min frequency = 1
+	  .gravity_frequency = 225,             // Max frequency = 225, min frequency = 1
+	  .linearAcceleration_frequency = 225,  // Max frequency = 225, min frequency = 1
+	  .quaternion6_frequency = 225,        // Max frequency = 225, min frequency = 50
 	  .quaternion9_frequency = 50,        // Max frequency = 225, min frequency = 50
-	  .har_frequency = 50,                // Max frequency = 225, min frequency = 50
-	  .steps_frequency = 50               // Max frequency = 225, min frequency = 50
+	  .har_frequency = 225,                // Max frequency = 225, min frequency = 50
+	  .steps_frequency =225               // Max frequency = 225, min frequency = 50
 
 	};
 
 	icm.init(icmSettings);
+	HAL_UART_RegisterCallback(&huart1, HAL_UART_TX_COMPLETE_CB_ID, tx_done);
 
 
 	while(1){
@@ -46,9 +112,7 @@ void app() {
 		    //run_icm20948_har_controller();
 		    //run_icm20948_steps_controller();
 
-		//HAL_UART_Transmit(&huart2, (const uint8_t*)sensor_string_buff, 5, 1000);
-
-		HAL_Delay(100);
+		HAL_Delay(100);  // pozor na tento delay
 	}
 
 }

+ 1 - 0
inc/HAL_STM32_config.h

@@ -10,6 +10,7 @@
 
 #include "stm32l0xx_hal.h"
 #include "HAL_impl.h"
+#include "main.h"
 
 #define USE_SPI 1
 

+ 24 - 0
inc/HAL_impl.h

@@ -0,0 +1,24 @@
+#ifndef _HAL_IMPLEMENTATION_H_
+#define _HAL_IMPLEMENTATION_H_
+
+#include "HAL_STM32_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+void initiliaze_SPI(void);
+int spi_master_read_register(uint8_t reg, uint8_t* rbuffer, uint32_t rlen);
+int spi_master_write_register(uint8_t reg, const uint8_t* wbuffer, uint32_t wlen);
+
+void initiliaze_I2C(void);
+int i2c_master_write_register(uint8_t address, uint8_t reg, uint32_t len, const uint8_t *data);
+int i2c_master_read_register(uint8_t address, uint8_t reg, uint32_t len, uint8_t *buff);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif

+ 8 - 71
src/DMP_ICM20948.cpp

@@ -51,61 +51,6 @@ unsigned long steps;
 bool steps_data_ready = false;
 
 
-
-
-
-int i2c_master_write_register(uint8_t address, uint8_t reg, uint32_t len, const uint8_t *data)
-{
-
-#ifdef HAL_I2C_MODULE_ENABLED
-
-	HAL_StatusTypeDef status = HAL_I2C_Mem_Write(
-        &I2C_INSTANCE,
-        (address << 1),       // STM32 expects 8-bit address
-        reg,                  // Register address
-        I2C_MEMADD_SIZE_8BIT, // Register size
-        (uint8_t *)data,
-        len,
-        HAL_MAX_DELAY
-    );
-
-    if (status != HAL_OK)
-    {
-
-        return -1;
-    }
-
-#endif // HAL_I2C_MODULE_ENABLED
-
-    return 0;
-}
-
-int i2c_master_read_register(uint8_t address, uint8_t reg, uint32_t len, uint8_t *buff)
-{
-
-#ifdef HAL_I2C_MODULE_ENABLED
-
-    HAL_StatusTypeDef status = HAL_I2C_Mem_Read(
-        &I2C_INSTANCE,
-        (address << 1),       // STM32 expects 8-bit address
-        reg,                  // Register address
-        I2C_MEMADD_SIZE_8BIT, // Register size
-        buff,
-        len,
-        HAL_MAX_DELAY
-    );
-
-    if (status != HAL_OK)
-    {
-        return -1;
-    }
-
-#endif // HAL_I2C_MODULE_ENABLED
-
-    return 0;
-}
-
-
 /*************************************************************************
   Invensense Variables
 *************************************************************************/
@@ -163,21 +108,13 @@ uint64_t inv_icm20948_get_time_us(void)
 }
 
 
+//bool is_interface_SPI = false;
 
-void initiliaze_I2C(void)
-{
-#ifdef HAL_I2C_MODULE_ENABLED
-	I2C_Address = I2C_ADDRESS;
-#endif
-}
-
-bool is_interface_SPI = false;
-
-void set_comm_interface(DMP_ICM20948Settings settings)
+void set_comm_interface()
 {
-    is_interface_SPI = IS_SPI;
+//    is_interface_SPI = IS_SPI;
 
-    if (is_interface_SPI)
+    if (IS_SPI)
     {
         initiliaze_SPI();
     }
@@ -189,13 +126,13 @@ void set_comm_interface(DMP_ICM20948Settings settings)
 }
 inv_bool_t interface_is_SPI(void)
 {
-  return is_interface_SPI;
+  return IS_SPI;
 }
 
 //---------------------------------------------------------------------
 int idd_io_hal_read_reg(void *context, uint8_t reg, uint8_t *rbuffer, uint32_t rlen)
 {
-    if (interface_is_SPI())
+    if (IS_SPI)
     {
         return spi_master_read_register(reg, rbuffer, rlen);
     }
@@ -206,7 +143,7 @@ int idd_io_hal_read_reg(void *context, uint8_t reg, uint8_t *rbuffer, uint32_t r
 
 int idd_io_hal_write_reg(void *context, uint8_t reg, const uint8_t *wbuffer, uint32_t wlen)
 {
-    if (interface_is_SPI())
+	if (IS_SPI)
     {
         return spi_master_write_register(reg, wbuffer, wlen);
     }
@@ -514,7 +451,7 @@ DMP_ICM20948::DMP_ICM20948()
 
 void DMP_ICM20948::init(DMP_ICM20948Settings settings)
 {
-  set_comm_interface(settings);
+  set_comm_interface();
   ///Serial.println("Initializing ICM-20948...");
 
   // Initialize icm20948 serif structure

+ 161 - 0
src/HAL_impl.c

@@ -0,0 +1,161 @@
+#include "HAL_impl.h"
+
+// Funkcia na nastavenie CS pinu
+static inline void CS_Select(void) {
+    HAL_GPIO_WritePin(CHIP_SELECT_PORT, CHIP_SELECT_PIN, GPIO_PIN_RESET);
+}
+
+static inline void CS_Deselect(void) {
+    HAL_GPIO_WritePin(CHIP_SELECT_PORT, CHIP_SELECT_PIN, GPIO_PIN_SET);
+}
+
+
+/*---------------------------------------------------------------------*/
+/*                                SPI                                  */
+/*---------------------------------------------------------------------*/
+
+void initiliaze_SPI(void)
+{
+    CS_Deselect();
+    uint8_t dummy = 0x00;
+    HAL_SPI_Transmit(&SPI_INSTANCE, &dummy, 1, HAL_MAX_DELAY);
+}
+
+
+int spi_master_read_register(uint8_t reg, uint8_t* rbuffer, uint32_t rlen)
+{
+#ifdef HAL_SPI_MODULE_ENABLED
+
+	uint8_t dummy = 0x00;
+	uint8_t status = HAL_SPI_Transmit(&SPI_INSTANCE, &dummy, 1, HAL_MAX_DELAY);
+	if (status != HAL_OK) return status;
+
+	CS_Select();
+
+    // 3. Adresovanie registra
+    uint8_t cmd = (reg & 0x7F) | 0x80;
+    status = HAL_SPI_Transmit(&SPI_INSTANCE, &cmd, 1, HAL_MAX_DELAY);
+
+    // 4. Čítanie dát
+    for (uint32_t indi = 0; indi < rlen; indi++) {
+        uint8_t rx = 0x00;
+        status = HAL_SPI_TransmitReceive(&SPI_INSTANCE, &rx, &rbuffer[indi], 1, HAL_MAX_DELAY);
+        if (status != HAL_OK) {
+            CS_Deselect();
+            return status;
+        }
+    }
+
+    // 5. Chip select HIGH
+    CS_Deselect();
+
+#endif // HAL_SPI_MODULE_ENABLED
+
+    return 0;
+}
+
+int spi_master_write_register(uint8_t reg, const uint8_t* wbuffer, uint32_t wlen)
+{
+
+#ifdef HAL_SPI_MODULE_ENABLED
+
+	HAL_StatusTypeDef status;
+	uint8_t dummy = 0x00;
+	uint8_t addr  = (reg & 0x7F) | 0x00;
+
+	// 1. Dummy transfer (pôvodne SPI.transfer(0x00) mimo transakcie)
+	status = HAL_SPI_Transmit(&SPI_INSTANCE, &dummy, 1, HAL_MAX_DELAY);
+	if (status != HAL_OK) return -1;
+
+	// 2. Chip Select LOW
+	CS_Select();
+
+	// 3. Odoslanie adresy registra
+	status = HAL_SPI_Transmit(&SPI_INSTANCE, &addr, 1, HAL_MAX_DELAY);
+	if (status != HAL_OK) {
+		CS_Deselect();
+		return -2;
+	}
+
+	// 4. Odoslanie všetkých dát
+	if (wlen > 0) {
+		status = HAL_SPI_Transmit(&SPI_INSTANCE, (uint8_t*)wbuffer, wlen, HAL_MAX_DELAY);
+		if (status != HAL_OK) {
+			CS_Deselect();
+			return -3;
+		}
+	}
+
+	// 5. Chip Select HIGH
+	CS_Deselect();
+
+#endif // HAL_SPI_MODULE_ENABLED
+
+	return 0;
+}
+
+/*---------------------------------------------------------------------*/
+/*                                I2C                                  */
+/*---------------------------------------------------------------------*/
+
+void initiliaze_I2C(void)
+{
+#ifdef HAL_I2C_MODULE_ENABLED
+	I2C_Address = I2C_ADDRESS;
+#endif
+}
+
+
+
+int i2c_master_write_register(uint8_t address, uint8_t reg, uint32_t len, const uint8_t *data)
+{
+
+#ifdef HAL_I2C_MODULE_ENABLED
+
+	HAL_StatusTypeDef status = HAL_I2C_Mem_Write(
+        &I2C_INSTANCE,
+        (address << 1),       // STM32 expects 8-bit address
+        reg,                  // Register address
+        I2C_MEMADD_SIZE_8BIT, // Register size
+        (uint8_t *)data,
+        len,
+        HAL_MAX_DELAY
+    );
+
+    if (status != HAL_OK)
+    {
+
+        return -1;
+    }
+
+#endif // HAL_I2C_MODULE_ENABLED
+
+    return 0;
+}
+
+int i2c_master_read_register(uint8_t address, uint8_t reg, uint32_t len, uint8_t *buff)
+{
+
+#ifdef HAL_I2C_MODULE_ENABLED
+
+    HAL_StatusTypeDef status = HAL_I2C_Mem_Read(
+        &I2C_INSTANCE,
+        (address << 1),       // STM32 expects 8-bit address
+        reg,                  // Register address
+        I2C_MEMADD_SIZE_8BIT, // Register size
+        buff,
+        len,
+        HAL_MAX_DELAY
+    );
+
+    if (status != HAL_OK)
+    {
+        return -1;
+    }
+
+#endif // HAL_I2C_MODULE_ENABLED
+
+    return 0;
+}
+
+