mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Files at this revision

API Documentation at this revision

Comitter:
mbed_official
Date:
Mon Jul 06 09:00:34 2015 +0100
Parent:
581:39197bcd20f2
Child:
583:967d0d8b7aed
Commit message:
Synchronized with git revision 45004fb61e4af8f74f4e916318df5207fcf6076d

Full URL: https://github.com/mbedmicro/mbed/commit/45004fb61e4af8f74f4e916318df5207fcf6076d/

DISCO_F746NG - Fix several issues

Changed in this revision

targets/cmsis/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/system_stm32f7xx.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/PeripheralNames.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/PeripheralPins.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/PinNames.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/device.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_STM32F7/analogin_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_STM32F7/analogout_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_STM32F7/gpio_object.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_STM32F7/i2c_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_STM32F7/pwmout_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_STM32F7/rtc_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_STM32F7/serial_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_STM32F7/sleep.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_STM32F7/spi_api.c Show annotated file Show diff for this revision Revisions of this file
--- a/targets/cmsis/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/system_stm32f7xx.c	Thu Jul 02 16:30:08 2015 +0100
+++ b/targets/cmsis/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/system_stm32f7xx.c	Mon Jul 06 09:00:34 2015 +0100
@@ -227,6 +227,10 @@
   SystemCoreClock = HSI_VALUE; // At this stage the HSI is used as system clock
   HAL_Init();
 
+  // Enable CPU L1-Cache
+  SCB_EnableICache();
+  SCB_EnableDCache();
+
   /* Configure the System clock source, PLL Multiplier and Divider factors,
      AHB/APBx prescalers and Flash settings */
   SetSysClock();
@@ -575,10 +579,6 @@
   RCC_ClkInitTypeDef RCC_ClkInitStruct;
   RCC_OscInitTypeDef RCC_OscInitStruct;
 
-  // Enable CPU L1-Cache
-  SCB_EnableICache();
-  SCB_EnableDCache();
-
   // Enable power clock  
   __PWR_CLK_ENABLE();
   
--- a/targets/hal/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/PeripheralNames.h	Thu Jul 02 16:30:08 2015 +0100
+++ b/targets/hal/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/PeripheralNames.h	Mon Jul 06 09:00:34 2015 +0100
@@ -57,9 +57,9 @@
     UART_8 = (int)UART8_BASE
 } UARTName;
 
-#define STDIO_UART_TX  PC_6
-#define STDIO_UART_RX  PC_7
-#define STDIO_UART     UART_6
+#define STDIO_UART_TX  PA_9
+#define STDIO_UART_RX  PB_7
+#define STDIO_UART     UART_1
 
 typedef enum {
     SPI_1 = (int)SPI1_BASE,
--- a/targets/hal/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/PeripheralPins.c	Thu Jul 02 16:30:08 2015 +0100
+++ b/targets/hal/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/PeripheralPins.c	Mon Jul 06 09:00:34 2015 +0100
@@ -41,12 +41,12 @@
 //*** ADC ***
 
 const PinMap PinMap_ADC[] = {
-    {PA_0,  ADC_3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0,  0)}, // ADC3_IN0 - ARDUINO A0
-    {PF_6,  ADC_3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4,  0)}, // ADC3_IN4 - ARDUINO A5
-    {PF_7,  ADC_3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5,  0)}, // ADC3_IN5 - ARDUINO A4
-    {PF_8,  ADC_3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6,  0)}, // ADC3_IN6 - ARDUINO A3
-    {PF_9,  ADC_3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7,  0)}, // ADC3_IN7 - ARDUINO A2
-    {PF_10, ADC_3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC3_IN10 - ARDUINO A1
+    {PA_0,  ADC_3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC3_IN0 - ARDUINO A0
+    {PF_6,  ADC_3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC3_IN4 - ARDUINO A5
+    {PF_7,  ADC_3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC3_IN5 - ARDUINO A4
+    {PF_8,  ADC_3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC3_IN6 - ARDUINO A3
+    {PF_9,  ADC_3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC3_IN7 - ARDUINO A2
+    {PF_10, ADC_3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC3_IN8 - ARDUINO A1
     {NC,    NC,    0}
 };
 
@@ -84,7 +84,7 @@
 //  {PB_9,  PWM_11, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM11, 1, 0)}, // TIM11_CH1 - ARDUINO D14
 //  {PB_14, PWM_1,  STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1,  2, 1)}, // TIM1_CH2N - ARDUINO D12
 //  {PB_14, PWM_8,  STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8,  2, 1)}, // TIM8_CH2N - ARDUINO D12
-    {PB_14, PWM_12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM12, 1, 0)}, // TIM12_CH1 - ARDUINO D12 
+    {PB_14, PWM_12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM12, 1, 0)}, // TIM12_CH1 - ARDUINO D12
 //  {PB_15, PWM_1,  STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1,  3, 1)}, // TIM1_CH3N - ARDUINO D11
 //  {PB_15, PWM_8,  STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8,  3, 1)}, // TIM8_CH3N - ARDUINO D11
     {PB_15, PWM_12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM12, 2, 0)}, // TIM12_CH2 - ARDUINO D11
@@ -94,6 +94,8 @@
     {PC_7,  PWM_8,  STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8,  2, 0)}, // TIM8_CH2 - ARDUINO D0
     {PF_6,  PWM_10, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM10, 1, 0)}, // TIM10_CH1 - ARDUINO A5
     {PF_7,  PWM_11, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM11, 1, 0)}, // TIM11_CH1 - ARDUINO A4
+    {PF_8,  PWM_13, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM13, 1, 0)}, // TIM13_CH1 - ARDUINO A3
+    {PF_9,  PWM_14, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM14, 1, 0)}, // TIM14_CH1 - ARDUINO A2
     {PH_6,  PWM_12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM12, 1, 0)}, // TIM12_CH1 - ARDUINO D6
 //  {PI_0,  PWM_5,  STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5,  4, 0)}, // TIM5_CH4 - ARDUINO D10 (used by us_ticker)
     {PI_2,  PWM_8,  STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8,  4, 0)}, // TIM8_CH4 - ARDUINO D8
@@ -104,12 +106,14 @@
 
 const PinMap PinMap_UART_TX[] = {
     {PA_0,  UART_4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)}, // ARDUINO A0
+    {PA_9,  UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, // Virtual Com Port
     {PC_6,  UART_6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, // ARDUINO D1
     {PF_7,  UART_7, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART7)}, // ARDUINO A4
     {NC,    NC,     0}
 };
 
 const PinMap PinMap_UART_RX[] = {
+    {PB_7,  UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)}, // Virtual Com Port
     {PC_7,  UART_6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, // ARDUINO D0
     {PF_6,  UART_7, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART7)}, // ARDUINO A5
     {NC,    NC,     0}
--- a/targets/hal/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/PinNames.h	Thu Jul 02 16:30:08 2015 +0100
+++ b/targets/hal/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/PinNames.h	Mon Jul 06 09:00:34 2015 +0100
@@ -268,12 +268,12 @@
     D2          = PG_6,
     D3          = PB_4,
     D4          = PG_7,
-    D5          = PA_8,
+    D5          = PI_0,
     D6          = PH_6,
     D7          = PI_3,
     D8          = PI_2,
     D9          = PA_15,
