Il y avait des problèmes dans la libraire...

Dependents:   X_NUCLEO_CCA02M1

Fork of ST_I2S by ST

Revision:
2:0c9ce59aee25
Parent:
1:f90318e0923b
Child:
3:25de898f5354
--- a/targets/TARGET_STM/stm_i2s_api.c	Tue Nov 29 14:43:26 2016 +0100
+++ b/targets/TARGET_STM/stm_i2s_api.c	Tue Dec 13 18:09:02 2016 +0100
@@ -11,8 +11,9 @@
 #include "cmsis.h"
 #include "pinmap.h"
 #include "PeripheralPins.h"
+#include "StmI2sPeripheralPins.h"
 
-// #define DEBUG_STDIO 1 // betzw - TODO: temporarily enable debug printfs
+//#define DEBUG_STDIO 1 // betzw - TODO: temporarily enable debug printfs
 
 #ifndef DEBUG_STDIO
 #   define DEBUG_STDIO 0
@@ -41,8 +42,7 @@
 static I2S_HandleTypeDef I2sHandle[I2S_NUM];
 static DMA_HandleTypeDef DMaHandles[I2S_NUM][NUM_OF_DIRECTIONS];
 
-static void init_i2s(i2s_t *obj)
-{
+static void init_i2s(i2s_t *obj) {
     I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module];
 
     __HAL_I2S_DISABLE(handle);
@@ -50,83 +50,82 @@
     __HAL_I2S_ENABLE(handle);
 }
 
