aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2015-11-02 10:07:40 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2015-11-02 10:07:40 +0000
commitb8c517e46d35e5c9691545eda8fe9b6c40d6943a (patch)
tree1979780cb2222b6ee45d49fe054343e5cc99fbd8
parentca59ce3238108443bf04729f717f9c37d3472937 (diff)
downloadChibiOS-b8c517e46d35e5c9691545eda8fe9b6c40d6943a.tar.gz
ChibiOS-b8c517e46d35e5c9691545eda8fe9b6c40d6943a.tar.bz2
ChibiOS-b8c517e46d35e5c9691545eda8fe9b6c40d6943a.zip
Lines support in PAL driver.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8417 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r--demos/STM32/RT-STM32F746G-DISCOVERY-LWIP-FATFS-USB/main.c4
-rw-r--r--demos/STM32/RT-STM32F746G-DISCOVERY/main.c8
-rw-r--r--os/hal/boards/ST_STM32F746G_DISCOVERY/board.h210
-rw-r--r--os/hal/boards/ST_STM32F746G_DISCOVERY/cfg/board.chcfg12
-rw-r--r--os/hal/dox/pal.dox2
-rw-r--r--os/hal/include/pal.h102
-rw-r--r--os/hal/ports/STM32/LLD/GPIOv1/pal_lld.h64
-rw-r--r--os/hal/ports/STM32/LLD/GPIOv2/pal_lld.h66
-rw-r--r--os/hal/templates/pal_lld.h51
-rw-r--r--readme.txt3
-rw-r--r--testhal/STM32/STM32F7xx/GPT-ADC/main.c6
-rw-r--r--testhal/STM32/STM32F7xx/PWM-ICU/main.c12
-rw-r--r--testhal/STM32/STM32F7xx/SPI/main.c35
-rw-r--r--testhal/STM32/STM32F7xx/USB_CDC/main.c8
14 files changed, 489 insertions, 94 deletions
diff --git a/demos/STM32/RT-STM32F746G-DISCOVERY-LWIP-FATFS-USB/main.c b/demos/STM32/RT-STM32F746G-DISCOVERY-LWIP-FATFS-USB/main.c
index bcb252bcf..3885ec198 100644
--- a/demos/STM32/RT-STM32F746G-DISCOVERY-LWIP-FATFS-USB/main.c
+++ b/demos/STM32/RT-STM32F746G-DISCOVERY-LWIP-FATFS-USB/main.c
@@ -297,7 +297,7 @@ static THD_FUNCTION(Thread1, arg) {
(void)arg;
chRegSetThreadName("blinker");
while (true) {
- palTogglePad(GPIOI, GPIOI_ARD_D13);
+ palToggleLine(LINE_ARD_D13);
chThdSleepMilliseconds(fs_ready ? 250 : 500);
}
}
@@ -328,7 +328,7 @@ int main(void) {
/*
* Initialize board LED.
*/
- palSetPadMode(GPIOI, GPIOI_ARD_D13, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetLineMode(LINE_ARD_D13, PAL_MODE_OUTPUT_PUSHPULL);
/*
* Initializes a serial-over-USB CDC driver.
diff --git a/demos/STM32/RT-STM32F746G-DISCOVERY/main.c b/demos/STM32/RT-STM32F746G-DISCOVERY/main.c
index c14bcf0cb..eea6da024 100644
--- a/demos/STM32/RT-STM32F746G-DISCOVERY/main.c
+++ b/demos/STM32/RT-STM32F746G-DISCOVERY/main.c
@@ -28,9 +28,9 @@ static THD_FUNCTION(Thread1, arg) {
(void)arg;
chRegSetThreadName("blinker");
while (true) {
- palSetPad(GPIOI, GPIOI_ARD_D13);
+ palSetLine(LINE_ARD_D13);
chThdSleepMilliseconds(500);
- palClearPad(GPIOI, GPIOI_ARD_D13);
+ palClearLine(LINE_ARD_D13);
chThdSleepMilliseconds(500);
}
}
@@ -53,8 +53,8 @@ int main(void) {
/*
* GPIOI1 is programmed as output (board LED).
*/
- palClearPad(GPIOI, GPIOI_ARD_D13);
- palSetPadMode(GPIOI, GPIOI_ARD_D13, PAL_MODE_OUTPUT_PUSHPULL);
+ palClearLine(LINE_ARD_D13);
+ palSetLineMode(LINE_ARD_D13, PAL_MODE_OUTPUT_PUSHPULL);
/*
* Activates the serial driver 1 using the driver default configuration.
diff --git a/os/hal/boards/ST_STM32F746G_DISCOVERY/board.h b/os/hal/boards/ST_STM32F746G_DISCOVERY/board.h
index 5237d95c5..bfe13a4fc 100644
--- a/os/hal/boards/ST_STM32F746G_DISCOVERY/board.h
+++ b/os/hal/boards/ST_STM32F746G_DISCOVERY/board.h
@@ -238,7 +238,7 @@
#define GPIOK_LCD_G5 0U
#define GPIOK_LCD_G6 1U
#define GPIOK_LCD_G7 2U
-#define GPIOK_LCD_B4 3U
+#define GPIOK_LCD_BL_CTRL 3U
#define GPIOK_LCD_B5 4U
#define GPIOK_LCD_B6 5U
#define GPIOK_LCD_B7 6U
@@ -253,6 +253,196 @@
#define GPIOK_PIN15 15U
/*
+ * IO lines assignments.
+ */
+#define LINE_ARD_A0 PAL_LINE(GPIOA, 0U)
+#define LINE_RMII_REF_CLK PAL_LINE(GPIOA, 1U)
+#define LINE_RMII_MDIO PAL_LINE(GPIOA, 2U)
+#define LINE_ULPI_D0 PAL_LINE(GPIOA, 3U)
+#define LINE_DCMI_HSYNC PAL_LINE(GPIOA, 4U)
+#define LINE_ULPI_CK PAL_LINE(GPIOA, 5U)
+#define LINE_DCMI_PIXCK PAL_LINE(GPIOA, 6U)
+#define LINE_RMII_CRS_DV PAL_LINE(GPIOA, 7U)
+#define LINE_ARD_D5 PAL_LINE(GPIOA, 8U)
+#define LINE_VCP_TX PAL_LINE(GPIOA, 9U)
+#define LINE_OTG_FS_ID PAL_LINE(GPIOA, 10U)
+#define LINE_OTG_FS_DM PAL_LINE(GPIOA, 11U)
+#define LINE_OTG_FS_DP PAL_LINE(GPIOA, 12U)
+#define LINE_SWDIO PAL_LINE(GPIOA, 13U)
+#define LINE_SWCLK PAL_LINE(GPIOA, 14U)
+#define LINE_ARD_D9 PAL_LINE(GPIOA, 15U)
+
+#define LINE_ULPI_D1 PAL_LINE(GPIOB, 0U)
+#define LINE_ULPI_D2 PAL_LINE(GPIOB, 1U)
+#define LINE_QSPI_CLK PAL_LINE(GPIOB, 2U)
+#define LINE_SWO PAL_LINE(GPIOB, 3U)
+#define LINE_ARD_D3 PAL_LINE(GPIOB, 4U)
+#define LINE_ULPI_D7 PAL_LINE(GPIOB, 5U)
+#define LINE_QSPI_NCS PAL_LINE(GPIOB, 6U)
+#define LINE_VCP_RX PAL_LINE(GPIOB, 7U)
+#define LINE_ARD_D15 PAL_LINE(GPIOB, 8U)
+#define LINE_ARD_D14 PAL_LINE(GPIOB, 9U)
+#define LINE_ULPI_D3 PAL_LINE(GPIOB, 10U)
+#define LINE_ULPI_D4 PAL_LINE(GPIOB, 11U)
+#define LINE_ULPI_D5 PAL_LINE(GPIOB, 12U)
+#define LINE_ULPI_D6 PAL_LINE(GPIOB, 13U)
+#define LINE_ARD_D12 PAL_LINE(GPIOB, 14U)
+#define LINE_ARD_D11 PAL_LINE(GPIOB, 15U)
+
+#define LINE_ULPI_STP PAL_LINE(GPIOC, 0U)
+#define LINE_RMII_MDC PAL_LINE(GPIOC, 1U)
+#define LINE_ULPI_DIR PAL_LINE(GPIOC, 2U)
+#define LINE_FMC_SDCKE0 PAL_LINE(GPIOC, 3U)
+#define LINE_RMII_RXD0 PAL_LINE(GPIOC, 4U)
+#define LINE_RMII_RXD1 PAL_LINE(GPIOC, 5U)
+#define LINE_ARD_D1 PAL_LINE(GPIOC, 6U)
+#define LINE_ARD_D0 PAL_LINE(GPIOC, 7U)
+#define LINE_SD_D0 PAL_LINE(GPIOC, 8U)
+#define LINE_SD_D1 PAL_LINE(GPIOC, 9U)
+#define LINE_SD_D2 PAL_LINE(GPIOC, 10U)
+#define LINE_SD_D3 PAL_LINE(GPIOC, 11U)
+#define LINE_SD_CLK PAL_LINE(GPIOC, 12U)
+#define LINE_SD_DETECT PAL_LINE(GPIOC, 13U)
+#define LINE_OSC32_IN PAL_LINE(GPIOC, 14U)
+#define LINE_OSC32_OUT PAL_LINE(GPIOC, 15U)
+
+#define LINE_FMC_D2 PAL_LINE(GPIOD, 0U)
+#define LINE_FMC_D3 PAL_LINE(GPIOD, 1U)
+#define LINE_SD_CMD PAL_LINE(GPIOD, 2U)
+#define LINE_DCMI_D5 PAL_LINE(GPIOD, 3U)
+#define LINE_OTG_FS_OVER_CURRENT PAL_LINE(GPIOD, 4U)
+#define LINE_OTG_FS_PWR_SW_ON PAL_LINE(GPIOD, 5U)
+#define LINE_AUDIO_INT PAL_LINE(GPIOD, 6U)
+#define LINE_SPDIF_RX0 PAL_LINE(GPIOD, 7U)
+#define LINE_FMC_D13 PAL_LINE(GPIOD, 8U)
+#define LINE_FMC_D14 PAL_LINE(GPIOD, 9U)
+#define LINE_FMC_D15 PAL_LINE(GPIOD, 10U)
+#define LINE_QSPI_D0 PAL_LINE(GPIOD, 11U)
+#define LINE_QSPI_D1 PAL_LINE(GPIOD, 12U)
+#define LINE_QSPI_D3 PAL_LINE(GPIOD, 13U)
+#define LINE_FMC_D0 PAL_LINE(GPIOD, 14U)
+#define LINE_FMC_D1 PAL_LINE(GPIOD, 15U)
+
+#define LINE_FMC_NBL0 PAL_LINE(GPIOE, 0U)
+#define LINE_FMC_NBL1 PAL_LINE(GPIOE, 1U)
+#define LINE_QSPI_D2 PAL_LINE(GPIOE, 2U)
+#define LINE_OTG_HS_OVER_CURRENT PAL_LINE(GPIOE, 3U)
+#define LINE_LCD_B0 PAL_LINE(GPIOE, 4U)
+#define LINE_DCMI_D6 PAL_LINE(GPIOE, 5U)
+#define LINE_DCMI_D7 PAL_LINE(GPIOE, 6U)
+#define LINE_FMC_D4 PAL_LINE(GPIOE, 7U)
+#define LINE_FMC_D5 PAL_LINE(GPIOE, 8U)
+#define LINE_FMC_D6 PAL_LINE(GPIOE, 9U)
+#define LINE_FMC_D7 PAL_LINE(GPIOE, 10U)
+#define LINE_FMC_D8 PAL_LINE(GPIOE, 11U)
+#define LINE_FMC_D9 PAL_LINE(GPIOE, 12U)
+#define LINE_FMC_D10 PAL_LINE(GPIOE, 13U)
+#define LINE_FMC_11 PAL_LINE(GPIOE, 14U)
+#define LINE_FMC_D12 PAL_LINE(GPIOE, 15U)
+
+#define LINE_FMC_A0 PAL_LINE(GPIOF, 0U)
+#define LINE_FMC_A1 PAL_LINE(GPIOF, 1U)
+#define LINE_FMC_A2 PAL_LINE(GPIOF, 2U)
+#define LINE_FMC_A3 PAL_LINE(GPIOF, 3U)
+#define LINE_FMC_A4 PAL_LINE(GPIOF, 4U)
+#define LINE_FMC_A5 PAL_LINE(GPIOF, 5U)
+#define LINE_ARD_A5 PAL_LINE(GPIOF, 6U)
+#define LINE_ARD_A4 PAL_LINE(GPIOF, 7U)
+#define LINE_ARD_A3 PAL_LINE(GPIOF, 8U)
+#define LINE_ARD_A2 PAL_LINE(GPIOF, 9U)
+#define LINE_ARD_A1 PAL_LINE(GPIOF, 10U)
+#define LINE_FMC_SDNRAS PAL_LINE(GPIOF, 11U)
+#define LINE_FMC_A6 PAL_LINE(GPIOF, 12U)
+#define LINE_FMC_A7 PAL_LINE(GPIOF, 13U)
+#define LINE_FMC_A8 PAL_LINE(GPIOF, 14U)
+#define LINE_FMC_A9 PAL_LINE(GPIOF, 15U)
+
+#define LINE_FMC_A10 PAL_LINE(GPIOG, 0U)
+#define LINE_FMC_A11 PAL_LINE(GPIOG, 1U)
+#define LINE_RMII_RXER PAL_LINE(GPIOG, 2U)
+#define LINE_EXT_RST PAL_LINE(GPIOG, 3U)
+#define LINE_FMC_BA0 PAL_LINE(GPIOG, 4U)
+#define LINE_FMC_BA1 PAL_LINE(GPIOG, 5U)
+#define LINE_ARD_D2 PAL_LINE(GPIOG, 6U)
+#define LINE_ARD_D4 PAL_LINE(GPIOG, 7U)
+#define LINE_FMC_SDCLK PAL_LINE(GPIOG, 8U)
+#define LINE_DCMI_VSYNC PAL_LINE(GPIOG, 9U)
+#define LINE_SAI2_SDB PAL_LINE(GPIOG, 10U)
+#define LINE_RMII_TX_EN PAL_LINE(GPIOG, 11U)
+#define LINE_LCD_B4 PAL_LINE(GPIOG, 12U)
+#define LINE_RMII_TXD0 PAL_LINE(GPIOG, 13U)
+#define LINE_RMII_TXD1 PAL_LINE(GPIOG, 14U)
+#define LINE_FMC_SDNCAS PAL_LINE(GPIOG, 15U)
+
+#define LINE_OSC_IN PAL_LINE(GPIOH, 0U)
+#define LINE_OSC_OUT PAL_LINE(GPIOH, 1U)
+#define LINE_TP1 PAL_LINE(GPIOH, 2U)
+#define LINE_FMC_SDNE0 PAL_LINE(GPIOH, 3U)
+#define LINE_ULPI_NXT PAL_LINE(GPIOH, 4U)
+#define LINE_FMC_SDNWE PAL_LINE(GPIOH, 5U)
+#define LINE_ARD_D6 PAL_LINE(GPIOH, 6U)
+#define LINE_LCD_SCL PAL_LINE(GPIOH, 7U)
+#define LINE_LCD_SDA PAL_LINE(GPIOH, 8U)
+#define LINE_DCMI_D0 PAL_LINE(GPIOH, 9U)
+#define LINE_DCMI_D1 PAL_LINE(GPIOH, 10U)
+#define LINE_DCMI_D2 PAL_LINE(GPIOH, 11U)
+#define LINE_DCMI_D3 PAL_LINE(GPIOH, 12U)
+#define LINE_DCMI_PWR_EN PAL_LINE(GPIOH, 13U)
+#define LINE_DCMI_D4 PAL_LINE(GPIOH, 14U)
+#define LINE_TP_PH15 PAL_LINE(GPIOH, 15U)
+
+#define LINE_ARD_D10 PAL_LINE(GPIOI, 0U)
+#define LINE_ARD_D13 PAL_LINE(GPIOI, 1U)
+#define LINE_ARD_D8 PAL_LINE(GPIOI, 2U)
+#define LINE_ARD_D7 PAL_LINE(GPIOI, 3U)
+#define LINE_SAI2_MCLKA PAL_LINE(GPIOI, 4U)
+#define LINE_SAI2_SCKA PAL_LINE(GPIOI, 5U)
+#define LINE_SAI2_SDA PAL_LINE(GPIOI, 6U)
+#define LINE_SAI2_FSA PAL_LINE(GPIOI, 7U)
+#define LINE_TP2 PAL_LINE(GPIOI, 8U)
+#define LINE_LCD_VSYNC PAL_LINE(GPIOI, 9U)
+#define LINE_LCD_HSYNC PAL_LINE(GPIOI, 10U)
+#define LINE_BUTTON_USER PAL_LINE(GPIOI, 11U)
+#define LINE_LCD_DISP PAL_LINE(GPIOI, 12U)
+#define LINE_LCD_INT PAL_LINE(GPIOI, 13U)
+#define LINE_LCD_CLK PAL_LINE(GPIOI, 14U)
+#define LINE_LCD_R0 PAL_LINE(GPIOI, 15U)
+
+#define LINE_LCD_R1 PAL_LINE(GPIOJ, 0U)
+#define LINE_LCD_R2 PAL_LINE(GPIOJ, 1U)
+#define LINE_LCD_R3 PAL_LINE(GPIOJ, 2U)
+#define LINE_LCD_R4 PAL_LINE(GPIOJ, 3U)
+#define LINE_LCD_R5 PAL_LINE(GPIOJ, 4U)
+#define LINE_LCD_R6 PAL_LINE(GPIOJ, 5U)
+#define LINE_LCD_R7 PAL_LINE(GPIOJ, 6U)
+#define LINE_LCD_G0 PAL_LINE(GPIOJ, 7U)
+#define LINE_LCD_G1 PAL_LINE(GPIOJ, 8U)
+#define LINE_LCD_G2 PAL_LINE(GPIOJ, 9U)
+#define LINE_LCD_G3 PAL_LINE(GPIOJ, 10U)
+#define LINE_LCD_G4 PAL_LINE(GPIOJ, 11U)
+#define LINE_OTG_FS_VBUS PAL_LINE(GPIOJ, 12U)
+#define LINE_LCD_B1 PAL_LINE(GPIOJ, 13U)
+#define LINE_LCD_B2 PAL_LINE(GPIOJ, 14U)
+#define LINE_LCD_B3 PAL_LINE(GPIOJ, 15U)
+
+#define LINE_LCD_G5 PAL_LINE(GPIOK, 0U)
+#define LINE_LCD_G6 PAL_LINE(GPIOK, 1U)
+#define LINE_LCD_G7 PAL_LINE(GPIOK, 2U)
+#define LINE_LCD_BL_CTRL PAL_LINE(GPIOK, 3U)
+#define LINE_LCD_B5 PAL_LINE(GPIOK, 4U)
+#define LINE_LCD_B6 PAL_LINE(GPIOK, 5U)
+#define LINE_LCD_B7 PAL_LINE(GPIOK, 6U)
+#define LINE_LCD_DE PAL_LINE(GPIOK, 7U)
+#define LINE_PIN8 PAL_LINE(GPIOK, 8U)
+#define LINE_PIN9 PAL_LINE(GPIOK, 9U)
+#define LINE_PIN10 PAL_LINE(GPIOK, 10U)
+#define LINE_PIN11 PAL_LINE(GPIOK, 11U)
+#define LINE_PIN12 PAL_LINE(GPIOK, 12U)
+#define LINE_PIN13 PAL_LINE(GPIOK, 13U)
+#define LINE_PIN14 PAL_LINE(GPIOK, 14U)
+#define LINE_PIN15 PAL_LINE(GPIOK, 15U)
+
+/*
* 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.
@@ -991,7 +1181,7 @@
* PG9 - DCMI_VSYNC (input pullup).
* PG10 - SAI2_SDB (input pullup).
* PG11 - RMII_TX_EN (alternate 11).
- * PG12 - LCD_B4 (alternate 14).
+ * PG12 - LCD_B4 (alternate 9).
* PG13 - RMII_TXD0 (alternate 11).
* PG14 - RMII_TXD1 (alternate 11).
* PG15 - FMC_SDNCAS (alternate 12).
@@ -1088,7 +1278,7 @@
PIN_AFIO_AF(GPIOG_DCMI_VSYNC, 0) | \
PIN_AFIO_AF(GPIOG_SAI2_SDB, 0) | \
PIN_AFIO_AF(GPIOG_RMII_TX_EN, 11) | \
- PIN_AFIO_AF(GPIOG_LCD_B4, 14) | \
+ PIN_AFIO_AF(GPIOG_LCD_B4, 9) | \
PIN_AFIO_AF(GPIOG_RMII_TXD0, 11) | \
PIN_AFIO_AF(GPIOG_RMII_TXD1, 11) | \
PIN_AFIO_AF(GPIOG_FMC_SDNCAS, 12))
@@ -1450,7 +1640,7 @@
* PK0 - LCD_G5 (alternate 14).
* PK1 - LCD_G6 (alternate 14).
* PK2 - LCD_G7 (alternate 14).
- * PK3 - LCD_B4 (alternate 14).
+ * PK3 - LCD_BL_CTRL (output pushpull minimum).
* PK4 - LCD_B5 (alternate 14).
* PK5 - LCD_B6 (alternate 14).
* PK6 - LCD_B7 (alternate 14).
@@ -1467,7 +1657,7 @@
#define VAL_GPIOK_MODER (PIN_MODE_ALTERNATE(GPIOK_LCD_G5) | \
PIN_MODE_ALTERNATE(GPIOK_LCD_G6) | \
PIN_MODE_ALTERNATE(GPIOK_LCD_G7) | \
- PIN_MODE_ALTERNATE(GPIOK_LCD_B4) | \
+ PIN_MODE_OUTPUT(GPIOK_LCD_BL_CTRL) | \
PIN_MODE_ALTERNATE(GPIOK_LCD_B5) | \
PIN_MODE_ALTERNATE(GPIOK_LCD_B6) | \
PIN_MODE_ALTERNATE(GPIOK_LCD_B7) | \
@@ -1483,7 +1673,7 @@
#define VAL_GPIOK_OTYPER (PIN_OTYPE_PUSHPULL(GPIOK_LCD_G5) | \
PIN_OTYPE_PUSHPULL(GPIOK_LCD_G6) | \
PIN_OTYPE_PUSHPULL(GPIOK_LCD_G7) | \
- PIN_OTYPE_PUSHPULL(GPIOK_LCD_B4) | \
+ PIN_OTYPE_PUSHPULL(GPIOK_LCD_BL_CTRL) |\
PIN_OTYPE_PUSHPULL(GPIOK_LCD_B5) | \
PIN_OTYPE_PUSHPULL(GPIOK_LCD_B6) | \
PIN_OTYPE_PUSHPULL(GPIOK_LCD_B7) | \
@@ -1499,7 +1689,7 @@
#define VAL_GPIOK_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOK_LCD_G5) | \
PIN_OSPEED_VERYLOW(GPIOK_LCD_G6) | \
PIN_OSPEED_VERYLOW(GPIOK_LCD_G7) | \
- PIN_OSPEED_VERYLOW(GPIOK_LCD_B4) | \
+ PIN_OSPEED_VERYLOW(GPIOK_LCD_BL_CTRL) |\
PIN_OSPEED_VERYLOW(GPIOK_LCD_B5) | \
PIN_OSPEED_VERYLOW(GPIOK_LCD_B6) | \
PIN_OSPEED_VERYLOW(GPIOK_LCD_B7) | \
@@ -1515,7 +1705,7 @@
#define VAL_GPIOK_PUPDR (PIN_PUPDR_FLOATING(GPIOK_LCD_G5) | \
PIN_PUPDR_FLOATING(GPIOK_LCD_G6) | \
PIN_PUPDR_FLOATING(GPIOK_LCD_G7) | \
- PIN_PUPDR_FLOATING(GPIOK_LCD_B4) | \
+ PIN_PUPDR_FLOATING(GPIOK_LCD_BL_CTRL) |\
PIN_PUPDR_FLOATING(GPIOK_LCD_B5) | \
PIN_PUPDR_FLOATING(GPIOK_LCD_B6) | \
PIN_PUPDR_FLOATING(GPIOK_LCD_B7) | \
@@ -1531,7 +1721,7 @@
#define VAL_GPIOK_ODR (PIN_ODR_HIGH(GPIOK_LCD_G5) | \
PIN_ODR_HIGH(GPIOK_LCD_G6) | \
PIN_ODR_HIGH(GPIOK_LCD_G7) | \
- PIN_ODR_HIGH(GPIOK_LCD_B4) | \
+ PIN_ODR_LOW(GPIOK_LCD_BL_CTRL) | \
PIN_ODR_HIGH(GPIOK_LCD_B5) | \
PIN_ODR_HIGH(GPIOK_LCD_B6) | \
PIN_ODR_HIGH(GPIOK_LCD_B7) | \
@@ -1547,7 +1737,7 @@
#define VAL_GPIOK_AFRL (PIN_AFIO_AF(GPIOK_LCD_G5, 14) | \
PIN_AFIO_AF(GPIOK_LCD_G6, 14) | \
PIN_AFIO_AF(GPIOK_LCD_G7, 14) | \
- PIN_AFIO_AF(GPIOK_LCD_B4, 14) | \
+ PIN_AFIO_AF(GPIOK_LCD_BL_CTRL, 0) | \
PIN_AFIO_AF(GPIOK_LCD_B5, 14) | \
PIN_AFIO_AF(GPIOK_LCD_B6, 14) | \
PIN_AFIO_AF(GPIOK_LCD_B7, 14) | \
diff --git a/os/hal/boards/ST_STM32F746G_DISCOVERY/cfg/board.chcfg b/os/hal/boards/ST_STM32F746G_DISCOVERY/cfg/board.chcfg
index ecd64ea91..5dddc2ffb 100644
--- a/os/hal/boards/ST_STM32F746G_DISCOVERY/cfg/board.chcfg
+++ b/os/hal/boards/ST_STM32F746G_DISCOVERY/cfg/board.chcfg
@@ -916,7 +916,7 @@
Speed="Maximum"
Resistor="Floating"
Mode="Alternate"
- Alternate="14" />
+ Alternate="9" />
<pin13
ID="RMII_TXD0"
Type="PushPull"
@@ -1358,13 +1358,13 @@
Mode="Alternate"
Alternate="14" />
<pin3
- ID="LCD_B4"
+ ID="LCD_BL_CTRL"
Type="PushPull"
Speed="Minimum"
Resistor="Floating"
- Level="High"
- Mode="Alternate"
- Alternate="14" />
+ Level="Low"
+ Mode="Output"
+ Alternate="0" />
<pin4
ID="LCD_B5"
Type="PushPull"
@@ -1372,7 +1372,7 @@
Resistor="Floating"
Level="High"
Mode="Alternate"
- Alternate="14" />
+ Alternate="14" ></pin4>
<pin5
ID="LCD_B6"
Type="PushPull"
diff --git a/os/hal/dox/pal.dox b/os/hal/dox/pal.dox
index 6ba7bbd00..06915e24a 100644
--- a/os/hal/dox/pal.dox
+++ b/os/hal/dox/pal.dox
@@ -23,7 +23,7 @@
* PAL Low Level Driver if the target hardware supports special
* features like, for example, atomic bit set/reset/masking. Please
* refer to the ports specific documentation for details.<br>
- * The @ref PAL has the advantage to make the access to the I/O
+ * The @ref PAL driver has the advantage to make the access to the I/O
* ports platform independent and still be optimized for the specific
* architectures.<br>
* Note that the PAL Low Level Driver may also offer non standard
diff --git a/os/hal/include/pal.h b/os/hal/include/pal.h
index 49f8e182e..604a04956 100644
--- a/os/hal/include/pal.h
+++ b/os/hal/include/pal.h
@@ -126,7 +126,7 @@ typedef struct {
ioportid_t portid;
/**
* @brief Bus mask aligned to port bit 0.
- * @note The bus mask implicitly define the bus width. A logical AND is
+ * @note The bus mask implicitly define the bus width. A logic AND is
* performed on the bus data.
*/
ioportmask_t mask;
@@ -210,7 +210,7 @@ typedef struct {
* @note The function can be called from any context.
*
* @param[in] port port identifier
- * @return The port logical states.
+ * @return The port logic states.
*
* @special
*/
@@ -229,7 +229,7 @@ typedef struct {
* @note The function can be called from any context.
*
* @param[in] port port identifier
- * @return The latched logical states.
+ * @return The latched logic states.
*
* @special
*/
@@ -330,10 +330,10 @@ typedef struct {
* @note The function can be called from any context.
*
* @param[in] port port identifier
- * @param[in] mask group mask, a logical AND is performed on the input
+ * @param[in] mask group mask, a logic AND is performed on the input
* data
* @param[in] offset group bit offset within the port
- * @return The group logical states.
+ * @return The group logic states.
*
* @special
*/
@@ -349,7 +349,7 @@ typedef struct {
* @note The function can be called from any context.
*
* @param[in] port port identifier
- * @param[in] mask group mask, a logical AND is performed on the
+ * @param[in] mask group mask, a logic AND is performed on the
* output data
* @param[in] offset group bit offset within the port
* @param[in] bits bits to be written. Values exceeding the group
@@ -389,7 +389,7 @@ typedef struct {
#endif
/**
- * @brief Reads an input pad logical state.
+ * @brief Reads an input pad logic state.
* @note The default implementation not necessarily optimal. Low level
* drivers may optimize the function by using specific hardware
* or coding.
@@ -398,9 +398,9 @@ typedef struct {
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
- * @return The logical state.
- * @retval PAL_LOW low logical state.
- * @retval PAL_HIGH high logical state.
+ * @return The logic state.
+ * @retval PAL_LOW low logic state.
+ * @retval PAL_HIGH high logic state.
*
* @special
*/
@@ -411,7 +411,7 @@ typedef struct {
#endif
/**
- * @brief Writes a logical state on an output pad.
+ * @brief Writes a logic state on an output pad.
* @note The operation is not guaranteed to be atomic on all the
* architectures, for atomicity and/or portability reasons you may
* need to enclose port I/O operations between @p chSysLock() and
@@ -425,7 +425,7 @@ typedef struct {
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
- * @param[in] bit logical value, the value must be @p PAL_LOW or
+ * @param[in] bit logic value, the value must be @p PAL_LOW or
* @p PAL_HIGH
*
* @special
@@ -439,7 +439,7 @@ typedef struct {
#endif
/**
- * @brief Sets a pad logical state to @p PAL_HIGH.
+ * @brief Sets a pad logic state to @p PAL_HIGH.
* @note The operation is not guaranteed to be atomic on all the
* architectures, for atomicity and/or portability reasons you may
* need to enclose port I/O operations between @p chSysLock() and
@@ -462,7 +462,7 @@ typedef struct {
#endif
/**
- * @brief Clears a pad logical state to @p PAL_LOW.
+ * @brief Clears a pad logic state to @p PAL_LOW.
* @note The operation is not guaranteed to be atomic on all the
* architectures, for atomicity and/or portability reasons you may
* need to enclose port I/O operations between @p chSysLock() and
@@ -485,7 +485,7 @@ typedef struct {
#endif
/**
- * @brief Toggles a pad logical state.
+ * @brief Toggles a pad logic state.
* @note The operation is not guaranteed to be atomic on all the
* architectures, for atomicity and/or portability reasons you may
* need to enclose port I/O operations between @p chSysLock() and
@@ -528,6 +528,78 @@ typedef struct {
#else
#define palSetPadMode(port, pad, mode) pal_lld_setpadmode(port, pad, mode)
#endif
+
+/**
+ * @brief Reads an input line logic state.
+ * @note The function can be called from any context.
+ *
+ * @param[in] line line identifier
+ * @return The logic state.
+ * @retval PAL_LOW low logic state.
+ * @retval PAL_HIGH high logic state.
+ *
+ * @special
+ */
+#define palReadLine(line) \
+ palReadPad(PAL_PORT(line), PAL_PAD(line))
+
+/**
+ * @brief Writes a logic state on an output line.
+ * @note The function can be called from any context.
+ *
+ * @param[in] line line identifier
+ * @param[in] bit logic value, the value must be @p PAL_LOW or
+ * @p PAL_HIGH
+ *
+ * @special
+ */
+#define palWriteLine(pin, bit) \
+ palWrite(PAL_PORT(line), PAL_PAD(line), bit)
+
+/**
+ * @brief Sets a line logic state to @p PAL_HIGH.
+ * @note The function can be called from any context.
+ *
+ * @param[in] line line identifier
+ *
+ * @special
+ */
+#define palSetLine(line) \
+ palSetPad(PAL_PORT(line), PAL_PAD(line))
+
+/**
+ * @brief Clears a line logic state to @p PAL_LOW.
+ * @note The function can be called from any context.
+ *
+ * @param[in] line line identifier
+ *
+ * @special
+ */
+#define palClearLine(line) \
+ palClearPad(PAL_PORT(line), PAL_PAD(line))
+
+/**
+ * @brief Toggles a line logic state.
+ * @note The function can be called from any context.
+ *
+ * @param[in] line line identifier
+ *
+ * @special
+ */
+#define palToggleLine(line) \
+ palTogglePad(PAL_PORT(line), PAL_PAD(line))
+
+/**
+ * @brief Line mode setup.
+ * @note The function can be called from any context.
+ *
+ * @param[in] line line identifier
+ * @param[in] mode pad mode
+ *
+ * @special
+ */
+#define palSetLineMode(line, mode) \
+ palSetPadMode(PAL_PORT(line), PAL_PAD(line), mode)
/** @} */
/*===========================================================================*/
diff --git a/os/hal/ports/STM32/LLD/GPIOv1/pal_lld.h b/os/hal/ports/STM32/LLD/GPIOv1/pal_lld.h
index c083ca0ff..bf84466c3 100644
--- a/os/hal/ports/STM32/LLD/GPIOv1/pal_lld.h
+++ b/os/hal/ports/STM32/LLD/GPIOv1/pal_lld.h
@@ -51,6 +51,54 @@
/*===========================================================================*/
/**
+ * @name Port related definitions
+ * @{
+ */
+/**
+ * @brief Width, in bits, of an I/O port.
+ */
+#define PAL_IOPORTS_WIDTH 16
+
+/**
+ * @brief Whole port mask.
+ * @details This macro specifies all the valid bits into a port.
+ */
+#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFF)
+/** @} */
+
+/**
+ * @name Line handling macros
+ * @{
+ */
+/**
+ * @brief Forms a line identifier.
+ * @details A port/pad pair are encoded into an @p ioline_t type. The encoding
+ * of this type is platform-dependent.
+ * @note In this driver the pad number is encoded in the lower 4 bits of
+ * the GPIO address which are guaranteed to be zero.
+ */
+#define PAL_LINE(port, pad) \
+ ((ioline_t)((uint32_t)(port)) | ((uint32_t)(pad)))
+
+/**
+ * @brief Decodes a port identifier from a line identifier.
+ */
+#define PAL_PORT(line) \
+ ((stm32_gpio_t *)(((uint32_t)(line)) & 0xFFFFFFF0U))
+
+/**
+ * @brief Decodes a pad identifier from a line identifier.
+ */
+#define PAL_PAD(line) \
+ ((uint32_t)((uint32_t)(line) & 0x0000000FU))
+
+/**
+ * @brief Value identifying an invalid line.
+ */
+#define PAL_NOLINE 0U
+/** @} */
+
+/**
* @brief GPIO port setup info.
*/
typedef struct {
@@ -93,17 +141,6 @@ typedef struct {
} PALConfig;
/**
- * @brief Width, in bits, of an I/O port.
- */
-#define PAL_IOPORTS_WIDTH 16
-
-/**
- * @brief Whole port mask.
- * @details This macro specifies all the valid bits into a port.
- */
-#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFF)
-
-/**
* @brief Digital I/O port sized unsigned type.
*/
typedef uint32_t ioportmask_t;
@@ -114,6 +151,11 @@ typedef uint32_t ioportmask_t;
typedef uint32_t iomode_t;
/**
+ * @brief Type of an I/O line.
+ */
+typedef uint32_t ioline_t;
+
+/**
* @brief Port Identifier.
* @details This type can be a scalar or some kind of pointer, do not make
* any assumption about it, use the provided macros when populating
diff --git a/os/hal/ports/STM32/LLD/GPIOv2/pal_lld.h b/os/hal/ports/STM32/LLD/GPIOv2/pal_lld.h
index a9f40b905..d17063564 100644
--- a/os/hal/ports/STM32/LLD/GPIOv2/pal_lld.h
+++ b/os/hal/ports/STM32/LLD/GPIOv2/pal_lld.h
@@ -168,6 +168,54 @@
/*===========================================================================*/
/**
+ * @name Port related definitions
+ * @{
+ */
+/**
+ * @brief Width, in bits, of an I/O port.
+ */
+#define PAL_IOPORTS_WIDTH 16
+
+/**
+ * @brief Whole port mask.
+ * @details This macro specifies all the valid bits into a port.
+ */
+#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFF)
+/** @} */
+
+/**
+ * @name Line handling macros
+ * @{
+ */
+/**
+ * @brief Forms a line identifier.
+ * @details A port/pad pair are encoded into an @p ioline_t type. The encoding
+ * of this type is platform-dependent.
+ * @note In this driver the pad number is encoded in the lower 4 bits of
+ * the GPIO address which are guaranteed to be zero.
+ */
+#define PAL_LINE(port, pad) \
+ ((ioline_t)((uint32_t)(port)) | ((uint32_t)(pad)))
+
+/**
+ * @brief Decodes a port identifier from a line identifier.
+ */
+#define PAL_PORT(line) \
+ ((stm32_gpio_t *)(((uint32_t)(line)) & 0xFFFFFFF0U))
+
+/**
+ * @brief Decodes a pad identifier from a line identifier.
+ */
+#define PAL_PAD(line) \
+ ((uint32_t)((uint32_t)(line) & 0x0000000FU))
+
+/**
+ * @brief Value identifying an invalid line.
+ */
+#define PAL_NOLINE 0U
+/** @} */
+
+/**
* @brief STM32 GPIO registers block.
*/
typedef struct {
@@ -266,25 +314,19 @@ typedef struct {
} PALConfig;
/**
- * @brief Width, in bits, of an I/O port.
+ * @brief Type of digital I/O port sized unsigned integer.
*/
-#define PAL_IOPORTS_WIDTH 16
-
-/**
- * @brief Whole port mask.
- * @details This macro specifies all the valid bits into a port.
- */
-#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFF)
+typedef uint32_t ioportmask_t;
/**
- * @brief Digital I/O port sized unsigned type.
+ * @brief Type of digital I/O modes.
*/
-typedef uint32_t ioportmask_t;
+typedef uint32_t iomode_t;
/**
- * @brief Digital I/O modes.
+ * @brief Type of an I/O line.
*/
-typedef uint32_t iomode_t;
+typedef uint32_t ioline_t;
/**
* @brief Port Identifier.
diff --git a/os/hal/templates/pal_lld.h b/os/hal/templates/pal_lld.h
index 71a85d1d9..d8be65452 100644
--- a/os/hal/templates/pal_lld.h
+++ b/os/hal/templates/pal_lld.h
@@ -36,6 +36,52 @@
/*===========================================================================*/
/**
+ * @name Port related definitions
+ * @{
+ */
+/**
+ * @brief Width, in bits, of an I/O port.
+ */
+#define PAL_IOPORTS_WIDTH 16
+
+/**
+ * @brief Whole port mask.
+ * @details This macro specifies all the valid bits into a port.
+ */
+#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFF)
+/** @} */
+
+/**
+ * @name Line handling macros
+ * @{
+ */
+/**
+ * @brief Forms a line identifier.
+ * @details A port/pad pair are encoded into an @p ioline_t type. The encoding
+ * of this type is platform-dependent.
+ */
+#define PAL_LINE(port, pad) \
+ ((ioline_t)((uint32_t)(port)) | ((uint32_t)(pad)))
+
+/**
+ * @brief Decodes a port identifier from a line identifier.
+ */
+#define PAL_PORT(line) \
+ ((stm32_gpio_t *)(((uint32_t)(line)) & 0xFFFFFFF0U))
+
+/**
+ * @brief Decodes a pad identifier from a line identifier.
+ */
+#define PAL_PAD(line) \
+ ((uint32_t)((uint32_t)(line) & 0x0000000FU))
+
+/**
+ * @brief Value identifying an invalid line.
+ */
+#define PAL_NOLINE 0U
+/** @} */
+
+/**
* @brief Generic I/O ports static initializer.
* @details An instance of this structure must be passed to @p palInit() at
* system startup time in order to initialized the digital I/O
@@ -70,6 +116,11 @@ typedef uint32_t ioportmask_t;
typedef uint32_t iomode_t;
/**
+ * @brief Type of an I/O line.
+ */
+typedef uint32_t ioline_t;
+
+/**
* @brief Port Identifier.
* @details This type can be a scalar or some kind of pointer, do not make
* any assumption about it, use the provided macros when populating
diff --git a/readme.txt b/readme.txt
index 0907abdf9..06aaec32a 100644
--- a/readme.txt
+++ b/readme.txt
@@ -73,6 +73,9 @@
*****************************************************************************
*** 3.1.0 ***
+- HAL: Added "lines" handling to PAL driver, hal are identifiers of both
+ ports and pins encoded in a single value. Added a set of macros
+ operating on lines.
- HAL: Merged the latest STM32F2xx CMSIS headers and fixed the support
broken in 3.0.x.
- RT: Added new function chVTGetTimersStateI() returning the state of the
diff --git a/testhal/STM32/STM32F7xx/GPT-ADC/main.c b/testhal/STM32/STM32F7xx/GPT-ADC/main.c
index e3790371a..06fc68a26 100644
--- a/testhal/STM32/STM32F7xx/GPT-ADC/main.c
+++ b/testhal/STM32/STM32F7xx/GPT-ADC/main.c
@@ -120,11 +120,11 @@ static THD_FUNCTION(Thread1, arg) {
(void)arg;
chRegSetThreadName("blinker");
- palSetPadMode(GPIOI, GPIOI_ARD_D13, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetLineMode(LINE_ARD_D13, PAL_MODE_OUTPUT_PUSHPULL);
while (true) {
- palSetPad(GPIOI, GPIOI_ARD_D13);
+ palSetLine(LINE_ARD_D13);
chThdSleepMilliseconds(500);
- palClearPad(GPIOI, GPIOI_ARD_D13);
+ palClearLine(LINE_ARD_D13);
chThdSleepMilliseconds(500);
}
}
diff --git a/testhal/STM32/STM32F7xx/PWM-ICU/main.c b/testhal/STM32/STM32F7xx/PWM-ICU/main.c
index 78d51d7da..27bb7edac 100644
--- a/testhal/STM32/STM32F7xx/PWM-ICU/main.c
+++ b/testhal/STM32/STM32F7xx/PWM-ICU/main.c
@@ -53,13 +53,13 @@ icucnt_t last_width, last_period;
static void icuwidthcb(ICUDriver *icup) {
- palSetPad(GPIOI, GPIOI_ARD_D13);
+ palSetLine(LINE_ARD_D13);
last_width = icuGetWidthX(icup);
}
static void icuperiodcb(ICUDriver *icup) {
- palClearPad(GPIOI, GPIOI_ARD_D13);
+ palClearLine(LINE_ARD_D13);
last_period = icuGetPeriodX(icup);
}
@@ -103,20 +103,20 @@ int main(void) {
*/
pwmStart(&PWMD1, &pwmcfg);
pwmEnablePeriodicNotification(&PWMD1);
- palSetPadMode(GPIOA, GPIOA_ARD_D5, PAL_MODE_ALTERNATE(1));
+ palSetLineMode(LINE_ARD_D5, PAL_MODE_ALTERNATE(1));
/*
* Starting ICU driver 2.
* GPIOA15 is programmed as ICU input (channel 1 of TIM2).
*/
icuStart(&ICUD2, &icucfg);
- palSetPadMode(GPIOA, GPIOA_ARD_D9, PAL_MODE_ALTERNATE(1));
+ palSetLineMode(LINE_ARD_D9, PAL_MODE_ALTERNATE(1));
/*
* GPIOI1 is programmed as output (board LED).
*/
- palClearPad(GPIOI, GPIOI_ARD_D13);
- palSetPadMode(GPIOI, GPIOI_ARD_D13, PAL_MODE_OUTPUT_PUSHPULL);
+ palClearLine(LINE_ARD_D13);
+ palSetLineMode(LINE_ARD_D13, PAL_MODE_OUTPUT_PUSHPULL);
chThdSleepMilliseconds(1000);
/*
diff --git a/testhal/STM32/STM32F7xx/SPI/main.c b/testhal/STM32/STM32F7xx/SPI/main.c
index 547e49501..4a89aa958 100644
--- a/testhal/STM32/STM32F7xx/SPI/main.c
+++ b/testhal/STM32/STM32F7xx/SPI/main.c
@@ -148,26 +148,21 @@ int main(void) {
/*
* SPI2 I/O pins setup.
*/
- palSetPadMode(GPIOI,
- GPIOI_ARD_D13,
- PAL_MODE_ALTERNATE(5) |
- PAL_STM32_OSPEED_HIGHEST); /* SPI SCK. */
- palSetPadMode(GPIOB,
- GPIOB_ARD_D12,
- PAL_MODE_ALTERNATE(5) |
- PAL_STM32_OSPEED_HIGHEST); /* MISO. */
- palSetPadMode(GPIOB,
- GPIOB_ARD_D11,
- PAL_MODE_ALTERNATE(5) |
- PAL_STM32_OSPEED_HIGHEST); /* MOSI. */
- palSetPad(GPIOB, GPIOB_ARD_D15);
- palSetPadMode(GPIOB,
- GPIOB_ARD_D15,
- PAL_MODE_OUTPUT_PUSHPULL); /* CS0. */
- palSetPad(GPIOB, GPIOB_ARD_D14);
- palSetPadMode(GPIOB,
- GPIOB_ARD_D14,
- PAL_MODE_OUTPUT_PUSHPULL); /* CS1. */
+ palSetLineMode(LINE_ARD_D13,
+ PAL_MODE_ALTERNATE(5) |
+ PAL_STM32_OSPEED_HIGHEST); /* SPI SCK. */
+ palSetLineMode(LINE_ARD_D12,
+ PAL_MODE_ALTERNATE(5) |
+ PAL_STM32_OSPEED_HIGHEST); /* MISO. */
+ palSetLineMode(LINE_ARD_D11,
+ PAL_MODE_ALTERNATE(5) |
+ PAL_STM32_OSPEED_HIGHEST); /* MOSI. */
+ palSetLine(LINE_ARD_D15);
+ palSetLineMode(LINE_ARD_D15,
+ PAL_MODE_OUTPUT_PUSHPULL); /* CS0. */
+ palSetLine(LINE_ARD_D14);
+ palSetLineMode(LINE_ARD_D14,
+ PAL_MODE_OUTPUT_PUSHPULL); /* CS1. */
/*
* Starting the transmitter and receiver threads.
diff --git a/testhal/STM32/STM32F7xx/USB_CDC/main.c b/testhal/STM32/STM32F7xx/USB_CDC/main.c
index 92894ee5a..d992623c0 100644
--- a/testhal/STM32/STM32F7xx/USB_CDC/main.c
+++ b/testhal/STM32/STM32F7xx/USB_CDC/main.c
@@ -147,9 +147,9 @@ static THD_FUNCTION(Thread1, arg) {
systime_t time;
time = serusbcfg.usbp->state == USB_ACTIVE ? 250 : 500;
- palClearPad(GPIOI, GPIOI_ARD_D13);
+ palClearLine(LINE_ARD_D13);
chThdSleepMilliseconds(time);
- palSetPad(GPIOI, GPIOI_ARD_D13);
+ palSetLine(LINE_ARD_D13);
chThdSleepMilliseconds(time);
}
}
@@ -179,8 +179,8 @@ int main(void) {
/*
* GPIOI1 is programmed as output (board LED).
*/
- palClearPad(GPIOI, GPIOI_ARD_D13);
- palSetPadMode(GPIOI, GPIOI_ARD_D13, PAL_MODE_OUTPUT_PUSHPULL);
+ palClearLine(LINE_ARD_D13);
+ palSetLineMode(LINE_ARD_D13, PAL_MODE_OUTPUT_PUSHPULL);
/*
* Activates the USB driver and then the USB bus pull-up on D+.