-    D10         = PI_0,
+    D10         = PA_8,
     D11         = PB_15,
     D12         = PB_14,
     D13         = PI_1,
@@ -286,17 +286,17 @@
     LED3        = PI_1,
     LED4        = PI_1,
     USER_BUTTON = PI_11,
-    SERIAL_TX   = PC_6,
-    SERIAL_RX   = PC_7,
-    USBTX       = PC_6,
-    USBRX       = PC_7,
-    I2C_SCL     = PB_8,
-    I2C_SDA     = PB_9,
-    SPI_MOSI    = PB_15,
-    SPI_MISO    = PB_14,
-    SPI_SCK     = PI_1,
-    SPI_CS      = PI_0,
-    PWM_OUT     = PB_4,
+    SERIAL_TX   = D1,
+    SERIAL_RX   = D0,
+    USBTX       = PA_9, // Virtual Com Port
+    USBRX       = PB_7, // Virtual Com Port
+    I2C_SCL     = D15,
+    I2C_SDA     = D14,
+    SPI_MOSI    = D11,
+    SPI_MISO    = D12,
+    SPI_SCK     = D13,
+    SPI_CS      = D10,
+    PWM_OUT     = D9,
 
     // Not connected
     NC = (int)0xFFFFFFFF
--- a/targets/hal/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/device.h	Thu Jul 02 16:30:08 2015 +0100
+++ b/targets/hal/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/device.h	Mon Jul 06 09:00:34 2015 +0100
@@ -41,8 +41,8 @@
 
 #define DEVICE_SERIAL           1
 
-#define DEVICE_I2C              0
-#define DEVICE_I2CSLAVE         0
+#define DEVICE_I2C              1
+#define DEVICE_I2CSLAVE         1
 
 #define DEVICE_SPI              1
 #define DEVICE_SPISLAVE         1
--- a/targets/hal/TARGET_STM/TARGET_STM32F7/analogin_api.c	Thu Jul 02 16:30:08 2015 +0100
+++ b/targets/hal/TARGET_STM/TARGET_STM32F7/analogin_api.c	Mon Jul 06 09:00:34 2015 +0100
@@ -34,13 +34,22 @@
 #include "cmsis.h"
 #include "pinmap.h"
 #include "PeripheralPins.h"
+#include "mbed_error.h"
 
 ADC_HandleTypeDef AdcHandle;
 
-int adc_inited = 0;
-
 void analogin_init(analogin_t *obj, PinName pin)
 {
+#if defined(ADC1)
+    static int adc1_inited = 0;
+#endif
+#if defined(ADC2)
+    static int adc2_inited = 0;
+#endif
+#if defined(ADC3)
+    static int adc3_inited = 0;
+#endif
+
     // Get the peripheral name from the pin and assign it to the object
     obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
     MBED_ASSERT(obj->adc != (ADCName)NC);
@@ -56,40 +65,59 @@
     // Save pin number for the read function
     obj->pin = pin;
 
-    // The ADC initialization is done once
-    if (adc_inited == 0) {
-        adc_inited = 1;
-
-        // Enable ADC clock
-        __ADC1_CLK_ENABLE();
+    // Check if ADC is already initialized
+    // Enable ADC clock
+#if defined(ADC1)
+    if ((obj->adc == ADC_1) && adc1_inited) return;
+    if (obj->adc == ADC_1) {
+        __HAL_RCC_ADC1_CLK_ENABLE();
+        adc1_inited = 1;
+    }
+#endif
+#if defined(ADC2)
+    if ((obj->adc == ADC_2) && adc2_inited) return;
+    if (obj->adc == ADC_2) {
+        __HAL_RCC_ADC2_CLK_ENABLE();
+        adc2_inited = 1;
+    }
+#endif
+#if defined(ADC3)
+    if ((obj->adc == ADC_3) && adc3_inited) return;
+    if (obj->adc == ADC_3) {
+        __HAL_RCC_ADC3_CLK_ENABLE();
+        adc3_inited = 1;
+    }
+#endif
 
-        // Configure ADC
-        AdcHandle.Instance = (ADC_TypeDef *)(obj->adc);
-        AdcHandle.Init.ClockPrescaler        = ADC_CLOCKPRESCALER_PCLK_DIV2;
-        AdcHandle.Init.Resolution            = ADC_RESOLUTION12b;
-        AdcHandle.Init.ScanConvMode          = DISABLE;
-        AdcHandle.Init.ContinuousConvMode    = DISABLE;
-        AdcHandle.Init.DiscontinuousConvMode = DISABLE;
-        AdcHandle.Init.NbrOfDiscConversion   = 0;
-        AdcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;
-        AdcHandle.Init.ExternalTrigConv      = ADC_EXTERNALTRIGCONV_T1_CC1;
-        AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
-        AdcHandle.Init.NbrOfConversion       = 1;
-        AdcHandle.Init.DMAContinuousRequests = DISABLE;
-        AdcHandle.Init.EOCSelection          = DISABLE;
-        HAL_ADC_Init(&AdcHandle);
+    // Configure ADC
+    AdcHandle.Instance = (ADC_TypeDef *)(obj->adc);
+    AdcHandle.Init.ClockPrescaler        = ADC_CLOCKPRESCALER_PCLK_DIV4;
+    AdcHandle.Init.Resolution            = ADC_RESOLUTION_12B;
+    AdcHandle.Init.ScanConvMode          = DISABLE;
+    AdcHandle.Init.ContinuousConvMode    = DISABLE;
+    AdcHandle.Init.DiscontinuousConvMode = DISABLE;
+    AdcHandle.Init.NbrOfDiscConversion   = 0;
+    AdcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;
+    AdcHandle.Init.ExternalTrigConv      = ADC_EXTERNALTRIGCONV_T1_CC1;
+    AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
+    AdcHandle.Init.NbrOfConversion       = 1;
+    AdcHandle.Init.DMAContinuousRequests = DISABLE;
+    AdcHandle.Init.EOCSelection          = DISABLE;
+
+    if (HAL_ADC_Init(&AdcHandle) != HAL_OK) {
+        error("Cannot initialize ADC");
     }
 }
 
 static inline uint16_t adc_read(analogin_t *obj)
 {
-    ADC_ChannelConfTypeDef sConfig;
+    ADC_ChannelConfTypeDef sConfig = {0};
 
     AdcHandle.Instance = (ADC_TypeDef *)(obj->adc);
 
     // Configure ADC channel
     sConfig.Rank         = 1;
-    sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
+    sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
     sConfig.Offset       = 0;
 
     switch (obj->channel) {
@@ -141,16 +169,28 @@
         case 15:
             sConfig.Channel = ADC_CHANNEL_15;
             break;
+        case 16:
+            sConfig.Channel = ADC_CHANNEL_16;
+            break;
+        case 17:
+            sConfig.Channel = ADC_CHANNEL_17;
+            break;
+        case 18:
+            sConfig.Channel = ADC_CHANNEL_18;
+            break;
         default:
             return 0;
     }
 
-    HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
+    if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK) {
+        error("Cannot configure ADC channel");
+    }
 
     HAL_ADC_Start(&AdcHandle); // Start conversion
 
     // Wait end of conversion and get value
-    if (HAL_ADC_PollForConversion(&AdcHandle, 10) == HAL_OK) {
+    HAL_ADC_PollForConversion(&AdcHandle, 10);
+    if (HAL_ADC_GetState(&AdcHandle) == HAL_ADC_STATE_EOC_REG) {
         return (HAL_ADC_GetValue(&AdcHandle));
     } else {
         return 0;
--- a/targets/hal/TARGET_STM/TARGET_STM32F7/analogout_api.c	Thu Jul 02 16:30:08 2015 +0100
+++ b/targets/hal/TARGET_STM/TARGET_STM32F7/analogout_api.c	Mon Jul 06 09:00:34 2015 +0100
@@ -67,7 +67,7 @@
     DacHandle.Instance = DAC;
 
     status = HAL_DAC_Init(&DacHandle);
-    if ( status != HAL_OK ) {
+    if (status != HAL_OK) {
         error("HAL_DAC_Init failed");
     }
 
@@ -75,7 +75,7 @@
     sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
 
     if (obj->channel == 1) {
-        channel = DAC_CHANNEL_1; 
+        channel = DAC_CHANNEL_1;
     } else {
         channel = DAC_CHANNEL_2;
     }
@@ -108,7 +108,7 @@
         status = HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_2, DAC_ALIGN_12B_R, value);
     }
 
-    if ( status != HAL_OK ) {
+    if (status != HAL_OK) {
         error("DAC pin mapping failed");
     }
 }
@@ -120,7 +120,7 @@
     } else if (obj->channel == 2) {
         return (int)HAL_DAC_GetValue(&DacHandle, DAC_CHANNEL_2);
     }
-	return 0;	/* Just silented warning */
+    return 0;   /* Just silented warning */
 }
 
 void analogout_write(dac_t *obj, float value)
