Skip to content

Commit 01597f1

Browse files
committed
Fixes test-ability of sai drivers
1 parent 81d1099 commit 01597f1

File tree

6 files changed

+81
-8
lines changed

6 files changed

+81
-8
lines changed

hal/mbed_sai_api.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,13 @@ const sai_format_t sai_mode_pcm16s = {
9191
.bit_shift = 0
9292
};
9393

94+
95+
bool sai_check_sanity(sai_init_t *init) {
96+
return (init != NULL) &&
97+
(init->sample_rate != 0) &&
98+
(init->format.ws_length <= init->format.word_length) &&
99+
(init->format.bit_shift <= (init->format.word_length - init->format.data_length)) &&
100+
(init->format.data_length <= init->format.word_length);
101+
}
102+
94103
#endif // DEVICE_SAI

hal/sai_api.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,16 @@ bool sai_xfer(sai_t *obj, uint32_t *psample);
185185
*/
186186
void sai_free(sai_t *obj);
187187

188+
189+
/**
190+
* Checks init parameter sanity.
191+
* @param init A config to be sanity checked.
192+
* @return True if the init is sane.
193+
* @note It does not guaranty that this configuration will be supported by the
194+
* device.
195+
*/
196+
bool sai_check_sanity(sai_init_t *init);
197+
188198
/**@}*/
189199

190200
#ifdef __cplusplus

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/api/sai_api.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,23 @@
3232

3333
static I2S_Type *const sai_addrs[] = I2S_BASE_PTRS;
3434

