From df83a822859090b7d564c1778a647693eb1f050c Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sun, 20 Mar 2022 09:52:35 +0100 Subject: [PATCH] EEPROM & Digital Volume I2C driver using generic I2C HAL driver --- radio/src/CMakeLists.txt | 3 - radio/src/hal/eeprom_driver.h | 30 ++ radio/src/opentx.cpp | 4 + radio/src/storage/eeprom_raw.h | 67 --- radio/src/storage/eeprom_rlc.cpp | 1 + radio/src/storage/eeprom_rlc.h | 2 - .../arm/stm32/bootloader/CMakeLists.txt | 8 +- .../common/arm/stm32/bootloader/boot.cpp | 5 +- .../common/arm/stm32/f2/CMakeLists.txt | 6 +- .../src/targets/common/arm/stm32/stm32_hal.h | 1 + .../common/arm/stm32/stm32_i2c_driver.cpp | 75 +++- .../common/arm/stm32/stm32_i2c_driver.h | 10 + .../common/arm/stm32/stm32f2xx_hal_conf.h | 425 ++++++++++++++++++ radio/src/targets/taranis/CMakeLists.txt | 3 +- radio/src/targets/taranis/board.cpp | 3 - radio/src/targets/taranis/board.h | 8 - radio/src/targets/taranis/eeprom_driver.cpp | 171 +++++++ radio/src/targets/taranis/hal.h | 100 ++--- radio/src/targets/taranis/i2c_driver.cpp | 293 ------------ radio/src/targets/taranis/volume_i2c.cpp | 56 +++ 20 files changed, 821 insertions(+), 450 deletions(-) create mode 100644 radio/src/hal/eeprom_driver.h delete mode 100644 radio/src/storage/eeprom_raw.h create mode 100644 radio/src/targets/common/arm/stm32/stm32f2xx_hal_conf.h create mode 100644 radio/src/targets/taranis/eeprom_driver.cpp delete mode 100644 radio/src/targets/taranis/i2c_driver.cpp create mode 100644 radio/src/targets/taranis/volume_i2c.cpp diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index dc0272f80..44ea98dc3 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -180,9 +180,6 @@ elseif(${STORAGE} STREQUAL EEPROM) if(${STORAGE_FORMAT} STREQUAL RLC) set(SRC ${SRC} storage/eeprom_rlc.cpp) add_definitions(-DEEPROM_RLC) - elseif(${STORAGE_FORMAT} STREQUAL RAW) - set(SRC ${SRC} storage/eeprom_raw.cpp) - add_definitions(-DEEPROM_RAW) else() set(SRC ${SRC} storage/eeprom_none.cpp) add_definitions(-DEEPROM_NONE) diff --git a/radio/src/hal/eeprom_driver.h b/radio/src/hal/eeprom_driver.h new file mode 100644 index 000000000..9f0e4443e --- /dev/null +++ b/radio/src/hal/eeprom_driver.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#pragma once + +#include + +void eepromInit(); +void eepromReadBlock(uint8_t * buffer, size_t address, size_t size); +void eepromWriteBlock(uint8_t * buffer, size_t address, size_t size); + +uint8_t eepromIsTransferComplete(); diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 9347d57a6..d1f258c5d 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -1876,6 +1876,10 @@ int main() } #endif +#if defined(EEPROM) && defined(EEPROM_RLC) + eepromInit(); +#endif + tasksStart(); } diff --git a/radio/src/storage/eeprom_raw.h b/radio/src/storage/eeprom_raw.h deleted file mode 100644 index 116b2763f..000000000 --- a/radio/src/storage/eeprom_raw.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _EEPROM_RAW_H_ -#define _EEPROM_RAW_H_ - -#include -#include - -bool eeLoadGeneral(bool allowFixes); -void eeDeleteModel( uint8_t id ); -bool eeCopyModel(uint8_t dst, uint8_t src); -void eeSwapModels(uint8_t id1, uint8_t id2); - -#if defined(SDCARD) -const char * eeBackupModel(uint8_t i_fileSrc); -const char * eeRestoreModel(uint8_t i_fileDst, char *model_name); -#endif - -enum EepromWriteState { - EEPROM_IDLE = 0, - EEPROM_START_WRITE, - EEPROM_ERASING_FILE_BLOCK1, - EEPROM_ERASING_FILE_BLOCK1_WAIT, - EEPROM_ERASE_FILE_BLOCK2, - EEPROM_ERASING_FILE_BLOCK2, - EEPROM_ERASING_FILE_BLOCK2_WAIT, - EEPROM_WRITE_BUFFER, - EEPROM_WRITING_BUFFER, - EEPROM_WRITING_BUFFER_WAIT, - EEPROM_WRITE_NEXT_BUFFER, - EEPROM_ERASING_FAT_BLOCK, - EEPROM_ERASING_FAT_BLOCK_WAIT, - EEPROM_WRITE_NEW_FAT, - EEPROM_WRITING_NEW_FAT, - EEPROM_WRITING_NEW_FAT_WAIT, - EEPROM_END_WRITE -}; - -extern volatile EepromWriteState eepromWriteState; -inline bool eepromIsWriting() -{ - return (eepromWriteState != EEPROM_IDLE); -} -void eepromWriteProcess(); -void eepromWriteWait(EepromWriteState state = EEPROM_IDLE); -bool eepromOpen(); - -#endif // _EEPROM_RAW_H_ diff --git a/radio/src/storage/eeprom_rlc.cpp b/radio/src/storage/eeprom_rlc.cpp index e40377ea3..cfaa9106e 100644 --- a/radio/src/storage/eeprom_rlc.cpp +++ b/radio/src/storage/eeprom_rlc.cpp @@ -24,6 +24,7 @@ #include "opentx.h" #include "../timers.h" +#include "hal/eeprom_driver.h" #include "storage/eeprom_common.h" #include "storage/eeprom_rlc.h" #include "conversions/conversions.h" diff --git a/radio/src/storage/eeprom_rlc.h b/radio/src/storage/eeprom_rlc.h index cb67208f3..8beb827ef 100644 --- a/radio/src/storage/eeprom_rlc.h +++ b/radio/src/storage/eeprom_rlc.h @@ -154,8 +154,6 @@ inline void eeFlush() theFile.flush(); } -void eepromWriteBlock(uint8_t * buffer, size_t address, size_t size); - inline bool eepromIsWriting() { return theFile.isWriting(); diff --git a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt index a73b73a38..bd06a8e36 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt +++ b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt @@ -103,12 +103,6 @@ if(BLUETOOTH) ) endif() -if(NOT (PCB STREQUAL X10 OR PCB STREQUAL X12S OR PCB STREQUAL NV14)) - set(BOOTLOADER_SRC - ${BOOTLOADER_SRC} - ../../../../../targets/${TARGET_DIR}/i2c_driver.cpp - ) -endif() if(PCB STREQUAL X10 OR PCB STREQUAL X12S OR PCB STREQUAL NV14) set(BOOTLOADER_SRC @@ -158,7 +152,7 @@ else() ${BOOTLOADER_SRC} ../../../../../gui/common/stdlcd/fonts.cpp ../../../../../gui/common/stdlcd/utf8.cpp - ../../../../../targets/${TARGET_DIR}/i2c_driver.cpp + ../../../../../targets/${TARGET_DIR}/eeprom_driver.cpp ) remove_definitions(-DDEBUG) endif() diff --git a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp index 1b388cb38..79fbd8437 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp +++ b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp @@ -280,9 +280,10 @@ void bootloaderInitApp() bluetoothInit(BLUETOOTH_DEFAULT_BAUDRATE, false); #endif -#if defined(PCBTARANIS) - i2cInit(); +#if defined(EEPROM) && defined(EEPROM_RLC) + eepromInit(); #endif + init10msTimer(); // SD card detect pin diff --git a/radio/src/targets/common/arm/stm32/f2/CMakeLists.txt b/radio/src/targets/common/arm/stm32/f2/CMakeLists.txt index 7cb9f26cf..8b4d31200 100644 --- a/radio/src/targets/common/arm/stm32/f2/CMakeLists.txt +++ b/radio/src/targets/common/arm/stm32/f2/CMakeLists.txt @@ -4,18 +4,22 @@ set(FPU_FLAGS "") # STM32 HAL/LL library set(STM32CUBE_DIR ${THIRDPARTY_DIR}/STM32F2xx_HAL_Driver) +include_directories(${STM32CUBE_DIR}/Inc) add_library(stm32cube_ll OBJECT EXCLUDE_FROM_ALL + # LL drivers ${STM32CUBE_DIR}/Src/stm32f2xx_ll_gpio.c ${STM32CUBE_DIR}/Src/stm32f2xx_ll_tim.c ${STM32CUBE_DIR}/Src/stm32f2xx_ll_dma.c ${STM32CUBE_DIR}/Src/stm32f2xx_ll_usart.c ${STM32CUBE_DIR}/Src/stm32f2xx_ll_rcc.c + # HAL drivers + ${STM32CUBE_DIR}/Src/stm32f2xx_hal_rcc.c + ${STM32CUBE_DIR}/Src/stm32f2xx_hal_i2c.c ) target_compile_options(stm32cube_ll PRIVATE -DUSE_FULL_LL_DRIVER) target_include_directories(stm32cube_ll PRIVATE - ${STM32CUBE_DIR}/Inc ${THIRDPARTY_DIR}/CMSIS/Device/ST/STM32F2xx/Include ${THIRDPARTY_DIR}/CMSIS/Include) diff --git a/radio/src/targets/common/arm/stm32/stm32_hal.h b/radio/src/targets/common/arm/stm32/stm32_hal.h index 651b61552..90f829274 100644 --- a/radio/src/targets/common/arm/stm32/stm32_hal.h +++ b/radio/src/targets/common/arm/stm32/stm32_hal.h @@ -26,6 +26,7 @@ extern "C" { #include "CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h" #include "stm32f4xx_hal.h" #elif defined(STM32F2) + #include "CMSIS/Device/ST/STM32F2xx/Include/stm32f2xx.h" #include "stm32f2xx_hal.h" #endif } diff --git a/radio/src/targets/common/arm/stm32/stm32_i2c_driver.cpp b/radio/src/targets/common/arm/stm32/stm32_i2c_driver.cpp index 165360ed4..406fb4157 100644 --- a/radio/src/targets/common/arm/stm32/stm32_i2c_driver.cpp +++ b/radio/src/targets/common/arm/stm32/stm32_i2c_driver.cpp @@ -27,8 +27,9 @@ #include "debug.h" struct _i2c_defs { - GPIO_TypeDef* GPIOx; + GPIO_TypeDef* SCL_GPIOx; uint32_t SCL_Pin; + GPIO_TypeDef* SDA_GPIOx; uint32_t SDA_Pin; uint32_t Alternate; }; @@ -39,8 +40,9 @@ static I2C_HandleTypeDef hi2c1 = { .Init = { 0, 0, 0, 0, 0, 0, 0, 0 }, }; static const _i2c_defs pins_hi2c1 = { - .GPIOx = I2C_B1_GPIO, + .SCL_GPIOx = I2C_B1_GPIO, .SCL_Pin = I2C_B1_SCL_GPIO_PIN, + .SDA_GPIOx = I2C_B1_GPIO, .SDA_Pin = I2C_B1_SDA_GPIO_PIN, .Alternate = I2C_B1_GPIO_AF, }; @@ -52,8 +54,17 @@ static I2C_HandleTypeDef hi2c2 = { .Init = { 0, 0, 0, 0, 0, 0, 0, 0 }, }; static const _i2c_defs pins_hi2c2 = { - .GPIOx = I2C_B2_GPIO, +#if defined(I2C_B2_GPIO) + .SCL_GPIOx = I2C_B2_GPIO, +#else + .SCL_GPIOx = I2C_B2_SCL_GPIO, +#endif .SCL_Pin = I2C_B2_SCL_GPIO_PIN, +#if defined(I2C_B2_GPIO) + .SDA_GPIOx = I2C_B2_GPIO, +#else + .SDA_GPIOx = I2C_B2_SDA_GPIO, +#endif .SDA_Pin = I2C_B2_SDA_GPIO_PIN, .Alternate = I2C_B2_GPIO_AF, }; @@ -95,6 +106,7 @@ int stm32_i2c_init(uint8_t bus, uint32_t clock_rate) return -1; } +#if defined(I2C_FLTR_ANOFF) && defined(I2C_FLTR_DNF) // Configure Analogue filter if (HAL_I2CEx_ConfigAnalogFilter(h, I2C_ANALOGFILTER_ENABLE) != HAL_OK) { TRACE("I2C ERROR: HAL_I2CEx_ConfigAnalogFilter() failed"); @@ -106,6 +118,7 @@ int stm32_i2c_init(uint8_t bus, uint32_t clock_rate) TRACE("I2C ERROR: HAL_I2CEx_ConfigDigitalFilter() failed"); return -1; } +#endif return 1; } @@ -145,6 +158,43 @@ int stm32_i2c_master_rx(uint8_t bus, uint16_t addr, uint8_t *data, uint16_t len, return 0; } +int stm32_i2c_read(uint8_t bus, uint16_t addr, uint16_t reg, uint16_t reg_size, + uint8_t* data, uint16_t len, uint32_t timeout) +{ + I2C_HandleTypeDef* h = get_i2c_handle(bus); + if (!h) return -1; + + if (HAL_I2C_Mem_Read(h, addr << 1, reg, reg_size, data, len, timeout) != HAL_OK) { + return -1; + } + + return 0; +} + +int stm32_i2c_write(uint8_t bus, uint16_t addr, uint16_t reg, uint16_t reg_size, + uint8_t* data, uint16_t len, uint32_t timeout) +{ + I2C_HandleTypeDef* h = get_i2c_handle(bus); + if (!h) return -1; + + if (HAL_I2C_Mem_Write(h, addr << 1, reg, reg_size, data, len, timeout) != HAL_OK) { + return -1; + } + + return 0; +} + +int stm32_i2c_is_dev_ready(uint8_t bus, uint16_t addr, uint32_t timeout) +{ + I2C_HandleTypeDef* h = get_i2c_handle(bus); + if (!h) return -1; + + HAL_StatusTypeDef err = HAL_I2C_IsDeviceReady(h, addr << 1, (uint32_t)-1, timeout); + if (err != HAL_OK) return -1; + + return 0; +} + static int i2c_enable_gpio_clock(GPIO_TypeDef *GPIOx) { if (GPIOx == GPIOA) @@ -193,19 +243,24 @@ static int i2c_disable_clock(I2C_TypeDef* instance) static int i2c_pins_init(const _i2c_defs* def) { - if (i2c_enable_gpio_clock(def->GPIOx) < 0) return -1; + if (i2c_enable_gpio_clock(def->SCL_GPIOx) < 0) return -1; + if (i2c_enable_gpio_clock(def->SDA_GPIOx) < 0) return -1; LL_GPIO_InitTypeDef pinInit; LL_GPIO_StructInit(&pinInit); - pinInit.Pin = def->SCL_Pin | def->SDA_Pin; pinInit.Speed = LL_GPIO_SPEED_FREQ_LOW; pinInit.Mode = LL_GPIO_MODE_ALTERNATE; pinInit.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; pinInit.Pull = LL_GPIO_PULL_NO; pinInit.Alternate = def->Alternate; - LL_GPIO_Init(def->GPIOx, &pinInit); + pinInit.Pin = def->SCL_Pin; + LL_GPIO_Init(def->SCL_GPIOx, &pinInit); + + pinInit.Pin = def->SDA_Pin; + LL_GPIO_Init(def->SDA_GPIOx, &pinInit); + return 0; } @@ -215,14 +270,18 @@ static int i2c_pins_deinit(const _i2c_defs* def) LL_GPIO_InitTypeDef pinInit; LL_GPIO_StructInit(&pinInit); - pinInit.Pin = def->SCL_Pin | def->SDA_Pin; pinInit.Speed = LL_GPIO_SPEED_FREQ_LOW; pinInit.Mode = LL_GPIO_MODE_INPUT; pinInit.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; pinInit.Pull = LL_GPIO_PULL_NO; pinInit.Alternate = 0; - LL_GPIO_Init(def->GPIOx, &pinInit); + pinInit.Pin = def->SCL_Pin; + LL_GPIO_Init(def->SCL_GPIOx, &pinInit); + + pinInit.Pin = def->SDA_Pin; + LL_GPIO_Init(def->SDA_GPIOx, &pinInit); + return 0; } diff --git a/radio/src/targets/common/arm/stm32/stm32_i2c_driver.h b/radio/src/targets/common/arm/stm32/stm32_i2c_driver.h index 06decad03..a5632b6a5 100644 --- a/radio/src/targets/common/arm/stm32/stm32_i2c_driver.h +++ b/radio/src/targets/common/arm/stm32/stm32_i2c_driver.h @@ -42,3 +42,13 @@ int stm32_i2c_master_tx(uint8_t bus, uint16_t addr, uint8_t *data, uint16_t len, // @return -1 if error, 0 otherwise int stm32_i2c_master_rx(uint8_t bus, uint16_t addr, uint8_t *data, uint16_t len, uint32_t timeout); + +// Read memory from address 'reg' (blocking mode) +int stm32_i2c_read(uint8_t bus, uint16_t addr, uint16_t reg, uint16_t reg_size, + uint8_t* data, uint16_t len, uint32_t timeout); + +// Write memory from address 'reg' (blocking mode) +int stm32_i2c_write(uint8_t bus, uint16_t addr, uint16_t reg, uint16_t reg_size, + uint8_t* data, uint16_t len, uint32_t timeout); + +int stm32_i2c_is_dev_ready(uint8_t bus, uint16_t addr, uint32_t timeout); diff --git a/radio/src/targets/common/arm/stm32/stm32f2xx_hal_conf.h b/radio/src/targets/common/arm/stm32/stm32f2xx_hal_conf.h new file mode 100644 index 000000000..4d2ecc3eb --- /dev/null +++ b/radio/src/targets/common/arm/stm32/stm32f2xx_hal_conf.h @@ -0,0 +1,425 @@ +/** + ****************************************************************************** + * @file stm32f2xx_hal_conf_template.h + * @author MCD Application Team + * @brief HAL configuration template file. + * This file should be copied to the application folder and renamed + * to stm32f2xx_hal_conf.h. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F2xx_HAL_CONF_H +#define __STM32F2xx_HAL_CONF_H + +// Include common definitions for Cortex MCUs +#include "stm32f2xx_hal_cortex.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +// #define HAL_MODULE_ENABLED +// #define HAL_ADC_MODULE_ENABLED +// #define HAL_CAN_MODULE_ENABLED +// #define HAL_CAN_LEGACY_MODULE_ENABLED +// #define HAL_CRC_MODULE_ENABLED +// #define HAL_CRYP_MODULE_ENABLED +// #define HAL_DAC_MODULE_ENABLED +// #define HAL_DCMI_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +// #define HAL_ETH_MODULE_ENABLED +// #define HAL_EXTI_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +// #define HAL_NAND_MODULE_ENABLED +// #define HAL_NOR_MODULE_ENABLED +// #define HAL_PCCARD_MODULE_ENABLED +// #define HAL_SRAM_MODULE_ENABLED +// #define HAL_HASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +// #define HAL_I2S_MODULE_ENABLED +// #define HAL_IWDG_MODULE_ENABLED +// #define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +// #define HAL_RNG_MODULE_ENABLED +// #define HAL_RTC_MODULE_ENABLED +// #define HAL_SD_MODULE_ENABLED +// #define HAL_SPI_MODULE_ENABLED +// #define HAL_TIM_MODULE_ENABLED +// #define HAL_UART_MODULE_ENABLED +// #define HAL_USART_MODULE_ENABLED +// #define HAL_IRDA_MODULE_ENABLED +// #define HAL_SMARTCARD_MODULE_ENABLED +// #define HAL_WWDG_MODULE_ENABLED +// #define HAL_CORTEX_MODULE_ENABLED +// #define HAL_PCD_MODULE_ENABLED +// #define HAL_HCD_MODULE_ENABLED +// #define HAL_MMC_MODULE_ENABLED + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE 25000000U /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE 32000U /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE 32768U /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE 12288000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE 3300U /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY 0x0FU /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB 4U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848 PHY Address*/ +#define DP83848_PHY_ADDRESS 0x01U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY 0x000000FFU +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY 0x00000FFFU + +#define PHY_READ_TO 0x0000FFFFU +#define PHY_WRITE_TO 0x0000FFFFU + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x0010) /*!< PHY status register Offset */ +#define PHY_MICR ((uint16_t)0x0011) /*!< MII Interrupt Control Register */ +#define PHY_MISR ((uint16_t)0x0012) /*!< MII Interrupt Status and Misc. Control Register */ + +#define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */ +#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */ + +#define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */ +#define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */ + +#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */ +#define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 1U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f2xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f2xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f2xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f2xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f2xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f2xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f2xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "stm32f2xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f2xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f2xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f2xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f2xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f2xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f2xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f2xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f2xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f2xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f2xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f2xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f2xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f2xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f2xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f2xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f2xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f2xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f2xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f2xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f2xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f2xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f2xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f2xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f2xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f2xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f2xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f2xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32f2xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F2xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/radio/src/targets/taranis/CMakeLists.txt b/radio/src/targets/taranis/CMakeLists.txt index cf34d2cb3..db7576fef 100644 --- a/radio/src/targets/taranis/CMakeLists.txt +++ b/radio/src/targets/taranis/CMakeLists.txt @@ -535,7 +535,8 @@ set(FIRMWARE_TARGET_SRC ${LED_DRIVER} ${LCD_DRIVER} board.cpp - i2c_driver.cpp + volume_i2c.cpp + eeprom_driver.cpp backlight_driver.cpp trainer_driver.cpp ) diff --git a/radio/src/targets/taranis/board.cpp b/radio/src/targets/taranis/board.cpp index 110f431f0..8159c9b0b 100644 --- a/radio/src/targets/taranis/board.cpp +++ b/radio/src/targets/taranis/board.cpp @@ -105,7 +105,6 @@ void boardInit() AUDIO_RCC_AHB1Periph | BACKLIGHT_RCC_AHB1Periph | ADC_RCC_AHB1Periph | - I2C_B1_RCC_AHB1Periph | SD_RCC_AHB1Periph | HAPTIC_RCC_AHB1Periph | INTMODULE_RCC_AHB1Periph | @@ -128,7 +127,6 @@ void boardInit() HAPTIC_RCC_APB1Periph | INTERRUPT_xMS_RCC_APB1Periph | TIMER_2MHz_RCC_APB1Periph | - I2C_B1_RCC_APB1Periph | SD_RCC_APB1Periph | TRAINER_RCC_APB1Periph | TELEMETRY_RCC_APB1Periph | @@ -238,7 +236,6 @@ void boardInit() init2MhzTimer(); init1msTimer(); __enable_irq(); - i2cInit(); usbInit(); #if defined(DEBUG) diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index 77a3a4c52..0964c81dc 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -749,14 +749,6 @@ uint8_t isBacklightEnabled(); } #endif -// I2C driver: EEPROM + Audio Volume -#define EEPROM_SIZE (32*1024) - -void i2cInit(); -void eepromReadBlock(uint8_t * buffer, size_t address, size_t size); -void eepromStartWrite(uint8_t * buffer, size_t address, size_t size); -uint8_t eepromIsTransferComplete(); - // Debug driver void debugPutc(const char c); diff --git a/radio/src/targets/taranis/eeprom_driver.cpp b/radio/src/targets/taranis/eeprom_driver.cpp new file mode 100644 index 000000000..c91207d4a --- /dev/null +++ b/radio/src/targets/taranis/eeprom_driver.cpp @@ -0,0 +1,171 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "stm32_hal_ll.h" +#include "stm32_hal.h" +#include "stm32_i2c_driver.h" +#include "hal.h" + +#include "hal/eeprom_driver.h" + +static int enable_wp_clock(GPIO_TypeDef *GPIOx) +{ + if (GPIOx == GPIOB) + __HAL_RCC_GPIOB_CLK_ENABLE(); + else if (GPIOx == GPIOD) + __HAL_RCC_GPIOD_CLK_ENABLE(); + else if (GPIOx == GPIOF) + __HAL_RCC_GPIOF_CLK_ENABLE(); + else + return -1; + + return 0; +} + +static void init_wp_pin() +{ + enable_wp_clock(EEPROM_WP_GPIO); + + LL_GPIO_InitTypeDef pinInit; + LL_GPIO_StructInit(&pinInit); + + pinInit.Pin = EEPROM_WP_GPIO_PIN; + pinInit.Speed = LL_GPIO_SPEED_FREQ_LOW; + pinInit.Mode = LL_GPIO_MODE_OUTPUT; + pinInit.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; + pinInit.Pull = LL_GPIO_PULL_UP; + LL_GPIO_Init(EEPROM_WP_GPIO, &pinInit); + + // Enable write operations on EEPROM + LL_GPIO_ResetOutputPin(EEPROM_WP_GPIO, EEPROM_WP_GPIO_PIN); +} + +void eepromInit() +{ + stm32_i2c_deinit(EEPROM_I2C_BUS); + stm32_i2c_init(EEPROM_I2C_BUS, I2C_B1_CLK_RATE); + init_wp_pin(); +} + +/** + * @brief Wait for EEPROM Standby state + * @param None + * @retval None + */ +static bool I2C_EE_WaitEepromStandbyState(void) +{ + if (stm32_i2c_is_dev_ready(EEPROM_I2C_BUS, EEPROM_I2C_ADDRESS, 20 /* 20ms */) < 0) + return false; + + return true; +} + +static void eepromWaitEepromStandbyState(void) +{ + // TODO: seriously? no timeout, no bailout ??? + while (!I2C_EE_WaitEepromStandbyState()) { + eepromInit(); + } +} + +/** + * @brief Reads a block of data from the EEPROM. + * @param pBuffer : pointer to the buffer that receives the data read + * from the EEPROM. + * @param ReadAddr : EEPROM's internal address to read from. + * @param NumByteToRead : number of bytes to read from the EEPROM. + * @retval None + */ +static bool I2C_EE_ReadBlock(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t NumByteToRead) +{ + if (stm32_i2c_read(EEPROM_I2C_BUS, EEPROM_I2C_ADDRESS, ReadAddr, 1, + pBuffer, NumByteToRead, 100) < 0) { + return false; + } + + return true; +} + +void eepromReadBlock(uint8_t * buffer, size_t address, size_t size) +{ + while (!I2C_EE_ReadBlock(buffer, address, size)) { + eepromInit(); + } +} + +/** + * @brief Writes more than one byte to the EEPROM with a single WRITE cycle. + * @note The number of byte can't exceed the EEPROM page size. + * @param pBuffer : pointer to the buffer containing the data to be + * written to the EEPROM. + * @param WriteAddr : EEPROM's internal address to write to. + * @param NumByteToWrite : number of bytes to write to the EEPROM. + * @retval None + */ +static bool I2C_EE_PageWrite(uint8_t * pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite) +{ + if (stm32_i2c_write(EEPROM_I2C_BUS, EEPROM_I2C_ADDRESS, WriteAddr, 1, + pBuffer, NumByteToWrite, 100) < 0) { + return false; + } + + return true; +} + +static void eepromPageWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite) +{ + while (!I2C_EE_PageWrite(pBuffer, WriteAddr, NumByteToWrite)) { + eepromInit(); + } +} + +/** + * @brief Writes buffer of data to the I2C EEPROM. + * @param buffer : pointer to the buffer containing the data to be + * written to the EEPROM. + * @param address : EEPROM's internal address to write to. + * @param size : number of bytes to write to the EEPROM. + * @retval None + */ +void eepromWriteBlock(uint8_t * buffer, size_t address, size_t size) +{ + uint8_t offset = address % EEPROM_PAGESIZE; + uint8_t count = EEPROM_PAGESIZE - offset; + if (size < count) { + count = size; + } + while (count > 0) { + eepromPageWrite(buffer, address, count); + eepromWaitEepromStandbyState(); + address += count; + buffer += count; + size -= count; + count = EEPROM_PAGESIZE; + if (size < EEPROM_PAGESIZE) { + count = size; + } + } +} + +uint8_t eepromIsTransferComplete() +{ + return 1; +} diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index 44b62dd48..354ef96d0 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -2105,60 +2105,52 @@ #endif #define LCD_RCC_APB2Periph 0 -// I2C Bus: EEPROM and CAT5137 digital pot for volume control -#define I2C_B1_RCC_APB1Periph RCC_APB1Periph_I2C1 +// I2C Bus 1: EEPROM and CAT5137 digital pot for volume control #define I2C_B1 I2C1 -#define I2C_B1_GPIO_AF GPIO_AF_I2C1 -#if defined(PCBXLITE) || defined(PCBX9LITE) - #define I2C_B1_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOD) - #define I2C_B1_SPI_GPIO GPIOB - #define I2C_B1_SDA_GPIO_PIN GPIO_Pin_9 // PB.09 - #define I2C_B1_SCL_GPIO_PIN GPIO_Pin_8 // PB.08 - #define I2C_B1_WP_GPIO GPIOD - #define I2C_B1_WP_GPIO_PIN GPIO_Pin_7 // PD.07 - #define I2C_B1_SCL_GPIO_PinSource GPIO_PinSource8 - #define I2C_B1_SDA_GPIO_PinSource GPIO_PinSource9 -#elif defined(PCBX7ACCESS) - #define I2C_B1_RCC_AHB1Periph RCC_AHB1Periph_GPIOB - #define I2C_B1_SPI_GPIO GPIOB - #define I2C_B1_SDA_GPIO_PIN GPIO_Pin_9 // PB.09 - #define I2C_B1_SCL_GPIO_PIN GPIO_Pin_8 // PB.08 - #define I2C_B1_WP_GPIO GPIOB - #define I2C_B1_WP_GPIO_PIN GPIO_Pin_5 // PB.05 - #define I2C_B1_SDA_GPIO_PinSource GPIO_PinSource9 - #define I2C_B1_SCL_GPIO_PinSource GPIO_PinSource8 -#elif defined(RADIO_ZORRO) - #define I2C_B1_RCC_AHB1Periph RCC_AHB1Periph_GPIOB - #define I2C_B1_SPI_GPIO GPIOB - #define I2C_B1_SDA_GPIO_PIN GPIO_Pin_9 // PB.09 - #define I2C_B1_SCL_GPIO_PIN GPIO_Pin_8 // PB.08 - #define I2C_B1_WP_GPIO GPIOD - #define I2C_B1_WP_GPIO_PIN GPIO_Pin_10 // PD.10 - #define I2C_B1_SDA_GPIO_PinSource GPIO_PinSource9 - #define I2C_B1_SCL_GPIO_PinSource GPIO_PinSource8 -#elif defined(RADIO_X9DP2019) - #define I2C_B1_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOF) - #define I2C_B1_SPI_GPIO GPIOB - #define I2C_B1_SDA_GPIO_PIN GPIO_Pin_9 // PB.09 - #define I2C_B1_SCL_GPIO_PIN GPIO_Pin_8 // PB.08 - #define I2C_B1_WP_GPIO GPIOF - #define I2C_B1_WP_GPIO_PIN GPIO_Pin_0 // PF.00 - #define I2C_B1_SCL_GPIO_PinSource GPIO_PinSource8 - #define I2C_B1_SDA_GPIO_PinSource GPIO_PinSource9 +#define I2C_B1_GPIO_AF LL_GPIO_AF_4 + +#if defined(PCBXLITE) || defined(PCBX9LITE) || defined(PCBX7ACCESS) || \ + defined(RADIO_ZORRO) || defined(RADIO_X9DP2019) + #define I2C_B1_GPIO GPIOB + #define I2C_B1_SDA_GPIO_PIN LL_GPIO_PIN_9 // PB.09 + #define I2C_B1_SCL_GPIO_PIN LL_GPIO_PIN_8 // PB.08 #else - #define I2C_B1_RCC_AHB1Periph RCC_AHB1Periph_GPIOB - #define I2C_B1_SPI_GPIO GPIOB - #define I2C_B1_SCL_GPIO_PIN GPIO_Pin_6 // PB.06 - #define I2C_B1_SDA_GPIO_PIN GPIO_Pin_7 // PB.07 - #define I2C_B1_WP_GPIO GPIOB - #define I2C_B1_WP_GPIO_PIN GPIO_Pin_9 // PB.09 - #define I2C_B1_SCL_GPIO_PinSource GPIO_PinSource6 - #define I2C_B1_SDA_GPIO_PinSource GPIO_PinSource7 - #define I2C_ADDRESS_VOLUME 0x5C + #define I2C_B1_GPIO GPIOB + #define I2C_B1_SCL_GPIO_PIN LL_GPIO_PIN_6 // PB.06 + #define I2C_B1_SDA_GPIO_PIN LL_GPIO_PIN_7 // PB.07 #endif + +// EEPROM +#if defined(PCBXLITE) || defined(PCBX9LITE) + #define EEPROM_WP_GPIO GPIOD + #define EEPROM_WP_GPIO_PIN LL_GPIO_PIN_7 // PD.07 +#elif defined(PCBX7ACCESS) + #define EEPROM_WP_GPIO GPIOB + #define EEPROM_WP_GPIO_PIN LL_GPIO_PIN_5 // PB.05 +#elif defined(RADIO_ZORRO) + #define EEPROM_WP_GPIO GPIOD + #define EEPROM_WP_GPIO_PIN LL_GPIO_PIN_10 // PD.10 +#elif defined(RADIO_X9DP2019) + #define EEPROM_WP_GPIO GPIOF + #define EEPROM_WP_GPIO_PIN LL_GPIO_PIN_0 // PF.00 +#else + #define EEPROM_WP_GPIO GPIOB + #define EEPROM_WP_GPIO_PIN LL_GPIO_PIN_9 // PB.09 +#endif + +// I2C Volume control +#if !defined(SOFTWARE_VOLUME) + #define VOLUME_I2C_ADDRESS 0x2E + #define VOLUME_I2C_BUS I2C_Bus_1 +#endif + #define I2C_B1_CLK_RATE 400000 -#define I2C_ADDRESS_EEPROM 0xA2 -#define I2C_FLASH_PAGESIZE 64 + +// EEPROM +#define EEPROM_I2C_ADDRESS 0x51 +#define EEPROM_I2C_BUS I2C_Bus_1 +#define EEPROM_PAGESIZE 64 +#define EEPROM_SIZE (32*1024) // Second I2C Bus: IMU #if defined(PCBXLITES) @@ -2166,12 +2158,10 @@ #define I2C_B2_RCC_APB1Periph RCC_APB1Periph_I2C3 #define I2C_B2 I2C3 #define I2C_B2_SCL_GPIO GPIOA - #define I2C_B2_SCL_GPIO_PIN GPIO_Pin_8 // PA.08 + #define I2C_B2_SCL_GPIO_PIN LL_GPIO_PIN_8 // PA.08 #define I2C_B2_SDA_GPIO GPIOC - #define I2C_B2_SDA_GPIO_PIN GPIO_Pin_9 // PC.09 - #define I2C_B2_GPIO_AF GPIO_AF_I2C3 - #define I2C_B2_SCL_GPIO_PinSource GPIO_PinSource8 - #define I2C_B2_SDA_GPIO_PinSource GPIO_PinSource9 + #define I2C_B2_SDA_GPIO_PIN LL_GPIO_PIN_9 // PC.09 + #define I2C_B2_GPIO_AF LL_GPIO_AF_4 #define I2C_B2_SPEED 400000 #else #define I2C_B2_RCC_AHB1Periph 0 diff --git a/radio/src/targets/taranis/i2c_driver.cpp b/radio/src/targets/taranis/i2c_driver.cpp deleted file mode 100644 index 82572dd57..000000000 --- a/radio/src/targets/taranis/i2c_driver.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "board.h" - -void eepromPageWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite); -void eepromWaitEepromStandbyState(void); - -void i2cInit() -{ - I2C_DeInit(I2C_B1); - - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = I2C_B1_WP_GPIO_PIN; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_Init(I2C_B1_WP_GPIO, &GPIO_InitStructure); - GPIO_ResetBits(I2C_B1_WP_GPIO, I2C_B1_WP_GPIO_PIN); - - I2C_InitTypeDef I2C_InitStructure; - I2C_InitStructure.I2C_ClockSpeed = I2C_B1_CLK_RATE; - I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; - I2C_InitStructure.I2C_OwnAddress1 = 0x00; - I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; - I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; - I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; - I2C_Init(I2C_B1, &I2C_InitStructure); - I2C_Cmd(I2C_B1, ENABLE); - - GPIO_PinAFConfig(I2C_B1_SPI_GPIO, I2C_B1_SCL_GPIO_PinSource, I2C_B1_GPIO_AF); - GPIO_PinAFConfig(I2C_B1_SPI_GPIO, I2C_B1_SDA_GPIO_PinSource, I2C_B1_GPIO_AF); - - GPIO_InitStructure.GPIO_Pin = I2C_B1_SCL_GPIO_PIN | I2C_B1_SDA_GPIO_PIN; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_Init(I2C_B1_SPI_GPIO, &GPIO_InitStructure); -} - -#define I2C_TIMEOUT_MAX 1000 -bool I2C_WaitEvent(uint32_t event) -{ - uint32_t timeout = I2C_TIMEOUT_MAX; - while (!I2C_CheckEvent(I2C_B1, event)) { - if ((timeout--) == 0) return false; - } - return true; -} - -bool I2C_WaitEventCleared(uint32_t event) -{ - uint32_t timeout = I2C_TIMEOUT_MAX; - while (I2C_CheckEvent(I2C_B1, event)) { - if ((timeout--) == 0) return false; - } - return true; -} - -/** - * @brief Reads a block of data from the EEPROM. - * @param pBuffer : pointer to the buffer that receives the data read - * from the EEPROM. - * @param ReadAddr : EEPROM's internal address to read from. - * @param NumByteToRead : number of bytes to read from the EEPROM. - * @retval None - */ -bool I2C_EE_ReadBlock(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t NumByteToRead) -{ - if (!I2C_WaitEventCleared(I2C_FLAG_BUSY)) - return false; - - I2C_GenerateSTART(I2C_B1, ENABLE); - if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT)) - return false; - - I2C_Send7bitAddress(I2C_B1, I2C_ADDRESS_EEPROM, I2C_Direction_Transmitter); - if (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) - return false; - - I2C_SendData(I2C_B1, (uint8_t)((ReadAddr & 0xFF00) >> 8)); - if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING)) - return false; - I2C_SendData(I2C_B1, (uint8_t)(ReadAddr & 0x00FF)); - if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED)) - return false; - - I2C_GenerateSTART(I2C_B1, ENABLE); - if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT)) - return false; - - I2C_Send7bitAddress(I2C_B1, I2C_ADDRESS_EEPROM, I2C_Direction_Receiver); - if (!I2C_WaitEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) - return false; - - if (NumByteToRead > 1) { - I2C_AcknowledgeConfig(I2C_B1, ENABLE); - } - - while (NumByteToRead) { - if (NumByteToRead == 1) { - I2C_AcknowledgeConfig(I2C_B1, DISABLE); - } - if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_RECEIVED)) - return false; - *pBuffer++ = I2C_ReceiveData(I2C_B1); - NumByteToRead--; - } - - I2C_GenerateSTOP(I2C_B1, ENABLE); - return true; -} - -void eepromReadBlock(uint8_t * buffer, size_t address, size_t size) -{ - while (!I2C_EE_ReadBlock(buffer, address, size)) { - i2cInit(); - } -} - -/** - * @brief Writes buffer of data to the I2C EEPROM. - * @param buffer : pointer to the buffer containing the data to be - * written to the EEPROM. - * @param address : EEPROM's internal address to write to. - * @param size : number of bytes to write to the EEPROM. - * @retval None - */ -void eepromWriteBlock(uint8_t * buffer, size_t address, size_t size) -{ - uint8_t offset = address % I2C_FLASH_PAGESIZE; - uint8_t count = I2C_FLASH_PAGESIZE - offset; - if (size < count) { - count = size; - } - while (count > 0) { - eepromPageWrite(buffer, address, count); - eepromWaitEepromStandbyState(); - address += count; - buffer += count; - size -= count; - count = I2C_FLASH_PAGESIZE; - if (size < I2C_FLASH_PAGESIZE) { - count = size; - } - } -} - -uint8_t eepromIsTransferComplete() -{ - return 1; -} - -/** - * @brief Writes more than one byte to the EEPROM with a single WRITE cycle. - * @note The number of byte can't exceed the EEPROM page size. - * @param pBuffer : pointer to the buffer containing the data to be - * written to the EEPROM. - * @param WriteAddr : EEPROM's internal address to write to. - * @param NumByteToWrite : number of bytes to write to the EEPROM. - * @retval None - */ -bool I2C_EE_PageWrite(uint8_t * pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite) -{ - if (!I2C_WaitEventCleared(I2C_FLAG_BUSY)) - return false; - - I2C_GenerateSTART(I2C_B1, ENABLE); - if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT)) - return false; - - I2C_Send7bitAddress(I2C_B1, I2C_ADDRESS_EEPROM, I2C_Direction_Transmitter); - if (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) - return false; - - I2C_SendData(I2C_B1, (uint8_t)((WriteAddr & 0xFF00) >> 8)); - if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING)) - return false; - I2C_SendData(I2C_B1, (uint8_t)(WriteAddr & 0x00FF)); - if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING)) - return false; - - /* While there is data to be written */ - while (NumByteToWrite--) { - I2C_SendData(I2C_B1, *pBuffer); - if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING)) - return false; - pBuffer++; - } - - if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED)) - return false; - - I2C_GenerateSTOP(I2C_B1, ENABLE); - return true; -} - -void eepromPageWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite) -{ - while (!I2C_EE_PageWrite(pBuffer, WriteAddr, NumByteToWrite)) { - i2cInit(); - } -} - -/** - * @brief Wait for EEPROM Standby state - * @param None - * @retval None - */ -bool I2C_EE_WaitEepromStandbyState(void) -{ - do { - I2C_GenerateSTART(I2C_B1, ENABLE); - if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT)) - return false; - - I2C_Send7bitAddress(I2C_B1, I2C_ADDRESS_EEPROM, I2C_Direction_Transmitter); - } while (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); - - I2C_GenerateSTOP(I2C_B1, ENABLE); - return true; -} - -void eepromWaitEepromStandbyState(void) -{ - while (!I2C_EE_WaitEepromStandbyState()) { - i2cInit(); - } -} - -#if !defined(BOOT) && !defined(SOFTWARE_VOLUME) -const uint8_t volumeScale[VOLUME_LEVEL_MAX+1] = { - 0, 1, 2, 3, 5, 9, 13, 17, 22, 27, 33, 40, - 64, 82, 96, 105, 112, 117, 120, 122, 124, 125, 126, 127 -}; - -void setScaledVolume(uint8_t volume) -{ - if (volume > VOLUME_LEVEL_MAX) { - volume = VOLUME_LEVEL_MAX; - } - - setVolume(volumeScale[volume]); -} - -void setVolume(uint8_t volume) -{ - if (!I2C_WaitEventCleared(I2C_FLAG_BUSY)) - return; - - I2C_GenerateSTART(I2C_B1, ENABLE); - if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT)) - return; - - I2C_Send7bitAddress(I2C_B1, I2C_ADDRESS_VOLUME, I2C_Direction_Transmitter); - if (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) - return; - - I2C_SendData(I2C_B1, 0); - if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING)) - return; - I2C_SendData(I2C_B1, volume); - if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED)) - return; - - I2C_GenerateSTOP(I2C_B1, ENABLE); -} - -int32_t getVolume() -{ - return -1; // TODO -} -#endif diff --git a/radio/src/targets/taranis/volume_i2c.cpp b/radio/src/targets/taranis/volume_i2c.cpp new file mode 100644 index 000000000..9a5635c89 --- /dev/null +++ b/radio/src/targets/taranis/volume_i2c.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#if !defined(SOFTWARE_VOLUME) + +#include "stm32_i2c_driver.h" +#include "board.h" + +static const uint8_t volumeScale[VOLUME_LEVEL_MAX+1] = { + 0, 1, 2, 3, 5, 9, 13, 17, 22, 27, 33, 40, + 64, 82, 96, 105, 112, 117, 120, 122, 124, 125, 126, 127 +}; + +int32_t getVolume() +{ + uint8_t value = 0; + if (stm32_i2c_read(VOLUME_I2C_BUS, VOLUME_I2C_ADDRESS, 0, 1, &value, 1, 10) < 0) + return -1; + + return value; +} + +void setVolume(uint8_t volume) +{ + // stm32_i2c_init(VOLUME_I2C_BUS, I2C_B1_CLK_RATE); + stm32_i2c_write(VOLUME_I2C_BUS, VOLUME_I2C_ADDRESS, 0, 1, &volume, 1, 10); +} + +void setScaledVolume(uint8_t volume) +{ + if (volume > VOLUME_LEVEL_MAX) { + volume = VOLUME_LEVEL_MAX; + } + + setVolume(volumeScale[volume]); +} + +#endif