--- a/targets/hal/TARGET_STM/TARGET_STM32F7/gpio_object.h	Thu Jul 02 16:30:08 2015 +0100
+++ b/targets/hal/TARGET_STM/TARGET_STM32F7/gpio_object.h	Mon Jul 06 09:00:34 2015 +0100
@@ -63,7 +63,8 @@
     return ((*obj->reg_in & obj->mask) ? 1 : 0);
 }
 
-static inline int gpio_is_connected(const gpio_t *obj) {
+static inline int gpio_is_connected(const gpio_t *obj)
+{
     return obj->pin != (PinName)NC;
 }
 
--- a/targets/hal/TARGET_STM/TARGET_STM32F7/i2c_api.c	Thu Jul 02 16:30:08 2015 +0100
+++ b/targets/hal/TARGET_STM/TARGET_STM32F7/i2c_api.c	Mon Jul 06 09:00:34 2015 +0100
@@ -35,18 +35,22 @@
 #include "cmsis.h"
 #include "pinmap.h"
 #include "PeripheralPins.h"
+#include "mbed_error.h"
 
 /* Timeout values for flags and events waiting loops. These timeouts are
    not based on accurate values, they just guarantee that the application will
    not remain stuck if the I2C communication is corrupted. */
-#define FLAG_TIMEOUT ((int)0x1000)
+#define FLAG_TIMEOUT ((int)0x4000)
 #define LONG_TIMEOUT ((int)0x8000)
 
 I2C_HandleTypeDef I2cHandle;
 
 int i2c1_inited = 0;
+/* Ready for next F7 devices
 int i2c2_inited = 0;
 int i2c3_inited = 0;
+int i2c4_inited = 0;
+*/
 
 void i2c_init(i2c_t *obj, PinName sda, PinName scl)
 {
@@ -57,72 +61,116 @@
     obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
     MBED_ASSERT(obj->i2c != (I2CName)NC);
 
-    // Enable I2C1 clock and pinout if not done
+    // Enable I2C clock and pinout if not done
     if ((obj->i2c == I2C_1) && !i2c1_inited) {
         i2c1_inited = 1;
-        __I2C1_CLK_ENABLE();
-        // Configure I2C pins
-        pinmap_pinout(sda, PinMap_I2C_SDA);
-        pinmap_pinout(scl, PinMap_I2C_SCL);
-        pin_mode(sda, OpenDrain);
-        pin_mode(scl, OpenDrain);
-    }
-    // Enable I2C2 clock and pinout if not done
-    if ((obj->i2c == I2C_2) && !i2c2_inited) {
-        i2c2_inited = 1;
-        __I2C2_CLK_ENABLE();
-        // Configure I2C pins
-        pinmap_pinout(sda, PinMap_I2C_SDA);
-        pinmap_pinout(scl, PinMap_I2C_SCL);
-        pin_mode(sda, OpenDrain);
-        pin_mode(scl, OpenDrain);
-    }
-    // Enable I2C3 clock and pinout if not done
-    if ((obj->i2c == I2C_3) && !i2c3_inited) {
-        i2c3_inited = 1;
-        __I2C3_CLK_ENABLE();
-        // Configure I2C pins
+        __HAL_RCC_I2C1_CONFIG(RCC_I2C1CLKSOURCE_PCLK1);
+        __HAL_RCC_I2C1_CLK_ENABLE();
+        // Configure I2C1 pins
         pinmap_pinout(sda, PinMap_I2C_SDA);
         pinmap_pinout(scl, PinMap_I2C_SCL);
         pin_mode(sda, OpenDrain);
         pin_mode(scl, OpenDrain);
     }
 
+    /* Ready for next F7 devices
+    #if defined(I2C2_BASE)
+        if ((obj->i2c == I2C_2) && !i2c2_inited) {
+            i2c2_inited = 1;
+            __HAL_RCC_I2C2_CONFIG(RCC_I2C2CLKSOURCE_PCLK1);
+            __HAL_RCC_I2C2_CLK_ENABLE();
+            // Configure I2C2 pins
+            pinmap_pinout(sda, PinMap_I2C_SDA);
+            pinmap_pinout(scl, PinMap_I2C_SCL);
+            pin_mode(sda, OpenDrain);
+            pin_mode(scl, OpenDrain);
+        }
+    #endif
+
+    #if defined(I2C3_BASE)
+        if ((obj->i2c == I2C_3) && !i2c3_inited) {
+            i2c3_inited = 1;
+            __HAL_RCC_I2C3_CONFIG(RCC_I2C3CLKSOURCE_PCLK1);
+            __HAL_RCC_I2C3_CLK_ENABLE();
+            // Configure I2C3 pins
+            pinmap_pinout(sda, PinMap_I2C_SDA);
+            pinmap_pinout(scl, PinMap_I2C_SCL);
+            pin_mode(sda, OpenDrain);
+            pin_mode(scl, OpenDrain);
+        }
+    #endif
+
+    #if defined(I2C4_BASE)
+        if ((obj->i2c == I2C_4) && !i2c4_inited) {
+            i2c4_inited = 1;
+            __HAL_RCC_I2C4_CONFIG(RCC_I2C4CLKSOURCE_PCLK1);
+            __HAL_RCC_I2C4_CLK_ENABLE();
+            // Configure I2C4 pins
+            pinmap_pinout(sda, PinMap_I2C_SDA);
+            pinmap_pinout(scl, PinMap_I2C_SCL);
+            pin_mode(sda, OpenDrain);
+            pin_mode(scl, OpenDrain);
+        }
+    #endif
+    */
+
     // Reset to clear pending flags if any
     i2c_reset(obj);
 
     // I2C configuration
     i2c_frequency(obj, 100000); // 100 kHz per default
-
-    // I2C master by default
-    obj->slave = 0;
 }
 
 void i2c_frequency(i2c_t *obj, int hz)
 {
-    MBED_ASSERT((hz != 0) && (hz <= 400000));
+    uint32_t tim = 0;
+
+    MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
+
     I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
     int timeout;
 
     // wait before init
     timeout = LONG_TIMEOUT;
-    while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
+    while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0)) {}
+
+    /*
+       Values calculated with I2C_Timing_Configuration tool (excel file)
+       * Standard mode (up to 100 kHz)
+       * Fast Mode (up to 400 kHz)
+       * Fast Mode Plus (up to 1 MHz)
+       Below values obtained with:
+       - I2Cx clock source = APB1CLK = 54 MHz
+       - Analog filter delay = ON
+       - Digital filter coefficient = 0
+    */
+    switch (hz) {
+        case 100000:
+            tim = 0x10916998; // Standard mode with Rise time = 120ns, Fall time = 120ns
+            break;
+        case 400000:
+            tim = 0x00B11B54; // Fast Mode with Rise time = 120ns, Fall time = 120ns
+            break;
+        case 1000000:
+            tim = 0x0090091B; // Fast Mode Plus with Rise time = 120ns, Fall time = 10ns
+            break;
+        default:
+            break;
+    }
 
     // I2C configuration
