diff options
Diffstat (limited to 'os')
-rw-r--r-- | os/hal/boards/NONSTANDARD_STM32F4_BARTHESS2/board.c | 108 | ||||
-rw-r--r-- | os/hal/boards/NONSTANDARD_STM32F4_BARTHESS2/board.h | 1152 | ||||
-rw-r--r-- | os/hal/boards/NONSTANDARD_STM32F4_BARTHESS2/board.mk | 5 | ||||
-rw-r--r-- | os/hal/hal.mk | 5 | ||||
-rw-r--r-- | os/hal/include/nand.h | 148 | ||||
-rw-r--r-- | os/hal/ports/STM32/LLD/FSMCv1/fsmc.c | 196 | ||||
-rw-r--r-- | os/hal/ports/STM32/LLD/FSMCv1/fsmc.h | 334 | ||||
-rw-r--r-- | os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c | 212 | ||||
-rw-r--r-- | os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h | 172 | ||||
-rw-r--r-- | os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c | 159 | ||||
-rw-r--r-- | os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.h | 173 | ||||
-rw-r--r-- | os/hal/ports/STM32/LLD/FSMCv1/nand_lld.c | 515 | ||||
-rw-r--r-- | os/hal/ports/STM32/LLD/FSMCv1/nand_lld.h | 335 | ||||
-rw-r--r-- | os/hal/ports/STM32/STM32F4xx/platform.mk | 8 | ||||
-rw-r--r-- | os/hal/src/nand.c | 601 |
15 files changed, 4123 insertions, 0 deletions
diff --git a/os/hal/boards/NONSTANDARD_STM32F4_BARTHESS2/board.c b/os/hal/boards/NONSTANDARD_STM32F4_BARTHESS2/board.c new file mode 100644 index 0000000..cd7c951 --- /dev/null +++ b/os/hal/boards/NONSTANDARD_STM32F4_BARTHESS2/board.c @@ -0,0 +1,108 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2014 Giovanni Di Sirio + + Licensed 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 "ch.h" +#include "hal.h" + +#if HAL_USE_PAL || defined(__DOXYGEN__) +/** + * @brief PAL setup. + * @details Digital I/O ports static configuration as defined in @p board.h. + * This variable is used by the HAL when initializing the PAL driver. + */ +const PALConfig pal_default_config = +{ + {VAL_GPIOA_MODER, VAL_GPIOA_OTYPER, VAL_GPIOA_OSPEEDR, VAL_GPIOA_PUPDR, + VAL_GPIOA_ODR, VAL_GPIOA_AFRL, VAL_GPIOA_AFRH}, + {VAL_GPIOB_MODER, VAL_GPIOB_OTYPER, VAL_GPIOB_OSPEEDR, VAL_GPIOB_PUPDR, + VAL_GPIOB_ODR, VAL_GPIOB_AFRL, VAL_GPIOB_AFRH}, + {VAL_GPIOC_MODER, VAL_GPIOC_OTYPER, VAL_GPIOC_OSPEEDR, VAL_GPIOC_PUPDR, + VAL_GPIOC_ODR, VAL_GPIOC_AFRL, VAL_GPIOC_AFRH}, + {VAL_GPIOD_MODER, VAL_GPIOD_OTYPER, VAL_GPIOD_OSPEEDR, VAL_GPIOD_PUPDR, + VAL_GPIOD_ODR, VAL_GPIOD_AFRL, VAL_GPIOD_AFRH}, + {VAL_GPIOE_MODER, VAL_GPIOE_OTYPER, VAL_GPIOE_OSPEEDR, VAL_GPIOE_PUPDR, + VAL_GPIOE_ODR, VAL_GPIOE_AFRL, VAL_GPIOE_AFRH}, + {VAL_GPIOF_MODER, VAL_GPIOF_OTYPER, VAL_GPIOF_OSPEEDR, VAL_GPIOF_PUPDR, + VAL_GPIOF_ODR, VAL_GPIOF_AFRL, VAL_GPIOF_AFRH}, + {VAL_GPIOG_MODER, VAL_GPIOG_OTYPER, VAL_GPIOG_OSPEEDR, VAL_GPIOG_PUPDR, + VAL_GPIOG_ODR, VAL_GPIOG_AFRL, VAL_GPIOG_AFRH}, + {VAL_GPIOH_MODER, VAL_GPIOH_OTYPER, VAL_GPIOH_OSPEEDR, VAL_GPIOH_PUPDR, + VAL_GPIOH_ODR, VAL_GPIOH_AFRL, VAL_GPIOH_AFRH}, + {VAL_GPIOI_MODER, VAL_GPIOI_OTYPER, VAL_GPIOI_OSPEEDR, VAL_GPIOI_PUPDR, + VAL_GPIOI_ODR, VAL_GPIOI_AFRL, VAL_GPIOI_AFRH} +}; +#endif + +/** + * @brief Early initialization code. + * @details This initialization must be performed just after stack setup + * and before any other initialization. + */ +void __early_init(void) { + + stm32_clock_init(); +} + +#if HAL_USE_SDC || defined(__DOXYGEN__) +/** + * @brief SDC card detection. + */ +bool_t sdc_lld_is_card_inserted(SDCDriver *sdcp) { + + (void)sdcp; + /* TODO: Fill the implementation.*/ + return TRUE; +} + +/** + * @brief SDC card write protection detection. + */ +bool_t sdc_lld_is_write_protected(SDCDriver *sdcp) { + + (void)sdcp; + /* TODO: Fill the implementation.*/ + return FALSE; +} +#endif /* HAL_USE_SDC */ + +#if HAL_USE_MMC_SPI || defined(__DOXYGEN__) +/** + * @brief MMC_SPI card detection. + */ +bool_t mmc_lld_is_card_inserted(MMCDriver *mmcp) { + + (void)mmcp; + /* TODO: Fill the implementation.*/ + return TRUE; +} + +/** + * @brief MMC_SPI card write protection detection. + */ +bool_t mmc_lld_is_write_protected(MMCDriver *mmcp) { + + (void)mmcp; + /* TODO: Fill the implementation.*/ + return FALSE; +} +#endif + +/** + * @brief Board-specific initialization code. + * @todo Add your board-specific code, if any. + */ +void boardInit(void) { +} diff --git a/os/hal/boards/NONSTANDARD_STM32F4_BARTHESS2/board.h b/os/hal/boards/NONSTANDARD_STM32F4_BARTHESS2/board.h new file mode 100644 index 0000000..dd5cb4b --- /dev/null +++ b/os/hal/boards/NONSTANDARD_STM32F4_BARTHESS2/board.h @@ -0,0 +1,1152 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2014 Giovanni Di Sirio + + Licensed 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. +*/ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +/* + * Setup for STMicroelectronics STM32F4-Discovery board. + */ + +/* + * Board identifier. + */ +#define BOARD_NAME "NAND and SRAM test board. Codename Buod" + +/* + * Board oscillators-related settings. + */ +#if !defined(STM32_LSECLK) +#define STM32_LSECLK 32768 +#endif + +#if !defined(STM32_HSECLK) +#define STM32_HSECLK 12000000 +#endif + +/* + * Board voltages. + * Required for performance limits calculation. + */ +#define STM32_VDD 300 + +/* + * MCU type, supported types are defined in ./os/hal/platforms/hal_lld.h. + */ +#define STM32F407xx + +/* + * IO pins assignments. + */ +#define GPIOA_PIN0 0 +#define GPIOA_PIN1 1 +#define GPIOA_PIN2 2 +#define GPIOA_PIN3 3 +#define GPIOA_SPI1_NSS 4 +#define GPIOA_PIN5 5 +#define GPIOA_PIN6 6 +#define GPIOA_PIN7 7 +#define GPIOA_PIN8 8 +#define GPIOA_PIN9 9 +#define GPIOA_PIN10 10 +#define GPIOA_PIN11 11 +#define GPIOA_PIN12 12 +#define GPIOA_JTMS 13 +#define GPIOA_JTCK 14 +#define GPIOA_JTDI 15 + +#define GPIOB_PIN0 0 +#define GPIOB_NAND_WP 1 +#define GPIOB_PIN2 2 +#define GPIOB_JTDO 3 +#define GPIOB_JTRST 4 +#define GPIOB_NVRAM_PWR 5 +#define GPIOB_PIN6 6 +#define GPIOB_PIN7 7 +#define GPIOB_PIN8 8 +#define GPIOB_PIN9 9 +#define GPIOB_PIN10 10 +#define GPIOB_PIN11 11 +#define GPIOB_PIN12 12 +#define GPIOB_PIN13 13 +#define GPIOB_PIN14 14 +#define GPIOB_PIN15 15 + +#define GPIOC_PIN0 0 +#define GPIOC_PIN1 1 +#define GPIOC_PIN2 2 +#define GPIOC_PIN3 3 +#define GPIOC_PIN4 4 +#define GPIOC_PIN5 5 +#define GPIOC_PIN6 6 +#define GPIOC_PIN7 7 +#define GPIOC_PIN8 8 +#define GPIOC_PIN9 9 +#define GPIOC_PIN10 10 +#define GPIOC_PIN11 11 +#define GPIOC_PIN12 12 +#define GPIOC_PIN13 13 +#define GPIOC_PIN14 14 +#define GPIOC_PIN15 15 + +#define GPIOD_MEM_D2 0 +#define GPIOD_MEM_D3 1 +#define GPIOD_PIN2 2 +#define GPIOD_PIN3 3 +#define GPIOD_MEM_OE 4 +#define GPIOD_MEM_WE 5 +#define GPIOD_NAND_RB_NWAIT 6 +#define GPIOD_NAND_CE1 7 +#define GPIOD_MEM_D13 8 +#define GPIOD_MEM_D14 9 +#define GPIOD_MEM_D15 10 +#define GPIOD_MEM_A16 11 +#define GPIOD_MEM_A17 12 +#define GPIOD_PIN13 13 +#define GPIOD_MEM_D0 14 +#define GPIOD_MEM_D1 15 + +#define GPIOE_SRAM_LB 0 +#define GPIOE_SRAM_UB 1 +#define GPIOE_PIN2 2 +#define GPIOE_PIN3 3 +#define GPIOE_PIN4 4 +#define GPIOE_PIN5 5 +#define GPIOE_PIN6 6 +#define GPIOE_MEM_D4 7 +#define GPIOE_MEM_D5 8 +#define GPIOE_MEM_D6 9 +#define GPIOE_MEM_D7 10 +#define GPIOE_MEM_D8 11 +#define GPIOE_MEM_D9 12 +#define GPIOE_MEM_D10 13 +#define GPIOE_MEM_D11 14 +#define GPIOE_MEM_D12 15 + +#define GPIOF_MEM_A0 0 +#define GPIOF_MEM_A1 1 +#define GPIOF_MEM_A2 2 +#define GPIOF_MEM_A3 3 +#define GPIOF_MEM_A4 4 +#define GPIOF_MEM_A5 5 +#define GPIOF_PIN6 6 +#define GPIOF_PIN7 7 +#define GPIOF_PIN8 8 +#define GPIOF_PIN9 9 +#define GPIOF_PIN10 10 +#define GPIOF_PIN11 11 +#define GPIOF_MEM_A6 12 +#define GPIOF_MEM_A7 13 +#define GPIOF_MEM_A8 14 +#define GPIOF_MEM_A9 15 + +#define GPIOG_MEM_A10 0 +#define GPIOG_MEM_A11 1 +#define GPIOG_MEM_A12 2 +#define GPIOG_MEM_A13 3 +#define GPIOG_MEM_A14 4 +#define GPIOG_MEM_A15 5 +#define GPIOG_NAND_RB1 6 +#define GPIOG_NAND_RB2 7 +#define GPIOG_PIN8 8 +#define GPIOG_NAND_CE2 9 +#define GPIOG_PIN10 10 +#define GPIOG_PIN11 11 +#define GPIOG_SRAM_CS1 12 +#define GPIOG_PIN13 13 +#define GPIOG_PIN14 14 +#define GPIOG_PIN15 15 + +#define GPIOH_OSC_IN 0 +#define GPIOH_OSC_OUT 1 +#define GPIOH_PIN2 2 +#define GPIOH_PIN3 3 +#define GPIOH_PIN4 4 +#define GPIOH_PIN5 5 +#define GPIOH_PIN6 6 +#define GPIOH_I2C3_SCL 7 +#define GPIOH_I2C3_SDA 8 +#define GPIOH_PIN9 9 +#define GPIOH_PIN10 10 +#define GPIOH_PIN11 11 +#define GPIOH_PIN12 12 +#define GPIOH_PIN13 13 +#define GPIOH_PIN14 14 +#define GPIOH_PIN15 15 + +#define GPIOI_PIN0 0 +#define GPIOI_PIN1 1 +#define GPIOI_PIN2 2 +#define GPIOI_PIN3 3 +#define GPIOI_PIN4 4 +#define GPIOI_PIN5 5 +#define GPIOI_PIN6 6 +#define GPIOI_PIN7 7 +#define GPIOI_PIN8 8 +#define GPIOI_PIN9 9 +#define GPIOI_LED_R 10 +#define GPIOI_LED_G 11 +#define GPIOI_PIN12 12 +#define GPIOI_PIN13 13 +#define GPIOI_PIN14 14 +#define GPIOI_PIN15 15 + +/* + * I/O ports initial setup, this configuration is established soon after reset + * in the initialization code. + * Please refer to the STM32 Reference Manual for details. + */ +#define PIN_MODE_INPUT(n) (0U << ((n) * 2)) +#define PIN_MODE_OUTPUT(n) (1U << ((n) * 2)) +#define PIN_MODE_ALTERNATE(n) (2U << ((n) * 2)) +#define PIN_MODE_ANALOG(n) (3U << ((n) * 2)) +#define PIN_ODR_LOW(n) (0U << (n)) +#define PIN_ODR_HIGH(n) (1U << (n)) +#define PIN_OTYPE_PUSHPULL(n) (0U << (n)) +#define PIN_OTYPE_OPENDRAIN(n) (1U << (n)) +#define PIN_OSPEED_2M(n) (0U << ((n) * 2)) +#define PIN_OSPEED_25M(n) (1U << ((n) * 2)) +#define PIN_OSPEED_50M(n) (2U << ((n) * 2)) +#define PIN_OSPEED_100M(n) (3U << ((n) * 2)) +#define PIN_PUPDR_FLOATING(n) (0U << ((n) * 2)) +#define PIN_PUPDR_PULLUP(n) (1U << ((n) * 2)) +#define PIN_PUPDR_PULLDOWN(n) (2U << ((n) * 2)) +#define PIN_AFIO_AF(n, v) ((v##U) << ((n % 8) * 4)) + +/* + * GPIOA setup: + */ +#define VAL_GPIOA_MODER (PIN_MODE_INPUT(GPIOA_PIN0) | \ + PIN_MODE_INPUT(GPIOA_PIN1) | \ + PIN_MODE_INPUT(GPIOA_PIN2) | \ + PIN_MODE_INPUT(GPIOA_PIN3) | \ + PIN_MODE_ALTERNATE(GPIOA_SPI1_NSS) | \ + PIN_MODE_INPUT(GPIOA_PIN5) | \ + PIN_MODE_INPUT(GPIOA_PIN6) | \ + PIN_MODE_INPUT(GPIOA_PIN7) | \ + PIN_MODE_INPUT(GPIOA_PIN8) | \ + PIN_MODE_INPUT(GPIOA_PIN9) | \ + PIN_MODE_INPUT(GPIOA_PIN10) | \ + PIN_MODE_INPUT(GPIOA_PIN11) | \ + PIN_MODE_INPUT(GPIOA_PIN12) | \ + PIN_MODE_ALTERNATE(GPIOA_JTMS) | \ + PIN_MODE_ALTERNATE(GPIOA_JTCK) | \ + PIN_MODE_ALTERNATE(GPIOA_JTDI)) +#define VAL_GPIOA_OTYPER (PIN_OTYPE_PUSHPULL(GPIOA_PIN0) | \ + PIN_OTYPE_PUSHPULL(GPIOA_PIN1) | \ + PIN_OTYPE_PUSHPULL(GPIOA_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOA_PIN3) | \ + PIN_OTYPE_PUSHPULL(GPIOA_SPI1_NSS) | \ + PIN_OTYPE_PUSHPULL(GPIOA_PIN5) | \ + PIN_OTYPE_PUSHPULL(GPIOA_PIN6) | \ + PIN_OTYPE_PUSHPULL(GPIOA_PIN7) | \ + PIN_OTYPE_PUSHPULL(GPIOA_PIN8) | \ + PIN_OTYPE_PUSHPULL(GPIOA_PIN9) | \ + PIN_OTYPE_PUSHPULL(GPIOA_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOA_PIN11) | \ + PIN_OTYPE_PUSHPULL(GPIOA_PIN12) | \ + PIN_OTYPE_PUSHPULL(GPIOA_JTMS) | \ + PIN_OTYPE_PUSHPULL(GPIOA_JTCK) | \ + PIN_OTYPE_PUSHPULL(GPIOA_JTDI)) +#define VAL_GPIOA_OSPEEDR (PIN_OSPEED_100M(GPIOA_PIN0) | \ + PIN_OSPEED_100M(GPIOA_PIN1) | \ + PIN_OSPEED_100M(GPIOA_PIN2) | \ + PIN_OSPEED_100M(GPIOA_PIN3) | \ + PIN_OSPEED_100M(GPIOA_SPI1_NSS) | \ + PIN_OSPEED_100M(GPIOA_PIN5) | \ + PIN_OSPEED_100M(GPIOA_PIN6) | \ + PIN_OSPEED_100M(GPIOA_PIN7) | \ + PIN_OSPEED_100M(GPIOA_PIN8) | \ + PIN_OSPEED_100M(GPIOA_PIN9) | \ + PIN_OSPEED_100M(GPIOA_PIN10) | \ + PIN_OSPEED_100M(GPIOA_PIN11) | \ + PIN_OSPEED_100M(GPIOA_PIN12) | \ + PIN_OSPEED_100M(GPIOA_JTMS) | \ + PIN_OSPEED_100M(GPIOA_JTCK) | \ + PIN_OSPEED_100M(GPIOA_JTDI)) +#define VAL_GPIOA_PUPDR (PIN_PUPDR_FLOATING(GPIOA_PIN0) | \ + PIN_PUPDR_FLOATING(GPIOA_PIN1) | \ + PIN_PUPDR_FLOATING(GPIOA_PIN2) | \ + PIN_PUPDR_FLOATING(GPIOA_PIN3) | \ + PIN_PUPDR_FLOATING(GPIOA_SPI1_NSS) | \ + PIN_PUPDR_FLOATING(GPIOA_PIN5) | \ + PIN_PUPDR_FLOATING(GPIOA_PIN6) | \ + PIN_PUPDR_FLOATING(GPIOA_PIN7) | \ + PIN_PUPDR_FLOATING(GPIOA_PIN8) | \ + PIN_PUPDR_FLOATING(GPIOA_PIN9) | \ + PIN_PUPDR_FLOATING(GPIOA_PIN10) | \ + PIN_PUPDR_FLOATING(GPIOA_PIN11) | \ + PIN_PUPDR_FLOATING(GPIOA_PIN12) | \ + PIN_PUPDR_FLOATING(GPIOA_JTMS) | \ + PIN_PUPDR_FLOATING(GPIOA_JTCK) | \ + PIN_PUPDR_FLOATING(GPIOA_JTDI)) +#define VAL_GPIOA_ODR (PIN_ODR_HIGH(GPIOA_PIN0) | \ + PIN_ODR_HIGH(GPIOA_PIN1) | \ + PIN_ODR_HIGH(GPIOA_PIN2) | \ + PIN_ODR_HIGH(GPIOA_PIN3) | \ + PIN_ODR_HIGH(GPIOA_SPI1_NSS) | \ + PIN_ODR_HIGH(GPIOA_PIN5) | \ + PIN_ODR_HIGH(GPIOA_PIN6) | \ + PIN_ODR_HIGH(GPIOA_PIN7) | \ + PIN_ODR_HIGH(GPIOA_PIN8) | \ + PIN_ODR_HIGH(GPIOA_PIN9) | \ + PIN_ODR_HIGH(GPIOA_PIN10) | \ + PIN_ODR_HIGH(GPIOA_PIN11) | \ + PIN_ODR_HIGH(GPIOA_PIN12) | \ + PIN_ODR_HIGH(GPIOA_JTMS) | \ + PIN_ODR_HIGH(GPIOA_JTCK) | \ + PIN_ODR_HIGH(GPIOA_JTDI)) +#define VAL_GPIOA_AFRL (PIN_AFIO_AF(GPIOA_PIN0, 0) | \ + PIN_AFIO_AF(GPIOA_PIN1, 0) | \ + PIN_AFIO_AF(GPIOA_PIN2, 0) | \ + PIN_AFIO_AF(GPIOA_PIN3, 0) | \ + PIN_AFIO_AF(GPIOA_SPI1_NSS, 5) | \ + PIN_AFIO_AF(GPIOA_PIN5, 0) | \ + PIN_AFIO_AF(GPIOA_PIN6, 0) | \ + PIN_AFIO_AF(GPIOA_PIN7, 0)) +#define VAL_GPIOA_AFRH (PIN_AFIO_AF(GPIOA_PIN8, 0) | \ + PIN_AFIO_AF(GPIOA_PIN9, 0) | \ + PIN_AFIO_AF(GPIOA_PIN10, 0) | \ + PIN_AFIO_AF(GPIOA_PIN11, 0) | \ + PIN_AFIO_AF(GPIOA_PIN12, 0) | \ + PIN_AFIO_AF(GPIOA_JTMS, 0) | \ + PIN_AFIO_AF(GPIOA_JTCK, 0) | \ + PIN_AFIO_AF(GPIOA_JTDI, 0)) + +/* + * GPIOB setup: + */ +#define VAL_GPIOB_MODER (PIN_MODE_INPUT(GPIOB_PIN0) | \ + PIN_MODE_OUTPUT(GPIOB_NAND_WP) | \ + PIN_MODE_INPUT(GPIOB_PIN2) | \ + PIN_MODE_ALTERNATE(GPIOB_JTDO) | \ + PIN_MODE_ALTERNATE(GPIOB_JTRST) | \ + PIN_MODE_OUTPUT(GPIOB_NVRAM_PWR) | \ + PIN_MODE_INPUT(GPIOB_PIN6) | \ + PIN_MODE_INPUT(GPIOB_PIN7) | \ + PIN_MODE_INPUT(GPIOB_PIN8) | \ + PIN_MODE_INPUT(GPIOB_PIN9) | \ + PIN_MODE_INPUT(GPIOB_PIN10) | \ + PIN_MODE_INPUT(GPIOB_PIN11) | \ + PIN_MODE_INPUT(GPIOB_PIN12) | \ + PIN_MODE_INPUT(GPIOB_PIN13) | \ + PIN_MODE_INPUT(GPIOB_PIN14) | \ + PIN_MODE_INPUT(GPIOB_PIN15)) + +#define VAL_GPIOB_OTYPER (PIN_OTYPE_PUSHPULL(GPIOB_PIN0) | \ + PIN_OTYPE_PUSHPULL(GPIOB_NAND_WP) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOB_JTDO) | \ + PIN_OTYPE_PUSHPULL(GPIOB_JTRST) | \ + PIN_OTYPE_OPENDRAIN(GPIOB_NVRAM_PWR) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN6) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN7) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN8) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN9) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN11) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN12) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN13) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN14) | \ + PIN_OTYPE_PUSHPULL(GPIOB_PIN15)) +#define VAL_GPIOB_OSPEEDR (PIN_OSPEED_100M(GPIOB_PIN0) | \ + PIN_OSPEED_100M(GPIOB_NAND_WP) | \ + PIN_OSPEED_100M(GPIOB_PIN2) | \ + PIN_OSPEED_100M(GPIOB_JTDO) | \ + PIN_OSPEED_100M(GPIOB_JTRST) | \ + PIN_OSPEED_2M(GPIOB_NVRAM_PWR) | \ + PIN_OSPEED_100M(GPIOB_PIN6) | \ + PIN_OSPEED_100M(GPIOB_PIN7) | \ + PIN_OSPEED_100M(GPIOB_PIN8) | \ + PIN_OSPEED_100M(GPIOB_PIN9) | \ + PIN_OSPEED_100M(GPIOB_PIN10) | \ + PIN_OSPEED_100M(GPIOB_PIN11) | \ + PIN_OSPEED_100M(GPIOB_PIN12) | \ + PIN_OSPEED_100M(GPIOB_PIN13) | \ + PIN_OSPEED_100M(GPIOB_PIN14) | \ + PIN_OSPEED_100M(GPIOB_PIN15)) +#define VAL_GPIOB_PUPDR (PIN_PUPDR_FLOATING(GPIOB_PIN0) | \ + PIN_PUPDR_PULLDOWN(GPIOB_NAND_WP) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN2) | \ + PIN_PUPDR_FLOATING(GPIOB_JTDO) | \ + PIN_PUPDR_FLOATING(GPIOB_JTRST) | \ + PIN_PUPDR_FLOATING(GPIOB_NVRAM_PWR) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN6) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN7) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN8) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN9) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN10) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN11) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN12) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN13) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN14) | \ + PIN_PUPDR_FLOATING(GPIOB_PIN15)) +#define VAL_GPIOB_ODR (PIN_ODR_HIGH(GPIOB_PIN0) | \ + PIN_ODR_LOW(GPIOB_NAND_WP) | \ + PIN_ODR_HIGH(GPIOB_PIN2) | \ + PIN_ODR_HIGH(GPIOB_JTDO) | \ + PIN_ODR_HIGH(GPIOB_JTRST) | \ + PIN_ODR_LOW(GPIOB_NVRAM_PWR) | \ + PIN_ODR_HIGH(GPIOB_PIN6) | \ + PIN_ODR_HIGH(GPIOB_PIN7) | \ + PIN_ODR_HIGH(GPIOB_PIN8) | \ + PIN_ODR_HIGH(GPIOB_PIN9) | \ + PIN_ODR_HIGH(GPIOB_PIN10) | \ + PIN_ODR_HIGH(GPIOB_PIN11) | \ + PIN_ODR_HIGH(GPIOB_PIN12) | \ + PIN_ODR_HIGH(GPIOB_PIN13) | \ + PIN_ODR_HIGH(GPIOB_PIN14) | \ + PIN_ODR_HIGH(GPIOB_PIN15)) +#define VAL_GPIOB_AFRL (PIN_AFIO_AF(GPIOB_PIN0, 0) | \ + PIN_AFIO_AF(GPIOB_NAND_WP, 0) | \ + PIN_AFIO_AF(GPIOB_PIN2, 0) | \ + PIN_AFIO_AF(GPIOB_JTDO, 0) | \ + PIN_AFIO_AF(GPIOB_JTRST, 0) | \ + PIN_AFIO_AF(GPIOB_NVRAM_PWR, 0) | \ + PIN_AFIO_AF(GPIOB_PIN6, 0) | \ + PIN_AFIO_AF(GPIOB_PIN7, 0)) +#define VAL_GPIOB_AFRH (PIN_AFIO_AF(GPIOB_PIN8, 0) | \ + PIN_AFIO_AF(GPIOB_PIN9, 0) | \ + PIN_AFIO_AF(GPIOB_PIN10, 0) | \ + PIN_AFIO_AF(GPIOB_PIN11, 0) | \ + PIN_AFIO_AF(GPIOB_PIN12, 0) | \ + PIN_AFIO_AF(GPIOB_PIN13, 0) | \ + PIN_AFIO_AF(GPIOB_PIN14, 0) | \ + PIN_AFIO_AF(GPIOB_PIN15, 0)) + +/* + * GPIOC setup: + */ +#define VAL_GPIOC_MODER (PIN_MODE_INPUT(GPIOC_PIN0) | \ + PIN_MODE_INPUT(GPIOC_PIN1) | \ + PIN_MODE_INPUT(GPIOC_PIN2) | \ + PIN_MODE_INPUT(GPIOC_PIN3) | \ + PIN_MODE_INPUT(GPIOC_PIN4) | \ + PIN_MODE_INPUT(GPIOC_PIN5) | \ + PIN_MODE_INPUT(GPIOC_PIN6) | \ + PIN_MODE_INPUT(GPIOC_PIN7) | \ + PIN_MODE_INPUT(GPIOC_PIN8) | \ + PIN_MODE_INPUT(GPIOC_PIN9) | \ + PIN_MODE_INPUT(GPIOC_PIN10) | \ + PIN_MODE_INPUT(GPIOC_PIN11) | \ + PIN_MODE_INPUT(GPIOC_PIN12) | \ + PIN_MODE_INPUT(GPIOC_PIN13) | \ + PIN_MODE_INPUT(GPIOC_PIN14) | \ + PIN_MODE_INPUT(GPIOC_PIN15)) +#define VAL_GPIOC_OTYPER (PIN_OTYPE_PUSHPULL(GPIOC_PIN0) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN1) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN3) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN4) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN5) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN6) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN7) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN8) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN9) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN11) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN12) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN13) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN14) | \ + PIN_OTYPE_PUSHPULL(GPIOC_PIN15)) +#define VAL_GPIOC_OSPEEDR (PIN_OSPEED_100M(GPIOC_PIN0) |\ + PIN_OSPEED_100M(GPIOC_PIN1) | \ + PIN_OSPEED_100M(GPIOC_PIN2) | \ + PIN_OSPEED_100M(GPIOC_PIN3) | \ + PIN_OSPEED_100M(GPIOC_PIN4) | \ + PIN_OSPEED_100M(GPIOC_PIN5) | \ + PIN_OSPEED_100M(GPIOC_PIN6) | \ + PIN_OSPEED_100M(GPIOC_PIN7) | \ + PIN_OSPEED_100M(GPIOC_PIN8) | \ + PIN_OSPEED_100M(GPIOC_PIN9) | \ + PIN_OSPEED_100M(GPIOC_PIN10) | \ + PIN_OSPEED_100M(GPIOC_PIN11) | \ + PIN_OSPEED_100M(GPIOC_PIN12) | \ + PIN_OSPEED_100M(GPIOC_PIN13) | \ + PIN_OSPEED_100M(GPIOC_PIN14) | \ + PIN_OSPEED_100M(GPIOC_PIN15)) +#define VAL_GPIOC_PUPDR (PIN_PUPDR_FLOATING(GPIOC_PIN0) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN1) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN2) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN3) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN4) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN5) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN6) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN7) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN8) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN9) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN10) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN11) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN12) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN13) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN14) | \ + PIN_PUPDR_FLOATING(GPIOC_PIN15)) +#define VAL_GPIOC_ODR (PIN_ODR_HIGH(GPIOC_PIN0) | \ + PIN_ODR_HIGH(GPIOC_PIN1) | \ + PIN_ODR_HIGH(GPIOC_PIN2) | \ + PIN_ODR_HIGH(GPIOC_PIN3) | \ + PIN_ODR_HIGH(GPIOC_PIN4) | \ + PIN_ODR_HIGH(GPIOC_PIN5) | \ + PIN_ODR_HIGH(GPIOC_PIN6) | \ + PIN_ODR_HIGH(GPIOC_PIN7) | \ + PIN_ODR_HIGH(GPIOC_PIN8) | \ + PIN_ODR_HIGH(GPIOC_PIN9) | \ + PIN_ODR_HIGH(GPIOC_PIN10) | \ + PIN_ODR_HIGH(GPIOC_PIN11) | \ + PIN_ODR_HIGH(GPIOC_PIN12) | \ + PIN_ODR_HIGH(GPIOC_PIN13) | \ + PIN_ODR_HIGH(GPIOC_PIN14) | \ + PIN_ODR_HIGH(GPIOC_PIN15)) +#define VAL_GPIOC_AFRL (PIN_AFIO_AF(GPIOC_PIN0, 0) | \ + PIN_AFIO_AF(GPIOC_PIN1, 0) | \ + PIN_AFIO_AF(GPIOC_PIN2, 0) | \ + PIN_AFIO_AF(GPIOC_PIN3, 0) | \ + PIN_AFIO_AF(GPIOC_PIN4, 0) | \ + PIN_AFIO_AF(GPIOC_PIN5, 0) | \ + PIN_AFIO_AF(GPIOC_PIN6, 0) | \ + PIN_AFIO_AF(GPIOC_PIN7, 0)) +#define VAL_GPIOC_AFRH (PIN_AFIO_AF(GPIOC_PIN8, 0) | \ + PIN_AFIO_AF(GPIOC_PIN9, 0) | \ + PIN_AFIO_AF(GPIOC_PIN10, 0) | \ + PIN_AFIO_AF(GPIOC_PIN11, 0) | \ + PIN_AFIO_AF(GPIOC_PIN12, 0) | \ + PIN_AFIO_AF(GPIOC_PIN13, 0) | \ + PIN_AFIO_AF(GPIOC_PIN14, 0) | \ + PIN_AFIO_AF(GPIOC_PIN15, 0)) + +/* + * GPIOD setup: + */ +#define VAL_GPIOD_MODER (PIN_MODE_ALTERNATE(GPIOD_MEM_D2) | \ + PIN_MODE_ALTERNATE(GPIOD_MEM_D3) | \ + PIN_MODE_INPUT(GPIOD_PIN2) | \ + PIN_MODE_INPUT(GPIOD_PIN3) | \ + PIN_MODE_ALTERNATE(GPIOD_MEM_OE) | \ + PIN_MODE_ALTERNATE(GPIOD_MEM_WE) | \ + PIN_MODE_INPUT(GPIOD_NAND_RB_NWAIT) | \ + PIN_MODE_ALTERNATE(GPIOD_NAND_CE1) | \ + PIN_MODE_ALTERNATE(GPIOD_MEM_D13) | \ + PIN_MODE_ALTERNATE(GPIOD_MEM_D14) | \ + PIN_MODE_ALTERNATE(GPIOD_MEM_D15) | \ + PIN_MODE_ALTERNATE(GPIOD_MEM_A16) | \ + PIN_MODE_ALTERNATE(GPIOD_MEM_A17) | \ + PIN_MODE_INPUT(GPIOD_PIN13) | \ + PIN_MODE_ALTERNATE(GPIOD_MEM_D0) | \ + PIN_MODE_ALTERNATE(GPIOD_MEM_D1)) +#define VAL_GPIOD_OTYPER (PIN_OTYPE_PUSHPULL(GPIOD_MEM_D2) | \ + PIN_OTYPE_PUSHPULL(GPIOD_MEM_D3) | \ + PIN_OTYPE_PUSHPULL(GPIOD_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOD_PIN3) | \ + PIN_OTYPE_PUSHPULL(GPIOD_MEM_OE) | \ + PIN_OTYPE_PUSHPULL(GPIOD_MEM_WE) | \ + PIN_OTYPE_PUSHPULL(GPIOD_NAND_RB_NWAIT) |\ + PIN_OTYPE_PUSHPULL(GPIOD_NAND_CE1) | \ + PIN_OTYPE_PUSHPULL(GPIOD_MEM_D13) | \ + PIN_OTYPE_PUSHPULL(GPIOD_MEM_D14) | \ + PIN_OTYPE_PUSHPULL(GPIOD_MEM_D15) | \ + PIN_OTYPE_PUSHPULL(GPIOD_MEM_A16) | \ + PIN_OTYPE_PUSHPULL(GPIOD_MEM_A17) | \ + PIN_OTYPE_PUSHPULL(GPIOD_PIN13) | \ + PIN_OTYPE_PUSHPULL(GPIOD_MEM_D0) | \ + PIN_OTYPE_PUSHPULL(GPIOD_MEM_D1)) +#define VAL_GPIOD_OSPEEDR (PIN_OSPEED_100M(GPIOD_MEM_D2) | \ + PIN_OSPEED_100M(GPIOD_MEM_D3) | \ + PIN_OSPEED_100M(GPIOD_PIN2) | \ + PIN_OSPEED_100M(GPIOD_PIN3) | \ + PIN_OSPEED_100M(GPIOD_MEM_OE) | \ + PIN_OSPEED_100M(GPIOD_MEM_WE) | \ + PIN_OSPEED_100M(GPIOD_NAND_RB_NWAIT) | \ + PIN_OSPEED_100M(GPIOD_NAND_CE1) | \ + PIN_OSPEED_100M(GPIOD_MEM_D13) | \ + PIN_OSPEED_100M(GPIOD_MEM_D14) | \ + PIN_OSPEED_100M(GPIOD_MEM_D15) | \ + PIN_OSPEED_100M(GPIOD_MEM_A16) | \ + PIN_OSPEED_100M(GPIOD_MEM_A17) | \ + PIN_OSPEED_100M(GPIOD_PIN13) | \ + PIN_OSPEED_100M(GPIOD_MEM_D0) | \ + PIN_OSPEED_100M(GPIOD_MEM_D1)) + +#if STM32_NAND_USE_EXT_INT +#define NAND_RB_NWAIT_PUPDR(pin) (PIN_PUPDR_PULLUP(pin)) +#else +#define NAND_RB_NWAIT_PUPDR(pin) (PIN_PUPDR_FLOATING(pin)) +#endif +#define VAL_GPIOD_PUPDR (PIN_PUPDR_FLOATING(GPIOD_MEM_D2) | \ + PIN_PUPDR_FLOATING(GPIOD_MEM_D3) | \ + PIN_PUPDR_FLOATING(GPIOD_PIN2) | \ + PIN_PUPDR_FLOATING(GPIOD_PIN3) | \ + PIN_PUPDR_FLOATING(GPIOD_MEM_OE) | \ + PIN_PUPDR_FLOATING(GPIOD_MEM_WE) | \ + NAND_RB_NWAIT_PUPDR(GPIOD_NAND_RB_NWAIT) | \ + PIN_PUPDR_FLOATING(GPIOD_NAND_CE1) | \ + PIN_PUPDR_FLOATING(GPIOD_MEM_D13) | \ + PIN_PUPDR_FLOATING(GPIOD_MEM_D14) | \ + PIN_PUPDR_FLOATING(GPIOD_MEM_D15) | \ + PIN_PUPDR_FLOATING(GPIOD_MEM_A16) | \ + PIN_PUPDR_FLOATING(GPIOD_MEM_A17) | \ + PIN_PUPDR_FLOATING(GPIOD_PIN13) | \ + PIN_PUPDR_FLOATING(GPIOD_MEM_D0) | \ + PIN_PUPDR_FLOATING(GPIOD_MEM_D1)) +#define VAL_GPIOD_ODR (PIN_ODR_HIGH(GPIOD_MEM_D2) | \ + PIN_ODR_HIGH(GPIOD_MEM_D3) | \ + PIN_ODR_HIGH(GPIOD_PIN2) | \ + PIN_ODR_HIGH(GPIOD_PIN3) | \ + PIN_ODR_HIGH(GPIOD_MEM_OE) | \ + PIN_ODR_HIGH(GPIOD_MEM_WE) | \ + PIN_ODR_HIGH(GPIOD_NAND_RB_NWAIT) | \ + PIN_ODR_HIGH(GPIOD_NAND_CE1) | \ + PIN_ODR_HIGH(GPIOD_MEM_D13) | \ + PIN_ODR_HIGH(GPIOD_MEM_D14) | \ + PIN_ODR_HIGH(GPIOD_MEM_D15) | \ + PIN_ODR_HIGH(GPIOD_MEM_A16) | \ + PIN_ODR_HIGH(GPIOD_MEM_A17) | \ + PIN_ODR_HIGH(GPIOD_PIN13) | \ + PIN_ODR_HIGH(GPIOD_MEM_D0) | \ + PIN_ODR_HIGH(GPIOD_MEM_D1)) +#define VAL_GPIOD_AFRL (PIN_AFIO_AF(GPIOD_MEM_D2, 12) | \ + PIN_AFIO_AF(GPIOD_MEM_D3, 12) | \ + PIN_AFIO_AF(GPIOD_PIN2, 0) | \ + PIN_AFIO_AF(GPIOD_PIN3, 0) | \ + PIN_AFIO_AF(GPIOD_MEM_OE, 12) | \ + PIN_AFIO_AF(GPIOD_MEM_WE, 12) | \ + PIN_AFIO_AF(GPIOD_NAND_RB_NWAIT, 0) | \ + PIN_AFIO_AF(GPIOD_NAND_CE1, 12)) +#define VAL_GPIOD_AFRH (PIN_AFIO_AF(GPIOD_MEM_D13, 12) | \ + PIN_AFIO_AF(GPIOD_MEM_D14, 12) | \ + PIN_AFIO_AF(GPIOD_MEM_D15, 12) | \ + PIN_AFIO_AF(GPIOD_MEM_A16, 12) | \ + PIN_AFIO_AF(GPIOD_MEM_A17, 12) | \ + PIN_AFIO_AF(GPIOD_PIN13, 0) | \ + PIN_AFIO_AF(GPIOD_MEM_D0, 12) | \ + PIN_AFIO_AF(GPIOD_MEM_D1, 12)) + +/* + * GPIOE setup: + */ +#define VAL_GPIOE_MODER (PIN_MODE_ALTERNATE(GPIOE_SRAM_LB) | \ + PIN_MODE_ALTERNATE(GPIOE_SRAM_UB) | \ + PIN_MODE_INPUT(GPIOE_PIN2) | \ + PIN_MODE_INPUT(GPIOE_PIN3) | \ + PIN_MODE_INPUT(GPIOE_PIN4) | \ + PIN_MODE_INPUT(GPIOE_PIN5) | \ + PIN_MODE_INPUT(GPIOE_PIN6) | \ + PIN_MODE_ALTERNATE(GPIOE_MEM_D4) | \ + PIN_MODE_ALTERNATE(GPIOE_MEM_D5) | \ + PIN_MODE_ALTERNATE(GPIOE_MEM_D6) | \ + PIN_MODE_ALTERNATE(GPIOE_MEM_D7) | \ + PIN_MODE_ALTERNATE(GPIOE_MEM_D8) | \ + PIN_MODE_ALTERNATE(GPIOE_MEM_D9) | \ + PIN_MODE_ALTERNATE(GPIOE_MEM_D10) | \ + PIN_MODE_ALTERNATE(GPIOE_MEM_D11) | \ + PIN_MODE_ALTERNATE(GPIOE_MEM_D12)) +#define VAL_GPIOE_OTYPER (PIN_OTYPE_PUSHPULL(GPIOE_SRAM_LB) | \ + PIN_OTYPE_PUSHPULL(GPIOE_SRAM_UB) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN3) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN4) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN5) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN6) | \ + PIN_OTYPE_PUSHPULL(GPIOE_MEM_D4) | \ + PIN_OTYPE_PUSHPULL(GPIOE_MEM_D5) | \ + PIN_OTYPE_PUSHPULL(GPIOE_MEM_D6) | \ + PIN_OTYPE_PUSHPULL(GPIOE_MEM_D7) | \ + PIN_OTYPE_PUSHPULL(GPIOE_MEM_D8) | \ + PIN_OTYPE_PUSHPULL(GPIOE_MEM_D9) | \ + PIN_OTYPE_PUSHPULL(GPIOE_MEM_D10) | \ + PIN_OTYPE_PUSHPULL(GPIOE_MEM_D11) | \ + PIN_OTYPE_PUSHPULL(GPIOE_MEM_D12)) +#define VAL_GPIOE_OSPEEDR (PIN_OSPEED_100M(GPIOE_SRAM_LB) | \ + PIN_OSPEED_100M(GPIOE_SRAM_UB) | \ + PIN_OSPEED_100M(GPIOE_PIN2) | \ + PIN_OSPEED_100M(GPIOE_PIN3) | \ + PIN_OSPEED_100M(GPIOE_PIN4) | \ + PIN_OSPEED_100M(GPIOE_PIN5) | \ + PIN_OSPEED_100M(GPIOE_PIN6) | \ + PIN_OSPEED_100M(GPIOE_MEM_D4) | \ + PIN_OSPEED_100M(GPIOE_MEM_D5) | \ + PIN_OSPEED_100M(GPIOE_MEM_D6) | \ + PIN_OSPEED_100M(GPIOE_MEM_D7) | \ + PIN_OSPEED_100M(GPIOE_MEM_D8) | \ + PIN_OSPEED_100M(GPIOE_MEM_D9) | \ + PIN_OSPEED_100M(GPIOE_MEM_D10) | \ + PIN_OSPEED_100M(GPIOE_MEM_D11) | \ + PIN_OSPEED_100M(GPIOE_MEM_D12)) +#define VAL_GPIOE_PUPDR (PIN_PUPDR_FLOATING(GPIOE_SRAM_LB) | \ + PIN_PUPDR_FLOATING(GPIOE_SRAM_UB) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN2) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN3) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN4) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN5) | \ + PIN_PUPDR_FLOATING(GPIOE_PIN6) | \ + PIN_PUPDR_FLOATING(GPIOE_MEM_D4) | \ + PIN_PUPDR_FLOATING(GPIOE_MEM_D5) | \ + PIN_PUPDR_FLOATING(GPIOE_MEM_D6) | \ + PIN_PUPDR_FLOATING(GPIOE_MEM_D7) | \ + PIN_PUPDR_FLOATING(GPIOE_MEM_D8) | \ + PIN_PUPDR_FLOATING(GPIOE_MEM_D9) | \ + PIN_PUPDR_FLOATING(GPIOE_MEM_D10) | \ + PIN_PUPDR_FLOATING(GPIOE_MEM_D11) | \ + PIN_PUPDR_FLOATING(GPIOE_MEM_D12)) +#define VAL_GPIOE_ODR (PIN_ODR_HIGH(GPIOE_SRAM_LB) | \ + PIN_ODR_HIGH(GPIOE_SRAM_UB) | \ + PIN_ODR_HIGH(GPIOE_PIN2) | \ + PIN_ODR_HIGH(GPIOE_PIN3) | \ + PIN_ODR_HIGH(GPIOE_PIN4) | \ + PIN_ODR_HIGH(GPIOE_PIN5) | \ + PIN_ODR_HIGH(GPIOE_PIN6) | \ + PIN_ODR_HIGH(GPIOE_MEM_D4) | \ + PIN_ODR_HIGH(GPIOE_MEM_D5) | \ + PIN_ODR_HIGH(GPIOE_MEM_D6) | \ + PIN_ODR_HIGH(GPIOE_MEM_D7) | \ + PIN_ODR_HIGH(GPIOE_MEM_D8) | \ + PIN_ODR_HIGH(GPIOE_MEM_D9) | \ + PIN_ODR_HIGH(GPIOE_MEM_D10) | \ + PIN_ODR_HIGH(GPIOE_MEM_D11) | \ + PIN_ODR_HIGH(GPIOE_MEM_D12)) +#define VAL_GPIOE_AFRL (PIN_AFIO_AF(GPIOE_SRAM_LB, 12) | \ + PIN_AFIO_AF(GPIOE_SRAM_UB, 12) | \ + PIN_AFIO_AF(GPIOE_PIN2, 0) | \ + PIN_AFIO_AF(GPIOE_PIN3, 0) | \ + PIN_AFIO_AF(GPIOE_PIN4, 0) | \ + PIN_AFIO_AF(GPIOE_PIN5, 0) | \ + PIN_AFIO_AF(GPIOE_PIN6, 0) | \ + PIN_AFIO_AF(GPIOE_MEM_D4, 12)) +#define VAL_GPIOE_AFRH (PIN_AFIO_AF(GPIOE_MEM_D5, 12) | \ + PIN_AFIO_AF(GPIOE_MEM_D6, 12) | \ + PIN_AFIO_AF(GPIOE_MEM_D7, 12) | \ + PIN_AFIO_AF(GPIOE_MEM_D8, 12) | \ + PIN_AFIO_AF(GPIOE_MEM_D9, 12) | \ + PIN_AFIO_AF(GPIOE_MEM_D10, 12) | \ + PIN_AFIO_AF(GPIOE_MEM_D11, 12) | \ + PIN_AFIO_AF(GPIOE_MEM_D12, 12)) + +/* + * GPIOF setup: + */ +#define VAL_GPIOF_MODER (PIN_MODE_ALTERNATE(GPIOF_MEM_A0) | \ + PIN_MODE_ALTERNATE(GPIOF_MEM_A1) | \ + PIN_MODE_ALTERNATE(GPIOF_MEM_A2) | \ + PIN_MODE_ALTERNATE(GPIOF_MEM_A3) | \ + PIN_MODE_ALTERNATE(GPIOF_MEM_A4) | \ + PIN_MODE_ALTERNATE(GPIOF_MEM_A5) | \ + PIN_MODE_INPUT(GPIOF_PIN6) | \ + PIN_MODE_INPUT(GPIOF_PIN7) | \ + PIN_MODE_INPUT(GPIOF_PIN8) | \ + PIN_MODE_INPUT(GPIOF_PIN9) | \ + PIN_MODE_INPUT(GPIOF_PIN10) | \ + PIN_MODE_INPUT(GPIOF_PIN11) | \ + PIN_MODE_ALTERNATE(GPIOF_MEM_A6) | \ + PIN_MODE_ALTERNATE(GPIOF_MEM_A7) | \ + PIN_MODE_ALTERNATE(GPIOF_MEM_A8) | \ + PIN_MODE_ALTERNATE(GPIOF_MEM_A9)) +#define VAL_GPIOF_OTYPER (PIN_OTYPE_PUSHPULL(GPIOF_MEM_A0) | \ + PIN_OTYPE_PUSHPULL(GPIOF_MEM_A1) | \ + PIN_OTYPE_PUSHPULL(GPIOF_MEM_A2) | \ + PIN_OTYPE_PUSHPULL(GPIOF_MEM_A3) | \ + PIN_OTYPE_PUSHPULL(GPIOF_MEM_A4) | \ + PIN_OTYPE_PUSHPULL(GPIOF_MEM_A5) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN6) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN7) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN8) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN9) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN11) | \ + PIN_OTYPE_PUSHPULL(GPIOF_MEM_A6) | \ + PIN_OTYPE_PUSHPULL(GPIOF_MEM_A7) | \ + PIN_OTYPE_PUSHPULL(GPIOF_MEM_A8) | \ + PIN_OTYPE_PUSHPULL(GPIOF_MEM_A9)) +#define VAL_GPIOF_OSPEEDR (PIN_OSPEED_100M(GPIOF_MEM_A0) | \ + PIN_OSPEED_100M(GPIOF_MEM_A1) | \ + PIN_OSPEED_100M(GPIOF_MEM_A2) | \ + PIN_OSPEED_100M(GPIOF_MEM_A3) | \ + PIN_OSPEED_100M(GPIOF_MEM_A4) | \ + PIN_OSPEED_100M(GPIOF_MEM_A5) | \ + PIN_OSPEED_100M(GPIOF_PIN6) | \ + PIN_OSPEED_100M(GPIOF_PIN7) | \ + PIN_OSPEED_100M(GPIOF_PIN8) | \ + PIN_OSPEED_100M(GPIOF_PIN9) | \ + PIN_OSPEED_100M(GPIOF_PIN10) | \ + PIN_OSPEED_100M(GPIOF_PIN11) | \ + PIN_OSPEED_100M(GPIOF_MEM_A6) | \ + PIN_OSPEED_100M(GPIOF_MEM_A7) | \ + PIN_OSPEED_100M(GPIOF_MEM_A8) | \ + PIN_OSPEED_100M(GPIOF_MEM_A9)) +#define VAL_GPIOF_PUPDR (PIN_PUPDR_FLOATING(GPIOF_MEM_A0) | \ + PIN_PUPDR_FLOATING(GPIOF_MEM_A1) | \ + PIN_PUPDR_FLOATING(GPIOF_MEM_A2) | \ + PIN_PUPDR_FLOATING(GPIOF_MEM_A3) | \ + PIN_PUPDR_FLOATING(GPIOF_MEM_A4) | \ + PIN_PUPDR_FLOATING(GPIOF_MEM_A5) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN6) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN7) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN8) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN9) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN10) | \ + PIN_PUPDR_FLOATING(GPIOF_PIN11) | \ + PIN_PUPDR_FLOATING(GPIOF_MEM_A6) | \ + PIN_PUPDR_FLOATING(GPIOF_MEM_A7) | \ + PIN_PUPDR_FLOATING(GPIOF_MEM_A8) | \ + PIN_PUPDR_FLOATING(GPIOF_MEM_A9)) +#define VAL_GPIOF_ODR (PIN_ODR_HIGH(GPIOF_MEM_A0) | \ + PIN_ODR_HIGH(GPIOF_MEM_A1) | \ + PIN_ODR_HIGH(GPIOF_MEM_A2) | \ + PIN_ODR_HIGH(GPIOF_MEM_A3) | \ + PIN_ODR_HIGH(GPIOF_MEM_A4) | \ + PIN_ODR_HIGH(GPIOF_MEM_A5) | \ + PIN_ODR_HIGH(GPIOF_PIN6) | \ + PIN_ODR_HIGH(GPIOF_PIN7) | \ + PIN_ODR_HIGH(GPIOF_PIN8) | \ + PIN_ODR_HIGH(GPIOF_PIN9) | \ + PIN_ODR_HIGH(GPIOF_PIN10) | \ + PIN_ODR_HIGH(GPIOF_PIN11) | \ + PIN_ODR_HIGH(GPIOF_MEM_A6) | \ + PIN_ODR_HIGH(GPIOF_MEM_A7) | \ + PIN_ODR_HIGH(GPIOF_MEM_A8) | \ + PIN_ODR_HIGH(GPIOF_MEM_A9)) +#define VAL_GPIOF_AFRL (PIN_AFIO_AF(GPIOF_MEM_A0, 12) | \ + PIN_AFIO_AF(GPIOF_MEM_A1, 12) | \ + PIN_AFIO_AF(GPIOF_MEM_A2, 12) | \ + PIN_AFIO_AF(GPIOF_MEM_A3, 12) | \ + PIN_AFIO_AF(GPIOF_MEM_A4, 12) | \ + PIN_AFIO_AF(GPIOF_MEM_A5, 12) | \ + PIN_AFIO_AF(GPIOF_PIN6, 0) | \ + PIN_AFIO_AF(GPIOF_PIN7, 0)) +#define VAL_GPIOF_AFRH (PIN_AFIO_AF(GPIOF_PIN8, 0) | \ + PIN_AFIO_AF(GPIOF_PIN9, 0) | \ + PIN_AFIO_AF(GPIOF_PIN10, 0) | \ + PIN_AFIO_AF(GPIOF_PIN11, 0) | \ + PIN_AFIO_AF(GPIOF_MEM_A6, 12) | \ + PIN_AFIO_AF(GPIOF_MEM_A7, 12) | \ + PIN_AFIO_AF(GPIOF_MEM_A8, 12) | \ + PIN_AFIO_AF(GPIOF_MEM_A9, 12)) + +/* + * GPIOG setup: + */ +#define VAL_GPIOG_MODER (PIN_MODE_ALTERNATE(GPIOG_MEM_A10) | \ + PIN_MODE_ALTERNATE(GPIOG_MEM_A11) | \ + PIN_MODE_ALTERNATE(GPIOG_MEM_A12) | \ + PIN_MODE_ALTERNATE(GPIOG_MEM_A13) | \ + PIN_MODE_ALTERNATE(GPIOG_MEM_A14) | \ + PIN_MODE_ALTERNATE(GPIOG_MEM_A15) | \ + PIN_MODE_ALTERNATE(GPIOG_NAND_RB1) | \ + PIN_MODE_ALTERNATE(GPIOG_NAND_RB2) | \ + PIN_MODE_INPUT(GPIOG_PIN8) | \ + PIN_MODE_ALTERNATE(GPIOG_NAND_CE2) | \ + PIN_MODE_INPUT(GPIOG_PIN10) | \ + PIN_MODE_INPUT(GPIOG_PIN11) | \ + PIN_MODE_ALTERNATE(GPIOG_SRAM_CS1) | \ + PIN_MODE_INPUT(GPIOG_PIN13) | \ + PIN_MODE_INPUT(GPIOG_PIN14) | \ + PIN_MODE_INPUT(GPIOG_PIN15)) +#define VAL_GPIOG_OTYPER (PIN_OTYPE_PUSHPULL(GPIOG_MEM_A10) | \ + PIN_OTYPE_PUSHPULL(GPIOG_MEM_A11) | \ + PIN_OTYPE_PUSHPULL(GPIOG_MEM_A12) | \ + PIN_OTYPE_PUSHPULL(GPIOG_MEM_A13) | \ + PIN_OTYPE_PUSHPULL(GPIOG_MEM_A14) | \ + PIN_OTYPE_PUSHPULL(GPIOG_MEM_A15) | \ + PIN_OTYPE_PUSHPULL(GPIOG_NAND_RB1) | \ + PIN_OTYPE_PUSHPULL(GPIOG_NAND_RB2) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN8) | \ + PIN_OTYPE_PUSHPULL(GPIOG_NAND_CE2) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN11) | \ + PIN_OTYPE_PUSHPULL(GPIOG_SRAM_CS1) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN13) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN14) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN15)) +#define VAL_GPIOG_OSPEEDR (PIN_OSPEED_100M(GPIOG_MEM_A10) | \ + PIN_OSPEED_100M(GPIOG_MEM_A11) | \ + PIN_OSPEED_100M(GPIOG_MEM_A12) | \ + PIN_OSPEED_100M(GPIOG_MEM_A13) | \ + PIN_OSPEED_100M(GPIOG_MEM_A14) | \ + PIN_OSPEED_100M(GPIOG_MEM_A15) | \ + PIN_OSPEED_100M(GPIOG_NAND_RB1) | \ + PIN_OSPEED_100M(GPIOG_NAND_RB2) | \ + PIN_OSPEED_100M(GPIOG_PIN8) | \ + PIN_OSPEED_100M(GPIOG_NAND_CE2) | \ + PIN_OSPEED_100M(GPIOG_PIN10) | \ + PIN_OSPEED_100M(GPIOG_PIN11) | \ + PIN_OSPEED_100M(GPIOG_SRAM_CS1) | \ + PIN_OSPEED_100M(GPIOG_PIN13) | \ + PIN_OSPEED_100M(GPIOG_PIN14) | \ + PIN_OSPEED_100M(GPIOG_PIN15)) + +#if STM32_NAND_USE_EXT_INT +#define NAND_RB1_PUPDR(pin) (PIN_PUPDR_FLOATING(pin)) +#else +#define NAND_RB1_PUPDR(pin) (PIN_PUPDR_PULLUP(pin)) +#endif +#define VAL_GPIOG_PUPDR (PIN_PUPDR_FLOATING(GPIOG_MEM_A10) | \ + PIN_PUPDR_FLOATING(GPIOG_MEM_A11) | \ + PIN_PUPDR_FLOATING(GPIOG_MEM_A12) | \ + PIN_PUPDR_FLOATING(GPIOG_MEM_A13) | \ + PIN_PUPDR_FLOATING(GPIOG_MEM_A14) | \ + PIN_PUPDR_FLOATING(GPIOG_MEM_A15) | \ + NAND_RB1_PUPDR(GPIOG_NAND_RB1) | \ + PIN_PUPDR_FLOATING(GPIOG_NAND_RB2) | \ + PIN_PUPDR_FLOATING(GPIOG_PIN8) | \ + PIN_PUPDR_FLOATING(GPIOG_NAND_CE2) | \ + PIN_PUPDR_FLOATING(GPIOG_PIN10) | \ + PIN_PUPDR_FLOATING(GPIOG_PIN11) | \ + PIN_PUPDR_FLOATING(GPIOG_SRAM_CS1) | \ + PIN_PUPDR_FLOATING(GPIOG_PIN13) | \ + PIN_PUPDR_FLOATING(GPIOG_PIN14) | \ + PIN_PUPDR_FLOATING(GPIOG_PIN15)) +#define VAL_GPIOG_ODR (PIN_ODR_HIGH(GPIOG_MEM_A10) | \ + PIN_ODR_HIGH(GPIOG_MEM_A11) | \ + PIN_ODR_HIGH(GPIOG_MEM_A12) | \ + PIN_ODR_HIGH(GPIOG_MEM_A13) | \ + PIN_ODR_HIGH(GPIOG_MEM_A14) | \ + PIN_ODR_HIGH(GPIOG_MEM_A15) | \ + PIN_ODR_HIGH(GPIOG_NAND_RB1) | \ + PIN_ODR_HIGH(GPIOG_NAND_RB2) | \ + PIN_ODR_HIGH(GPIOG_PIN8) | \ + PIN_ODR_HIGH(GPIOG_NAND_CE2) | \ + PIN_ODR_HIGH(GPIOG_PIN10) | \ + PIN_ODR_HIGH(GPIOG_PIN11) | \ + PIN_ODR_HIGH(GPIOG_SRAM_CS1) | \ + PIN_ODR_HIGH(GPIOG_PIN13) | \ + PIN_ODR_HIGH(GPIOG_PIN14) | \ + PIN_ODR_HIGH(GPIOG_PIN15)) +#define VAL_GPIOG_AFRL (PIN_AFIO_AF(GPIOG_MEM_A10, 12) | \ + PIN_AFIO_AF(GPIOG_MEM_A11, 12) | \ + PIN_AFIO_AF(GPIOG_MEM_A12, 12) | \ + PIN_AFIO_AF(GPIOG_MEM_A13, 12) | \ + PIN_AFIO_AF(GPIOG_MEM_A14, 12) | \ + PIN_AFIO_AF(GPIOG_MEM_A15, 12) | \ + PIN_AFIO_AF(GPIOG_NAND_RB1, 12) | \ + PIN_AFIO_AF(GPIOG_NAND_RB2, 12)) +#define VAL_GPIOG_AFRH (PIN_AFIO_AF(GPIOG_PIN8, 0) | \ + PIN_AFIO_AF(GPIOG_NAND_CE2, 12) | \ + PIN_AFIO_AF(GPIOG_PIN10, 0) | \ + PIN_AFIO_AF(GPIOG_PIN11, 0) | \ + PIN_AFIO_AF(GPIOG_SRAM_CS1, 12) | \ + PIN_AFIO_AF(GPIOG_PIN13, 0) | \ + PIN_AFIO_AF(GPIOG_PIN14, 0) | \ + PIN_AFIO_AF(GPIOG_PIN15, 0)) + +/* + * GPIOH setup: + */ +#define VAL_GPIOH_MODER (PIN_MODE_INPUT(GPIOH_OSC_IN) | \ + PIN_MODE_INPUT(GPIOH_OSC_OUT) | \ + PIN_MODE_INPUT(GPIOH_PIN2) | \ + PIN_MODE_INPUT(GPIOH_PIN3) | \ + PIN_MODE_INPUT(GPIOH_PIN4) | \ + PIN_MODE_INPUT(GPIOH_PIN5) | \ + PIN_MODE_INPUT(GPIOH_PIN6) | \ + PIN_MODE_ALTERNATE(GPIOH_I2C3_SCL) | \ + PIN_MODE_ALTERNATE(GPIOH_I2C3_SDA) | \ + PIN_MODE_INPUT(GPIOH_PIN9) | \ + PIN_MODE_INPUT(GPIOH_PIN10) | \ + PIN_MODE_INPUT(GPIOH_PIN11) | \ + PIN_MODE_INPUT(GPIOH_PIN12) | \ + PIN_MODE_INPUT(GPIOH_PIN13) | \ + PIN_MODE_INPUT(GPIOH_PIN14) | \ + PIN_MODE_INPUT(GPIOH_PIN15)) +#define VAL_GPIOH_OTYPER (PIN_OTYPE_PUSHPULL(GPIOH_OSC_IN) | \ + PIN_OTYPE_PUSHPULL(GPIOH_OSC_OUT) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN3) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN4) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN5) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN6) | \ + PIN_OTYPE_OPENDRAIN(GPIOH_I2C3_SCL) | \ + PIN_OTYPE_OPENDRAIN(GPIOH_I2C3_SDA) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN9) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN11) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN12) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN13) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN14) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN15)) +#define VAL_GPIOH_OSPEEDR (PIN_OSPEED_100M(GPIOH_OSC_IN) | \ + PIN_OSPEED_100M(GPIOH_OSC_OUT) | \ + PIN_OSPEED_100M(GPIOH_PIN2) | \ + PIN_OSPEED_100M(GPIOH_PIN3) | \ + PIN_OSPEED_100M(GPIOH_PIN4) | \ + PIN_OSPEED_100M(GPIOH_PIN5) | \ + PIN_OSPEED_100M(GPIOH_PIN6) | \ + PIN_OSPEED_2M(GPIOH_I2C3_SCL) | \ + PIN_OSPEED_2M(GPIOH_I2C3_SDA) | \ + PIN_OSPEED_100M(GPIOH_PIN9) | \ + PIN_OSPEED_100M(GPIOH_PIN10) | \ + PIN_OSPEED_100M(GPIOH_PIN11) | \ + PIN_OSPEED_100M(GPIOH_PIN12) | \ + PIN_OSPEED_100M(GPIOH_PIN13) | \ + PIN_OSPEED_100M(GPIOH_PIN14) | \ + PIN_OSPEED_100M(GPIOH_PIN15)) +#define VAL_GPIOH_PUPDR (PIN_PUPDR_FLOATING(GPIOH_OSC_IN) | \ + PIN_PUPDR_FLOATING(GPIOH_OSC_OUT) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN2) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN3) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN4) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN5) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN6) | \ + PIN_PUPDR_FLOATING(GPIOH_I2C3_SCL) | \ + PIN_PUPDR_FLOATING(GPIOH_I2C3_SDA) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN9) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN10) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN11) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN12) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN13) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN14) | \ + PIN_PUPDR_FLOATING(GPIOH_PIN15)) +#define VAL_GPIOH_ODR (PIN_ODR_HIGH(GPIOH_OSC_IN) | \ + PIN_ODR_HIGH(GPIOH_OSC_OUT) | \ + PIN_ODR_HIGH(GPIOH_PIN2) | \ + PIN_ODR_HIGH(GPIOH_PIN3) | \ + PIN_ODR_HIGH(GPIOH_PIN4) | \ + PIN_ODR_HIGH(GPIOH_PIN5) | \ + PIN_ODR_HIGH(GPIOH_PIN6) | \ + PIN_ODR_HIGH(GPIOH_I2C3_SCL) | \ + PIN_ODR_HIGH(GPIOH_I2C3_SDA) | \ + PIN_ODR_HIGH(GPIOH_PIN9) | \ + PIN_ODR_HIGH(GPIOH_PIN10) | \ + PIN_ODR_HIGH(GPIOH_PIN11) | \ + PIN_ODR_HIGH(GPIOH_PIN12) | \ + PIN_ODR_HIGH(GPIOH_PIN13) | \ + PIN_ODR_HIGH(GPIOH_PIN14) | \ + PIN_ODR_HIGH(GPIOH_PIN15)) +#define VAL_GPIOH_AFRL (PIN_AFIO_AF(GPIOH_OSC_IN, 0) | \ + PIN_AFIO_AF(GPIOH_OSC_OUT, 0) | \ + PIN_AFIO_AF(GPIOH_PIN2, 0) | \ + PIN_AFIO_AF(GPIOH_PIN3, 0) | \ + PIN_AFIO_AF(GPIOH_PIN4, 0) | \ + PIN_AFIO_AF(GPIOH_PIN5, 0) | \ + PIN_AFIO_AF(GPIOH_PIN6, 0) | \ + PIN_AFIO_AF(GPIOH_I2C3_SCL, 4)) +#define VAL_GPIOH_AFRH (PIN_AFIO_AF(GPIOH_I2C3_SDA, 4) | \ + PIN_AFIO_AF(GPIOH_PIN9, 0) | \ + PIN_AFIO_AF(GPIOH_PIN10, 0) | \ + PIN_AFIO_AF(GPIOH_PIN11, 0) | \ + PIN_AFIO_AF(GPIOH_PIN12, 0) | \ + PIN_AFIO_AF(GPIOH_PIN13, 0) | \ + PIN_AFIO_AF(GPIOH_PIN14, 0) | \ + PIN_AFIO_AF(GPIOH_PIN15, 0)) + +/* + * GPIOI setup: + */ +#define VAL_GPIOI_MODER (PIN_MODE_INPUT(GPIOI_PIN0) | \ + PIN_MODE_INPUT(GPIOI_PIN1) | \ + PIN_MODE_INPUT(GPIOI_PIN2) | \ + PIN_MODE_INPUT(GPIOI_PIN3) | \ + PIN_MODE_INPUT(GPIOI_PIN4) | \ + PIN_MODE_INPUT(GPIOI_PIN5) | \ + PIN_MODE_INPUT(GPIOI_PIN6) | \ + PIN_MODE_INPUT(GPIOI_PIN7) | \ + PIN_MODE_INPUT(GPIOI_PIN8) | \ + PIN_MODE_INPUT(GPIOI_PIN9) | \ + PIN_MODE_OUTPUT(GPIOI_LED_R) | \ + PIN_MODE_OUTPUT(GPIOI_LED_G) | \ + PIN_MODE_INPUT(GPIOI_PIN12) | \ + PIN_MODE_INPUT(GPIOI_PIN13) | \ + PIN_MODE_INPUT(GPIOI_PIN14) | \ + PIN_MODE_INPUT(GPIOI_PIN15)) +#define VAL_GPIOI_OTYPER (PIN_OTYPE_PUSHPULL(GPIOI_PIN0) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN1) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN3) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN4) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN5) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN6) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN7) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN8) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN9) | \ + PIN_OTYPE_PUSHPULL(GPIOI_LED_R) | \ + PIN_OTYPE_PUSHPULL(GPIOI_LED_G) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN12) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN13) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN14) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN15)) +#define VAL_GPIOI_OSPEEDR (PIN_OSPEED_100M(GPIOI_PIN0) | \ + PIN_OSPEED_100M(GPIOI_PIN1) | \ + PIN_OSPEED_100M(GPIOI_PIN2) | \ + PIN_OSPEED_100M(GPIOI_PIN3) | \ + PIN_OSPEED_100M(GPIOI_PIN4) | \ + PIN_OSPEED_100M(GPIOI_PIN5) | \ + PIN_OSPEED_100M(GPIOI_PIN6) | \ + PIN_OSPEED_100M(GPIOI_PIN7) | \ + PIN_OSPEED_100M(GPIOI_PIN8) | \ + PIN_OSPEED_100M(GPIOI_PIN9) | \ + PIN_OSPEED_100M(GPIOI_LED_R) | \ + PIN_OSPEED_100M(GPIOI_LED_G) | \ + PIN_OSPEED_100M(GPIOI_PIN12) | \ + PIN_OSPEED_100M(GPIOI_PIN13) | \ + PIN_OSPEED_100M(GPIOI_PIN14) | \ + PIN_OSPEED_100M(GPIOI_PIN15)) +#define VAL_GPIOI_PUPDR (PIN_PUPDR_FLOATING(GPIOI_PIN0) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN1) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN2) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN3) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN4) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN5) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN6) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN7) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN8) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN9) | \ + PIN_PUPDR_FLOATING(GPIOI_LED_R) | \ + PIN_PUPDR_FLOATING(GPIOI_LED_G) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN12) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN13) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN14) | \ + PIN_PUPDR_FLOATING(GPIOI_PIN15)) +#define VAL_GPIOI_ODR (PIN_ODR_HIGH(GPIOI_PIN0) | \ + PIN_ODR_HIGH(GPIOI_PIN1) | \ + PIN_ODR_HIGH(GPIOI_PIN2) | \ + PIN_ODR_HIGH(GPIOI_PIN3) | \ + PIN_ODR_HIGH(GPIOI_PIN4) | \ + PIN_ODR_HIGH(GPIOI_PIN5) | \ + PIN_ODR_HIGH(GPIOI_PIN6) | \ + PIN_ODR_HIGH(GPIOI_PIN7) | \ + PIN_ODR_HIGH(GPIOI_PIN8) | \ + PIN_ODR_HIGH(GPIOI_PIN9) | \ + PIN_ODR_LOW(GPIOI_LED_R) | \ + PIN_ODR_LOW(GPIOI_LED_G) | \ + PIN_ODR_HIGH(GPIOI_PIN12) | \ + PIN_ODR_HIGH(GPIOI_PIN13) | \ + PIN_ODR_HIGH(GPIOI_PIN14) | \ + PIN_ODR_HIGH(GPIOI_PIN15)) +#define VAL_GPIOI_AFRL (PIN_AFIO_AF(GPIOI_PIN0, 0) | \ + PIN_AFIO_AF(GPIOI_PIN1, 0) | \ + PIN_AFIO_AF(GPIOI_PIN2, 0) | \ + PIN_AFIO_AF(GPIOI_PIN3, 0) | \ + PIN_AFIO_AF(GPIOI_PIN4, 0) | \ + PIN_AFIO_AF(GPIOI_PIN5, 0) | \ + PIN_AFIO_AF(GPIOI_PIN6, 0) | \ + PIN_AFIO_AF(GPIOI_PIN7, 0)) +#define VAL_GPIOI_AFRH (PIN_AFIO_AF(GPIOI_PIN8, 0) | \ + PIN_AFIO_AF(GPIOI_PIN9, 0) | \ + PIN_AFIO_AF(GPIOI_LED_R, 0) | \ + PIN_AFIO_AF(GPIOI_LED_G, 0) | \ + PIN_AFIO_AF(GPIOI_PIN12, 0) | \ + PIN_AFIO_AF(GPIOI_PIN13, 0) | \ + PIN_AFIO_AF(GPIOI_PIN14, 0) | \ + PIN_AFIO_AF(GPIOI_PIN15, 0)) + +#if !defined(_FROM_ASM_) +#ifdef __cplusplus +extern "C" { +#endif + void boardInit(void); +#ifdef __cplusplus +} +#endif +#endif /* _FROM_ASM_ */ + +#endif /* _BOARD_H_ */ diff --git a/os/hal/boards/NONSTANDARD_STM32F4_BARTHESS2/board.mk b/os/hal/boards/NONSTANDARD_STM32F4_BARTHESS2/board.mk new file mode 100644 index 0000000..e970729 --- /dev/null +++ b/os/hal/boards/NONSTANDARD_STM32F4_BARTHESS2/board.mk @@ -0,0 +1,5 @@ +# List of all the board related files. +BOARDSRC = $(CHIBIOS)/community/os/hal/boards/NONSTANDARD_STM32F4_BARTHESS2/board.c + +# Required include directories +BOARDINC = $(CHIBIOS)/community/os/hal/boards/NONSTANDARD_STM32F4_BARTHESS2 diff --git a/os/hal/hal.mk b/os/hal/hal.mk new file mode 100644 index 0000000..72b9b74 --- /dev/null +++ b/os/hal/hal.mk @@ -0,0 +1,5 @@ +include ${CHIBIOS}/os/hal/hal.mk
+
+HALSRC += ${CHIBIOS}/community/os/hal/src/nand.c
+
+HALINC += ${CHIBIOS}/community/os/hal/include
diff --git a/os/hal/include/nand.h b/os/hal/include/nand.h new file mode 100644 index 0000000..77ca972 --- /dev/null +++ b/os/hal/include/nand.h @@ -0,0 +1,148 @@ +/* + ChibiOS/HAL - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012,2013,2014 Giovanni Di Sirio. + + This file is part of ChibiOS/HAL + + ChibiOS/HAL is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file nand.h + * @brief NAND Driver macros and structures. + * + * @addtogroup NAND + * @{ + */ + +#ifndef _NAND_H_ +#define _NAND_H_ + +#if HAL_USE_NAND || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/* + * Standard NAND flash commands + */ +#define NAND_CMD_READ0 0x00 +#define NAND_CMD_RNDOUT 0x05 +#define NAND_CMD_PAGEPROG 0x10 +#define NAND_CMD_READ0_CONFIRM 0x30 +#define NAND_CMD_READOOB 0x50 +#define NAND_CMD_ERASE 0x60 +#define NAND_CMD_STATUS 0x70 +#define NAND_CMD_STATUS_MULTI 0x71 +#define NAND_CMD_WRITE 0x80 +#define NAND_CMD_RNDIN 0x85 +#define NAND_CMD_READID 0x90 +#define NAND_CMD_ERASE_CONFIRM 0xD0 +#define NAND_CMD_RESET 0xFF + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ +/** + * @brief Enables the mutual exclusion APIs on the NAND. + */ +#if !defined(NAND_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define NAND_USE_MUTUAL_EXCLUSION FALSE +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ +#if NAND_USE_MUTUAL_EXCLUSION && !CH_CFG_USE_MUTEXES && !CH_CFG_USE_SEMAPHORES +#error "NAND_USE_MUTUAL_EXCLUSION requires CH_CFG_USE_MUTEXES and/or CH_CFG_USE_SEMAPHORES" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Driver state machine possible states. + */ +typedef enum { + NAND_UNINIT = 0, /**< Not initialized. */ + NAND_STOP = 1, /**< Stopped. */ + NAND_READY = 2, /**< Ready. */ + NAND_PROGRAM = 3, /**< Programming in progress. */ + NAND_ERASE = 4, /**< Erasing in progress. */ + NAND_WRITE = 5, /**< Writing to NAND buffer. */ + NAND_READ = 6, /**< Reading from NAND. */ + NAND_DMA_TX = 7, /**< DMA transmitting. */ + NAND_DMA_RX = 8, /**< DMA receiving. */ +} nandstate_t; + +/** + * @brief Type of a structure representing a NAND driver. + */ +typedef struct NANDDriver NANDDriver; + +#include "nand_lld.h" + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void nandInit(void); + void nandObjectInit(NANDDriver *nandp); + void nandStart(NANDDriver *nandp, const NANDConfig *config); + void nandStop(NANDDriver *nandp); + void nandReadPageWhole(NANDDriver *nandp, uint32_t block, + uint32_t page, uint8_t *data, size_t datalen); + uint8_t nandWritePageWhole(NANDDriver *nandp, uint32_t block, + uint32_t page, const uint8_t *data, size_t datalen); + void nandReadPageData(NANDDriver *nandp, uint32_t block, + uint32_t page, uint8_t *data, size_t datalen, uint32_t *ecc); + uint8_t nandWritePageData(NANDDriver *nandp, uint32_t block, + uint32_t page, const uint8_t *data, size_t datalen, uint32_t *ecc); + void nandReadPageSpare(NANDDriver *nandp, uint32_t block, + uint32_t page, uint8_t *spare, size_t sparelen); + uint8_t nandWritePageSpare(NANDDriver *nandp, uint32_t block, + uint32_t page, const uint8_t *spare, size_t sparelen); + void nandMarkBad(NANDDriver *nandp, uint32_t block); + uint8_t nandReadBadMark(NANDDriver *nandp, + uint32_t block, uint32_t page); + uint8_t nandErase(NANDDriver *nandp, uint32_t block); + bool nandIsBad(NANDDriver *nandp, uint32_t block); + +#if NAND_USE_MUTUAL_EXCLUSION + void nandAcquireBus(NANDDriver *nandp); + void nandReleaseBus(NANDDriver *nandp); +#endif /* NAND_USE_MUTUAL_EXCLUSION */ + +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_NAND */ + +#endif /* _NAND_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c new file mode 100644 index 0000000..274bc62 --- /dev/null +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c @@ -0,0 +1,196 @@ +/* + ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio + + Licensed 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file fsmc.c + * @brief FSMC Driver subsystem low level driver source template. + * + * @addtogroup FSMC + * @{ + */ +#include "hal.h" +#include "fsmc.h" + +#if HAL_USE_NAND || STM32_USE_FSMC_SRAM || STM32_USE_FSMC_SDRAM || \ + defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief FSMC1 driver identifier. + */ +#if STM32_FSMC_USE_FSMC1 || defined(__DOXYGEN__) +FSMCDriver FSMCD1; +#endif + +/*===========================================================================*/ +/* Driver local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level FSMC driver initialization. + * + * @notapi + */ +void fsmc_init(void) { + + if (FSMCD1.state == FSMC_UNINIT) { + FSMCD1.state = FSMC_STOP; + +#if STM32_SRAM_USE_FSMC_SRAM1 + FSMCD1.sram1 = (FSMC_SRAM_NOR_TypeDef *)(FSMC_Bank1_R_BASE); +#endif + +#if STM32_SRAM_USE_FSMC_SRAM2 + FSMCD1.sram2 = (FSMC_SRAM_NOR_TypeDef *)(FSMC_Bank1_R_BASE + 8); +#endif + +#if STM32_SRAM_USE_FSMC_SRAM3 + FSMCD1.sram3 = (FSMC_SRAM_NOR_TypeDef *)(FSMC_Bank1_R_BASE + 8 * 2); +#endif + +#if STM32_SRAM_USE_FSMC_SRAM4 + FSMCD1.sram4 = (FSMC_SRAM_NOR_TypeDef *)(FSMC_Bank1_R_BASE + 8 * 3); +#endif + +#if STM32_NAND_USE_FSMC_NAND1 + FSMCD1.nand1 = (FSMC_NAND_TypeDef *)FSMC_Bank2_R_BASE; +#endif + +#if STM32_NAND_USE_FSMC_NAND2 + FSMCD1.nand2 = (FSMC_NAND_TypeDef *)FSMC_Bank3_R_BASE; +#endif + +#if STM32_USE_FSMC_PCCARD + FSMCD1.pccard = (FSMC_PCCARD_TypeDef *)FSMC_Bank4_R_BASE; +#endif + +#if (defined(STM32F427xx) || defined(STM32F437xx) || \ + defined(STM32F429xx) || defined(STM32F439xx)) + #if STM32_USE_FSMC_SDRAM + FSMCD1.sdram = (FSMC_SDRAM_TypeDef *)FSMC_Bank5_6_R_BASE; + #endif +#endif + } +} + +/** + * @brief Configures and activates the FSMC peripheral. + * + * @param[in] fsmcp pointer to the @p FSMCDriver object + * + * @notapi + */ +void fsmc_start(FSMCDriver *fsmcp) { + + osalDbgAssert((fsmcp->state == FSMC_STOP) || (fsmcp->state == FSMC_READY), + "invalid state"); + + if (fsmcp->state == FSMC_STOP) { + /* Enables the peripheral.*/ +#if STM32_FSMC_USE_FSMC1 + if (&FSMCD1 == fsmcp) { + rccResetFSMC(); + rccEnableFSMC(FALSE); +#if (!STM32_NAND_USE_EXT_INT && HAL_USE_NAND) + nvicEnableVector(STM32_FSMC_NUMBER, STM32_FSMC_FSMC1_IRQ_PRIORITY); +#endif + } +#endif /* STM32_FSMC_USE_FSMC1 */ + + fsmcp->state = FSMC_READY; + } +} + +/** + * @brief Deactivates the FSMC peripheral. + * + * @param[in] emcp pointer to the @p FSMCDriver object + * + * @notapi + */ +void fsmc_stop(FSMCDriver *fsmcp) { + + if (fsmcp->state == FSMC_READY) { + /* Resets the peripheral.*/ + rccResetFSMC(); + + /* Disables the peripheral.*/ +#if STM32_FSMC_USE_FSMC1 + if (&FSMCD1 == fsmcp) { +#if (!STM32_NAND_USE_EXT_INT && HAL_USE_NAND) + nvicDisableVector(STM32_FSMC_NUMBER); +#endif + rccDisableFSMC(FALSE); + } +#endif /* STM32_FSMC_USE_FSMC1 */ + + fsmcp->state = FSMC_STOP; + } +} + +#if !STM32_NAND_USE_EXT_INT +/** + * @brief FSMC shared interrupt handler. + * + * @notapi + */ +CH_IRQ_HANDLER(STM32_FSMC_HANDLER) { + + CH_IRQ_PROLOGUE(); +#if STM32_NAND_USE_FSMC_NAND1 + if (FSMCD1.nand1->SR & FSMC_SR_ISR_MASK){ + NANDD1.isr_handler(&NANDD1); + } +#endif +#if STM32_NAND_USE_FSMC_NAND2 + if (FSMCD1.nand2->SR & FSMC_SR_ISR_MASK){ + NANDD2.isr_handler(&NANDD2); + } +#endif + CH_IRQ_EPILOGUE(); +} +#endif /* !STM32_NAND_USE_EXT_INT */ + +#endif /* HAL_USE_FSMC || STM32_USE_FSMC_SRAM || STM32_USE_FSMC_SDRAM */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h new file mode 100644 index 0000000..9ac64f7 --- /dev/null +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h @@ -0,0 +1,334 @@ +/* + ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio + + Licensed 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file fsmc.h + * @brief FSMC Driver subsystem low level driver header. + * + * @addtogroup FSMC + * @{ + */ + +#ifndef _FSMC_H_ +#define _FSMC_H_ + +#if HAL_USE_NAND || STM32_USE_FSMC_SRAM || STM32_USE_FSMC_SDRAM || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/* + * (Re)define if needed base address constants supplied in ST's CMSIS + */ +#if (defined(STM32F427xx) || defined(STM32F437xx) || \ + defined(STM32F429xx) || defined(STM32F439xx)) + #if !defined(FSMC_Bank1_R_BASE) + #define FSMC_Bank1_R_BASE (FMC_R_BASE + 0x0000) + #endif + #if !defined(FSMC_Bank1E_R_BASE) + #define FSMC_Bank1E_R_BASE (FMC_R_BASE + 0x0104) + #endif + #if !defined(FSMC_Bank2_R_BASE) + #define FSMC_Bank2_R_BASE (FMC_R_BASE + 0x0060) + #endif + #if !defined(FSMC_Bank3_R_BASE) + #define FSMC_Bank3_R_BASE (FMC_R_BASE + 0x0080) + #endif + #if !defined(FSMC_Bank4_R_BASE) + #define FSMC_Bank4_R_BASE (FMC_R_BASE + 0x00A0) + #endif + #if !defined(FSMC_Bank5_R_BASE) + #define FSMC_Bank5_6_R_BASE (FMC_R_BASE + 0x0140) + #endif +#else + #if !defined(FSMC_Bank1_R_BASE) + #define FSMC_Bank1_R_BASE (FSMC_R_BASE + 0x0000) + #endif + #if !defined(FSMC_Bank1E_R_BASE) + #define FSMC_Bank1E_R_BASE (FSMC_R_BASE + 0x0104) + #endif + #if !defined(FSMC_Bank2_R_BASE) + #define FSMC_Bank2_R_BASE (FSMC_R_BASE + 0x0060) + #endif + #if !defined(FSMC_Bank3_R_BASE) + #define FSMC_Bank3_R_BASE (FSMC_R_BASE + 0x0080) + #endif + #if !defined(FSMC_Bank4_R_BASE) + #define FSMC_Bank4_R_BASE (FSMC_R_BASE + 0x00A0) + #endif +#endif + +/* + * Base bank mappings + */ +#define FSMC_Bank1_MAP_BASE ((uint32_t) 0x60000000) +#define FSMC_Bank2_MAP_BASE ((uint32_t) 0x70000000) +#define FSMC_Bank3_MAP_BASE ((uint32_t) 0x80000000) +#define FSMC_Bank4_MAP_BASE ((uint32_t) 0x90000000) +#if (defined(STM32F427xx) || defined(STM32F437xx) || \ + defined(STM32F429xx) || defined(STM32F439xx)) + #define FSMC_Bank5_MAP_BASE ((uint32_t) 0xC0000000) + #define FSMC_Bank6_MAP_BASE ((uint32_t) 0xD0000000) +#endif + +/* + * Subbunks of bank1 + */ +#define FSMC_SUBBUNK_OFFSET (1024 * 1024 * 64) +#define FSMC_Bank1_1_MAP (FSMC_Bank1_MAP_BASE) +#define FSMC_Bank1_2_MAP (FSMC_Bank1_1_MAP + FSMC_SUBBUNK_OFFSET) +#define FSMC_Bank1_3_MAP (FSMC_Bank1_2_MAP + FSMC_SUBBUNK_OFFSET) +#define FSMC_Bank1_4_MAP (FSMC_Bank1_3_MAP + FSMC_SUBBUNK_OFFSET) + +/* + * Bank 2 (NAND) + */ +#define FSMC_Bank2_MAP_COMMON (FSMC_Bank2_MAP_BASE + 0) +#define FSMC_Bank2_MAP_ATTR (FSMC_Bank2_MAP_BASE + 0x8000000) + +#define FSMC_Bank2_MAP_COMMON_DATA (FSMC_Bank2_MAP_COMMON + 0) +#define FSMC_Bank2_MAP_COMMON_CMD (FSMC_Bank2_MAP_COMMON + 0x10000) +#define FSMC_Bank2_MAP_COMMON_ADDR (FSMC_Bank2_MAP_COMMON + 0x20000) + +#define FSMC_Bank2_MAP_ATTR_DATA (FSMC_Bank2_MAP_ATTR + 0) +#define FSMC_Bank2_MAP_ATTR_CMD (FSMC_Bank2_MAP_ATTR + 0x10000) +#define FSMC_Bank2_MAP_ATTR_ADDR (FSMC_Bank2_MAP_ATTR + 0x20000) + +/* + * Bank 3 (NAND) + */ +#define FSMC_Bank3_MAP_COMMON (FSMC_Bank3_MAP_BASE + 0) +#define FSMC_Bank3_MAP_ATTR (FSMC_Bank3_MAP_BASE + 0x8000000) + +#define FSMC_Bank3_MAP_COMMON_DATA (FSMC_Bank3_MAP_COMMON + 0) +#define FSMC_Bank3_MAP_COMMON_CMD (FSMC_Bank3_MAP_COMMON + 0x10000) +#define FSMC_Bank3_MAP_COMMON_ADDR (FSMC_Bank3_MAP_COMMON + 0x20000) + +#define FSMC_Bank3_MAP_ATTR_DATA (FSMC_Bank3_MAP_ATTR + 0) +#define FSMC_Bank3_MAP_ATTR_CMD (FSMC_Bank3_MAP_ATTR + 0x10000) +#define FSMC_Bank3_MAP_ATTR_ADDR (FSMC_Bank3_MAP_ATTR + 0x20000) + +/* + * Bank 4 (PC card) + */ +#define FSMC_Bank4_MAP_COMMON (FSMC_Bank4_MAP_BASE + 0) +#define FSMC_Bank4_MAP_ATTR (FSMC_Bank4_MAP_BASE + 0x8000000) +#define FSMC_Bank4_MAP_IO (FSMC_Bank4_MAP_BASE + 0xC000000) + +/* + * More convenient typedefs than CMSIS has + */ +typedef struct { + __IO uint32_t PCR; /**< NAND Flash control */ + __IO uint32_t SR; /**< NAND Flash FIFO status and interrupt */ + __IO uint32_t PMEM; /**< NAND Flash Common memory space timing */ + __IO uint32_t PATT; /**< NAND Flash Attribute memory space timing */ + uint32_t RESERVED0; /**< Reserved, 0x70 */ + __IO uint32_t ECCR; /**< NAND Flash ECC result registers */ +} FSMC_NAND_TypeDef; + +typedef struct { + __IO uint32_t PCR; /**< PC Card control */ + __IO uint32_t SR; /**< PC Card FIFO status and interrupt */ + __IO uint32_t PMEM; /**< PC Card Common memory space timing */ + __IO uint32_t PATT; /**< PC Card Attribute memory space timing */ + __IO uint32_t PIO; /**< PC Card I/O space timing */ +} FSMC_PCCard_TypeDef; + +typedef struct { + __IO uint32_t BCR; /**< SRAM/NOR chip-select control registers */ + __IO uint32_t BTR; /**< SRAM/NOR chip-select timing registers */ + uint32_t RESERVED[63]; /**< Reserved */ + __IO uint32_t BWTR; /**< SRAM/NOR write timing registers */ +} FSMC_SRAM_NOR_TypeDef; + +#if (defined(STM32F427xx) || defined(STM32F437xx) || \ + defined(STM32F429xx) || defined(STM32F439xx)) + +typedef struct { + __IO uint32_t SDCR1; /**< SDRAM control register (bank 1) */ + __IO uint32_t SDCR2; /**< SDRAM control register (bank 2) */ + __IO uint32_t SDTR1; /**< SDRAM timing register (bank 1) */ + __IO uint32_t SDTR2; /**< SDRAM timing register (bank 2) */ + __IO uint32_t SDCMR; /**< SDRAM comand mode register */ + __IO uint32_t SDRTR; /**< SDRAM refresh timer register */ + __IO uint32_t SDSR; /**< SDRAM status register */ +} FSMC_SDRAM_TypeDef; + +#endif + +/** + * @brief PCR register + */ +#define FSMC_PCR_PWAITEN ((uint32_t)0x00000002) +#define FSMC_PCR_PBKEN ((uint32_t)0x00000004) +#define FSMC_PCR_PTYP ((uint32_t)0x00000008) +#define FSMC_PCR_ECCEN ((uint32_t)0x00000040) +#define FSMC_PCR_PTYP_PCCARD 0 +#define FSMC_PCR_PTYP_NAND FSMC_PCR_PTYP + +/** + * @brief SR register + */ +#define FSMC_SR_IRS ((uint8_t)0x01) +#define FSMC_SR_ILS ((uint8_t)0x02) +#define FSMC_SR_IFS ((uint8_t)0x04) +#define FSMC_SR_IREN ((uint8_t)0x08) +#define FSMC_SR_ILEN ((uint8_t)0x10) +#define FSMC_SR_IFEN ((uint8_t)0x20) +#define FSMC_SR_FEMPT ((uint8_t)0x40) +#define FSMC_SR_ISR_MASK (FSMC_SR_IRS | FSMC_SR_ILS | FSMC_SR_IFS) + +/** + * @brief BCR register + */ +#define FSMC_BCR_MBKEN ((uint32_t)0x00000001) +#define FSMC_BCR_MUXEN ((uint32_t)0x00000002) +#define FSMC_BCR_MWID_0 ((uint32_t)0x00000010) +#define FSMC_BCR_FACCEN ((uint32_t)0x00000040) +#define FSMC_BCR_BURSTEN ((uint32_t)0x00000100) +#define FSMC_BCR_WAITPOL ((uint32_t)0x00000200) +#define FSMC_BCR_WRAPMOD ((uint32_t)0x00000400) +#define FSMC_BCR_WAITCFG ((uint32_t)0x00000800) +#define FSMC_BCR_WREN ((uint32_t)0x00001000) +#define FSMC_BCR_WAITEN ((uint32_t)0x00002000) +#define FSMC_BCR_EXTMOD ((uint32_t)0x00004000) +#define FSMC_BCR_ASYNCWAIT ((uint32_t)0x00008000) +#define FSMC_BCR_CBURSTRW ((uint32_t)0x00080000) + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief FSMC driver enable switch. + * @details If set to @p TRUE the support for FSMC is included. + */ +#if !defined(STM32_FSMC_USE_FSMC1) || defined(__DOXYGEN__) +#define STM32_FSMC_USE_FSMC1 FALSE +#endif + +/** + * @brief Internal FSMC interrupt enable switch + * @details MCUs in 100-pin package has no dedicated interrupt pin for FSMC. + * You have to use EXTI module instead to workaround this issue. + */ +#if !defined(STM32_NAND_USE_EXT_INT) || defined(__DOXYGEN__) +#define STM32_NAND_USE_EXT_INT FALSE +#endif + +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ +#if !STM32_FSMC_USE_FSMC1 +#error "FSMC driver activated but no FSMC peripheral assigned" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of a structure representing an FSMC driver. + */ +typedef struct FSMCDriver FSMCDriver; + +/** + * @brief Driver state machine possible states. + */ +typedef enum { + FSMC_UNINIT = 0, /**< Not initialized. */ + FSMC_STOP = 1, /**< Stopped. */ + FSMC_READY = 2, /**< Ready. */ +} fsmcstate_t; + +/** + * @brief Structure representing an FSMC driver. + */ +struct FSMCDriver { + /** + * @brief Driver state. + */ + fsmcstate_t state; + /* End of the mandatory fields.*/ + +#if STM32_SRAM_USE_FSMC_SRAM1 + FSMC_SRAM_NOR_TypeDef *sram1; +#endif +#if STM32_SRAM_USE_FSMC_SRAM2 + FSMC_SRAM_NOR_TypeDef *sram2; +#endif +#if STM32_SRAM_USE_FSMC_SRAM3 + FSMC_SRAM_NOR_TypeDef *sram3; +#endif +#if STM32_SRAM_USE_FSMC_SRAM4 + FSMC_SRAM_NOR_TypeDef *sram4; +#endif +#if STM32_NAND_USE_FSMC_NAND1 + FSMC_NAND_TypeDef *nand1; +#endif +#if STM32_NAND_USE_FSMC_NAND2 + FSMC_NAND_TypeDef *nand2; +#endif +#if STM32_USE_FSMC_PCCARD + FSMC_PCCard_TypeDef *pccard; +#endif +#if (defined(STM32F427xx) || defined(STM32F437xx) || \ + defined(STM32F429xx) || defined(STM32F439xx)) + #if STM32_USE_FSMC_SDRAM + FSMC_SDRAM_TypeDef *sdram; + #endif +#endif +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if STM32_FSMC_USE_FSMC1 && !defined(__DOXYGEN__) +extern FSMCDriver FSMCD1; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void fsmc_init(void); + void fsmc_start(FSMCDriver *fsmcp); + void fsmc_stop(FSMCDriver *fsmcp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_NAND || STM32_USE_FSMC_SRAM || STM32_USE_FSMC_SDRAM */ + +#endif /* _FSMC_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c new file mode 100644 index 0000000..ed415eb --- /dev/null +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c @@ -0,0 +1,212 @@ +/* + ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio + + Licensed 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess (SDRAM routines added by Nick Klimov aka progfin). + */ + +/** + * @file fsmc_sdram.c + * @brief SDRAM Driver subsystem low level driver source. + * + * @addtogroup SDRAM + * @{ + */ + +#include "hal.h" + +#if (defined(STM32F427xx) || defined(STM32F437xx) || \ + defined(STM32F429xx) || defined(STM32F439xx)) + +#if STM32_USE_FSMC_SDRAM || defined(__DOXYGEN__) + +#include "fsmc_sdram.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/** + * FMC_Command_Mode + */ +#define FMCCM_NORMAL ((uint32_t)0x00000000) +#define FMCCM_CLK_ENABLED ((uint32_t)0x00000001) +#define FMCCM_PALL ((uint32_t)0x00000002) +#define FMCCM_AUTO_REFRESH ((uint32_t)0x00000003) +#define FMCCM_LOAD_MODE ((uint32_t)0x00000004) +#define FMCCM_SELFREFRESH ((uint32_t)0x00000005) +#define FMCCM_POWER_DOWN ((uint32_t)0x00000006) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ +/** + * @brief SDRAM driver identifier. + */ +SDRAMDriver SDRAMD; + +/*===========================================================================*/ +/* Driver local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Wait until the SDRAM controller is ready. + * + * @notapi + */ +static void _sdram_wait_ready(void) { + /* Wait until the SDRAM controller is ready */ + while (SDRAMD.sdram->SDSR & FMC_SDSR_BUSY); +} + +/** + * @brief Executes the SDRAM memory initialization sequence. + * + * @param[in] cfgp pointer to the @p SDRAMConfig object + * + * @notapi + */ +static void _sdram_init_sequence(const SDRAMConfig *cfgp) { + + uint32_t command_target = 0; + +#if STM32_SDRAM_USE_FSMC_SDRAM1 + command_target |= FMC_SDCMR_CTB1; +#endif +#if STM32_SDRAM_USE_FSMC_SDRAM2 + command_target |= FMC_SDCMR_CTB2; +#endif + + /* Step 3: Configure a clock configuration enable command.*/ + _sdram_wait_ready(); + SDRAMD.sdram->SDCMR = FMCCM_CLK_ENABLED | command_target; + + /* Step 4: Insert delay (tipically 100uS).*/ + osalThreadSleepMilliseconds(100); + + /* Step 5: Configure a PALL (precharge all) command.*/ + _sdram_wait_ready(); + SDRAMD.sdram->SDCMR = FMCCM_PALL | command_target; + + /* Step 6.1: Configure a Auto-Refresh command: send the first command.*/ + _sdram_wait_ready(); + SDRAMD.sdram->SDCMR = FMCCM_AUTO_REFRESH | command_target | + (cfgp->sdcmr & FMC_SDCMR_NRFS); + + /* Step 6.2: Send the second command.*/ + _sdram_wait_ready(); + SDRAMD.sdram->SDCMR = FMCCM_AUTO_REFRESH | command_target | + (cfgp->sdcmr & FMC_SDCMR_NRFS); + + /* Step 7: Program the external memory mode register.*/ + _sdram_wait_ready(); + SDRAMD.sdram->SDCMR = FMCCM_LOAD_MODE | command_target | + (cfgp->sdcmr & FMC_SDCMR_MRD); + + /* Step 8: Set clock.*/ + _sdram_wait_ready(); + SDRAMD.sdram->SDRTR = cfgp->sdrtr & FMC_SDRTR_COUNT; + + _sdram_wait_ready(); +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level SDRAM driver initialization. + */ +void fsmcSdramInit(void) { + + fsmc_init(); + + SDRAMD.sdram = FSMCD1.sdram; + SDRAMD.state = SDRAM_STOP; +} + +/** + * @brief Configures and activates the SDRAM peripheral. + * + * @param[in] sdramp pointer to the @p SDRAMDriver object + * @param[in] cfgp pointer to the @p SDRAMConfig object + */ +void fsmcSdramStart(SDRAMDriver *sdramp, const SDRAMConfig *cfgp) { + + if (FSMCD1.state == FSMC_STOP) + fsmc_start(&FSMCD1); + + osalDbgAssert((sdramp->state == SDRAM_STOP) || (sdramp->state == SDRAM_READY), + "SDRAM. Invalid state."); + + if (sdramp->state == SDRAM_STOP) { + + /* Even if you need only bank2 you must properly set up SDCR and SDTR + regitsters for bank1 too. Both banks will be tuned equally assuming + connected memory ICs are equal.*/ + sdramp->sdram->SDCR1 = cfgp->sdcr; + sdramp->sdram->SDTR1 = cfgp->sdtr; + sdramp->sdram->SDCR2 = cfgp->sdcr; + sdramp->sdram->SDTR2 = cfgp->sdtr; + + _sdram_init_sequence(cfgp); + + sdramp->state = SDRAM_READY; + } +} + +/** + * @brief Deactivates the SDRAM peripheral. + * + * @param[in] sdramp pointer to the @p SDRAMDriver object + * + * @notapi + */ +void fsmcSdramStop(SDRAMDriver *sdramp) { + + uint32_t command_target = 0; + +#if STM32_SDRAM_USE_FSMC_SDRAM1 + command_target |= FMC_SDCMR_CTB1; +#endif +#if STM32_SDRAM_USE_FSMC_SDRAM2 + command_target |= FMC_SDCMR_CTB2; +#endif + + if (sdramp->state == SDRAM_READY) { + SDRAMD.sdram->SDCMR = FMCCM_POWER_DOWN | command_target; + sdramp->state = SDRAM_STOP; + } +} + +#endif /* STM32_USE_FSMC_SDRAM */ + +#endif /* STM32F427xx / STM32F429xx / STM32F437xx / STM32F439xx */ + +/** @} */ + diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h new file mode 100644 index 0000000..940679a --- /dev/null +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h @@ -0,0 +1,172 @@ +/* + ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio + + Licensed 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess (SDRAM routines added by Nick Klimov aka progfin). + */ + +/** + * @file fsmc_sdram.h + * @brief SDRAM Driver subsystem low level driver header. + * + * @addtogroup SDRAM + * @{ + */ + +#ifndef _FMC_SDRAM_H_ +#define _FMC_SDRAM_H_ + +#if (defined(STM32F427xx) || defined(STM32F437xx) || \ + defined(STM32F429xx) || defined(STM32F439xx)) + +#include "fsmc.h" + +#if STM32_USE_FSMC_SDRAM || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ + +/** + * @brief SDRAM driver enable switch. + * @details If set to @p TRUE the support for SDRAM1 is included. + */ +#if !defined(STM32_SDRAM_USE_FSMC_SDRAM1) || defined(__DOXYGEN__) +#define STM32_SDRAM_USE_FSMC_SDRAM1 FALSE +#else +#define STM32_SDRAM1_MAP_BASE FSMC_Bank5_MAP_BASE +#endif + +/** + * @brief SDRAM driver enable switch. + * @details If set to @p TRUE the support for SDRAM2 is included. + */ +#if !defined(STM32_SDRAM_USE_FSMC_SDRAM2) || defined(__DOXYGEN__) +#define STM32_SDRAM_USE_FSMC_SDRAM2 FALSE +#else +#define STM32_SDRAM2_MAP_BASE FSMC_Bank6_MAP_BASE +#endif + +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if !STM32_SDRAM_USE_FSMC_SDRAM1 && !STM32_SDRAM_USE_FSMC_SDRAM2 +#error "SDRAM driver activated but no SDRAM peripheral assigned" +#endif + +#if (STM32_SDRAM_USE_FSMC_SDRAM1 || STM32_SDRAM_USE_FSMC_SDRAM2) && !STM32_HAS_FSMC +#error "FMC not present in the selected device" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ +/** + * @brief Driver state machine possible states. + */ +typedef enum { + SDRAM_UNINIT = 0, /**< Not initialized. */ + SDRAM_STOP = 1, /**< Stopped. */ + SDRAM_READY = 2, /**< Ready. */ +} sdramstate_t; + +/** + * @brief Type of a structure representing an SDRAM driver. + */ +typedef struct SDRAMDriver SDRAMDriver; + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + /** + * @brief SDRAM control register. + * @note Its value will be used for both banks. + */ + uint32_t sdcr; + + /** + * @brief SDRAM timing register. + * @note Its value will be used for both banks. + */ + uint32_t sdtr; + + /** + * @brief SDRAM command mode register. + * @note Only its MRD and NRFS bits will be used. + */ + uint32_t sdcmr; + + /** + * @brief SDRAM refresh timer register. + * @note Only its COUNT bits will be used. + */ + uint32_t sdrtr; +} SDRAMConfig; + +/** + * @brief Structure representing an SDRAM driver. + */ +struct SDRAMDriver { + /** + * @brief Driver state. + */ + sdramstate_t state; + /** + * @brief Pointer to the FMC SDRAM registers block. + */ + FSMC_SDRAM_TypeDef *sdram; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +extern SDRAMDriver SDRAMD; + +#ifdef __cplusplus +extern "C" { +#endif + void fsmcSdramInit(void); + void fsmcSdramStart(SDRAMDriver *sdramp, const SDRAMConfig *cfgp); + void fsmcSdramStop(SDRAMDriver *sdramp); +#ifdef __cplusplus +} +#endif + +#endif /* STM32_USE_FSMC_SDRAM */ + +#endif /* STM32F427xx / STM32F429xx / STM32F437xx / STM32F439xx */ + +#endif /* _FMC_SDRAM_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c new file mode 100644 index 0000000..44f7ff2 --- /dev/null +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c @@ -0,0 +1,159 @@ +/* + ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio + + Licensed 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file fsmc_sram.c + * @brief SRAM Driver subsystem low level driver source. + * + * @addtogroup SRAM + * @{ + */ +#include "hal.h" +#include "fsmc_sram.h" + +#if STM32_USE_FSMC_SRAM || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ +/** + * @brief SRAM1 driver identifier. + */ +#if STM32_SRAM_USE_FSMC_SRAM1 || defined(__DOXYGEN__) +SRAMDriver SRAMD1; +#endif + +/** + * @brief SRAM2 driver identifier. + */ +#if STM32_SRAM_USE_FSMC_SRAM2 || defined(__DOXYGEN__) +SRAMDriver SRAMD2; +#endif + +/** + * @brief SRAM3 driver identifier. + */ +#if STM32_SRAM_USE_FSMC_SRAM3 || defined(__DOXYGEN__) +SRAMDriver SRAMD3; +#endif + +/** + * @brief SRAM4 driver identifier. + */ +#if STM32_SRAM_USE_FSMC_SRAM4 || defined(__DOXYGEN__) +SRAMDriver SRAMD4; +#endif + +/*===========================================================================*/ +/* Driver local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level SRAM driver initialization. + * + * @notapi + */ +void fsmcSramInit(void) { + + fsmc_init(); + +#if STM32_SRAM_USE_FSMC_SRAM1 + SRAMD1.sram = FSMCD1.sram1; + SRAMD1.state = SRAM_STOP; +#endif /* STM32_SRAM_USE_FSMC_SRAM1 */ + +#if STM32_SRAM_USE_FSMC_SRAM2 + SRAMD2.sram = FSMCD1.sram2; + SRAMD2.state = SRAM_STOP; +#endif /* STM32_SRAM_USE_FSMC_SRAM2 */ + +#if STM32_SRAM_USE_FSMC_SRAM3 + SRAMD3.sram = FSMCD1.sram3; + SRAMD3.state = SRAM_STOP; +#endif /* STM32_SRAM_USE_FSMC_SRAM3 */ + +#if STM32_SRAM_USE_FSMC_SRAM4 + SRAMD4.sram = FSMCD1.sram4; + SRAMD4.state = SRAM_STOP; +#endif /* STM32_SRAM_USE_FSMC_SRAM4 */ +} + +/** + * @brief Configures and activates the SRAM peripheral. + * + * @param[in] sramp pointer to the @p SRAMDriver object + * @param[in] cfgp pointer to the @p SRAMConfig object + * + * @notapi + */ +void fsmcSramStart(SRAMDriver *sramp, const SRAMConfig *cfgp) { + + if (FSMCD1.state == FSMC_STOP) + fsmc_start(&FSMCD1); + + osalDbgAssert((sramp->state == SRAM_STOP) || (sramp->state == SRAM_READY), + "invalid state"); + + if (sramp->state == SRAM_STOP) { + sramp->sram->BCR = FSMC_BCR_WREN | FSMC_BCR_MBKEN | FSMC_BCR_MWID_0; + sramp->sram->BTR = cfgp->btr; + sramp->state = SRAM_READY; + } +} + +/** + * @brief Deactivates the SRAM peripheral. + * + * @param[in] sramp pointer to the @p SRAMDriver object + * + * @notapi + */ +void fsmcSramStop(SRAMDriver *sramp) { + + if (sramp->state == SRAM_READY) { + sramp->sram->BCR &= ~FSMC_BCR_MBKEN; + sramp->state = SRAM_STOP; + } +} + +#endif /* STM32_USE_FSMC_SRAM */ + +/** @} */ + diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.h b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.h new file mode 100644 index 0000000..0113a04 --- /dev/null +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.h @@ -0,0 +1,173 @@ +/* + ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio + + Licensed 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file fsmc_sram.h + * @brief SRAM Driver subsystem low level driver header. + * + * @addtogroup SRAM + * @{ + */ + +#ifndef _FSMC_SRAM_H_ +#define _FSMC_SRAM_H_ + +#include "fsmc.h" + +#if STM32_USE_FSMC_SRAM || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ + +/** + * @brief SRAM driver enable switch. + * @details If set to @p TRUE the support for SRAM1 is included. + */ +#if !defined(STM32_SRAM_USE_FSMC_SRAM1) || defined(__DOXYGEN__) +#define STM32_SRAM_USE_FSMC_SRAM1 FALSE +#endif + +/** + * @brief SRAM driver enable switch. + * @details If set to @p TRUE the support for SRAM2 is included. + */ +#if !defined(STM32_SRAM_USE_FSMC_SRAM2) || defined(__DOXYGEN__) +#define STM32_SRAM_USE_FSMC_SRAM2 FALSE +#endif + +/** + * @brief SRAM driver enable switch. + * @details If set to @p TRUE the support for SRAM3 is included. + */ +#if !defined(STM32_SRAM_USE_FSMC_SRAM3) || defined(__DOXYGEN__) +#define STM32_SRAM_USE_FSMC_SRAM3 FALSE +#endif + +/** + * @brief SRAM driver enable switch. + * @details If set to @p TRUE the support for SRAM4 is included. + */ +#if !defined(STM32_SRAM_USE_FSMC_SRAM4) || defined(__DOXYGEN__) +#define STM32_SRAM_USE_FSMC_SRAM4 FALSE +#endif + +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if !STM32_SRAM_USE_FSMC_SRAM1 && !STM32_SRAM_USE_FSMC_SRAM2 && \ + !STM32_SRAM_USE_FSMC_SRAM3 && !STM32_SRAM_USE_FSMC_SRAM4 +#error "SRAM driver activated but no SRAM peripheral assigned" +#endif + +#if (STM32_SRAM_USE_FSMC_SRAM1 || STM32_SRAM_USE_FSMC_SRAM2 || \ + STM32_SRAM_USE_FSMC_SRAM3 || STM32_SRAM_USE_FSMC_SRAM4) && !STM32_HAS_FSMC +#error "FSMC not present in the selected device" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ +/** + * @brief Driver state machine possible states. + */ +typedef enum { + SRAM_UNINIT = 0, /**< Not initialized. */ + SRAM_STOP = 1, /**< Stopped. */ + SRAM_READY = 2, /**< Ready. */ +} sramstate_t; + +/** + * @brief Type of a structure representing an NAND driver. + */ +typedef struct SRAMDriver SRAMDriver; + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + uint32_t btr; +} SRAMConfig; + +/** + * @brief Structure representing an NAND driver. + */ +struct SRAMDriver { + /** + * @brief Driver state. + */ + sramstate_t state; + /** + * @brief Pointer to the FSMC SRAM registers block. + */ + FSMC_SRAM_NOR_TypeDef *sram; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if STM32_SRAM_USE_FSMC_SRAM1 && !defined(__DOXYGEN__) +extern SRAMDriver SRAMD1; +#endif + +#if STM32_SRAM_USE_FSMC_SRAM2 && !defined(__DOXYGEN__) +extern SRAMDriver SRAMD2; +#endif + +#if STM32_SRAM_USE_FSMC_SRAM3 && !defined(__DOXYGEN__) +extern SRAMDriver SRAMD3; +#endif + +#if STM32_SRAM_USE_FSMC_SRAM4 && !defined(__DOXYGEN__) +extern SRAMDriver SRAMD4; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void fsmcSramInit(void); + void fsmcSramStart(SRAMDriver *sramp, const SRAMConfig *cfgp); + void fsmcSramStop(SRAMDriver *sramp); +#ifdef __cplusplus +} +#endif + +#endif /* STM32_USE_FSMC_SRAM */ + +#endif /* _FSMC_SRAM_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/FSMCv1/nand_lld.c b/os/hal/ports/STM32/LLD/FSMCv1/nand_lld.c new file mode 100644 index 0000000..3739e88 --- /dev/null +++ b/os/hal/ports/STM32/LLD/FSMCv1/nand_lld.c @@ -0,0 +1,515 @@ +/* + ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio + + Licensed 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file nand_lld.c + * @brief NAND Driver subsystem low level driver source. + * + * @addtogroup NAND + * @{ + */ + +#include "hal.h" + +#if HAL_USE_NAND || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ +#define NAND_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_NAND_DMA_STREAM, \ + STM32_FSMC_DMA_CHN) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief NAND1 driver identifier. + */ +#if STM32_NAND_USE_FSMC_NAND1 || defined(__DOXYGEN__) +NANDDriver NANDD1; +#endif + +/** + * @brief NAND2 driver identifier. + */ +#if STM32_NAND_USE_FSMC_NAND2 || defined(__DOXYGEN__) +NANDDriver NANDD2; +#endif + +/*===========================================================================*/ +/* Driver local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ +/** + * @brief Wakes up the waiting thread. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] msg wakeup message + * + * @notapi + */ +static void wakeup_isr(NANDDriver *nandp){ + + osalDbgCheck(nandp->thread != NULL); + osalThreadResumeI(&nandp->thread, MSG_OK); +} + +/** + * @brief Put calling thread in suspend and switch driver state + * + * @param[in] nandp pointer to the @p NANDDriver object + */ +static void nand_lld_suspend_thread(NANDDriver *nandp) { + + osalThreadSuspendS(&nandp->thread); +} + +/** + * @brief Caclulate ECCPS register value + * + * @param[in] nandp pointer to the @p NANDDriver object + */ +static uint32_t calc_eccps(NANDDriver *nandp){ + + uint32_t i = 0; + uint32_t eccps = nandp->config->page_data_size; + + eccps = eccps >> 9; + while (eccps > 0){ + i++; + eccps >>= 1; + } + + return i << 17; +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/** + * @brief Enable interrupts from NAND + * + * @param[in] nandp pointer to the @p NANDDriver object + * + * @notapi + */ +static void nand_ready_isr_enable(NANDDriver *nandp) { +#if STM32_NAND_USE_EXT_INT + nandp->config->ext_nand_isr_enable(); +#else + nandp->nand->SR &= ~(FSMC_SR_IRS | FSMC_SR_ILS | FSMC_SR_IFS | + FSMC_SR_ILEN | FSMC_SR_IFEN); + nandp->nand->SR |= FSMC_SR_IREN; +#endif +} + +/** + * @brief Disable interrupts from NAND + * + * @param[in] nandp pointer to the @p NANDDriver object + * + * @notapi + */ +static void nand_ready_isr_disable(NANDDriver *nandp) { +#if STM32_NAND_USE_EXT_INT + nandp->config->ext_nand_isr_disable(); +#else + nandp->nand->SR &= ~FSMC_SR_IREN; +#endif +} + +/** + * @brief Ready interrupt handler + * + * @param[in] nandp pointer to the @p NANDDriver object + * + * @notapi + */ +static void nand_isr_handler (NANDDriver *nandp){ + + osalSysLockFromISR(); + +#if !STM32_NAND_USE_EXT_INT + osalDbgCheck(nandp->nand->SR & FSMC_SR_IRS); /* spurious interrupt happened */ + nandp->nand->SR &= ~FSMC_SR_IRS; +#endif + + switch (nandp->state){ + case NAND_READ: + nandp->state = NAND_DMA_RX; + dmaStartMemCopy(nandp->dma, nandp->dmamode, + nandp->map_data, nandp->rxdata, nandp->datalen); + /* thread will be waked up from DMA ISR */ + break; + + case NAND_ERASE: + /* NAND reports about erase finish */ + nandp->state = NAND_READY; + wakeup_isr(nandp); + break; + + case NAND_PROGRAM: + /* NAND reports about page programming finish */ + nandp->state = NAND_READY; + wakeup_isr(nandp); + break; + + default: + osalSysHalt("Unhandled case"); + break; + } + osalSysUnlockFromISR(); +} + +/** + * @brief DMA RX end IRQ handler. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] flags pre-shifted content of the ISR register + * + * @notapi + */ +static void nand_lld_serve_transfer_end_irq(NANDDriver *nandp, uint32_t flags) { + /* DMA errors handling.*/ +#if defined(STM32_NAND_DMA_ERROR_HOOK) + if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) { + STM32_NAND_DMA_ERROR_HOOK(nandp); + } +#else + (void)flags; +#endif + + osalSysLockFromISR(); + + dmaStreamDisable(nandp->dma); + + switch (nandp->state){ + case NAND_DMA_TX: + nandp->state = NAND_PROGRAM; + nandp->map_cmd[0] = NAND_CMD_PAGEPROG; + /* thread will be woken from ready_isr() */ + break; + + case NAND_DMA_RX: + nandp->state = NAND_READY; + nandp->rxdata = NULL; + nandp->datalen = 0; + wakeup_isr(nandp); + break; + + default: + osalSysHalt("Unhandled case"); + break; + } + + osalSysUnlockFromISR(); +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level NAND driver initialization. + * + * @notapi + */ +void nand_lld_init(void) { + + fsmc_init(); + +#if STM32_NAND_USE_FSMC_NAND1 + /* Driver initialization.*/ + nandObjectInit(&NANDD1); + NANDD1.rxdata = NULL; + NANDD1.datalen = 0; + NANDD1.thread = NULL; + NANDD1.dma = STM32_DMA_STREAM(STM32_NAND_DMA_STREAM); + NANDD1.nand = FSMCD1.nand1; + NANDD1.map_data = (uint8_t*)FSMC_Bank2_MAP_COMMON_DATA; + NANDD1.map_cmd = (uint8_t*)FSMC_Bank2_MAP_COMMON_CMD; + NANDD1.map_addr = (uint8_t*)FSMC_Bank2_MAP_COMMON_ADDR; +#endif /* STM32_NAND_USE_FSMC_NAND1 */ + +#if STM32_NAND_USE_FSMC_NAND2 + /* Driver initialization.*/ + nandObjectInit(&NANDD2); + NANDD2.rxdata = NULL; + NANDD2.datalen = 0; + NANDD2.thread = NULL; + NANDD2.dma = STM32_DMA_STREAM(STM32_NAND_DMA_STREAM); + NANDD2.nand = FSMCD1.nand2; + NANDD2.map_data = (uint8_t*)FSMC_Bank3_MAP_COMMON_DATA; + NANDD2.map_cmd = (uint8_t*)FSMC_Bank3_MAP_COMMON_CMD; + NANDD2.map_addr = (uint8_t*)FSMC_Bank3_MAP_COMMON_ADDR; +#endif /* STM32_NAND_USE_FSMC_NAND2 */ +} + +/** + * @brief Configures and activates the NAND peripheral. + * + * @param[in] nandp pointer to the @p NANDDriver object + * + * @notapi + */ +void nand_lld_start(NANDDriver *nandp) { + + bool b; + + if (FSMCD1.state == FSMC_STOP) + fsmc_start(&FSMCD1); + + if (nandp->state == NAND_STOP) { + b = dmaStreamAllocate(nandp->dma, + STM32_EMC_FSMC1_IRQ_PRIORITY, + (stm32_dmaisr_t)nand_lld_serve_transfer_end_irq, + (void *)nandp); + osalDbgAssert(!b, "stream already allocated"); + nandp->dmamode = STM32_DMA_CR_CHSEL(NAND_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_NAND_NAND1_DMA_PRIORITY) | + STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE | + STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | + STM32_DMA_CR_TCIE; + /* dmaStreamSetFIFO(nandp->dma, + STM32_DMA_FCR_DMDIS | NAND_STM32_DMA_FCR_FTH_LVL); */ + nandp->nand->PCR = calc_eccps(nandp) | FSMC_PCR_PTYP | FSMC_PCR_PBKEN; + nandp->nand->PMEM = nandp->config->pmem; + nandp->nand->PATT = nandp->config->pmem; + nandp->isr_handler = nand_isr_handler; + nand_ready_isr_enable(nandp); + } +} + +/** + * @brief Deactivates the NAND peripheral. + * + * @param[in] nandp pointer to the @p NANDDriver object + * + * @notapi + */ +void nand_lld_stop(NANDDriver *nandp) { + + if (nandp->state == NAND_READY) { + dmaStreamRelease(nandp->dma); + nandp->nand->PCR &= ~FSMC_PCR_PBKEN; + nand_ready_isr_disable(nandp); + nandp->isr_handler = NULL; + } +} + +/** + * @brief Read data from NAND. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[out] data pointer to data buffer + * @param[in] datalen size of data buffer + * @param[in] addr pointer to address buffer + * @param[in] addrlen length of address + * @param[out] ecc pointer to store computed ECC. Ignored when NULL. + * + * @notapi + */ +void nand_lld_read_data(NANDDriver *nandp, uint8_t *data, + size_t datalen, uint8_t *addr, size_t addrlen, uint32_t *ecc){ + + nandp->state = NAND_READ; + nandp->rxdata = data; + nandp->datalen = datalen; + + nand_lld_write_cmd (nandp, NAND_CMD_READ0); + nand_lld_write_addr(nandp, addr, addrlen); + osalSysLock(); + nand_lld_write_cmd (nandp, NAND_CMD_READ0_CONFIRM); + + /* Here NAND asserts busy signal and starts transferring from memory + array to page buffer. After the end of transmission ready_isr functions + starts DMA transfer from page buffer to MCU's RAM.*/ + osalDbgAssert((nandp->nand->PCR & FSMC_PCR_ECCEN) == 0, + "State machine broken. ECCEN must be previously disabled."); + + if (NULL != ecc){ + nandp->nand->PCR |= FSMC_PCR_ECCEN; + } + + nand_lld_suspend_thread(nandp); + osalSysUnlock(); + + /* thread was woken up from DMA ISR */ + if (NULL != ecc){ + while (! (nandp->nand->SR & FSMC_SR_FEMPT)) + ; + *ecc = nandp->nand->ECCR; + nandp->nand->PCR &= ~FSMC_PCR_ECCEN; + } +} + +/** + * @brief Write data to NAND. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] data buffer with data to be written + * @param[in] datalen size of data buffer + * @param[in] addr pointer to address buffer + * @param[in] addrlen length of address + * @param[out] ecc pointer to store computed ECC. Ignored when NULL. + * + * @return The operation status reported by NAND IC (0x70 command). + * + * @notapi + */ +uint8_t nand_lld_write_data(NANDDriver *nandp, const uint8_t *data, + size_t datalen, uint8_t *addr, size_t addrlen, uint32_t *ecc){ + + nandp->state = NAND_WRITE; + + nand_lld_write_cmd (nandp, NAND_CMD_WRITE); + osalSysLock(); + nand_lld_write_addr(nandp, addr, addrlen); + + /* Now start DMA transfer to NAND buffer and put thread in sleep state. + Tread will we woken up from ready ISR. */ + nandp->state = NAND_DMA_TX; + osalDbgAssert((nandp->nand->PCR & FSMC_PCR_ECCEN) == 0, + "State machine broken. ECCEN must be previously disabled."); + + if (NULL != ecc){ + nandp->nand->PCR |= FSMC_PCR_ECCEN; + } + + dmaStartMemCopy(nandp->dma, nandp->dmamode, data, nandp->map_data, datalen); + + nand_lld_suspend_thread(nandp); + osalSysUnlock(); + + if (NULL != ecc){ + while (! (nandp->nand->SR & FSMC_SR_FEMPT)) + ; + *ecc = nandp->nand->ECCR; + nandp->nand->PCR &= ~FSMC_PCR_ECCEN; + } + + return nand_lld_read_status(nandp); +} + +/** + * @brief Erase block. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] addr pointer to address buffer + * @param[in] addrlen length of address + * + * @return The operation status reported by NAND IC (0x70 command). + * + * @notapi + */ +uint8_t nand_lld_erase(NANDDriver *nandp, uint8_t *addr, size_t addrlen){ + + nandp->state = NAND_ERASE; + + nand_lld_write_cmd (nandp, NAND_CMD_ERASE); + nand_lld_write_addr(nandp, addr, addrlen); + osalSysLock(); + nand_lld_write_cmd (nandp, NAND_CMD_ERASE_CONFIRM); + nand_lld_suspend_thread(nandp); + osalSysUnlock(); + + return nand_lld_read_status(nandp); +} + +/** + * @brief Read data from NAND using polling approach. + * + * @detatils Use this function to read data when no waiting expected. For + * Example read status word after 0x70 command + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[out] data pointer to output buffer + * @param[in] len length of data to be read + * + * @notapi + */ +void nand_lld_polled_read_data(NANDDriver *nandp, uint8_t *data, size_t len){ + size_t i = 0; + + for (i=0; i<len; i++) + data[i] = nandp->map_data[i]; +} + +/** + * @brief Send addres to NAND. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] len length of address array + * @param[in] addr pointer to address array + * + * @notapi + */ +void nand_lld_write_addr(NANDDriver *nandp, const uint8_t *addr, size_t len){ + size_t i = 0; + + for (i=0; i<len; i++) + nandp->map_addr[i] = addr[i]; +} + +/** + * @brief Send command to NAND. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] cmd command value + * + * @notapi + */ +void nand_lld_write_cmd(NANDDriver *nandp, uint8_t cmd){ + nandp->map_cmd[0] = cmd; +} + +/** + * @brief Read status byte from NAND. + * + * @param[in] nandp pointer to the @p NANDDriver object + * + * @return Status byte. + * + * @notapi + */ +uint8_t nand_lld_read_status(NANDDriver *nandp) { + + uint8_t status[1] = {0x01}; /* presume worse */ + + nand_lld_write_cmd(nandp, NAND_CMD_STATUS); + nand_lld_polled_read_data(nandp, status, 1); + + return status[0]; +} + +#endif /* HAL_USE_NAND */ + +/** @} */ + diff --git a/os/hal/ports/STM32/LLD/FSMCv1/nand_lld.h b/os/hal/ports/STM32/LLD/FSMCv1/nand_lld.h new file mode 100644 index 0000000..618255f --- /dev/null +++ b/os/hal/ports/STM32/LLD/FSMCv1/nand_lld.h @@ -0,0 +1,335 @@ +/* + ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio + + Licensed 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file nand_lld.h + * @brief NAND Driver subsystem low level driver header. + * + * @addtogroup NAND + * @{ + */ + +#ifndef _NAND_LLD_H_ +#define _NAND_LLD_H_ + +#include "fsmc.h" + +#if HAL_USE_NAND || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ +#define NAND_MIN_PAGE_SIZE 256 +#define NAND_MAX_PAGE_SIZE 8192 + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief FSMC1 interrupt priority level setting. + */ +#if !defined(STM32_EMC_FSMC1_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_EMC_FSMC1_IRQ_PRIORITY 10 +#endif + +/** + * @brief NAND driver enable switch. + * @details If set to @p TRUE the support for NAND1 is included. + */ +#if !defined(STM32_NAND_USE_NAND1) || defined(__DOXYGEN__) +#define STM32_NAND_USE_NAND1 FALSE +#endif + +/** + * @brief NAND driver enable switch. + * @details If set to @p TRUE the support for NAND2 is included. + */ +#if !defined(STM32_NAND_USE_NAND2) || defined(__DOXYGEN__) +#define STM32_NAND_USE_NAND2 FALSE +#endif + +/** + * @brief NAND DMA error hook. + * @note The default action for DMA errors is a system halt because DMA + * error can only happen because programming errors. + */ +#if !defined(STM32_NAND_DMA_ERROR_HOOK) || defined(__DOXYGEN__) +#define STM32_NAND_DMA_ERROR_HOOK(nandp) osalSysHalt("DMA failure") +#endif + +/** + * @brief NAND interrupt enable switch. + * @details If set to @p TRUE the support for internal FSMC interrupt included. + */ +#if !defined(STM32_NAND_USE_INT) || defined(__DOXYGEN__) +#define STM32_NAND_USE_INT FALSE +#endif + +/** +* @brief NAND1 DMA priority (0..3|lowest..highest). +*/ +#if !defined(STM32_NAND_NAND1_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_NAND_NAND1_DMA_PRIORITY 0 +#endif + +/** +* @brief NAND2 DMA priority (0..3|lowest..highest). +*/ +#if !defined(STM32_NAND_NAND2_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_NAND_NAND2_DMA_PRIORITY 0 +#endif + +/** + * @brief DMA stream used for NAND operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_NAND_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_NAND_DMA_STREAM STM32_DMA_STREAM_ID(2, 6) +#endif + +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if !STM32_NAND_USE_FSMC_NAND1 && !STM32_NAND_USE_FSMC_NAND2 +#error "NAND driver activated but no NAND peripheral assigned" +#endif + +#if (STM32_NAND_USE_FSMC_NAND2 || STM32_NAND_USE_FSMC_NAND1) && !STM32_HAS_FSMC +#error "FSMC not present in the selected device" +#endif + +#if STM32_NAND_USE_EXT_INT && !HAL_USE_EXT +#error "External interrupt controller must be enabled to use this feature" +#endif + +#if (STM32_NAND_USE_FSMC_NAND2 || STM32_NAND_USE_FSMC_NAND1) && \ + !STM32_DMA_IS_VALID_ID(STM32_NAND_DMA_STREAM, \ + STM32_FSMC_DMA_MSK) +#error "invalid DMA stream associated to NAND" +#endif + +#if !defined(STM32_DMA_REQUIRED) +#define STM32_DMA_REQUIRED +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief NAND driver condition flags type. + */ +typedef uint32_t nandflags_t; + +/** + * @brief Type of a structure representing an NAND driver. + */ +typedef struct NANDDriver NANDDriver; + +/** + * @brief Type of interrupt handler function + */ +typedef void (*nandisrhandler_t)(NANDDriver *nandp); + +#if STM32_NAND_USE_EXT_INT +/** + * @brief Type of function switching external interrupts on and off. + */ +typedef void (*nandisrswitch_t)(void); +#endif /* STM32_NAND_USE_EXT_INT */ + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + /** + * @brief Pointer to lower level driver. + */ + FSMCDriver *fsmcp; + /** + * @brief Number of erase blocks in NAND device. + */ + uint32_t blocks; + /** + * @brief Number of data bytes in page. + */ + uint32_t page_data_size; + /** + * @brief Number of spare bytes in page. + */ + uint32_t page_spare_size; + /** + * @brief Number of pages in block. + */ + uint32_t pages_per_block; +#if NAND_USE_BAD_MAP + /** + * @brief Pointer to bad block map. + * @details One bit per block. Memory for map must be allocated by user. + */ + uint32_t *bb_map; +#endif /* NAND_USE_BAD_MAP */ + /** + * @brief Number of write cycles for row addressing. + */ + uint8_t rowcycles; + /** + * @brief Number of write cycles for column addressing. + */ + uint8_t colcycles; + + /* End of the mandatory fields.*/ + /** + * @brief Number of wait cycles. This value will be used both for + * PMEM and PATTR registers + * + * @note For proper calculation procedure please look at AN2784 document + * from STMicroelectronics. + */ + uint32_t pmem; +#if STM32_NAND_USE_EXT_INT + /** + * @brief Function enabling interrupts from EXTI + */ + nandisrswitch_t ext_nand_isr_enable; + /** + * @brief Function disabling interrupts from EXTI + */ + nandisrswitch_t ext_nand_isr_disable; +#endif /* STM32_NAND_USE_EXT_INT */ +} NANDConfig; + +/** + * @brief Structure representing an NAND driver. + */ +struct NANDDriver { + /** + * @brief Driver state. + */ + nandstate_t state; + /** + * @brief Current configuration data. + */ + const NANDConfig *config; + /** + * @brief Array to store bad block map. + */ +#if NAND_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) +#if CH_CFG_USE_MUTEXES || defined(__DOXYGEN__) + /** + * @brief Mutex protecting the bus. + */ + mutex_t mutex; +#elif CH_CFG_USE_SEMAPHORES + semaphore_t semaphore; +#endif +#endif /* NAND_USE_MUTUAL_EXCLUSION */ + /* End of the mandatory fields.*/ + /** + * @brief Function enabling interrupts from FSMC + */ + nandisrhandler_t isr_handler; + /** + * @brief Pointer to current transaction buffer + */ + uint8_t *rxdata; + /** + * @brief Current transaction length + */ + size_t datalen; + /** + * @brief DMA mode bit mask. + */ + uint32_t dmamode; + /** + * @brief DMA channel. + */ + const stm32_dma_stream_t *dma; + /** + * @brief Thread waiting for I/O completion. + */ + thread_t *thread; + /** + * @brief Pointer to the FSMC NAND registers block. + */ + FSMC_NAND_TypeDef *nand; + /** + * @brief Memory mapping for data. + */ + uint8_t *map_data; + /** + * @brief Memory mapping for commands. + */ + uint8_t *map_cmd; + /** + * @brief Memory mapping for addresses. + */ + uint8_t *map_addr; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if STM32_NAND_USE_FSMC_NAND1 && !defined(__DOXYGEN__) +extern NANDDriver NANDD1; +#endif + +#if STM32_NAND_USE_FSMC_NAND2 && !defined(__DOXYGEN__) +extern NANDDriver NANDD2; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void nand_lld_init(void); + void nand_lld_start(NANDDriver *nandp); + void nand_lld_stop(NANDDriver *nandp); + uint8_t nand_lld_write_data(NANDDriver *nandp, const uint8_t *data, + size_t datalen, uint8_t *addr, size_t addrlen, uint32_t *ecc); + void nand_lld_read_data(NANDDriver *nandp, uint8_t *data, + size_t datalen, uint8_t *addr, size_t addrlen, uint32_t *ecc); + void nand_lld_polled_read_data(NANDDriver *nandp, uint8_t *data, size_t len); + uint8_t nand_lld_erase(NANDDriver *nandp, uint8_t *addr, size_t addrlen); + void nand_lld_write_addr(NANDDriver *nandp, const uint8_t *addr, size_t len); + void nand_lld_write_cmd(NANDDriver *nandp, uint8_t cmd); + uint8_t nand_lld_read_status(NANDDriver *nandp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_NAND */ + +#endif /* _NAND_LLD_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F4xx/platform.mk b/os/hal/ports/STM32/STM32F4xx/platform.mk new file mode 100644 index 0000000..2ede59d --- /dev/null +++ b/os/hal/ports/STM32/STM32F4xx/platform.mk @@ -0,0 +1,8 @@ +include ${CHIBIOS}/os/hal/ports/STM32/STM32F4xx/platform.mk
+
+PLATFORMSRC += ${CHIBIOS}/community/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c \
+ ${CHIBIOS}/community/os/hal/ports/STM32/LLD/FSMCv1/nand_lld.c \
+ ${CHIBIOS}/community/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c \
+ ${CHIBIOS}/community/os/hal/src/fsmc_sdram.c
+
+PLATFORMINC += ${CHIBIOS}/community/os/hal/ports/STM32/LLD/FSMCv1
diff --git a/os/hal/src/nand.c b/os/hal/src/nand.c new file mode 100644 index 0000000..ee2bd3b --- /dev/null +++ b/os/hal/src/nand.c @@ -0,0 +1,601 @@ +/* + ChibiOS/HAL - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012,2013,2014 Giovanni Di Sirio. + + This file is part of ChibiOS/HAL + + ChibiOS/HAL is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file nand.c + * @brief NAND Driver code. + * + * @addtogroup NAND + * @{ + */ + +#include "hal.h" + +#if HAL_USE_NAND || defined(__DOXYGEN__) + +#include "string.h" /* for memset */ + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Check page size. + * + * @param[in] page_data_size size of page data area + * + * @notapi + */ +static void pagesize_check(size_t page_data_size){ + + /* Page size out of bounds.*/ + osalDbgCheck((page_data_size >= NAND_MIN_PAGE_SIZE) && + (page_data_size <= NAND_MAX_PAGE_SIZE)); + + /* Page size must be power of 2.*/ + osalDbgCheck(((page_data_size - 1) & page_data_size) == 0); +} + +/** + * @brief Translate block-page-offset scheme to NAND internal address. + * + * @param[in] cfg pointer to the @p NANDConfig from + * corresponding NAND driver + * @param[in] block block number + * @param[in] page page number related to begin of block + * @param[in] offset data offset related to begin of page + * @param[out] addr buffer to store calculated address + * @param[in] addr_len length of address buffer + * + * @notapi + */ +static void calc_addr(const NANDConfig *cfg, + uint32_t block, uint32_t page, uint32_t offset, + uint8_t *addr, size_t addr_len){ + size_t i = 0; + uint32_t row = 0; + + /* Incorrect buffer length.*/ + osalDbgCheck(cfg->rowcycles + cfg->colcycles == addr_len); + osalDbgCheck((block < cfg->blocks) && (page < cfg->pages_per_block) && + (offset < cfg->page_data_size + cfg->page_spare_size)); + + /* convert address to NAND specific */ + memset(addr, 0, addr_len); + row = (block * cfg->pages_per_block) + page; + for (i=0; i<cfg->colcycles; i++){ + addr[i] = offset & 0xFF; + offset = offset >> 8; + } + for (; i<addr_len; i++){ + addr[i] = row & 0xFF; + row = row >> 8; + } +} + +/** + * @brief Translate block number to NAND internal address. + * @note This function designed for erasing purpose. + * + * @param[in] cfg pointer to the @p NANDConfig from + * corresponding NAND driver + * @param[in] block block number + * @param[out] addr buffer to store calculated address + * @param[in] addr_len length of address buffer + * + * @notapi + */ +static void calc_blk_addr(const NANDConfig *cfg, + uint32_t block, uint8_t *addr, size_t addr_len){ + size_t i = 0; + uint32_t row = 0; + + /* Incorrect buffer length.*/ + osalDbgCheck(cfg->rowcycles == addr_len); + osalDbgCheck((block < cfg->blocks)); + + /* convert address to NAND specific */ + memset(addr, 0, addr_len); + row = block * cfg->pages_per_block; + for (i=0; i<addr_len; i++){ + addr[i] = row & 0xFF; + row = row >> 8; + } +} + +#if NAND_USE_BAD_MAP +/** + * @brief Add new bad block to map. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] block block number + * @param[in] map pointer to bad block map + */ +static void bad_map_update(NANDDriver *nandp, size_t block) { + + uint32_t *map = nandp->config->bb_map; + const size_t BPMC = sizeof(uint32_t) * 8; /* bits per map claster */ + size_t i; + size_t shift; + + /* Nand device overflow.*/ + osalDbgCheck(nandp->config->blocks > block); + + i = block / BPMC; + shift = block % BPMC; + /* This block already mapped.*/ + osalDbgCheck(((map[i] >> shift) & 1) != 1); + map[i] |= (uint32_t)1 << shift; +} + +/** + * @brief Scan for bad blocks and fill map with their numbers. + * + * @param[in] nandp pointer to the @p NANDDriver object + */ +static void scan_bad_blocks(NANDDriver *nandp) { + + const size_t blocks = nandp->config->blocks; + const size_t maplen = blocks / 32; + + size_t b; + uint8_t m0; + uint8_t m1; + + /* clear map just to be safe */ + for (b=0; b<maplen; b++) + nandp->config->bb_map[b] = 0; + + /* now write numbers of bad block to map */ + for (b=0; b<blocks; b++){ + m0 = nandReadBadMark(nandp, b, 0); + m1 = nandReadBadMark(nandp, b, 1); + if ((0xFF != m0) || (0xFF != m1)){ + bad_map_update(nandp, b); + } + } +} +#endif /* NAND_USE_BAD_MAP */ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief NAND Driver initialization. + * @note This function is implicitly invoked by @p halInit(), there is + * no need to explicitly initialize the driver. + * + * @init + */ +void nandInit(void) { + + nand_lld_init(); +} + +/** + * @brief Initializes the standard part of a @p NANDDriver structure. + * + * @param[out] nandp pointer to the @p NANDDriver object + * + * @init + */ +void nandObjectInit(NANDDriver *nandp) { + +#if NAND_USE_MUTUAL_EXCLUSION +#if CH_CFG_USE_MUTEXES + chMtxObjectInit(&nandp->mutex); +#else + chSemObjectInit(&nandp->semaphore, 1); +#endif /* CH_CFG_USE_MUTEXES */ +#endif /* NAND_USE_MUTUAL_EXCLUSION */ + + nandp->state = NAND_STOP; + nandp->config = NULL; +} + +/** + * @brief Configures and activates the NAND peripheral. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] config pointer to the @p NANDConfig object + * + * @api + */ +void nandStart(NANDDriver *nandp, const NANDConfig *config) { + + osalDbgCheck((nandp != NULL) && (config != NULL)); + osalDbgAssert((nandp->state == NAND_STOP) || + (nandp->state == NAND_READY), + "invalid state"); + + nandp->config = config; + pagesize_check(nandp->config->page_data_size); + nand_lld_start(nandp); + nandp->state = NAND_READY; + +#if NAND_USE_BAD_MAP + scan_bad_blocks(nandp); +#endif /* NAND_USE_BAD_MAP */ +} + +/** + * @brief Deactivates the NAND peripheral. + * + * @param[in] nandp pointer to the @p NANDDriver object + * + * @api + */ +void nandStop(NANDDriver *nandp) { + + osalDbgCheck(nandp != NULL); + osalDbgAssert((nandp->state == NAND_STOP) || + (nandp->state == NAND_READY), + "invalid state"); + nand_lld_stop(nandp); + nandp->state = NAND_STOP; +} + +/** + * @brief Read whole page. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] block block number + * @param[in] page page number related to begin of block + * @param[out] data buffer to store data + * @param[in] datalen length of data buffer + * + * @api + */ +void nandReadPageWhole(NANDDriver *nandp, uint32_t block, + uint32_t page, uint8_t *data, size_t datalen) { + + const NANDConfig *cfg = nandp->config; + uint8_t addrbuf[8]; + size_t addrlen = cfg->rowcycles + cfg->colcycles; + + osalDbgCheck((nandp != NULL) && (data != NULL)); + osalDbgCheck((datalen <= (cfg->page_data_size + cfg->page_spare_size))); + osalDbgAssert(nandp->state == NAND_READY, "invalid state"); + + calc_addr(cfg, block, page, 0, addrbuf, addrlen); + nand_lld_read_data(nandp, data, datalen, addrbuf, addrlen, NULL); +} + +/** + * @brief Write whole page. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] block block number + * @param[in] page page number related to begin of block + * @param[in] data buffer with data to be written + * @param[in] datalen length of data buffer + * + * @return The operation status reported by NAND IC (0x70 command). + * + * @api + */ +uint8_t nandWritePageWhole(NANDDriver *nandp, uint32_t block, + uint32_t page, const uint8_t *data, size_t datalen) { + + uint8_t retval; + const NANDConfig *cfg = nandp->config; + uint8_t addr[8]; + size_t addrlen = cfg->rowcycles + cfg->colcycles; + + osalDbgCheck((nandp != NULL) && (data != NULL)); + osalDbgCheck((datalen <= (cfg->page_data_size + cfg->page_spare_size))); + osalDbgAssert(nandp->state == NAND_READY, "invalid state"); + + calc_addr(cfg, block, page, 0, addr, addrlen); + retval = nand_lld_write_data(nandp, data, datalen, addr, addrlen, NULL); + return retval; +} + +/** + * @brief Read page data without spare area. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] block block number + * @param[in] page page number related to begin of block + * @param[out] data buffer to store data + * @param[in] datalen length of data buffer + * @param[out] ecc pointer to calculated ECC. Ignored when NULL. + * + * @api + */ +void nandReadPageData(NANDDriver *nandp, uint32_t block, uint32_t page, + uint8_t *data, size_t datalen, uint32_t *ecc) { + + const NANDConfig *cfg = nandp->config; + uint8_t addrbuf[8]; + size_t addrlen = cfg->rowcycles + cfg->colcycles; + + osalDbgCheck((nandp != NULL) && (data != NULL)); + osalDbgCheck((datalen <= cfg->page_data_size)); + osalDbgAssert(nandp->state == NAND_READY, "invalid state"); + + calc_addr(cfg, block, page, 0, addrbuf, addrlen); + nand_lld_read_data(nandp, data, datalen, addrbuf, addrlen, ecc); +} + +/** + * @brief Write page data without spare area. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] block block number + * @param[in] page page number related to begin of block + * @param[in] data buffer with data to be written + * @param[in] datalen length of data buffer + * @param[out] ecc pointer to calculated ECC. Ignored when NULL. + * + * @return The operation status reported by NAND IC (0x70 command). + * + * @api + */ +uint8_t nandWritePageData(NANDDriver *nandp, uint32_t block, + uint32_t page, const uint8_t *data, size_t datalen, uint32_t *ecc) { + + uint8_t retval; + const NANDConfig *cfg = nandp->config; + uint8_t addr[8]; + size_t addrlen = cfg->rowcycles + cfg->colcycles; + + osalDbgCheck((nandp != NULL) && (data != NULL)); + osalDbgCheck((datalen <= cfg->page_data_size)); + osalDbgAssert(nandp->state == NAND_READY, "invalid state"); + + calc_addr(cfg, block, page, 0, addr, addrlen); + retval = nand_lld_write_data(nandp, data, datalen, addr, addrlen, ecc); + return retval; +} + +/** + * @brief Read page spare area. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] block block number + * @param[in] page page number related to begin of block + * @param[out] spare buffer to store data + * @param[in] sparelen length of data buffer + * + * @api + */ +void nandReadPageSpare(NANDDriver *nandp, uint32_t block, + uint32_t page, uint8_t *spare, size_t sparelen) { + + const NANDConfig *cfg = nandp->config; + uint8_t addr[8]; + size_t addrlen = cfg->rowcycles + cfg->colcycles; + + osalDbgCheck((NULL != spare) && (nandp != NULL)); + osalDbgCheck(sparelen <= cfg->page_spare_size); + osalDbgAssert(nandp->state == NAND_READY, "invalid state"); + + calc_addr(cfg, block, page, cfg->page_data_size, addr, addrlen); + nand_lld_read_data(nandp, spare, sparelen, addr, addrlen, NULL); +} + +/** + * @brief Write page spare area. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] block block number + * @param[in] page page number related to begin of block + * @param[in] spare buffer with spare data to be written + * @param[in] sparelen length of data buffer + * + * @return The operation status reported by NAND IC (0x70 command). + * + * @api + */ +uint8_t nandWritePageSpare(NANDDriver *nandp, uint32_t block, + uint32_t page, const uint8_t *spare, size_t sparelen) { + + uint8_t retVal; + const NANDConfig *cfg = nandp->config; + uint8_t addr[8]; + size_t addrlen = cfg->rowcycles + cfg->colcycles; + + osalDbgCheck((NULL != spare) && (nandp != NULL)); + osalDbgCheck(sparelen <= cfg->page_spare_size); + osalDbgAssert(nandp->state == NAND_READY, "invalid state"); + + calc_addr(cfg, block, page, cfg->page_data_size, addr, addrlen); + retVal = nand_lld_write_data(nandp, spare, sparelen, addr, addrlen, NULL); + return retVal; +} + +/** + * @brief Mark block as bad. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] block block number + * + * @api + */ +void nandMarkBad(NANDDriver *nandp, uint32_t block) { + + uint8_t bb_mark[2] = {0, 0}; + uint8_t op_status; + op_status = nandWritePageSpare(nandp, block, 0, bb_mark, sizeof(bb_mark)); + osalDbgCheck(0 == (op_status & 1)); /* operation failed*/ + op_status = nandWritePageSpare(nandp, block, 1, bb_mark, sizeof(bb_mark)); + osalDbgCheck(0 == (op_status & 1)); /* operation failed*/ + +#if NAND_USE_BAD_MAP + bad_map_update(nandp, block); +#endif +} + +/** + * @brief Read bad mark out. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] block block number + * @param[in] page page number related to begin of block + * + * @return Bad mark. + * + * @api + */ +uint8_t nandReadBadMark(NANDDriver *nandp, + uint32_t block, uint32_t page) { + uint8_t bb_mark[1]; + nandReadPageSpare(nandp, block, page, bb_mark, sizeof(bb_mark)); + return bb_mark[0]; +} + +/** + * @brief Erase block. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] block block number + * + * @return The operation status reported by NAND IC (0x70 command). + * + * @api + */ +uint8_t nandErase(NANDDriver *nandp, uint32_t block){ + + uint8_t retVal; + const NANDConfig *cfg = nandp->config; + uint8_t addr[4]; + size_t addrlen = cfg->rowcycles; + + osalDbgCheck(nandp != NULL); + osalDbgAssert(nandp->state == NAND_READY, "invalid state"); + + calc_blk_addr(cfg, block, addr, addrlen); + retVal = nand_lld_erase(nandp, addr, addrlen); + return retVal; +} + +/** + * @brief Report block badness. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] block block number + * + * @return block condition + * @retval true if the block is bad. + * @retval false if the block is good. + * + * @api + */ +bool nandIsBad(NANDDriver *nandp, uint32_t block){ + + osalDbgCheck(nandp != NULL); + osalDbgAssert(nandp->state == NAND_READY, "invalid state"); + +#if NAND_USE_BAD_MAP + uint32_t *map = nandp->config->bb_map; + const size_t BPMC = sizeof(uint32_t) * 8; /* bits per map claster */ + size_t i; + size_t shift; + + i = block / BPMC; + shift = block % BPMC; + if (((map[i] >> shift) & 1) == 1) + return true; + else + return false; +#else + uint8_t m0, m1; + m0 = nandReadBadMark(nandp, block, 0); + m1 = nandReadBadMark(nandp, block, 1); + if ((0xFF != m0) || (0xFF != m1)) + return true; + else + return false; +#endif /* NAND_USE_BAD_MAP */ +} + +#if NAND_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) +/** + * @brief Gains exclusive access to the NAND bus. + * @details This function tries to gain ownership to the NAND bus, if the bus + * is already being used then the invoking thread is queued. + * @pre In order to use this function the option + * @p NAND_USE_MUTUAL_EXCLUSION must be enabled. + * + * @param[in] nandp pointer to the @p NANDDriver object + * + * @api + */ +void nandAcquireBus(NANDDriver *nandp) { + + osalDbgCheck(nandp != NULL); + +#if CH_CFG_USE_MUTEXES + chMtxLock(&nandp->mutex); +#elif CH_CFG_USE_SEMAPHORES + chSemWait(&nandp->semaphore); +#endif +} + +/** + * @brief Releases exclusive access to the NAND bus. + * @pre In order to use this function the option + * @p NAND_USE_MUTUAL_EXCLUSION must be enabled. + * + * @param[in] nandp pointer to the @p NANDDriver object + * + * @api + */ +void nandReleaseBus(NANDDriver *nandp) { + + osalDbgCheck(nandp != NULL); + +#if CH_CFG_USE_MUTEXES + chMtxUnlock(&nandp->mutex); +#elif CH_CFG_USE_SEMAPHORES + chSemSignal(&nandp->semaphore); +#endif +} +#endif /* NAND_USE_MUTUAL_EXCLUSION */ + +#endif /* HAL_USE_NAND */ + +/** @} */ + + + + |