-static void init_dmas(i2s_t *obj)
-{
+static void init_dmas(i2s_t *obj) {
     DMA_HandleTypeDef *primary_handle = NULL;
     DMA_HandleTypeDef *secondary_handle = NULL;
     DMA_HandleTypeDef *hdmatx = NULL;
 
     switch(obj->dma.dma_direction) {
-    case DMA_TX:
-	if(obj->dma.dma[DMA_TX] != NULL) {
-	    hdmatx = primary_handle = &DMaHandles[obj->i2s.module][DMA_TX];
-	}
-	if(obj->dma.dma[DMA_RX] != NULL) {
-	    secondary_handle = &DMaHandles[obj->i2s.module][DMA_RX];
-	}
-	break;
-    case DMA_RX:
-    default:
-	if(obj->dma.dma[DMA_RX] != NULL) {
-	    primary_handle = &DMaHandles[obj->i2s.module][DMA_RX];
-	}
-	if(obj->dma.dma[DMA_TX] != NULL) {
-	    hdmatx = secondary_handle = &DMaHandles[obj->i2s.module][DMA_TX];
-	}
-	break;
+	    case DMA_TX:
+			if(obj->dma.dma[DMA_TX] != NULL) {
+			    hdmatx = primary_handle = &DMaHandles[obj->i2s.module][DMA_TX];
+			}
+			if(obj->dma.dma[DMA_RX] != NULL) {
+			    secondary_handle = &DMaHandles[obj->i2s.module][DMA_RX];
+			}
+			break;
+	    case DMA_RX:
+    	default:
+			if(obj->dma.dma[DMA_RX] != NULL) {
+			    primary_handle = &DMaHandles[obj->i2s.module][DMA_RX];
+			}
+			if(obj->dma.dma[DMA_TX] != NULL) {
+			    hdmatx = secondary_handle = &DMaHandles[obj->i2s.module][DMA_TX];
+			}
+			break;
     }
 
     if(primary_handle != NULL) {
-	__HAL_DMA_DISABLE(primary_handle);
-	HAL_DMA_Init(primary_handle);
+		__HAL_DMA_DISABLE(primary_handle);
+		HAL_DMA_Init(primary_handle);
 
-	if(hdmatx == primary_handle) {
-	    __HAL_LINKDMA(&I2sHandle[obj->i2s.module], hdmatx, *primary_handle);
-	} else {
-	    __HAL_LINKDMA(&I2sHandle[obj->i2s.module], hdmarx, *primary_handle);
-	}
+		if(hdmatx == primary_handle) {
+		    __HAL_LINKDMA(&I2sHandle[obj->i2s.module], hdmatx, *primary_handle);
+		} else {
+		    __HAL_LINKDMA(&I2sHandle[obj->i2s.module], hdmarx, *primary_handle);
+		}
     }
 
     if(secondary_handle != NULL) {
-	__HAL_DMA_DISABLE(secondary_handle);
-	HAL_DMA_Init(secondary_handle);
+		__HAL_DMA_DISABLE(secondary_handle);
+		HAL_DMA_Init(secondary_handle);
 
-	if(hdmatx == secondary_handle) {
-	    __HAL_LINKDMA(&I2sHandle[obj->i2s.module], hdmatx, *secondary_handle);
-	} else {
-	    __HAL_LINKDMA(&I2sHandle[obj->i2s.module], hdmarx, *secondary_handle);
-	}
+		if(hdmatx == secondary_handle) {
+		    __HAL_LINKDMA(&I2sHandle[obj->i2s.module], hdmatx, *secondary_handle);
+		} else {
+		    __HAL_LINKDMA(&I2sHandle[obj->i2s.module], hdmarx, *secondary_handle);
+		}
     }
 }
 
 static inline uint32_t i2s_get_mode(i2s_mode_t mode, uint8_t *direction) {
     switch(mode) {
-    case SLAVE_TX:
-	*direction = DMA_TX;
-	return I2S_MODE_SLAVE_TX;
-    case SLAVE_RX:
-	*direction = DMA_RX;
-	return I2S_MODE_SLAVE_RX;
-    case MASTER_TX:
-	*direction = DMA_TX;
-	return I2S_MODE_MASTER_TX;
-    case MASTER_RX:
-    default:
-	*direction = DMA_RX;
-	return I2S_MODE_MASTER_RX;
+	    case SLAVE_TX:
+			*direction = DMA_TX;
+			return I2S_MODE_SLAVE_TX;
+	    case SLAVE_RX:
+			*direction = DMA_RX;
+			return I2S_MODE_SLAVE_RX;
+	    case MASTER_TX:
+			*direction = DMA_TX;
+			return I2S_MODE_MASTER_TX;
+	    case MASTER_RX:
+	    default:
+			*direction = DMA_RX;
+			return I2S_MODE_MASTER_RX;
     }
 }
 
 static inline uint32_t i2s_get_priority(i2s_dma_prio_t priority) {
     switch(priority) {
-    case LOW:
-	return DMA_PRIORITY_LOW;
-    case URGENT:
-	return DMA_PRIORITY_VERY_HIGH;
-    case HIGH:
-	return DMA_PRIORITY_HIGH;
-    default:
-	return DMA_PRIORITY_MEDIUM;
+	    case LOW:
+			return DMA_PRIORITY_LOW;
+	    case URGENT:
+			return DMA_PRIORITY_VERY_HIGH;
+	    case HIGH:
+			return DMA_PRIORITY_HIGH;
+	    default:
+			return DMA_PRIORITY_MEDIUM;
     }
 }
 
@@ -136,82 +135,82 @@
     DMA_HandleTypeDef *secondary_handle = NULL;
 
     // DMA initialization & configuration
-    dma_init();
+    stm_dma_init();
     obj->dma.dma[DMA_TX] = obj->dma.dma[DMA_RX] = NULL;
 
     switch(obj->dma.dma_direction) {
-    case DMA_TX:
-	if(*use_tx) {
-	    obj->dma.dma[DMA_TX] = dma_channel_allocate(MAKE_CAP(obj->dma.dma_device, DMA_TX));
-	    MBED_ASSERT(obj->dma.dma[DMA_TX] != DMA_ERROR_OUT_OF_CHANNELS);
-	}
-	break;
-    case DMA_RX:
-    default:
-	if(*use_rx) {
-	    obj->dma.dma[DMA_RX] = dma_channel_allocate(MAKE_CAP(obj->dma.dma_device, DMA_RX));
-	    MBED_ASSERT(obj->dma.dma[DMA_RX] != DMA_ERROR_OUT_OF_CHANNELS);
-	}
-	break;
+	    case DMA_TX:
+			if(*use_tx) {
+			    obj->dma.dma[DMA_TX] = stm_dma_channel_allocate(MAKE_CAP(obj->dma.dma_device, DMA_TX));
+			    MBED_ASSERT(obj->dma.dma[DMA_TX] != DMA_ERROR_OUT_OF_CHANNELS);
+			}
+			break;
+	    case DMA_RX:
+	    default:
+			if(*use_rx) {
+			    obj->dma.dma[DMA_RX] = stm_dma_channel_allocate(MAKE_CAP(obj->dma.dma_device, DMA_RX));
+			    MBED_ASSERT(obj->dma.dma[DMA_RX] != DMA_ERROR_OUT_OF_CHANNELS);
+			}
+			break;
     }
 
     // Primary DMA configuration
     if(obj->dma.dma[obj->dma.dma_direction] != NULL) {
-	primary_handle->Instance = obj->dma.dma[obj->dma.dma_direction]->dma_stream;
-	primary_handle->Init.Channel = obj->dma.dma[obj->dma.dma_direction]->channel_nr;
-	primary_handle->Init.Direction = (obj->dma.dma_direction == DMA_TX) ? 
-	    DMA_MEMORY_TO_PERIPH : DMA_PERIPH_TO_MEMORY;
-	primary_handle->Init.FIFOMode = DMA_FIFOMODE_DISABLE;
-	primary_handle->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
-	primary_handle->Init.MemBurst = DMA_MBURST_SINGLE;
-	primary_handle->Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
-	primary_handle->Init.MemInc = DMA_MINC_ENABLE;
-	primary_handle->Init.Mode = (circular ? DMA_CIRCULAR : DMA_NORMAL);
-	primary_handle->Init.PeriphBurst = DMA_PBURST_SINGLE;
-	primary_handle->Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
-	primary_handle->Init.PeriphInc = DMA_PINC_DISABLE;
-	primary_handle->Init.Priority = i2s_get_priority(prio);
+		primary_handle->Instance = obj->dma.dma[obj->dma.dma_direction]->dma_stream;
+		primary_handle->Init.Channel = obj->dma.dma[obj->dma.dma_direction]->channel_nr;
+		primary_handle->Init.Direction = (obj->dma.dma_direction == DMA_TX) ? 
+		    DMA_MEMORY_TO_PERIPH : DMA_PERIPH_TO_MEMORY;
+		primary_handle->Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+		primary_handle->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+		primary_handle->Init.MemBurst = DMA_MBURST_SINGLE;
+		primary_handle->Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
+		primary_handle->Init.MemInc = DMA_MINC_ENABLE;
+		primary_handle->Init.Mode = (circular ? DMA_CIRCULAR : DMA_NORMAL);
+		primary_handle->Init.PeriphBurst = DMA_PBURST_SINGLE;
+		primary_handle->Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
+		primary_handle->Init.PeriphInc = DMA_PINC_DISABLE;
+		primary_handle->Init.Priority = i2s_get_priority(prio);
     }
 
     // Allocate secondary DMA channel (if full-duplex)
     if(obj->i2s.pin_fdpx != NC) {
-	switch(obj->dma.dma_direction) {
-	case DMA_TX:
-	    if(*use_rx) {
-		obj->dma.dma[DMA_RX] = dma_channel_allocate(MAKE_CAP(obj->dma.dma_device, DMA_RX));
-		secondary_handle = &DMaHandles[obj->i2s.module][DMA_RX];
-		MBED_ASSERT(obj->dma.dma[DMA_RX] != DMA_ERROR_OUT_OF_CHANNELS);
-	    }
-	    break;
-	case DMA_RX:
-	default:
-	    if(*use_tx) {
-		obj->dma.dma[DMA_TX] = dma_channel_allocate(MAKE_CAP(obj->dma.dma_device, DMA_TX));
-		secondary_handle = &DMaHandles[obj->i2s.module][DMA_TX];
-		MBED_ASSERT(obj->dma.dma[DMA_TX] != DMA_ERROR_OUT_OF_CHANNELS);
-	    }
-	    break;
-	}
+		switch(obj->dma.dma_direction) {
+			case DMA_TX:
+			    if(*use_rx) {
+				obj->dma.dma[DMA_RX] = stm_dma_channel_allocate(MAKE_CAP(obj->dma.dma_device, DMA_RX));
+				secondary_handle = &DMaHandles[obj->i2s.module][DMA_RX];
+				MBED_ASSERT(obj->dma.dma[DMA_RX] != DMA_ERROR_OUT_OF_CHANNELS);
+			    }
+			    break;
+			case DMA_RX:
+			default:
+			    if(*use_tx) {
+				obj->dma.dma[DMA_TX] = stm_dma_channel_allocate(MAKE_CAP(obj->dma.dma_device, DMA_TX));
+				secondary_handle = &DMaHandles[obj->i2s.module][DMA_TX];
+				MBED_ASSERT(obj->dma.dma[DMA_TX] != DMA_ERROR_OUT_OF_CHANNELS);
+			    }
+			    break;
+		}
     }
 
     // Secondary DMA configuration
     if(secondary_handle != NULL) {
-	uint8_t secondary_dma_direction = (obj->dma.dma_direction == DMA_TX) ? DMA_RX : DMA_TX;
+		uint8_t secondary_dma_direction = (obj->dma.dma_direction == DMA_TX) ? DMA_RX : DMA_TX;
 
-	secondary_handle->Instance = obj->dma.dma[secondary_dma_direction]->dma_stream;
-	secondary_handle->Init.Channel = obj->dma.dma[secondary_dma_direction]->channel_nr_fd;
-	secondary_handle->Init.Direction = (secondary_dma_direction == DMA_TX) ? 
-	    DMA_MEMORY_TO_PERIPH : DMA_PERIPH_TO_MEMORY;
-	secondary_handle->Init.FIFOMode = DMA_FIFOMODE_DISABLE;
-	secondary_handle->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
-	secondary_handle->Init.MemBurst = DMA_MBURST_SINGLE;
-	secondary_handle->Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
-	secondary_handle->Init.MemInc = DMA_MINC_ENABLE;
-	secondary_handle->Init.Mode = (circular ? DMA_CIRCULAR : DMA_NORMAL);
-	secondary_handle->Init.PeriphBurst = DMA_PBURST_SINGLE;
-	secondary_handle->Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
-	secondary_handle->Init.PeriphInc = DMA_PINC_DISABLE;
-	secondary_handle->Init.Priority = i2s_get_priority(prio);
+		secondary_handle->Instance = obj->dma.dma[secondary_dma_direction]->dma_stream;
+		secondary_handle->Init.Channel = obj->dma.dma[secondary_dma_direction]->channel_nr_fd;
+		secondary_handle->Init.Direction = (secondary_dma_direction == DMA_TX) ? 
+		    DMA_MEMORY_TO_PERIPH : DMA_PERIPH_TO_MEMORY;
+		secondary_handle->Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+		secondary_handle->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+		secondary_handle->Init.MemBurst = DMA_MBURST_SINGLE;
+		secondary_handle->Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
+		secondary_handle->Init.MemInc = DMA_MINC_ENABLE;
+		secondary_handle->Init.Mode = (circular ? DMA_CIRCULAR : DMA_NORMAL);
+		secondary_handle->Init.PeriphBurst = DMA_PBURST_SINGLE;
+		secondary_handle->Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
+		secondary_handle->Init.PeriphInc = DMA_PINC_DISABLE;
+		secondary_handle->Init.Priority = i2s_get_priority(prio);
     }
 
     if(obj->dma.dma[DMA_TX] == NULL) *use_tx = false;
@@ -219,11 +218,12 @@
 
     // don't do anything, if the buffers aren't valid
     if (!use_tx && !use_rx) {
-	DEBUG_PRINTF("I2S%u: No DMAs to init\n", obj->i2s.module+1);
-	return;
+		DEBUG_PRINTF("    I2S%u: No DMAs to init\r\n", obj->i2s.module + 1);
+		return;
     }
 
-    DEBUG_PRINTF("I2S%u: DMA(s) Init\n", obj->i2s.module+1);
+    DEBUG_PRINTF("    I2S%u: DMA(s) Init\r\n", obj->i2s.module + 1);
+
     init_dmas(obj);
 }
 