-    I2cHandle.Init.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;
-    I2cHandle.Init.ClockSpeed      = hz;
-    I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
-    I2cHandle.Init.DutyCycle       = I2C_DUTYCYCLE_2;
-    I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
-    I2cHandle.Init.NoStretchMode   = I2C_NOSTRETCH_DISABLED;
-    I2cHandle.Init.OwnAddress1     = 0;
-    I2cHandle.Init.OwnAddress2     = 0;
-    HAL_I2C_Init(&I2cHandle);
-    if (obj->slave) {
-        /* Enable Address Acknowledge */
-        I2cHandle.Instance->CR1 |= I2C_CR1_ACK;
+    I2cHandle.Init.Timing           = tim;
+    I2cHandle.Init.AddressingMode   = I2C_ADDRESSINGMODE_7BIT;
+    I2cHandle.Init.DualAddressMode  = I2C_DUALADDRESS_DISABLE;
+    I2cHandle.Init.GeneralCallMode  = I2C_GENERALCALL_DISABLE;
+    I2cHandle.Init.NoStretchMode    = I2C_NOSTRETCH_DISABLE;
+    I2cHandle.Init.OwnAddress1      = 0;
+    I2cHandle.Init.OwnAddress2      = 0;
+    I2cHandle.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
+
+    if (HAL_I2C_Init(&I2cHandle) != HAL_OK) {
+        error("Cannot initialize I2C");
     }
-
 }
 
 inline int i2c_start(i2c_t *obj)
@@ -136,11 +184,11 @@
     __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
 
     // Generate the START condition
-    i2c->CR1 |= I2C_CR1_START;
+    i2c->CR2 |= I2C_CR2_START;
 
     // Wait the START condition has been correctly sent
     timeout = FLAG_TIMEOUT;
-    while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_SB) == RESET) {
+    while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == RESET) {
         if ((timeout--) == 0) {
             return 1;
         }
@@ -154,7 +202,7 @@
     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
 
     // Generate the STOP condition
-    i2c->CR1 |= I2C_CR1_STOP;
+    i2c->CR2 |= I2C_CR2_STOP;
 
     return 0;
 }
@@ -167,46 +215,42 @@
     int count;
     int value;
 
-    i2c_start(obj);
+    /* update CR2 register */
+    i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)))
+               | (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_READ);
 
-    // Wait until SB flag is set
-    timeout = FLAG_TIMEOUT;
-    while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_SB) == RESET) {
+    // Read all bytes
+    for (count = 0; count < length; count++) {
+        value = i2c_byte_read(obj, 0);
+        data[count] = (char)value;
+    }
+
+    // Wait transfer complete
+    timeout = LONG_TIMEOUT;
+    while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) {
         timeout--;
         if (timeout == 0) {
             return -1;
         }
     }
 
-    i2c->DR = __HAL_I2C_7BIT_ADD_READ(address);
-
-
-    // Wait address is acknowledged
-    timeout = FLAG_TIMEOUT;
-    while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == RESET) {
-        timeout--;
-        if (timeout == 0) {
-            return -1;
-        }
-    }
-    __HAL_I2C_CLEAR_ADDRFLAG(&I2cHandle);
-
-    // Read all bytes except last one
-    for (count = 0; count < (length - 1); count++) {
-        value = i2c_byte_read(obj, 0);
-        data[count] = (char)value;
-    }
+    __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_TC);
 
     // If not repeated start, send stop.
-    // Warning: must be done BEFORE the data is read.
     if (stop) {
         i2c_stop(obj);
+        /* Wait until STOPF flag is set */
+        timeout = FLAG_TIMEOUT;
+        while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
+            timeout--;
+            if (timeout == 0) {
+                return -1;
+            }
+        }
+        /* Clear STOP Flag */
+        __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF);
     }
 
-    // Read the last byte
-    value = i2c_byte_read(obj, 1);
-    data[count] = (char)value;
-
     return length;
 }
 
@@ -217,40 +261,38 @@
     int timeout;
     int count;
 
-    i2c_start(obj);
+    /* update CR2 register */
+    i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)))
+               | (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_WRITE);
 
-    // Wait until SB flag is set
+    for (count = 0; count < length; count++) {
+        i2c_byte_write(obj, data[count]);
+    }
+
+    // Wait transfer complete
     timeout = FLAG_TIMEOUT;
-    while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_SB) == RESET) {
+    while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) {
         timeout--;
         if (timeout == 0) {
             return -1;
         }
     }
 
-    i2c->DR = __HAL_I2C_7BIT_ADD_WRITE(address);
-
-
-    // Wait address is acknowledged
-    timeout = FLAG_TIMEOUT;
-    while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == RESET) {
-        timeout--;
-        if (timeout == 0) {
-            return -1;
-        }
-    }
-    __HAL_I2C_CLEAR_ADDRFLAG(&I2cHandle);
-
-    for (count = 0; count < length; count++) {
-        if (i2c_byte_write(obj, data[count]) != 1) {
-            i2c_stop(obj);
-            return -1;
-        }
-    }
+    __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_TC);
 
     // If not repeated start, send stop.
     if (stop) {
         i2c_stop(obj);
+        /* Wait until STOPF flag is set */
+        timeout = FLAG_TIMEOUT;
+        while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
+            timeout--;
+            if (timeout == 0) {
+                return -1;
+            }
+        }
+        /* Clear STOP Flag */
+        __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF);
     }
 
     return count;
@@ -261,14 +303,6 @@
     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
     int timeout;
 
-    if (last) {
-        // Don't acknowledge the last byte
-        i2c->CR1 &= ~I2C_CR1_ACK;
-    } else {
-        // Acknowledge the byte
-        i2c->CR1 |= I2C_CR1_ACK;
-    }
-
     // Wait until the byte is received
     timeout = FLAG_TIMEOUT;
     while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
@@ -277,7 +311,7 @@
         }
     }
 
-    return (int)i2c->DR;
+    return (int)i2c->RXDR;
 }
 
 int i2c_byte_write(i2c_t *obj, int data)
@@ -285,17 +319,16 @@
     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
     int timeout;
 