35+
bool sai_receiver_initialized = false;
36+
bool sai_transmitter_initialized = false;
37+
3538
sai_result_t sai_init(sai_t *obj, sai_init_t *init) {
3639
int32_t base = NC;
3740
int32_t tx = NC;
3841
int32_t rx = NC;
3942

40-
MBED_ASSERT(init != NULL);
41-
if (memcmp(&(init->format), &sai_mode_i2s16w32, sizeof(sai_format_t)) != 0) {
43+
if ((obj == NULL) || !sai_check_sanity(init)) {
44+
return SAI_RESULT_INVALID_PARAM;
45+
}
46+
if ((init->is_receiver && sai_receiver_initialized) ||
47+
(!init->is_receiver && sai_transmitter_initialized)) {
48+
return SAI_RESULT_ALREADY_INITIALIZED;
49+
}
50+
if ((memcmp(&(init->format), &sai_mode_i2s16w32, sizeof(sai_format_t)) != 0) &&
51+
(memcmp(&(init->format), &sai_mode_i2s16, sizeof(sai_format_t)) != 0)) {
4252
// we only support 1 format so far
4353
return SAI_RESULT_CONFIG_UNSUPPORTED;
4454
}
@@ -129,14 +139,20 @@ sai_result_t sai_init(sai_t *obj, sai_init_t *init) {
129139

130140
if (obj->is_receiver) {
131141
SAI_RxSetFormat(obj->base, &format, mclk_freq, format.masterClockHz);
142+
sai_receiver_initialized = true;
132143
} else {
133144
SAI_TxSetFormat(obj->base, &format, mclk_freq, format.masterClockHz);
145+
sai_transmitter_initialized = true;
134146
}
135147

136148
return SAI_RESULT_OK;
137149
}
138150

139151
bool sai_xfer(sai_t *obj, uint32_t *sample) {
152+
if (obj == NULL) {
153+
return false;
154+
}
155+
140156
bool ret = false;
141157
if (obj->is_receiver) {
142158
if (sample != NULL) {
@@ -173,10 +189,16 @@ bool sai_xfer(sai_t *obj, uint32_t *sample) {
173189

174190
/** Releases & de-initialize the referenced peripherals. */
175191
void sai_free(sai_t *obj) {
192+
if (obj == NULL) {
193+
return;
194+
}
195+
176196
if (obj->is_receiver) {
177197
SAI_RxEnable(obj->base, false);
198+
sai_receiver_initialized = false;
178199
} else {
179200
SAI_TxEnable(obj->base, false);
201+
sai_transmitter_initialized = false;
180202
}
181203
// Should it also unclock the periph ?
182204
}

targets/TARGET_STM/TARGET_STM32F4/sai_api.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,26 +55,56 @@ static const sai_base_t sai_bases[] = {
5555
}
5656
};
5757

58+
#define SAI_COUNT (sizeof(sai_bases)/sizeof(sai_base_t))
59+
60+
static bool sai_initialized[SAI_COUNT] = {false};
61+
5862
sai_result_t sai_init(sai_t *obj, sai_init_t *init) {
59-
MBED_ASSERT((init != NULL) && (obj != NULL));
63+
if ((obj == NULL) || !sai_check_sanity(init)) {
64+
return SAI_RESULT_INVALID_PARAM;
65+
}
6066

6167
SAIName base = (SAIName)pinmap_peripheral(init->sd, PinMap_SAI_SD);
6268
MBED_ASSERT(base != (SAIName)NC);
6369

70+
if (sai_initialized[base]) {
71+
return SAI_RESULT_ALREADY_INITIALIZED;
72+
}
73+
6474
obj->base = &sai_bases[base];
6575
obj->is_receiver = init->is_receiver;
6676
obj->sd = init->sd;
67-
return sai_vtable[obj->base->type]->init(obj, init);
77+
78+
sai_result_t res = sai_vtable[obj->base->type]->init(obj, init);
79+
if (res == SAI_RESULT_OK) {
80+
sai_initialized[base] = true;
81+
}
82+
83+
return res;
6884
}
6985

7086
/** Transfer a sample and return the sample received meanwhile. */
7187
bool sai_xfer(sai_t *obj, uint32_t *sample) {
88+
if (obj == NULL) {
89+
return false;
90+
}
91+
7292
return sai_vtable[obj->base->type]->xfer(obj, sample);
7393
}
7494

7595
/** Releases & de-initialize the referenced peripherals. */
7696
void sai_free(sai_t *obj) {
97+
if (obj == NULL) {
98+
return;
99+
}
100+
77101
sai_vtable[obj->base->type]->free(obj);
102+
for (uint32_t i = 0; i < SAI_COUNT; i ++) {
103+
if (obj->base == &sai_bases[i]) {
104+
sai_initialized[i] = false;
105+
break;
106+
}
107+
}
78108
}
79109

80110
#endif // DEVICE_SAI

targets/TARGET_STM/TARGET_STM32F4/stm_i2s_driver.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ const stm_sai_api_t stm_i2s_vtable = {
3333
};
3434

3535
static sai_result_t stm_i2s_init(sai_t *obj, sai_init_t *init) {
36-
if (memcmp(&(init->format), &sai_mode_i2s16w32, sizeof(sai_format_t)) != 0) {
36+
if ((memcmp(&(init->format), &sai_mode_i2s16w32, sizeof(sai_format_t)) != 0) &&
37+
(memcmp(&(init->format), &sai_mode_i2s16, sizeof(sai_format_t)) != 0)) {
3738
// we only support 1 format so far
3839
return SAI_RESULT_CONFIG_UNSUPPORTED;
3940
}

targets/TARGET_STM/TARGET_STM32F4/stm_sai_driver.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ const stm_sai_api_t stm_sai_vtable = {
3232

3333
static sai_result_t stm_sai_init(sai_t *obj, sai_init_t *init) {
3434
uint32_t tmpreg = 0;
35-
if (memcmp(&(init->format), &sai_mode_i2s16w32, sizeof(sai_format_t)) != 0) {
35+
if ((memcmp(&(init->format), &sai_mode_i2s16w32, sizeof(sai_format_t)) != 0) &&
36+
(memcmp(&(init->format), &sai_mode_i2s16, sizeof(sai_format_t)) != 0)) {
3637
// we only support 1 format so far
3738
return SAI_RESULT_CONFIG_UNSUPPORTED;
3839
}
@@ -119,8 +120,8 @@ static sai_result_t stm_sai_init(sai_t *obj, sai_init_t *init) {
119120
/*
120121
sample rate * frame length
121122
*/
122-
uint32_t data_size = 16; // possible values : 8, 10, 16, 20, 24, 32
123-
uint32_t slot_size = 32; // 0, 16, 32. 0 means = datasize
123+
uint32_t data_size = init->format.data_length; // possible values : 8, 10, 16, 20, 24, 32
124+
uint32_t slot_size = init->format.word_length; // 0, 16, 32. 0 means = datasize
124125
uint32_t slot_count = 2;
125126

126127
/* compute hirez div times 2^n to keep some precision yet having fast results

0 commit comments

Comments
 (0)