You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ut...@apache.org on 2018/04/18 21:56:36 UTC
[mynewt-core] 13/13: Initial stm32f1 i2c support + olimex-p103
config
This is an automated email from the ASF dual-hosted git repository.
utzig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit 9f4fc4aaf90791b060a64bafa3184e8623b8f387
Author: Fabio Utzig <ut...@apache.org>
AuthorDate: Fri Mar 23 11:22:45 2018 -0300
Initial stm32f1 i2c support + olimex-p103 config
---
hw/bsp/nucleo-f401re/src/hal_bsp.c | 2 +-
hw/bsp/olimex-p103/src/hal_bsp.c | 11 +-
hw/mcu/stm/stm32_common/src/hal_i2c.c | 77 +++++++++
hw/mcu/stm/stm32f1xx/include/mcu/stm32_hal.h | 5 +
.../stm32f1xx/include/mcu/stm32f1xx_mynewt_hal.h | 4 +-
hw/mcu/stm/stm32f1xx/src/hal_i2c.c | 190 ---------------------
hw/mcu/stm/stm32f1xx/syscfg.yml | 8 +-
7 files changed, 94 insertions(+), 203 deletions(-)
diff --git a/hw/bsp/nucleo-f401re/src/hal_bsp.c b/hw/bsp/nucleo-f401re/src/hal_bsp.c
index 05fb6ce..3c43d19 100644
--- a/hw/bsp/nucleo-f401re/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f401re/src/hal_bsp.c
@@ -86,7 +86,7 @@ static struct stm32_hal_i2c_cfg i2c_cfg0 = {
#endif
#if MYNEWT_VAL(SPI_0_SLAVE) || MYNEWT_VAL(SPI_0_MASTER)
-struct stm32f4_hal_spi_cfg spi0_cfg = {
+struct stm32_hal_spi_cfg spi0_cfg = {
.ss_pin = MCU_GPIO_PORTA(4), /* PA4 */
.sck_pin = MCU_GPIO_PORTA(5), /* PA5 */
.miso_pin = MCU_GPIO_PORTA(6), /* PA6 */
diff --git a/hw/bsp/olimex-p103/src/hal_bsp.c b/hw/bsp/olimex-p103/src/hal_bsp.c
index f06eb71..1c64825 100644
--- a/hw/bsp/olimex-p103/src/hal_bsp.c
+++ b/hw/bsp/olimex-p103/src/hal_bsp.c
@@ -90,16 +90,15 @@ struct stm32_hal_spi_cfg spi1_cfg = {
#endif
#if MYNEWT_VAL(I2C_0)
-/* TODO */
-static struct stm32f1_hal_i2c_cfg i2c_cfg0 = {
+static struct stm32_hal_i2c_cfg i2c_cfg0 = {
.hic_i2c = I2C1,
.hic_rcc_reg = &RCC->APB1ENR,
.hic_rcc_dev = RCC_APB1ENR_I2C1EN,
- .hic_pin_sda = MCU_GPIO_PORTB(9), /* PB9 */
- .hic_pin_scl = MCU_GPIO_PORTB(8), /* PB8 */
- .hic_pin_af = GPIO_AF4_I2C1,
+ .hic_pin_sda = MCU_GPIO_PORTB(7),
+ .hic_pin_scl = MCU_GPIO_PORTB(6),
+ .hic_pin_remap_fn = LL_GPIO_AF_DisableRemap_I2C1,
.hic_10bit = 0,
- .hic_speed = 100000 /* 100kHz */
+ .hic_speed = 100000,
};
#endif
diff --git a/hw/mcu/stm/stm32_common/src/hal_i2c.c b/hw/mcu/stm/stm32_common/src/hal_i2c.c
index a9c4cf4..83d4fe5 100644
--- a/hw/mcu/stm/stm32_common/src/hal_i2c.c
+++ b/hw/mcu/stm/stm32_common/src/hal_i2c.c
@@ -71,12 +71,26 @@ static struct stm32_hal_i2c *hal_i2c_devs[HAL_I2C_MAX_DEVS] = {
#endif
};
+#if defined(STM32F1)
+static void
+i2c_reset(I2C_HandleTypeDef *hi2c)
+{
+ __HAL_I2C_DISABLE(hi2c);
+ hi2c->Instance->CR1 |= I2C_CR1_SWRST;
+ hi2c->Instance->CR1 &= ~I2C_CR1_SWRST;
+ __HAL_I2C_ENABLE(hi2c);
+}
+#endif
+
int
hal_i2c_init(uint8_t i2c_num, void *usercfg)
{
struct stm32_hal_i2c_cfg *cfg = (struct stm32_hal_i2c_cfg *)usercfg;
struct stm32_hal_i2c *dev;
I2C_InitTypeDef *init;
+#if defined(STM32F1)
+ GPIO_InitTypeDef gpio;
+#endif
int rc;
if (i2c_num >= HAL_I2C_MAX_DEVS || !(dev = hal_i2c_devs[i2c_num])) {
@@ -102,6 +116,7 @@ hal_i2c_init(uint8_t i2c_num, void *usercfg)
* Configure GPIO pins for I2C.
* Enable clock routing for I2C.
*/
+#if !defined(STM32F1)
rc = hal_gpio_init_af(cfg->hic_pin_sda, cfg->hic_pin_af, HAL_GPIO_PULL_UP,
1);
if (rc) {
@@ -112,7 +127,62 @@ hal_i2c_init(uint8_t i2c_num, void *usercfg)
if (rc) {
goto err;
}
+
+ *cfg->hic_rcc_reg |= cfg->hic_rcc_dev;
+#else
+ /* For STM32F1x initialize I2C clock before GPIOs */
*cfg->hic_rcc_reg |= cfg->hic_rcc_dev;
+
+ if (cfg->hic_pin_remap_fn != NULL) {
+ cfg->hic_pin_remap_fn();
+ }
+
+ /*
+ * The block below applies a workaround described in 2.13.7
+ * of the STM32F103 errata (also described on F105/107 errata).
+ */
+ gpio.Mode = GPIO_MODE_OUTPUT_OD;
+ gpio.Speed = GPIO_SPEED_FREQ_LOW;
+ gpio.Pull = GPIO_NOPULL;
+
+ hal_gpio_init_stm(cfg->hic_pin_sda, &gpio);
+ hal_gpio_write(cfg->hic_pin_sda, 1);
+ hal_gpio_init_stm(cfg->hic_pin_scl, &gpio);
+ hal_gpio_write(cfg->hic_pin_scl, 1);
+
+ assert(hal_gpio_read(cfg->hic_pin_sda) == 1);
+ assert(hal_gpio_read(cfg->hic_pin_scl) == 1);
+
+ hal_gpio_write(cfg->hic_pin_sda, 0);
+ assert(hal_gpio_read(cfg->hic_pin_sda) == 0);
+
+ hal_gpio_write(cfg->hic_pin_scl, 0);
+ assert(hal_gpio_read(cfg->hic_pin_scl) == 0);
+
+ hal_gpio_write(cfg->hic_pin_scl, 1);
+ assert(hal_gpio_read(cfg->hic_pin_scl) == 1);
+
+ hal_gpio_write(cfg->hic_pin_sda, 1);
+ assert(hal_gpio_read(cfg->hic_pin_sda) == 1);
+
+ /*
+ * Normal I2C PIN initialization
+ */
+ gpio.Mode = GPIO_MODE_AF_OD;
+ gpio.Speed = GPIO_SPEED_FREQ_HIGH;
+ /* NOTE: Pull is not used in AF mode */
+ gpio.Pull = GPIO_NOPULL;
+
+ hal_gpio_init_stm(cfg->hic_pin_scl, &gpio);
+ hal_gpio_init_stm(cfg->hic_pin_sda, &gpio);
+
+ /*
+ * Reset I2C
+ */
+ dev->hid_handle.Instance->CR1 = I2C_CR1_SWRST;
+ dev->hid_handle.Instance->CR1 = 0;
+#endif
+
rc = HAL_I2C_Init(&dev->hid_handle);
if (rc) {
goto err;
@@ -163,5 +233,12 @@ hal_i2c_master_probe(uint8_t i2c_num, uint8_t address, uint32_t timo)
}
rc = HAL_I2C_IsDeviceReady(&dev->hid_handle, address << 1, 1, timo);
+
+#if defined(STM32F1)
+ if (rc == HAL_BUSY) {
+ i2c_reset(&dev->hid_handle);
+ }
+#endif
+
return rc;
}
diff --git a/hw/mcu/stm/stm32f1xx/include/mcu/stm32_hal.h b/hw/mcu/stm/stm32f1xx/include/mcu/stm32_hal.h
index 238888e..9694e72 100644
--- a/hw/mcu/stm/stm32f1xx/include/mcu/stm32_hal.h
+++ b/hw/mcu/stm/stm32f1xx/include/mcu/stm32_hal.h
@@ -54,6 +54,11 @@ struct stm32_hal_spi_cfg {
int irq_prio;
};
+/* hal_i2c */
+#include "stm32f1xx_hal_i2c.h"
+#include "mcu/stm32f1xx_mynewt_hal.h"
+#include "mcu/stm32f1_bsp.h"
+
#ifdef __cplusplus
}
#endif
diff --git a/hw/mcu/stm/stm32f1xx/include/mcu/stm32f1xx_mynewt_hal.h b/hw/mcu/stm/stm32f1xx/include/mcu/stm32f1xx_mynewt_hal.h
index e0eb123..437a3fd 100644
--- a/hw/mcu/stm/stm32f1xx/include/mcu/stm32f1xx_mynewt_hal.h
+++ b/hw/mcu/stm/stm32f1xx/include/mcu/stm32f1xx_mynewt_hal.h
@@ -48,13 +48,13 @@ extern "C" {
int hal_gpio_init_stm(int pin, GPIO_InitTypeDef *cfg);
int hal_gpio_deinit_stm(int pin, GPIO_InitTypeDef *cfg);
-struct stm32f1_hal_i2c_cfg {
+struct stm32_hal_i2c_cfg {
I2C_TypeDef *hic_i2c;
volatile uint32_t *hic_rcc_reg; /* RCC register to modify */
uint32_t hic_rcc_dev; /* RCC device ID */
uint8_t hic_pin_sda;
uint8_t hic_pin_scl;
- uint8_t hic_pin_af;
+ void (*hic_pin_remap_fn)(void);
uint8_t hic_10bit;
uint32_t hic_speed;
};
diff --git a/hw/mcu/stm/stm32f1xx/src/hal_i2c.c b/hw/mcu/stm/stm32f1xx/src/hal_i2c.c
deleted file mode 100644
index 0d8d8f8..0000000
--- a/hw/mcu/stm/stm32f1xx/src/hal_i2c.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#include "os/mynewt.h"
-
-#include <hal/hal_i2c.h>
-#include <hal/hal_gpio.h>
-
-#include "stm32f1xx.h"
-#include "stm32f1xx_hal_dma.h"
-#include "stm32f1xx_hal_i2c.h"
-#include "stm32f1xx_hal_gpio.h"
-#include "stm32f1xx_hal_rcc.h"
-#include "mcu/stm32f1xx_mynewt_hal.h"
-#include "mcu/stm32f1_bsp.h"
-
-#define HAL_I2C_MAX_DEVS 3
-
-#define I2C_ADDRESS 0xae
-
-struct stm32f1_hal_i2c {
- I2C_HandleTypeDef hid_handle;
-};
-
-#if MYNEWT_VAL(I2C_0)
-static struct stm32f1_hal_i2c i2c0;
-#endif
-#if MYNEWT_VAL(I2C_1)
-static struct stm32f1_hal_i2c i2c1;
-#endif
-#if MYNEWT_VAL(I2C_2)
-static struct stm32f1_hal_i2c i2c2;
-#endif
-
-static struct stm32f1_hal_i2c *hal_i2c_devs[HAL_I2C_MAX_DEVS] = {
-#if MYNEWT_VAL(I2C_0)
- &i2c0,
-#else
- NULL,
-#endif
-#if MYNEWT_VAL(I2C_1)
- &i2c1,
-#else
- NULL,
-#endif
-#if MYNEWT_VAL(I2C_2)
- &i2c2,
-#else
- NULL,
-#endif
-};
-
-int
-hal_i2c_init(uint8_t i2c_num, void *usercfg)
-{
- struct stm32f1_hal_i2c_cfg *cfg = (struct stm32f1_hal_i2c_cfg *)usercfg;
- struct stm32f1_hal_i2c *dev;
- I2C_InitTypeDef *init;
- GPIO_InitTypeDef gpio;
- int rc;
-
- if (i2c_num >= HAL_I2C_MAX_DEVS || !(dev = hal_i2c_devs[i2c_num])) {
- return -1;
- }
-
- init = &dev->hid_handle.Init;
- dev->hid_handle.Instance = cfg->hic_i2c;
- init->ClockSpeed = cfg->hic_speed;
- if (cfg->hic_10bit) {
- init->AddressingMode = I2C_ADDRESSINGMODE_10BIT;
- } else {
- init->AddressingMode = I2C_ADDRESSINGMODE_7BIT;
- }
- init->OwnAddress1 = I2C_ADDRESS;
- init->OwnAddress2 = 0xFE;
-
- init->DutyCycle = I2C_DUTYCYCLE_2;
- init->DualAddressMode = I2C_DUALADDRESS_DISABLE;
- init->GeneralCallMode = I2C_GENERALCALL_DISABLE;
- init->NoStretchMode = I2C_NOSTRETCH_DISABLE;
-
- /*
- * Configure GPIO pins for I2C.
- * Enable clock routing for I2C.
- */
- gpio.Speed = GPIO_SPEED_FREQ_HIGH;
- gpio.Pull = GPIO_NOPULL;
- gpio.Mode = GPIO_MODE_AF_OD;
- hal_gpio_init_stm(cfg->hic_pin_scl, &gpio);
- hal_gpio_init_stm(cfg->hic_pin_sda, &gpio);
-
-#if 0
- hal_gpio_write(cfg->hic_pin_scl, 0);
- //for (int i = 0; i < 1000; i++) asm("nop");
- hal_gpio_write(cfg->hic_pin_scl, 1);
-
- hal_gpio_write(cfg->hic_pin_sda, 0);
- //for (int i = 0; i < 1000; i++) asm("nop");
- hal_gpio_write(cfg->hic_pin_sda, 1);
-#endif
-
- if (cfg->hic_pin_remap_fn) {
- cfg->hic_pin_remap_fn();
- }
-
- *cfg->hic_rcc_reg |= cfg->hic_rcc_dev;
- rc = HAL_I2C_Init(&dev->hid_handle);
- if (rc) {
- goto err;
- }
-
- return 0;
-err:
- *cfg->hic_rcc_reg &= ~cfg->hic_rcc_dev;
- return rc;
-}
-
-int
-hal_i2c_master_write(uint8_t i2c_num, struct hal_i2c_master_data *data,
- uint32_t timo, uint8_t last_op)
-{
- struct stm32f1_hal_i2c *dev;
-
- if (i2c_num >= HAL_I2C_MAX_DEVS || !(dev = hal_i2c_devs[i2c_num])) {
- return -1;
- }
-
- if (!last_op) {
- //return HAL_I2C_Master_Transmit_NoStop(&dev->hid_handle,
- return HAL_I2C_Master_Transmit(&dev->hid_handle,
- data->address << 1, data->buffer, data->len, timo);
- } else {
- return HAL_I2C_Master_Transmit(&dev->hid_handle,
- data->address << 1, data->buffer, data->len, timo);
- }
-}
-
-int
-hal_i2c_master_read(uint8_t i2c_num, struct hal_i2c_master_data *pdata,
- uint32_t timo, uint8_t last_op)
-{
- struct stm32f1_hal_i2c *dev;
-
- if (i2c_num >= HAL_I2C_MAX_DEVS || !(dev = hal_i2c_devs[i2c_num])) {
- return -1;
- }
-
- if (!last_op) {
- //return HAL_I2C_Master_Receive_NoStop(&dev->hid_handle,
- return HAL_I2C_Master_Receive(&dev->hid_handle,
- pdata->address << 1, pdata->buffer, pdata->len, timo);
- } else {
- return HAL_I2C_Master_Receive(&dev->hid_handle, pdata->address << 1,
- pdata->buffer, pdata->len, timo);
- }
-}
-
-int
-hal_i2c_master_probe(uint8_t i2c_num, uint8_t address, uint32_t timo)
-{
- struct stm32f1_hal_i2c *dev;
- int rc;
-
- if (i2c_num >= HAL_I2C_MAX_DEVS || !(dev = hal_i2c_devs[i2c_num])) {
- return -1;
- }
-
- rc = HAL_I2C_IsDeviceReady(&dev->hid_handle, address, 1, timo);
- return rc;
-}
diff --git a/hw/mcu/stm/stm32f1xx/syscfg.yml b/hw/mcu/stm/stm32f1xx/syscfg.yml
index 2b35fd2..e59fc47 100644
--- a/hw/mcu/stm/stm32f1xx/syscfg.yml
+++ b/hw/mcu/stm/stm32f1xx/syscfg.yml
@@ -19,10 +19,6 @@
# Package: hw/bsp/stm32l152discovery
syscfg.defs:
- I2C_0:
- description: 'I2C (TWI) interface 0'
- value: 0
-
MCU_FLASH_MIN_WRITE_SIZE:
description: >
Specifies the required alignment for internal flash writes.
@@ -33,6 +29,10 @@ syscfg.defs:
description: MCUs are of STM32F1xx family
value: 1
+ I2C_0:
+ description: 'I2C (TWI) interface 0'
+ value: 0
+
SPI_0_MASTER:
description: 'SPI 0 master'
value: 0
--
To stop receiving notification emails like this one, please contact
utzig@apache.org.