-    i2c->DR = (uint8_t)data;
-
-    // Wait until the byte is transmitted
+    // Wait until the previous byte is transmitted
     timeout = FLAG_TIMEOUT;
-    while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXE) == RESET) &&
-            (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == RESET)) {
+    while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXIS) == RESET) {
         if ((timeout--) == 0) {
             return 0;
         }
     }
 
+    i2c->TXDR = (uint8_t)data;
+
     return 1;
 }
 
@@ -307,18 +340,8 @@
     timeout = LONG_TIMEOUT;
     while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
 
-    if (obj->i2c == I2C_1) {
-        __I2C1_FORCE_RESET();
-        __I2C1_RELEASE_RESET();
-    }
-    if (obj->i2c == I2C_2) {
-        __I2C2_FORCE_RESET();
-        __I2C2_RELEASE_RESET();
-    }
-    if (obj->i2c == I2C_3) {
-        __I2C3_FORCE_RESET();
-        __I2C3_RELEASE_RESET();
-    }
+    __I2C1_FORCE_RESET();
+    __I2C1_RELEASE_RESET();
 }
 
 #if DEVICE_I2CSLAVE
@@ -326,8 +349,10 @@
 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
 {
     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
-    uint16_t tmpreg = 0;
+    uint16_t tmpreg;
 
+    // disable
+    i2c->OAR1 &= (uint32_t)(~I2C_OAR1_OA1EN);
     // Get the old register value
     tmpreg = i2c->OAR1;
     // Reset address bits
@@ -336,16 +361,29 @@
     tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits
     // Store the new register value
     i2c->OAR1 = tmpreg;
+    // enable
+    i2c->OAR1 |= I2C_OAR1_OA1EN;
 }
 
 void i2c_slave_mode(i2c_t *obj, int enable_slave)
 {
-    I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
-    if (enable_slave) {
-        obj->slave = 1;
-        /* Enable Address Acknowledge */
-        I2cHandle.Instance->CR1 |= I2C_CR1_ACK;
+
+    I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
+    uint16_t tmpreg;
+
+    // Get the old register value
+    tmpreg = i2c->OAR1;
+
+    // Enable / disable slave
+    if (enable_slave == 1) {
+        tmpreg |= I2C_OAR1_OA1EN;
+    } else {
+        tmpreg &= (uint32_t)(~I2C_OAR1_OA1EN);
     }
+
+    // Set new mode
+    i2c->OAR1 = tmpreg;
+
 }
 
 // See I2CSlave.h
@@ -356,15 +394,15 @@
 
 int i2c_slave_receive(i2c_t *obj)
 {
+    I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
     int retValue = NoData;
 
     if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == 1) {
         if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == 1) {
-            if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TRA) == 1)
+            if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_DIR) == 1)
                 retValue = ReadAddressed;
             else
                 retValue = WriteAddressed;
-
             __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_ADDR);
         }
     }
@@ -374,117 +412,22 @@
 
 int i2c_slave_read(i2c_t *obj, char *data, int length)
 {
-    uint32_t Timeout;
-    int size = 0;
-
-    I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
-
-    while (length > 0) {
-        /* Wait until RXNE flag is set */
-        // Wait until the byte is received
-        Timeout = FLAG_TIMEOUT;
-        while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
-            Timeout--;
-            if (Timeout == 0) {
-                return -1;
-            }
-        }
-
-        /* Read data from DR */
-        (*data++) = I2cHandle.Instance->DR;
-        length--;
-        size++;
+    char size = 0;
 
-        if ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == SET) && (length != 0)) {
-            /* Read data from DR */
-            (*data++) = I2cHandle.Instance->DR;
-            length--;
-            size++;
-        }
-    }
-
-    /* Wait until STOP flag is set */
-    Timeout = FLAG_TIMEOUT;
-    while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
-        Timeout--;
-        if (Timeout == 0) {
-            return -1;
-        }
-    }
-
-    /* Clear STOP flag */
-    __HAL_I2C_CLEAR_STOPFLAG(&I2cHandle);
-
-    /* Wait until BUSY flag is reset */
-    Timeout = FLAG_TIMEOUT;
-    while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == SET) {
-        Timeout--;
-        if (Timeout == 0) {
-            return -1;
-        }
-    }
+    while (size < length) data[size++] = (char)i2c_byte_read(obj, 0);
 
     return size;
 }
 
 int i2c_slave_write(i2c_t *obj, const char *data, int length)
 {
-    uint32_t Timeout;
-    int size = 0;
-
+    char size = 0;
     I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
 
-    while (length > 0) {
-        /* Wait until TXE flag is set */
-        Timeout = FLAG_TIMEOUT;
-        while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXE) == RESET) {
-            Timeout--;
-            if (Timeout == 0) {
-                return -1;
-            }
-        }
-
-
-        /* Write data to DR */
-        I2cHandle.Instance->DR = (*data++);
-        length--;
+    do {
+        i2c_byte_write(obj, data[size]);
         size++;
-
-        if ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == SET) && (length != 0)) {
-            /* Write data to DR */
-            I2cHandle.Instance->DR = (*data++);
-            length--;
-            size++;
-        }
-    }
-
-    /* Wait until AF flag is set */
-    Timeout = FLAG_TIMEOUT;
-    while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_AF) == RESET) {
-        Timeout--;
-        if (Timeout == 0) {
-            return -1;
-        }
-    }
-
-
-    /* Clear AF flag */
-    __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
-
-
-    /* Wait until BUSY flag is reset */
-    Timeout = FLAG_TIMEOUT;
-    while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == SET) {
-        Timeout--;
-        if (Timeout == 0) {
-            return -1;
-        }
-    }
-
-    I2cHandle.State = HAL_I2C_STATE_READY;
-
-    /* Process Unlocked */
-    __HAL_UNLOCK(&I2cHandle);
+    } while (size < length);
 
     return size;
 }
--- a/targets/hal/TARGET_STM/TARGET_STM32F7/pwmout_api.c	Thu Jul 02 16:30:08 2015 +0100
+++ b/targets/hal/TARGET_STM/TARGET_STM32F7/pwmout_api.c	Mon Jul 06 09:00:34 2015 +0100
@@ -54,22 +54,16 @@
     }
 
     // Enable TIM clock
-    if (obj->pwm == PWM_1) __TIM1_CLK_ENABLE();
-    if (obj->pwm == PWM_2) __TIM2_CLK_ENABLE();
-    if (obj->pwm == PWM_3) __TIM3_CLK_ENABLE();
-    if (obj->pwm == PWM_4) __TIM4_CLK_ENABLE();
-#if defined(TIM8_BASE)
-    if (obj->pwm == PWM_8) __TIM8_CLK_ENABLE();
-#endif
-    if (obj->pwm == PWM_9) __TIM9_CLK_ENABLE();
-    if (obj->pwm == PWM_10) __TIM10_CLK_ENABLE();
-    if (obj->pwm == PWM_11) __TIM11_CLK_ENABLE();
-#if defined(TIM13_BASE)
-    if (obj->pwm == PWM_13) __TIM13_CLK_ENABLE();
-#endif
-#if defined(TIM14_BASE)
-    if (obj->pwm == PWM_14) __TIM14_CLK_ENABLE();
-#endif
+    if (obj->pwm ==  PWM_1) __HAL_RCC_TIM1_CLK_ENABLE();
+    if (obj->pwm ==  PWM_2) __HAL_RCC_TIM2_CLK_ENABLE();
+    if (obj->pwm ==  PWM_3) __HAL_RCC_TIM3_CLK_ENABLE();
+    if (obj->pwm ==  PWM_4) __HAL_RCC_TIM4_CLK_ENABLE();
+    if (obj->pwm ==  PWM_8) __HAL_RCC_TIM8_CLK_ENABLE();
+    if (obj->pwm ==  PWM_9) __HAL_RCC_TIM9_CLK_ENABLE();
+    if (obj->pwm == PWM_10) __HAL_RCC_TIM10_CLK_ENABLE();
+    if (obj->pwm == PWM_11) __HAL_RCC_TIM11_CLK_ENABLE();
+    if (obj->pwm == PWM_13) __HAL_RCC_TIM13_CLK_ENABLE();
+    if (obj->pwm == PWM_14) __HAL_RCC_TIM14_CLK_ENABLE();
 
     // Configure GPIO
     pinmap_pinout(pin, PinMap_PWM);
