mirror of https://github.com/ARMmbed/mbed-os.git
111 lines
2.8 KiB
C
111 lines
2.8 KiB
C
/* mbed Microcontroller Library
|
|
* Copyright (c) 2006-2018 ARM Limited
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#include "sai_api.h"
|
|
|
|
#if DEVICE_SAI
|
|
|
|
// math.h required for floating point operations for baud rate calculation
|
|
#include <math.h>
|
|
#include "mbed_assert.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include "cmsis.h"
|
|
#include "pinmap.h"
|
|
#include "objects.h"
|
|
#include "PeripheralPins.h"
|
|
|
|
#include "stm_sai_api.h"
|
|
#include "stm_sai_driver.h"
|
|
#include "stm_i2s_driver.h"
|
|
|
|
static const stm_sai_api_t *sai_vtable[] = { &stm_sai_vtable, &stm_i2s_vtable };
|
|
static const sai_base_t sai_bases[] = {
|
|
{
|
|
.type = SAI_PERIPH_TYPE_SAI,
|
|
.u.sai_block = SAI1_Block_A
|
|
}, {
|
|
.type = SAI_PERIPH_TYPE_SAI,
|
|
.u.sai_block = SAI1_Block_B
|
|
}, {
|
|
.type = SAI_PERIPH_TYPE_I2S,
|
|
.u.spi = SPI2
|
|
}, {
|
|
.type = SAI_PERIPH_TYPE_I2S,
|
|
.u.spi = I2S2ext
|
|
}, {
|
|
.type = SAI_PERIPH_TYPE_I2S,
|
|
.u.spi = SPI3
|
|
}, {
|
|
.type = SAI_PERIPH_TYPE_I2S,
|
|
.u.spi = I2S3ext
|
|
}
|
|
};
|
|
|
|
#define SAI_COUNT (sizeof(sai_bases)/sizeof(sai_base_t))
|
|
|
|
static bool sai_initialized[SAI_COUNT] = {false};
|
|
|
|
sai_result_t sai_init(sai_t *obj, sai_init_t *init) {
|
|
if ((obj == NULL) || !sai_check_sanity(init)) {
|
|
return SAI_RESULT_INVALID_PARAM;
|
|
}
|
|
|
|
SAIName base = (SAIName)pinmap_peripheral(init->sd, PinMap_SAI_SD);
|
|
MBED_ASSERT(base != (SAIName)NC);
|
|
|
|
if (sai_initialized[base]) {
|
|
return SAI_RESULT_ALREADY_INITIALIZED;
|
|
}
|
|
|
|
obj->base = &sai_bases[base];
|
|
obj->is_receiver = init->is_receiver;
|
|
obj->sd = init->sd;
|
|
|
|
sai_result_t res = sai_vtable[obj->base->type]->init(obj, init);
|
|
if (res == SAI_RESULT_OK) {
|
|
sai_initialized[base] = true;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
/** Transfer a sample and return the sample received meanwhile. */
|
|
bool sai_transfer(sai_t *obj, uint32_t *sample) {
|
|
if (obj == NULL) {
|
|
return false;
|
|
}
|
|
|
|
return sai_vtable[obj->base->type]->transfer(obj, sample);
|
|
}
|
|
|
|
/** Releases & de-initialize the referenced peripherals. */
|
|
void sai_free(sai_t *obj) {
|
|
if (obj == NULL) {
|
|
return;
|
|
}
|
|
|
|
sai_vtable[obj->base->type]->free(obj);
|
|
for (uint32_t i = 0; i < SAI_COUNT; i ++) {
|
|
if (obj->base == &sai_bases[i]) {
|
|
sai_initialized[i] = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif // DEVICE_SAI
|