@@ -236,12 +236,11 @@
     NVIC_DisableIRQ(stream->dma_stream_irq);
 
     // free channel
-    dma_channel_free((void*)stream);
+    stm_dma_channel_free((void*)stream);
     obj->dma.dma[direction] = NULL;
 }
 
-void i2s_init(i2s_t *obj, PinName data, PinName sclk, PinName wsel, PinName fdpx, PinName mclk, i2s_mode_t mode)
-{
+void i2s_init(i2s_t *obj, PinName data, PinName sclk, PinName wsel, PinName fdpx, PinName mclk, i2s_mode_t mode) {
     uint8_t dma_dev = 0, dma_direction = 0;
 
     // Determine the I2S/SPI to use
@@ -318,90 +317,108 @@
     obj->i2s.pin_fdpx = fdpx;
     obj->i2s.pin_mclk = mclk;
 
-    /* Configure PLLI2S */
+	/* Configure PLLI2S */
     static bool first_time = true;
-    if(first_time) {
-	RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
+    if (first_time)
+    {
+		RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
 
-	/* Get RTCClockSelection */
-	HAL_RCCEx_GetPeriphCLKConfig(&PeriphClkInitStruct);
+		/* Get RTCClockSelection */
+		HAL_RCCEx_GetPeriphCLKConfig(&PeriphClkInitStruct);
 
-	/* Set default configuration */
-	PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S;
-	PeriphClkInitStruct.PLLI2S.PLLI2SN = 271; // betzw: use values which are suggested in Table 90. of the
-	PeriphClkInitStruct.PLLI2S.PLLI2SR = 2;   //        reference manual for master clock enabled & 44100Hz
+		/* Set default configuration. Default frequency is 44100Hz. */
+		PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S;
+		PeriphClkInitStruct.PLLI2S.PLLI2SN = 271; // betzw: use values which are suggested in Table 91 of the
+		PeriphClkInitStruct.PLLI2S.PLLI2SR = 2;   //        reference manual for master clock enabled & 44100Hz.
+
 #ifdef NDEBUG
-	HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
+		HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
 #else
-	HAL_StatusTypeDef ret = HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
+		HAL_StatusTypeDef ret = HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
 #endif
-	MBED_ASSERT(ret == HAL_OK);
-	first_time = false;
+		MBED_ASSERT(ret == HAL_OK);
+
+		first_time = false;
     }
 
-    // initialize the handle for this master!
+    /* Initializing the handle for this master. */
     I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module];
 
     handle->Instance               = (SPI_TypeDef *)(instance);
     handle->Init.Mode              = i2s_get_mode(mode, &dma_direction);
     handle->Init.Standard          = I2S_STANDARD_PCM_SHORT;
     handle->Init.DataFormat        = I2S_DATAFORMAT_16B;
-    handle->Init.MCLKOutput        = I2S_MCLKOUTPUT_ENABLE; // betzw: always enable master clock to avoid frequency dis-alignment between I2S devices
-    handle->Init.AudioFreq         = I2S_AUDIOFREQ_44K;
     handle->Init.CPOL              = I2S_CPOL_LOW;
+    handle->Init.AudioFreq         = I2S_AUDIOFREQ_44K; //Default frequency is 44100Hz.
     handle->Init.ClockSource       = I2S_CLOCK_PLL;
-    handle->Init.FullDuplexMode    = (fdpx == NC) ? I2S_FULLDUPLEXMODE_DISABLE : I2S_FULLDUPLEXMODE_ENABLE;
+    handle->Init.FullDuplexMode    = (fdpx == NC ? I2S_FULLDUPLEXMODE_DISABLE : I2S_FULLDUPLEXMODE_ENABLE);
+	handle->Init.MCLKOutput        = (mclk == NC ? I2S_MCLKOUTPUT_DISABLE : I2S_MCLKOUTPUT_ENABLE); //Davide: Microphones need master clock disabled, while sound terminal needs it enabled.
+
+    DEBUG_PRINTF("--> %s\r\n", __FUNCTION__);
+    DEBUG_PRINTF("    I2S%u: Mode: %u (%u)\r\n", obj->i2s.module + 1,
+		(unsigned int)handle->Init.Mode, (unsigned int)mode);
+    DEBUG_PRINTF("    I2S%u: Standard: %u\r\n", obj->i2s.module + 1,
+		(unsigned int)handle->Init.Standard);
+    DEBUG_PRINTF("    I2S%u: DataFormat: %u\r\n", obj->i2s.module + 1,
+		(unsigned int)handle->Init.DataFormat);
+    DEBUG_PRINTF("    I2S%u: CPOL: %u\r\n", obj->i2s.module + 1,
+		(unsigned int)handle->Init.CPOL);
+    DEBUG_PRINTF("    I2S%u: AudioFreq: %u\r\n", obj->i2s.module + 1,
+    	(unsigned int)handle->Init.AudioFreq);
+    DEBUG_PRINTF("    I2S%u: ClockSource: %u\r\n", obj->i2s.module + 1,
+    	(unsigned int)handle->Init.ClockSource);
+    DEBUG_PRINTF("    I2S%u: FullDuplexMode: %u\r\n", obj->i2s.module + 1,
+    	(unsigned int)handle->Init.FullDuplexMode);
+    DEBUG_PRINTF("    I2S%u: MCLKOutput: %u\r\n", obj->i2s.module + 1,
+    	(unsigned int)handle->Init.MCLKOutput);
 
     // Save primary DMA direction
     obj->dma.dma_direction = dma_direction;
 
-    DEBUG_PRINTF("I2S%u: Init\n", obj->i2s.module+1);
-
     init_i2s(obj);
 }
 
-void i2s_free(i2s_t *obj)
-{
+void i2s_free(i2s_t *obj) {
     // Reset I2S and disable clock
     switch(obj->i2s.module) {
 #if defined(I2S1ext_BASE)
-    case 0:
-	__SPI1_FORCE_RESET();
-	__SPI1_RELEASE_RESET();
-	__SPI1_CLK_DISABLE();
-	break;
+	    case 0:
+			__SPI1_FORCE_RESET();
+			__SPI1_RELEASE_RESET();
+			__SPI1_CLK_DISABLE();
+			break;
 #endif
 #if defined(I2S2ext_BASE)
-    case 1:
-	__SPI2_FORCE_RESET();
-	__SPI2_RELEASE_RESET();
-	__SPI2_CLK_DISABLE();
-	break;
+	    case 1:
+			__SPI2_FORCE_RESET();
+			__SPI2_RELEASE_RESET();
+			__SPI2_CLK_DISABLE();
+			break;
 #endif
 #if defined(I2S3ext_BASE)
-    case 2:
-	__SPI3_FORCE_RESET();
-	__SPI3_RELEASE_RESET();
-	__SPI3_CLK_DISABLE();
-	break;
+	    case 2:
+			__SPI3_FORCE_RESET();
+			__SPI3_RELEASE_RESET();
+			__SPI3_CLK_DISABLE();
+			break;
 #endif
 #if defined(I2S4ext_BASE)
-    case 3:
-	__SPI4_FORCE_RESET();
-	__SPI4_RELEASE_RESET();
-	__SPI4_CLK_DISABLE();
-	break;
+	    case 3:
+			__SPI4_FORCE_RESET();
+			__SPI4_RELEASE_RESET();
+			__SPI4_CLK_DISABLE();
+			break;
 #endif
 #if defined(I2S5ext_BASE)
-    case 4:
-	__SPI5_FORCE_RESET();
-	__SPI5_RELEASE_RESET();
-	__SPI5_CLK_DISABLE();
-	break;
+	    case 4:
+			__SPI5_FORCE_RESET();
+			__SPI5_RELEASE_RESET();
+			__SPI5_CLK_DISABLE();
+			break;
 #endif
-    default:
-	MBED_ASSERT(0);
-	break;
+	    default:
+			MBED_ASSERT(0);
+			break;
     }
 
     // betzw - TODO: what about 'PLLI2S'?!?
@@ -414,42 +431,48 @@
     pin_function(obj->i2s.pin_fdpx, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
     pin_function(obj->i2s.pin_mclk, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
 
-    DEBUG_PRINTF("I2S%u: Free\n", obj->i2s.module+1);
+    DEBUG_PRINTF("--> %s\r\n", __FUNCTION__);
 }
 
-void i2s_format(i2s_t *obj, int dbits, int fbits, int polarity)
-{
+void i2s_format(i2s_t *obj, int dbits, int fbits, int polarity) {
     I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module];
 
     // Save new values
-    if (fbits == 16) { // format MUST be 16B
-	handle->Init.DataFormat = I2S_DATAFORMAT_16B;
+    if (fbits == 16)
+    { // format MUST be 16B
+		handle->Init.DataFormat = I2S_DATAFORMAT_16B;
     } else { // format may NOT be 16B
-	switch (dbits) {
-	case 16:
-	    handle->Init.DataFormat = I2S_DATAFORMAT_16B_EXTENDED;
-	    break;
-	case 24:
-	    handle->Init.DataFormat = I2S_DATAFORMAT_24B;
-	    break;
-	case 32:
-	default:
-	    handle->Init.DataFormat = I2S_DATAFORMAT_32B;
-	    break;
-	}
+		switch (dbits)
+		{
+			case 16:
+			    handle->Init.DataFormat = I2S_DATAFORMAT_16B_EXTENDED;
+			    break;
+			case 24:
+			    handle->Init.DataFormat = I2S_DATAFORMAT_24B;
+			    break;
+			case 32:
+			default:
+			    handle->Init.DataFormat = I2S_DATAFORMAT_32B;
+			    break;
+		}
     }
 
     handle->Init.CPOL = (polarity == 0) ? I2S_CPOL_LOW : I2S_CPOL_HIGH;
 
-    DEBUG_PRINTF("I2S%u: Format: %u (%u, %u), %u (%u)\n", obj->i2s.module+1,
-		 (unsigned int)handle->Init.DataFormat, (unsigned int)dbits, (unsigned int)fbits,
-		 (unsigned int)handle->Init.CPOL, (unsigned int)polarity);
+    DEBUG_PRINTF("--> %s\r\n", __FUNCTION__);
+    DEBUG_PRINTF("    I2S%u: DataFormat: %u\r\n", obj->i2s.module + 1,
+		(unsigned int)handle->Init.DataFormat);
+    DEBUG_PRINTF("    I2S%u: CPOL: %u\r\n", obj->i2s.module + 1,
+		(unsigned int)handle->Init.CPOL);
+    DEBUG_PRINTF("    I2S%u: (dbits, fbits): (%u, %u)\r\n", obj->i2s.module + 1,
+    	(unsigned int)dbits, (unsigned int)fbits);
+    DEBUG_PRINTF("    I2S%u: Polarity: %u\r\n", obj->i2s.module + 1,
+    	(unsigned int)polarity);
 
     init_i2s(obj);
 }
 
-void i2s_set_mode(i2s_t *obj, i2s_mode_t mode)
-{
+void i2s_set_mode(i2s_t *obj, i2s_mode_t mode) {
     uint8_t dma_direction;
     I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module];
 
@@ -458,112 +481,160 @@
     // Save primary DMA direction
     obj->dma.dma_direction = dma_direction;
 
-    DEBUG_PRINTF("I2S%u: Mode: %u (%u)\n", obj->i2s.module+1,
-		 (unsigned int)handle->Init.Mode, (unsigned int)mode);
+    DEBUG_PRINTF("--> %s\r\n", __FUNCTION__);
+    DEBUG_PRINTF("    I2S%u: Mode: %u (%u)\r\n", obj->i2s.module + 1,
+		(unsigned int)handle->Init.Mode, (unsigned int)mode);
+
+    init_i2s(obj);
+}
+
+void i2s_set_protocol(i2s_t *obj, i2s_bitorder_t protocol) {
+    I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module];
+
+    switch (protocol)
+    {
+    	case PHILIPS:
+			handle->Init.Standard = I2S_STANDARD_PHILIPS;
+			break;
+	    case MSB:
+			handle->Init.Standard = I2S_STANDARD_MSB;
+			break;
+		case LSB:
+			handle->Init.Standard = I2S_STANDARD_LSB;
+			break;
+	    case PCM_SHORT:
+			handle->Init.Standard = I2S_STANDARD_PCM_SHORT;
+			break;
+	    case PCM_LONG:
+	    default:
+			handle->Init.Standard = I2S_STANDARD_PCM_LONG;
+			break;
+    }
+
+    DEBUG_PRINTF("--> %s\r\n", __FUNCTION__);
+    DEBUG_PRINTF("    I2S%u: Standard: %u\r\n", obj->i2s.module + 1,
+		(unsigned int)handle->Init.Standard);
 
     init_i2s(obj);
 }
 
-void i2s_set_protocol(i2s_t *obj, i2s_bitorder_t protocol)
-{
+void i2s_audio_frequency(i2s_t *obj, uint32_t hz) {
     I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module];
 
-    switch (protocol) {
-    case PHILIPS:
-	handle->Init.Standard = I2S_STANDARD_PHILIPS;
-	break;
-    case MSB:
-	handle->Init.Standard = I2S_STANDARD_MSB;
-	break;
-    case LSB:
-	handle->Init.Standard = I2S_STANDARD_LSB;
-	break;
-    case PCM_SHORT:
-	handle->Init.Standard = I2S_STANDARD_PCM_SHORT;
-	break;
-    case PCM_LONG:
-    default:
-	handle->Init.Standard = I2S_STANDARD_PCM_LONG;
-	break;
+    if (IS_I2S_AUDIO_FREQ(hz) && (hz != I2S_AUDIOFREQ_DEFAULT)) {
+    	handle->Init.AudioFreq = hz;
+    }
+    else if (hz < I2S_AUDIOFREQ_8K) {
+		handle->Init.AudioFreq = I2S_AUDIOFREQ_8K;
+    }
+    else {
+		handle->Init.AudioFreq = I2S_AUDIOFREQ_192K; 
     }
 
-    DEBUG_PRINTF("I2S%u: Protocol: %u (%u)\n", obj->i2s.module+1,
-		 (unsigned int)handle->Init.Standard, (unsigned int)protocol);
+	/* Configuring PLLI2S. */
+	RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
+
+	/* Getting RTCClockSelection. */
+	HAL_RCCEx_GetPeriphCLKConfig(&PeriphClkInitStruct);
+
+	/* Setting configuration. */
+	PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S;
+
+	// Davide: All the following values are taken from Table 91 of the
+	//         reference manual for master clock enabled.
+	switch (hz) {
+  		case I2S_AUDIOFREQ_8K:
+			PeriphClkInitStruct.PLLI2S.PLLI2SN = 256;
+			PeriphClkInitStruct.PLLI2S.PLLI2SR = 5;
+			break;
+
+		case I2S_AUDIOFREQ_16K:
+		case I2S_AUDIOFREQ_32K:
+		case (I2S_AUDIOFREQ_32K << 1):
+			PeriphClkInitStruct.PLLI2S.PLLI2SN = 213;
+			PeriphClkInitStruct.PLLI2S.PLLI2SR = 2;
+			break;
+
+		case I2S_AUDIOFREQ_48K:
+			PeriphClkInitStruct.PLLI2S.PLLI2SN = 258;
+			PeriphClkInitStruct.PLLI2S.PLLI2SR = 3;
+			break;
+
+		case I2S_AUDIOFREQ_96K:
+			PeriphClkInitStruct.PLLI2S.PLLI2SN = 344;
+			PeriphClkInitStruct.PLLI2S.PLLI2SR = 2;
+			break;
+
+		case I2S_AUDIOFREQ_44K:
+		default:
+			PeriphClkInitStruct.PLLI2S.PLLI2SN = 271;
+			PeriphClkInitStruct.PLLI2S.PLLI2SR = 2;
+			break;
+	}
+#ifdef NDEBUG
+	HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
+#else
+	HAL_StatusTypeDef ret = HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
+#endif
+	MBED_ASSERT(ret == HAL_OK);
+
+	DEBUG_PRINTF("--> %s\r\n", __FUNCTION__);
+    DEBUG_PRINTF("    I2S%u: AudioFreq: %u\r\n", obj->i2s.module + 1,
+    	(unsigned int)handle->Init.AudioFreq);
 
     init_i2s(obj);
 }
 
-void i2s_audio_frequency(i2s_t *obj, uint32_t hz)
-{
-    I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module];
-
-    if (IS_I2S_AUDIO_FREQ(hz) && (hz != I2S_AUDIOFREQ_DEFAULT)) {
-	handle->Init.AudioFreq = hz;
-    } else if (hz < I2S_AUDIOFREQ_8K) {
-	handle->Init.AudioFreq = I2S_AUDIOFREQ_8K;
-    } else {
-	handle->Init.AudioFreq = I2S_AUDIOFREQ_192K;
-    }
-
-    DEBUG_PRINTF("I2S%u: Audio frequency: %u (%u)\n", obj->i2s.module+1,
-		 (unsigned int)handle->Init.AudioFreq, (unsigned int)hz);
-
-    init_i2s(obj);
-}
-
-uint8_t i2s_get_module(i2s_t *obj)
-{
+uint8_t i2s_get_module(i2s_t *obj) {
     return obj->i2s.module;
 }
 
-static void i2s_start_asynch_transfer(i2s_t *obj, transfer_type_t transfer_type,
-				      void *tx, void *rx, int length)
-{
+static void i2s_start_asynch_transfer(i2s_t *obj, transfer_type_t transfer_type, void *tx, void *rx, int length) {
     I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module];
     obj->i2s.transfer_type = transfer_type;
 
     // the HAL expects number of transfers instead of number of bytes
     int words;
     switch(handle->Init.DataFormat) {
-    case I2S_DATAFORMAT_16B:
-    case I2S_DATAFORMAT_16B_EXTENDED:
-	words = length / 2;
-	if(words > 0xFFFC) words = 0xFFFC; // truncate in order to respect max DMA length
-	break;
-    case I2S_DATAFORMAT_24B:
-    case I2S_DATAFORMAT_32B:
-    default:
-	words = length / 4;
-	if(words > 0x7FFC) words = 0x7FFC; // truncate in order to respect max DMA length
-	break;
+	    case I2S_DATAFORMAT_16B:
+	    case I2S_DATAFORMAT_16B_EXTENDED:
+			words = length / 2;
+			if(words > 0xFFFC) words = 0xFFFC; // truncate in order to respect max DMA length
+			break;
+	    case I2S_DATAFORMAT_24B:
+	    case I2S_DATAFORMAT_32B:
+	    default:
+			words = length / 4;
+			if(words > 0x7FFC) words = 0x7FFC; // truncate in order to respect max DMA length
+			break;
     }
 
     // enable the right hal transfer
     int rc = 0;
     switch(transfer_type) {
-    case I2S_TRANSFER_TYPE_TXRX:
-	// enable the interrupts
-	NVIC_EnableIRQ(obj->dma.dma[DMA_TX]->dma_stream_irq);
-	NVIC_EnableIRQ(obj->dma.dma[DMA_RX]->dma_stream_irq);
-	// trigger DMA transfers
-	rc = HAL_I2SEx_TransmitReceive_DMA(handle, (uint16_t*)tx, (uint16_t*)rx, (uint16_t)words);
-	break;
-    case I2S_TRANSFER_TYPE_TX:
-	// enable the interrupt
-	NVIC_EnableIRQ(obj->dma.dma[DMA_TX]->dma_stream_irq);
-	// trigger DMA transfer
-	rc = HAL_I2S_Transmit_DMA(handle, (uint16_t*)tx, (uint16_t)words);
-	break;
-    case I2S_TRANSFER_TYPE_RX:
-	// enable the interrupt
-	NVIC_EnableIRQ(obj->dma.dma[DMA_RX]->dma_stream_irq);
-	// trigger DMA transfer
-	rc = HAL_I2S_Receive_DMA(handle, (uint16_t*)rx, (uint16_t)words);
-	break;
+	    case I2S_TRANSFER_TYPE_TXRX:
+			// enable the interrupts
+			NVIC_EnableIRQ(obj->dma.dma[DMA_TX]->dma_stream_irq);
+			NVIC_EnableIRQ(obj->dma.dma[DMA_RX]->dma_stream_irq);
+			// trigger DMA transfers
+			rc = HAL_I2SEx_TransmitReceive_DMA(handle, (uint16_t*)tx, (uint16_t*)rx, (uint16_t)words);
+			break;
+	    case I2S_TRANSFER_TYPE_TX:
+			// enable the interrupt
+			NVIC_EnableIRQ(obj->dma.dma[DMA_TX]->dma_stream_irq);
+			// trigger DMA transfer
+			rc = HAL_I2S_Transmit_DMA(handle, (uint16_t*)tx, (uint16_t)words);
+			break;
+	    case I2S_TRANSFER_TYPE_RX:
+			// enable the interrupt
+			NVIC_EnableIRQ(obj->dma.dma[DMA_RX]->dma_stream_irq);
+			// trigger DMA transfer
+			rc = HAL_I2S_Receive_DMA(handle, (uint16_t*)rx, (uint16_t)words);
+			break;
     }
 
     if (rc) {
-	DEBUG_PRINTF("I2S%u: RC=%d\n", obj->i2s.module+1, rc);
+		DEBUG_PRINTF("    I2S%u: RC: %d\r\n", obj->i2s.module + 1, rc);
     }
 
     return;
@@ -574,8 +645,7 @@
 		  void *tx, int tx_length,
 		  void *rx, int rx_length,
 		  bool circular, i2s_dma_prio_t prio,
-		  uint32_t handler_tx, uint32_t handler_rx, uint32_t event)
-{
+		  uint32_t handler_tx, uint32_t handler_rx, uint32_t event) {
     // check which use-case we have
     bool use_tx = (tx != NULL && tx_length > 0);
     bool use_rx = (rx != NULL && rx_length > 0);
@@ -600,29 +670,28 @@
 
     obj->i2s.event = event;
 
-    DEBUG_PRINTF("I2S%u: Transfer: %u, %u\n", obj->i2s.module+1, tx_length, rx_length);
+    DEBUG_PRINTF("    I2S%u: Transfer: %u, %u\r\n", obj->i2s.module + 1, tx_length, rx_length);
 
     // register the thunking handler
-    if(use_tx) {
-	NVIC_SetVector(obj->dma.dma[DMA_TX]->dma_stream_irq, handler_tx);
+    if (use_tx) {
+		NVIC_SetVector(obj->dma.dma[DMA_TX]->dma_stream_irq, handler_tx);
     }
-    if(use_rx) {
-	NVIC_SetVector(obj->dma.dma[DMA_RX]->dma_stream_irq, handler_rx);
+    if (use_rx) {
+		NVIC_SetVector(obj->dma.dma[DMA_RX]->dma_stream_irq, handler_rx);
     }
 
     // enable the right hal transfer
     if (use_tx && use_rx) {
-	int size = (tx_length < rx_length)? tx_length : rx_length;
-	i2s_start_asynch_transfer(obj, I2S_TRANSFER_TYPE_TXRX, tx, rx, size);
+		int size = (tx_length < rx_length)? tx_length : rx_length;
+		i2s_start_asynch_transfer(obj, I2S_TRANSFER_TYPE_TXRX, tx, rx, size);
     } else if (use_tx) {
-	i2s_start_asynch_transfer(obj, I2S_TRANSFER_TYPE_TX, tx, NULL, tx_length);
+		i2s_start_asynch_transfer(obj, I2S_TRANSFER_TYPE_TX, tx, NULL, tx_length);
     } else if (use_rx) {
-	i2s_start_asynch_transfer(obj, I2S_TRANSFER_TYPE_RX, NULL, rx, rx_length);
+		i2s_start_asynch_transfer(obj, I2S_TRANSFER_TYPE_RX, NULL, rx, rx_length);
     }
 }
 
-uint32_t i2s_irq_handler_asynch(i2s_t *obj, uint8_t direction)
-{
+uint32_t i2s_irq_handler_asynch(i2s_t *obj, uint8_t direction) {
     direction = (direction == I2S_TX_EVENT) ? DMA_TX : DMA_RX;
 
     // use the right instance
@@ -636,150 +705,153 @@
     // call the Cube handler, this will update the handle
     HAL_DMA_IRQHandler(dma_handle);
 
-    switch(HAL_I2S_GetState(i2s_handle)) {
-    case HAL_I2S_STATE_READY: {
-	// adjust buffer positions (betzw - TODO: to be checked for DMA transfers!!!)
-	int tx_size = (i2s_handle->TxXferSize - i2s_handle->TxXferCount);
-	int rx_size = (i2s_handle->RxXferSize - i2s_handle->RxXferCount);
+    switch(HAL_I2S_GetState(i2s_handle))
+    {
+	    case HAL_I2S_STATE_READY: {
+			// adjust buffer positions (betzw - TODO: to be checked for DMA transfers!!!)
+			int tx_size = (i2s_handle->TxXferSize - i2s_handle->TxXferCount);
+			int rx_size = (i2s_handle->RxXferSize - i2s_handle->RxXferCount);
 
-	// take data format into consideration
-	switch(i2s_handle->Init.DataFormat) {
-	case I2S_DATAFORMAT_16B:
-	case I2S_DATAFORMAT_16B_EXTENDED:
-	    tx_size *= 2;
-	    rx_size *= 2;
-	    break;
-	case I2S_DATAFORMAT_24B:
-	case I2S_DATAFORMAT_32B:
-	default:
-	    tx_size *= 4;
-	    rx_size *= 4;
-	    break;
-	}
+			// take data format into consideration
+			switch(i2s_handle->Init.DataFormat)
+			{
+				case I2S_DATAFORMAT_16B:
+				case I2S_DATAFORMAT_16B_EXTENDED:
+				    tx_size *= 2;
+				    rx_size *= 2;
+				    break;
+				case I2S_DATAFORMAT_24B:
+				case I2S_DATAFORMAT_32B:
+				default:
+				    tx_size *= 4;
+				    rx_size *= 4;
+				    break;
+			}
 
-	// adjust buffer positions
-	if (obj->i2s.transfer_type != I2S_TRANSFER_TYPE_RX) {
-	    obj->tx_buff.pos += tx_size;
-	}
-	if (obj->i2s.transfer_type != I2S_TRANSFER_TYPE_TX) {
-	    obj->rx_buff.pos += rx_size;
-	}
+			// adjust buffer positions
+			if (obj->i2s.transfer_type != I2S_TRANSFER_TYPE_RX) {
+			    obj->tx_buff.pos += tx_size;
+			}
+			if (obj->i2s.transfer_type != I2S_TRANSFER_TYPE_TX) {
+			    obj->rx_buff.pos += rx_size;
+			}
 
-	if (i2s_handle->TxXferCount > 0) {
-	    DEBUG_PRINTF("I2S%u: TxXferCount: %u\n", obj->i2s.module+1, i2s_handle->TxXferCount);
-	}
-	if (i2s_handle->RxXferCount > 0) {
-	    DEBUG_PRINTF("I2S%u: RxXferCount: %u\n", obj->i2s.module+1, i2s_handle->RxXferCount);
-	}
-    }
-    /* no break */
+			if (i2s_handle->TxXferCount > 0) {
+			    DEBUG_PRINTF("    I2S%u: TxXferCount: %u\r\n", obj->i2s.module + 1, i2s_handle->TxXferCount);
+			}
+			if (i2s_handle->RxXferCount > 0) {
+			    DEBUG_PRINTF("    I2S%u: RxXferCount: %u\r\n", obj->i2s.module + 1, i2s_handle->RxXferCount);
+			}
+	    }
+    	/* no break */
 
-    case HAL_I2S_STATE_BUSY_TX:
-    case HAL_I2S_STATE_BUSY_RX:
-    case HAL_I2S_STATE_BUSY_TX_RX: {
-	int error = HAL_I2S_GetError(i2s_handle);
+	    case HAL_I2S_STATE_BUSY_TX:
+	    case HAL_I2S_STATE_BUSY_RX:
+	    case HAL_I2S_STATE_BUSY_TX_RX:
+			{
+				int error = HAL_I2S_GetError(i2s_handle);
 
-	if(error != HAL_I2S_ERROR_NONE) {
-	    // something went wrong and the transfer has definitely completed
-	    event = ((direction == DMA_TX) ? I2S_EVENT_TX_ERROR : I2S_EVENT_RX_ERROR) | I2S_EVENT_INTERNAL_TRANSFER_COMPLETE;
+				if (error != HAL_I2S_ERROR_NONE) {
+					// something went wrong and the transfer has definitely completed
+					event = ((direction == DMA_TX) ? I2S_EVENT_TX_ERROR : I2S_EVENT_RX_ERROR) | I2S_EVENT_INTERNAL_TRANSFER_COMPLETE;
 
-	    if (error & HAL_I2S_ERROR_OVR) {
-		// buffer overrun
-		event |= I2S_EVENT_RX_OVERFLOW;
-	    }
+					if (error & HAL_I2S_ERROR_OVR) {
+						// buffer overrun
+						event |= I2S_EVENT_RX_OVERFLOW;
+					}
 
-	    if (error & HAL_I2S_ERROR_UDR) {
-		// buffer underrun
-		event |= I2S_EVENT_TX_UNDERRUN;
-	    }
+					if (error & HAL_I2S_ERROR_UDR) {
+						// buffer underrun
+						event |= I2S_EVENT_TX_UNDERRUN;
+					}
 
-	    // cleanup DMA (after error)
-	    dma_i2s_free(obj, direction);
-	} else { // no error detected
-	    HAL_DMA_StateTypeDef dma_state = HAL_DMA_GetState(dma_handle);
+					// cleanup DMA (after error)
+					dma_i2s_free(obj, direction);
+				} else
+				{ // no error detected
+					HAL_DMA_StateTypeDef dma_state = HAL_DMA_GetState(dma_handle);
 
-	    switch(dma_state) {
-	    case HAL_DMA_STATE_READY_HALF_MEM0:
-	    case HAL_DMA_STATE_READY_HALF_MEM1:
-		event = ((direction == DMA_TX) ? I2S_EVENT_TX_HALF_COMPLETE : I2S_EVENT_RX_HALF_COMPLETE);
-		break;
-	    case HAL_DMA_STATE_READY_MEM0:
-	    case HAL_DMA_STATE_READY_MEM1:
-		event = ((direction == DMA_TX) ? I2S_EVENT_TX_COMPLETE : I2S_EVENT_RX_COMPLETE);
-
-		if(dma_handle->Init.Mode != DMA_CIRCULAR) {
-		    if (!i2s_active(obj)) { // Check for full-duplex transfer complete!
-			event |= I2S_EVENT_INTERNAL_TRANSFER_COMPLETE;
-		    }
+					switch(dma_state)
+					{
+						case HAL_DMA_STATE_READY_HALF_MEM0:
+						case HAL_DMA_STATE_READY_HALF_MEM1:
+							event = ((direction == DMA_TX) ? I2S_EVENT_TX_HALF_COMPLETE : I2S_EVENT_RX_HALF_COMPLETE);
+							break;
+						case HAL_DMA_STATE_READY_MEM0:
+						case HAL_DMA_STATE_READY_MEM1:
+							event = ((direction == DMA_TX) ? I2S_EVENT_TX_COMPLETE : I2S_EVENT_RX_COMPLETE);
+							if(dma_handle->Init.Mode != DMA_CIRCULAR)
+							{
+								if (!i2s_active(obj))
+								{ // Check for full-duplex transfer complete!
+									event |= I2S_EVENT_INTERNAL_TRANSFER_COMPLETE;
+								}
 
-		    // cleanup DMA (because we are done)
-		    dma_i2s_free(obj, direction);
-		}
-		break;
+								// cleanup DMA (because we are done)
+								dma_i2s_free(obj, direction);
+							}
+							break;
+						default:
+							printf("betzw(%s, %d): dma_state=0x%x\r\n", __func__, __LINE__, (int)dma_state);
+							MBED_ASSERT(0);
+							break;
+					}
+				}
+	    	}
+			break;
 	    default:
-		printf("betzw(%s, %d): dma_state=0x%x\r\n", __func__, __LINE__, (int)dma_state);
-		MBED_ASSERT(0);
-		break;
-	    }
-	}
-    }
-	break;
-
-    default:
-	// nothing to do?!?
-	break;
+			// nothing to do?!?
+			break;
     }
 
-    if (event) DEBUG_PRINTF("I2S%u: Event: 0x%x\n", obj->i2s.module+1, event);
+    if (event) DEBUG_PRINTF("    I2S%u: Event: 0x%x\r\n", obj->i2s.module + 1, event);
 
     return (event & (obj->i2s.event | I2S_EVENT_INTERNAL_TRANSFER_COMPLETE));
 }
 
-uint8_t i2s_active(i2s_t *obj)
-{
+uint8_t i2s_active(i2s_t *obj) {
     I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module];
     HAL_I2S_StateTypeDef state = HAL_I2S_GetState(handle);
 
-    switch(state) {
-    case HAL_I2S_STATE_RESET:
-    case HAL_I2S_STATE_READY:
-    case HAL_I2S_STATE_ERROR:
-	return 0;
-    default:
-	return -1;
+    switch(state){
+	    case HAL_I2S_STATE_RESET:
+	    case HAL_I2S_STATE_READY:
+	    case HAL_I2S_STATE_ERROR:
+			return 0;
+	    default:
+			return -1;
     }
 }
 
-void i2s_abort_asynch(i2s_t *obj)
-{
+void i2s_abort_asynch(i2s_t *obj) {
     I2S_HandleTypeDef *i2s_handle = &I2sHandle[obj->i2s.module];
 
     // Stop transfer
     HAL_I2S_DMAStop(i2s_handle);
 
     if(obj->dma.dma[DMA_TX] != NULL) {
-	DMA_HandleTypeDef *dma_handle_tx = &DMaHandles[obj->i2s.module][DMA_TX];
+		DMA_HandleTypeDef *dma_handle_tx = &DMaHandles[obj->i2s.module][DMA_TX];
 
-	// disable interrupt & free resource
-	dma_i2s_free(obj, DMA_TX);
- 
-	//clean up
-	__HAL_DMA_DISABLE(dma_handle_tx);
-	HAL_DMA_DeInit(dma_handle_tx);
-	HAL_DMA_Init(dma_handle_tx);
-	__HAL_DMA_ENABLE(dma_handle_tx);
+		// disable interrupt & free resource
+		dma_i2s_free(obj, DMA_TX);
+	 
+		//clean up
+		__HAL_DMA_DISABLE(dma_handle_tx);
+		HAL_DMA_DeInit(dma_handle_tx);
+		HAL_DMA_Init(dma_handle_tx);
+		__HAL_DMA_ENABLE(dma_handle_tx);
     }
     if(obj->dma.dma[DMA_RX] != NULL) {
-	DMA_HandleTypeDef *dma_handle_rx = &DMaHandles[obj->i2s.module][DMA_RX];
+		DMA_HandleTypeDef *dma_handle_rx = &DMaHandles[obj->i2s.module][DMA_RX];
 
-	// disable interrupt & free resource
-	dma_i2s_free(obj, DMA_RX);
+		// disable interrupt & free resource
+		dma_i2s_free(obj, DMA_RX);
 
-	//clean up
-	__HAL_DMA_DISABLE(dma_handle_rx);
-	HAL_DMA_DeInit(dma_handle_rx);
-	HAL_DMA_Init(dma_handle_rx);
-	__HAL_DMA_ENABLE(dma_handle_rx);
+		//clean up
+		__HAL_DMA_DISABLE(dma_handle_rx);
+		HAL_DMA_DeInit(dma_handle_rx);
+		HAL_DMA_Init(dma_handle_rx);
+		__HAL_DMA_ENABLE(dma_handle_rx);
     }
 
     // clean-up I2S