@@ -91,7 +85,6 @@
 {
     TIM_OC_InitTypeDef sConfig;
     int channel = 0;
-    int complementary_channel = 0;
 
     TimHandle.Instance = (TIM_TypeDef *)(obj->pwm);
 
@@ -112,31 +105,28 @@
     sConfig.OCIdleState  = TIM_OCIDLESTATE_RESET;
     sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;
 
-    complementary_channel = obj->inverted;
     switch (obj->channel) {
-
         case 1:
             channel = TIM_CHANNEL_1;
             break;
-
         case 2:
             channel = TIM_CHANNEL_2;
             break;
-
         case 3:
             channel = TIM_CHANNEL_3;
             break;
-
         case 4:
             channel = TIM_CHANNEL_4;
             break;
-
         default:
             return;
     }
 
-    HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, channel);
-    if (complementary_channel) {
+    if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, channel) != HAL_OK) {
+        error("Cannot configure PWM channel");
+    }
+
+    if (obj->inverted) {
         HAL_TIMEx_PWMN_Start(&TimHandle, channel);
     } else {
         HAL_TIM_PWM_Start(&TimHandle, channel);
@@ -165,88 +155,43 @@
 void pwmout_period_us(pwmout_t* obj, int us)
 {
     TimHandle.Instance = (TIM_TypeDef *)(obj->pwm);
-    RCC_ClkInitTypeDef RCC_ClkInitStruct;
     uint32_t PclkFreq;
-    uint32_t APBxCLKDivider;
+
     float dc = pwmout_read(obj);
 
     __HAL_TIM_DISABLE(&TimHandle);
 
-    // Update the SystemCoreClock variable
-    SystemCoreClockUpdate();
-
-    HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &PclkFreq);
-
+    // Get the PCLK used by the timer
     switch (obj->pwm) {
-
-        case PWM_1:
-            PclkFreq       = HAL_RCC_GetPCLK2Freq();
-            APBxCLKDivider = RCC_ClkInitStruct.APB2CLKDivider;
-            break;
-
         case PWM_2:
-            PclkFreq       = HAL_RCC_GetPCLK1Freq();
-            APBxCLKDivider = RCC_ClkInitStruct.APB1CLKDivider;
-            break;
-
         case PWM_3:
-            PclkFreq       = HAL_RCC_GetPCLK1Freq();
-            APBxCLKDivider = RCC_ClkInitStruct.APB1CLKDivider;
-            break;
-
         case PWM_4:
-            PclkFreq       = HAL_RCC_GetPCLK1Freq();
-            APBxCLKDivider = RCC_ClkInitStruct.APB1CLKDivider;
-            break;
-
-#if defined(TIM8_BASE)
-        case PWM_8:
-            PclkFreq       = HAL_RCC_GetPCLK2Freq();
-            APBxCLKDivider = RCC_ClkInitStruct.APB2CLKDivider;
+        case PWM_5:
+        case PWM_12:
+        case PWM_13:
+        case PWM_14:
+            PclkFreq = HAL_RCC_GetPCLK1Freq();
             break;
-#endif
-
+        case PWM_1:
+        case PWM_8:
         case PWM_9:
-            PclkFreq       = HAL_RCC_GetPCLK2Freq();
-            APBxCLKDivider = RCC_ClkInitStruct.APB2CLKDivider;
-            break;
-
         case PWM_10:
-            PclkFreq       = HAL_RCC_GetPCLK2Freq();
-            APBxCLKDivider = RCC_ClkInitStruct.APB2CLKDivider;
-            break;
-
         case PWM_11:
-            PclkFreq       = HAL_RCC_GetPCLK2Freq();
-            APBxCLKDivider = RCC_ClkInitStruct.APB2CLKDivider;
+            PclkFreq = HAL_RCC_GetPCLK2Freq();
             break;
-
-#if defined(TIM13_BASE)
-        case PWM_13:
-            PclkFreq       = HAL_RCC_GetPCLK1Freq();
-            APBxCLKDivider = RCC_ClkInitStruct.APB1CLKDivider;
-            break;
-#endif
-
-#if defined(TIM14_BASE)
-        case PWM_14:
-            PclkFreq       = HAL_RCC_GetPCLK1Freq();
-            APBxCLKDivider = RCC_ClkInitStruct.APB1CLKDivider;
-            break;
-#endif
-
         default:
             return;
     }
 
     TimHandle.Init.Period        = us - 1;
-    if (APBxCLKDivider == RCC_HCLK_DIV1)
-      TimHandle.Init.Prescaler   = (uint16_t)((PclkFreq*2) / 1000000) - 1; // 1 µs tick
-    else
-      TimHandle.Init.Prescaler   = (uint16_t)((PclkFreq) / 1000000) - 1; // 1 µs tick
+    // TIMxCLK = 2 x PCLKx when the APB prescaler is not equal to 1 (DIV4 or DIV2 in our case)
+    TimHandle.Init.Prescaler     = (uint16_t)((PclkFreq * 2) / 1000000) - 1; // 1 us tick
     TimHandle.Init.ClockDivision = 0;
     TimHandle.Init.CounterMode   = TIM_COUNTERMODE_UP;
-    HAL_TIM_PWM_Init(&TimHandle);
+
+    if (HAL_TIM_PWM_Init(&TimHandle) != HAL_OK) {
+        error("Cannot initialize PWM");
+    }
 
     // Set duty cycle again
     pwmout_write(obj, dc);
--- a/targets/hal/TARGET_STM/TARGET_STM32F7/rtc_api.c	Thu Jul 02 16:30:08 2015 +0100
+++ b/targets/hal/TARGET_STM/TARGET_STM32F7/rtc_api.c	Mon Jul 06 09:00:34 2015 +0100
@@ -59,8 +59,8 @@
 
     // Enable LSE Oscillator
     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
-    RCC_OscInitStruct.PLL.PLLState   = RCC_PLL_NONE; /* Mandatory, otherwise the PLL is reconfigured! */
-    RCC_OscInitStruct.LSEState       = RCC_LSE_ON; /* External 32.768 kHz clock on OSC_IN/OSC_OUT */
+    RCC_OscInitStruct.PLL.PLLState   = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured!
+    RCC_OscInitStruct.LSEState       = RCC_LSE_ON; // External 32.768 kHz clock on OSC_IN/OSC_OUT
     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK) {
         // Connect LSE to RTC
         __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSE);
