Il y avait des problèmes dans la libraire...
Fork of ST_I2S by
Diff: targets/TARGET_STM/stm_i2s_api.c
- Revision:
- 26:468cdd70cd3e
- Parent:
- 24:b78825180506
- Child:
- 27:c2fc3330d0df
--- a/targets/TARGET_STM/stm_i2s_api.c Fri Mar 10 13:25:07 2017 +0100 +++ b/targets/TARGET_STM/stm_i2s_api.c Mon Mar 27 16:15:20 2017 +0200 @@ -32,18 +32,27 @@ I2S_TRANSFER_TYPE_TXRX = 3, } transfer_type_t; +typedef enum { + I2S_HALF_TRANSFER = 0, + I2S_FULL_TRANSFER, +} dma_transfer_state_t; + typedef struct { - DMA_HandleTypeDef tx_dma_handle; - DMA_HandleTypeDef rx_dma_handle; -} dma_handles_t; + DMA_HandleTypeDef dma_handle; + dma_transfer_state_t t_state; +} dma_extra_state_t; + +typedef struct { + I2S_HandleTypeDef i2s_handle; + dma_extra_state_t dma_handles[NUM_OF_DIRECTIONS]; +} i2s_dma_handles_t; #define I2S_NUM (5) // TODO: this approach wastes quite a bit of memory - TO BE IMPROVED!?!? -static I2S_HandleTypeDef I2sHandle[I2S_NUM]; -static DMA_HandleTypeDef DMaHandles[I2S_NUM][NUM_OF_DIRECTIONS]; +static i2s_dma_handles_t I2sHandle[I2S_NUM]; static void init_i2s(i2s_t *obj) { - I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module]; + I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module].i2s_handle; __HAL_I2S_DISABLE(handle); HAL_I2S_Init(handle); @@ -58,19 +67,19 @@ switch(obj->dma.dma_direction) { case DMA_TX: if(obj->dma.dma[DMA_TX] != NULL) { - hdmatx = primary_handle = &DMaHandles[obj->i2s.module][DMA_TX]; + hdmatx = primary_handle = &I2sHandle[obj->i2s.module].dma_handles[DMA_TX].dma_handle; } if(obj->dma.dma[DMA_RX] != NULL) { - secondary_handle = &DMaHandles[obj->i2s.module][DMA_RX]; + secondary_handle = &I2sHandle[obj->i2s.module].dma_handles[DMA_RX].dma_handle; } break; case DMA_RX: default: if(obj->dma.dma[DMA_RX] != NULL) { - primary_handle = &DMaHandles[obj->i2s.module][DMA_RX]; + primary_handle = &I2sHandle[obj->i2s.module].dma_handles[DMA_RX].dma_handle; } if(obj->dma.dma[DMA_TX] != NULL) { - hdmatx = secondary_handle = &DMaHandles[obj->i2s.module][DMA_TX]; + hdmatx = secondary_handle = &I2sHandle[obj->i2s.module].dma_handles[DMA_TX].dma_handle; } break; } @@ -80,9 +89,9 @@ HAL_DMA_Init(primary_handle); if(hdmatx == primary_handle) { - __HAL_LINKDMA(&I2sHandle[obj->i2s.module], hdmatx, *primary_handle); + __HAL_LINKDMA(&I2sHandle[obj->i2s.module].i2s_handle, hdmatx, *primary_handle); } else { - __HAL_LINKDMA(&I2sHandle[obj->i2s.module], hdmarx, *primary_handle); + __HAL_LINKDMA(&I2sHandle[obj->i2s.module].i2s_handle, hdmarx, *primary_handle); } } @@ -91,9 +100,9 @@ HAL_DMA_Init(secondary_handle); if(hdmatx == secondary_handle) { - __HAL_LINKDMA(&I2sHandle[obj->i2s.module], hdmatx, *secondary_handle); + __HAL_LINKDMA(&I2sHandle[obj->i2s.module].i2s_handle, hdmatx, *secondary_handle); } else { - __HAL_LINKDMA(&I2sHandle[obj->i2s.module], hdmarx, *secondary_handle); + __HAL_LINKDMA(&I2sHandle[obj->i2s.module].i2s_handle, hdmarx, *secondary_handle); } } } @@ -131,7 +140,7 @@ static void dma_i2s_init(i2s_t *obj, bool *use_tx, bool *use_rx, bool circular, i2s_dma_prio_t prio) { // DMA declarations - DMA_HandleTypeDef *primary_handle = &DMaHandles[obj->i2s.module][obj->dma.dma_direction]; + DMA_HandleTypeDef *primary_handle = &I2sHandle[obj->i2s.module].dma_handles[obj->dma.dma_direction].dma_handle; DMA_HandleTypeDef *secondary_handle = NULL; // DMA initialization & configuration @@ -178,7 +187,7 @@ 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]; + secondary_handle = &I2sHandle[obj->i2s.module].dma_handles[DMA_RX].dma_handle; MBED_ASSERT(obj->dma.dma[DMA_RX] != STM_DMA_ERROR_OUT_OF_CHANNELS); } break; @@ -186,7 +195,7 @@ 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]; + secondary_handle = &I2sHandle[obj->i2s.module].dma_handles[DMA_TX].dma_handle; MBED_ASSERT(obj->dma.dma[DMA_TX] != STM_DMA_ERROR_OUT_OF_CHANNELS); } break; @@ -339,7 +348,7 @@ } // initialize the handle for this master! - I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module]; + I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module].i2s_handle; handle->Instance = (SPI_TypeDef *)(instance); handle->Init.Mode = i2s_get_mode(mode, &dma_direction); @@ -416,7 +425,7 @@ } void i2s_format(i2s_t *obj, int dbits, int fbits, int polarity) { - I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module]; + I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module].i2s_handle; // Save new values if (fbits == 16) { // format MUST be 16B @@ -447,7 +456,7 @@ void i2s_set_mode(i2s_t *obj, i2s_mode_t mode) { uint8_t dma_direction; - I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module]; + I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module].i2s_handle; handle->Init.Mode = i2s_get_mode(mode, &dma_direction); @@ -461,7 +470,7 @@ } void i2s_set_protocol(i2s_t *obj, i2s_bitorder_t protocol) { - I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module]; + I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module].i2s_handle; switch (protocol) { case PHILIPS: @@ -489,7 +498,7 @@ } void i2s_audio_frequency(i2s_t *obj, uint32_t hz) { - I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module]; + I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module].i2s_handle; if (IS_I2S_AUDIO_FREQ(hz) && (hz != I2S_AUDIOFREQ_DEFAULT)) { handle->Init.AudioFreq = hz; @@ -512,7 +521,7 @@ 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]; + I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module].i2s_handle; obj->i2s.transfer_type = transfer_type; // the HAL expects number of transfers instead of number of bytes @@ -618,7 +627,7 @@ direction = (direction == I2S_TX_EVENT) ? DMA_TX : DMA_RX; // use the right instance - I2S_HandleTypeDef *i2s_handle = &I2sHandle[obj->i2s.module]; + I2S_HandleTypeDef *i2s_handle = &I2sHandle[obj->i2s.module].i2s_handle; DMA_HandleTypeDef *dma_handle = (direction == DMA_TX) ? i2s_handle->hdmatx : i2s_handle->hdmarx; MBED_ASSERT(dma_handle != NULL); @@ -688,15 +697,15 @@ // cleanup DMA (after error) dma_i2s_free(obj, direction); } else { // no error detected - HAL_DMA_StateTypeDef dma_state = HAL_DMA_GetState(dma_handle); + size_t offset_dma_handle = offsetof(dma_extra_state_t, dma_handle); + dma_extra_state_t *extra_state = (dma_extra_state_t*)(((void*)dma_handle) - offset_dma_handle); + dma_transfer_state_t dma_state = extra_state->t_state; switch(dma_state) { - case HAL_DMA_STATE_READY_HALF_MEM0: - case HAL_DMA_STATE_READY_HALF_MEM1: + case I2S_HALF_TRANSFER: 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: + case I2S_FULL_TRANSFER: event = ((direction == DMA_TX) ? I2S_EVENT_TX_COMPLETE : I2S_EVENT_RX_COMPLETE); if(dma_handle->Init.Mode != DMA_CIRCULAR) { @@ -728,7 +737,7 @@ } uint8_t i2s_active(i2s_t *obj) { - I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module]; + I2S_HandleTypeDef *handle = &I2sHandle[obj->i2s.module].i2s_handle; HAL_I2S_StateTypeDef state = HAL_I2S_GetState(handle); switch(state) { @@ -742,13 +751,13 @@ } void i2s_abort_asynch(i2s_t *obj) { - I2S_HandleTypeDef *i2s_handle = &I2sHandle[obj->i2s.module]; + I2S_HandleTypeDef *i2s_handle = &I2sHandle[obj->i2s.module].i2s_handle; // 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 = &I2sHandle[obj->i2s.module].dma_handles[DMA_TX].dma_handle; // disable interrupt & free resource dma_i2s_free(obj, DMA_TX); @@ -760,7 +769,7 @@ __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 = &I2sHandle[obj->i2s.module].dma_handles[DMA_RX].dma_handle; // disable interrupt & free resource dma_i2s_free(obj, DMA_RX); @@ -779,10 +788,43 @@ __HAL_I2S_ENABLE(i2s_handle); } +/*** Weak function overwrites ***/ +void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s) { + size_t offset_i2s_handle = offsetof(i2s_dma_handles_t, i2s_handle); + i2s_dma_handles_t *i2s_dma_handle = (i2s_dma_handles_t*)(((void*)hi2s) - offset_i2s_handle); + dma_transfer_state_t *dma_t_state = &(i2s_dma_handle->dma_handles[DMA_TX].t_state); + + *dma_t_state = I2S_HALF_TRANSFER; +} + +void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s) { + size_t offset_i2s_handle = offsetof(i2s_dma_handles_t, i2s_handle); + i2s_dma_handles_t *i2s_dma_handle = (i2s_dma_handles_t*)(((void*)hi2s) - offset_i2s_handle); + dma_transfer_state_t *dma_t_state = &(i2s_dma_handle->dma_handles[DMA_RX].t_state); + + *dma_t_state = I2S_HALF_TRANSFER; +} + +void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s) { + size_t offset_i2s_handle = offsetof(i2s_dma_handles_t, i2s_handle); + i2s_dma_handles_t *i2s_dma_handle = (i2s_dma_handles_t*)(((void*)hi2s) - offset_i2s_handle); + dma_transfer_state_t *dma_t_state = &(i2s_dma_handle->dma_handles[DMA_TX].t_state); + + *dma_t_state = I2S_FULL_TRANSFER; +} + +void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s) { + size_t offset_i2s_handle = offsetof(i2s_dma_handles_t, i2s_handle); + i2s_dma_handles_t *i2s_dma_handle = (i2s_dma_handles_t*)(((void*)hi2s) - offset_i2s_handle); + dma_transfer_state_t *dma_t_state = &(i2s_dma_handle->dma_handles[DMA_RX].t_state); + + *dma_t_state = I2S_FULL_TRANSFER; +} + /*** Code for harmonizing frequencies ***/ static inline I2S_HandleTypeDef *i2s_get_handle(i2s_t *obj) { - return (I2S_HandleTypeDef *) &I2sHandle[obj->i2s.module]; + return (I2S_HandleTypeDef *) &I2sHandle[obj->i2s.module].i2s_handle; } static float i2s_compute_closest_frequency(i2s_t *dev_i2s, uint32_t target_freq) {