--- a/targets/hal/TARGET_STM/TARGET_STM32F7/serial_api.c	Thu Jul 02 16:30:08 2015 +0100
+++ b/targets/hal/TARGET_STM/TARGET_STM32F7/serial_api.c	Mon Jul 06 09:00:34 2015 +0100
@@ -36,6 +36,7 @@
 #include "pinmap.h"
 #include <string.h>
 #include "PeripheralPins.h"
+#include "mbed_error.h"
 
 #define UART_NUM (8)
 
@@ -66,7 +67,9 @@
         UartHandle.Init.Mode = UART_MODE_TX_RX;
     }
 
-    HAL_UART_Init(&UartHandle);
+    if (HAL_UART_Init(&UartHandle) != HAL_OK) {
+        error("Cannot initialize UART");
+    }
 }
 
 void serial_init(serial_t *obj, PinName tx, PinName rx)
@@ -282,21 +285,21 @@
 }
 
 #if defined(USART3_BASE)
-static void uart3_irq(void) 
+static void uart3_irq(void)
 {
     uart_irq(UART_3, 2);
 }
 #endif
 
 #if defined(UART4_BASE)
-static void uart4_irq(void) 
+static void uart4_irq(void)
 {
     uart_irq(UART_4, 3);
 }
 #endif
 
 #if defined(UART5_BASE)
-static void uart5_irq(void) 
+static void uart5_irq(void)
 {
     uart_irq(UART_5, 4);
 }
@@ -308,14 +311,14 @@
 }
 
 #if defined(UART7_BASE)
-static void uart7_irq(void) 
+static void uart7_irq(void)
 {
     uart_irq(UART_7, 6);
 }
 #endif
 
 #if defined(UART8_BASE)
-static void uart8_irq(void) 
+static void uart8_irq(void)
 {
     uart_irq(UART_8, 7);
 }
--- a/targets/hal/TARGET_STM/TARGET_STM32F7/sleep.c	Thu Jul 02 16:30:08 2015 +0100
+++ b/targets/hal/TARGET_STM/TARGET_STM32F7/sleep.c	Mon Jul 06 09:00:34 2015 +0100
@@ -54,7 +54,7 @@
     // Request to enter STOP mode with regulator in low power mode
     HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
 
-    // After wake-up from STOP reconfigure the PLL
+    // After wake-up from STOP need to reconfigure the system clock
     SetSysClock();
 }
 
--- a/targets/hal/TARGET_STM/TARGET_STM32F7/spi_api.c	Thu Jul 02 16:30:08 2015 +0100
+++ b/targets/hal/TARGET_STM/TARGET_STM32F7/spi_api.c	Mon Jul 06 09:00:34 2015 +0100
@@ -36,6 +36,7 @@
 #include "cmsis.h"
 #include "pinmap.h"
 #include "PeripheralPins.h"
+#include "mbed_error.h"
 
 static SPI_HandleTypeDef SpiHandle;
 
@@ -57,7 +58,9 @@
     SpiHandle.Init.NSS               = obj->nss;
     SpiHandle.Init.TIMode            = SPI_TIMODE_DISABLED;
 
-    HAL_SPI_Init(&SpiHandle);
+    if (HAL_SPI_Init(&SpiHandle) != HAL_OK) {
+        error("Cannot initialize SPI");
+    }
 
     __HAL_SPI_ENABLE(&SpiHandle);
 }
@@ -77,29 +80,13 @@
     MBED_ASSERT(obj->spi != (SPIName)NC);
 
     // Enable SPI clock
-    if (obj->spi == SPI_1) {
-        __SPI1_CLK_ENABLE();
-    }
-
     if (obj->spi == SPI_2) {
-        __SPI2_CLK_ENABLE();
-    }
-
-    if (obj->spi == SPI_3) {
-        __SPI3_CLK_ENABLE();
+        __HAL_RCC_SPI2_CLK_ENABLE();
     }
 
-#if defined SPI4_BASE
-    if (obj->spi == SPI_4) {
-        __SPI4_CLK_ENABLE();
+    if (obj->spi == SPI_5) {
+        __HAL_RCC_SPI5_CLK_ENABLE();
     }
-#endif
-
-#if defined SPI5_BASE
-    if (obj->spi == SPI_5) {
-        __SPI5_CLK_ENABLE();
-    }
-#endif
 
     // Configure the SPI pins
     pinmap_pinout(mosi, PinMap_SPI_MOSI);
@@ -129,40 +116,18 @@
 void spi_free(spi_t *obj)
 {
     // Reset SPI and disable clock
-    if (obj->spi == SPI_1) {
-        __SPI1_FORCE_RESET();
-        __SPI1_RELEASE_RESET();
-        __SPI1_CLK_DISABLE();
-    }
-
     if (obj->spi == SPI_2) {
-        __SPI2_FORCE_RESET();
-        __SPI2_RELEASE_RESET();
-        __SPI2_CLK_DISABLE();
+        __HAL_RCC_SPI2_FORCE_RESET();
+        __HAL_RCC_SPI2_RELEASE_RESET();
+        __HAL_RCC_SPI2_CLK_DISABLE();
     }
 
-    if (obj->spi == SPI_3) {
-        __SPI3_FORCE_RESET();
-        __SPI3_RELEASE_RESET();
-        __SPI3_CLK_DISABLE();
+    if (obj->spi == SPI_5) {
+        __HAL_RCC_SPI5_FORCE_RESET();
+        __HAL_RCC_SPI5_RELEASE_RESET();
+        __HAL_RCC_SPI5_CLK_DISABLE();
     }
 
-#if defined SPI4_BASE
-    if (obj->spi == SPI_4) {
-        __SPI4_FORCE_RESET();
-        __SPI4_RELEASE_RESET();
-        __SPI4_CLK_DISABLE();
-    }
-#endif
-
-#if defined SPI5_BASE
-    if (obj->spi == SPI_5) {
-        __SPI5_FORCE_RESET();
-        __SPI5_RELEASE_RESET();
-        __SPI5_CLK_DISABLE();
-    }
-#endif
-
     // Configure GPIOs
     pin_function(obj->pin_miso, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
     pin_function(obj->pin_mosi, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
@@ -209,108 +174,48 @@
 
 void spi_frequency(spi_t *obj, int hz)
 {
-#if defined(TARGET_STM32F401RE) || defined(TARGET_STM32F401VC) || defined(TARGET_STM32F407VG)
-    // Note: The frequencies are obtained with SPI1 clock = 84 MHz (APB2 clock)
-    if (hz < 600000) {
-        obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 330 kHz
-    } else if ((hz >= 600000) && (hz < 1000000)) {
-        obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 656 kHz
-    } else if ((hz >= 1000000) && (hz < 2000000)) {
-        obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1.3 MHz
-    } else if ((hz >= 2000000) && (hz < 5000000)) {
-        obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 2.6 MHz
-    } else if ((hz >= 5000000) && (hz < 10000000)) {
-        obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 5.25 MHz
-    } else if ((hz >= 10000000) && (hz < 21000000)) {
-        obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 10.5 MHz
-    } else if ((hz >= 21000000) && (hz < 42000000)) {
-        obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 21 MHz
-    } else { // >= 42000000
-        obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 42 MHz
-    }
-#elif defined(TARGET_STM32F405RG)
-    // Note: The frequencies are obtained with SPI1 clock = 48 MHz (APB2 clock)
-    if (obj->spi == SPI_1) {
-        if (hz < 375000) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 187.5 kHz
-        } else if ((hz >= 375000) && (hz < 750000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 375 kHz
-        } else if ((hz >= 750000) && (hz < 1500000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 0.75 MHz
-        } else if ((hz >= 1500000) && (hz < 3000000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1.5 MHz
-        } else if ((hz >= 3000000) && (hz < 6000000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 3 MHz
-        } else if ((hz >= 6000000) && (hz < 12000000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 6 MHz
-        } else if ((hz >= 12000000) && (hz < 24000000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 12 MHz
-        } else { // >= 24000000
-            obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 24 MHz
-        }
-    // Note: The frequencies are obtained with SPI2/3 clock = 48 MHz (APB1 clock)
-    } else if ((obj->spi == SPI_2) || (obj->spi == SPI_3)) {
-        if (hz < 375000) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 187.5 kHz
-        } else if ((hz >= 375000) && (hz < 750000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 375 kHz
-        } else if ((hz >= 750000) && (hz < 1500000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 0.75 MHz
-        } else if ((hz >= 1500000) && (hz < 3000000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1.5 MHz
+    // The frequencies are obtained with:
+    // - SPI2 clock =  54 MHz (APB1 clock)
+    // - SPI5 clock = 108 MHz (APB2 clock)
+    if (obj->spi == SPI_2) {
+        if (hz < 400000) {
+            obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 211 kHz
+        } else if ((hz >= 400000) && (hz < 800000)) {
+            obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 422 kHz
+        } else if ((hz >= 800000) && (hz < 1000000)) {
+            obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 844 kHz
+        } else if ((hz >= 1000000) && (hz < 3000000)) {
+            obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1.69 MHz
         } else if ((hz >= 3000000) && (hz < 6000000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 3 MHz
-        } else if ((hz >= 6000000) && (hz < 12000000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 6 MHz
-        } else if ((hz >= 12000000) && (hz < 24000000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 12 MHz
-        } else { // >= 24000000
-            obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 24 MHz
-        }
-    }
-#elif defined(TARGET_STM32F411RE) || defined(TARGET_STM32F429ZI)
-    // Values depend of PCLK2: 100 MHz
-    if ((obj->spi == SPI_1) || (obj->spi == SPI_4) || (obj->spi == SPI_5)) {
-        if (hz < 700000) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 391 kHz
-        } else if ((hz >= 700000) && (hz < 1000000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 781 kHz
-        } else if ((hz >= 1000000) && (hz < 3000000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_64;  // 1.56 MHz
-        } else if ((hz >= 3000000) && (hz < 6000000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_32;  // 3.13 MHz
+            obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 3.38 MHz
         } else if ((hz >= 6000000) && (hz < 12000000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_16;  // 6.25 MHz
-        } else if ((hz >= 12000000) && (hz < 25000000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_8;   // 12.5 MHz
-        } else if ((hz >= 25000000) && (hz < 50000000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_4;   // 25 MHz
-        } else { // >= 50000000
-            obj->br_presc = SPI_BAUDRATEPRESCALER_2;   // 50 MHz
+            obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 6.75 MHz
+        } else if ((hz >= 12000000) && (hz < 24000000)) {
+            obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 13.5 MHz
+        } else { // >= 24000000
+            obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 27 MHz
         }
+    } else if (obj->spi == SPI_5) {
+        if (hz < 800000) {
+            obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 422 kHz
+        } else if ((hz >= 800000) && (hz < 1000000)) {
+            obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 844 kHz
+        } else if ((hz >= 1000000) && (hz < 3000000)) {
+            obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1.69 MHz
+        } else if ((hz >= 3000000) && (hz < 6000000)) {
+            obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 3.38 MHz
+        } else if ((hz >= 6000000) && (hz < 12000000)) {
+            obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 6.75 MHz
+        } else if ((hz >= 12000000) && (hz < 24000000)) {
+            obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 13.5 MHz
+        } else if ((hz >= 24000000) && (hz < 54000000)) {
+            obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 27 MHz
+        } else { // >= 54000000
+            obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 54 MHz
+        }
+    } else {
+        return;
     }
-
-    // Values depend of PCLK1: 50 MHz
-    if ((obj->spi == SPI_2) || (obj->spi == SPI_3)) {
-        if (hz < 400000) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 195 kHz
-        } else if ((hz >= 400000) && (hz < 700000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 391 kHz
-        } else if ((hz >= 700000) && (hz < 1000000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_64;  // 781 MHz
-        } else if ((hz >= 1000000) && (hz < 3000000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_32;  // 1.56 MHz
-        } else if ((hz >= 3000000) && (hz < 6000000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_16;  // 3.13 MHz
-        } else if ((hz >= 6000000) && (hz < 12000000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_8;   // 6.25 MHz
-        } else if ((hz >= 12000000) && (hz < 25000000)) {
-            obj->br_presc = SPI_BAUDRATEPRESCALER_4;   // 12.5 MHz
-        } else { // >= 25000000
-            obj->br_presc = SPI_BAUDRATEPRESCALER_2;   // 25 MHz
-        }
-    }
-#endif
     init_spi(obj);
 }
 
@@ -336,14 +241,28 @@
 {
     SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
     while (!ssp_writeable(obj));
-    spi->DR = (uint16_t)value;
+    if (obj->bits == SPI_DATASIZE_8BIT) {
+        // Force 8-bit access to the data register
+        uint8_t *p_spi_dr = 0;
+        p_spi_dr = (uint8_t *) & (spi->DR);
+        *p_spi_dr = (uint8_t)value;
+    } else { // SPI_DATASIZE_16BIT
+        spi->DR = (uint16_t)value;
+    }
 }
 
 static inline int ssp_read(spi_t *obj)
 {
     SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
     while (!ssp_readable(obj));
-    return (int)spi->DR;
+    if (obj->bits == SPI_DATASIZE_8BIT) {
+        // Force 8-bit access to the data register
+        uint8_t *p_spi_dr = 0;
+        p_spi_dr = (uint8_t *) & (spi->DR);
+        return (int)(*p_spi_dr);
+    } else {
+        return (int)spi->DR;
+    }
 }
 
 static inline int ssp_busy(spi_t *obj)
@@ -369,14 +288,28 @@
 {
     SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
     while (!ssp_readable(obj));
-    return (int)spi->DR;
+    if (obj->bits == SPI_DATASIZE_8BIT) {
+        // Force 8-bit access to the data register
+        uint8_t *p_spi_dr = 0;
+        p_spi_dr = (uint8_t *) & (spi->DR);
+        return (int)(*p_spi_dr);
+    } else {
+        return (int)spi->DR;
+    }
 }
 
 void spi_slave_write(spi_t *obj, int value)
 {
     SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
     while (!ssp_writeable(obj));
-    spi->DR = (uint16_t)value;
+    if (obj->bits == SPI_DATASIZE_8BIT) {
+        // Force 8-bit access to the data register
+        uint8_t *p_spi_dr = 0;
+        p_spi_dr = (uint8_t *) & (spi->DR);
+        *p_spi_dr = (uint8_t)value;
+    } else { // SPI_DATASIZE_16BIT
+        spi->DR = (uint16_t)value;
+    }
 }
 
 int spi_busy(spi_t *obj)