From: asterix Date: Thu, 21 Jul 2011 15:49:29 +0000 (+0000) Subject: Add alpha api implementation for i2s module. X-Git-Url: https://codewiz.org/gitweb?a=commitdiff_plain;h=677c93e2b91e885d2bcb0ea313ad0a58b195fd09;p=bertos.git Add alpha api implementation for i2s module. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@4977 38d2e660-2303-0410-9eaa-f027e97ec537 --- diff --git a/bertos/cfg/cfg_i2s.h b/bertos/cfg/cfg_i2s.h index 6657157e..ad91bf8b 100644 --- a/bertos/cfg/cfg_i2s.h +++ b/bertos/cfg/cfg_i2s.h @@ -34,17 +34,28 @@ * * * \author Luca Ottaviano + * \author Daniele Basile */ #ifndef CFG_I2S_H #define CFG_I2S_H /** - * Length of each play buffer. + * Module logging level. * - * $WIZ$ type = "int" + * $WIZ$ type = "enum" + * $WIZ$ value_list = "log_level" */ -#define CONFIG_PLAY_BUF_LEN 8192 +#define I2S_LOG_LEVEL LOG_LVL_INFO + +/** + * Module logging format. + * + * $WIZ$ type = "enum" + * $WIZ$ value_list = "log_format" + */ +#define I2S_LOG_FORMAT LOG_FMT_TERSE + /** * Sampling frequency of the audio file. @@ -53,22 +64,68 @@ * $WIZ$ min = 32000 * $WIZ$ max = 192000 */ -#define CONFIG_SAMPLE_FREQ 44100UL +#define CONFIG_SAMPLE_FREQ 44800UL /** - * Module logging level. + * Sample bits per channel. * - * $WIZ$ type = "enum" - * $WIZ$ value_list = "log_level" + * $WIZ$ type = "int" + * * $WIZ$ min = 8 + * $WIZ$ max = 32 */ -#define I2S_LOG_LEVEL LOG_LVL_INFO +#define CONFIG_WORD_BIT_SIZE 16 /** - * Module logging format. + * Number of channel. * - * $WIZ$ type = "enum" - * $WIZ$ value_list = "log_format" + * $WIZ$ type = "int" */ -#define I2S_LOG_FORMAT LOG_FMT_TERSE +#define CONFIG_CHANNEL_NUM 2 + +/** + * Size of trasmit start delay + * + * $WIZ$ type = "int" + * $WIZ$ min = 0 + * $WIZ$ max = 255 + */ +#define CONFIG_DELAY 0 + +/** + * Generate frame sync every 2 x CONFIG_PERIOD bits (zero based) + * + * $WIZ$ type = "int" + * $WIZ$ min = 0 + * $WIZ$ max = 512 + */ +#define CONFIG_PERIOD 15 + +/** + * Number of words transmitted in frame + * + * $WIZ$ type = "int" + * $WIZ$ min = 0 + * $WIZ$ max = 16 + */ +#define CONFIG_WORD_PER_FRAME 1 + +/** + * Size of Synchro data register (zero based) + * + * $WIZ$ type = "int" + * $WIZ$ min = 0 + * $WIZ$ max = 15 + */ +#define CONFIG_FRAME_SYNC_SIZE 15 + + +/** + * Extra Size of Synchro data register (CONFIG_FRAME_SYNC_SIZE + CONFIG_EXTRA_FRAME_SYNC_SIZE * 16 + 1) (zero based) + * + * $WIZ$ type = "int" + * $WIZ$ min = 0 + * $WIZ$ max = 15 + */ +#define CONFIG_EXTRA_FRAME_SYNC_SIZE 0 #endif /* CFG_I2S_H */ diff --git a/bertos/drv/i2s.h b/bertos/drv/i2s.h new file mode 100644 index 00000000..73768c31 --- /dev/null +++ b/bertos/drv/i2s.h @@ -0,0 +1,188 @@ +/** + * \file + * + * + * \defgroup i2s Generic I2S driver + * \ingroup drivers + * \{ + * \brief + * + * Configuration file: cfg_i2s.h + * + * \author Daniele Basile + * + * $WIZ$ module_name = "i2s" + * $WIZ$ module_configuration = "bertos/cfg/cfg_i2s.h" + * $WIZ$ module_supports = "not all" + */ + + +#ifndef DRV_I2S_H +#define DRV_I2S_H + +#warning This API is ALPHA! we could change it.. + +#include +#include +#include + +#include + +#include CPU_HEADER(i2s) + +struct I2sContext; +struct I2s; + +typedef int (*i2s_write_t) (struct I2s *i2s, uint32_t sample); +typedef uint32_t (*i2s_read_t) (struct I2s *i2s); +typedef void (*i2s_dma_tx_buf_t) (struct I2s *i2s, void *buf, size_t len); +typedef void (*i2s_dma_rx_buf_t) (struct I2s *i2s, void *buf, size_t len); +typedef bool (*i2s_dma_tx_is_finished_t) (struct I2s *i2s); +typedef bool (*i2s_dma_rx_is_finished_t) (struct I2s *i2s); +typedef void (*i2s_dma_callback_t) (struct I2s *i2s, void *_buf, size_t len); +typedef void (*i2s_dma_start_streaming_t) (struct I2s *i2s, void *buf, size_t len, size_t slice_len); +typedef void (*i2s_dma_wait_t) (struct I2s *i2s); +typedef void (*i2s_dma_stop_t) (struct I2s *i2s); + +typedef struct I2sContext +{ + i2s_write_t write; + i2s_dma_tx_buf_t tx_buf; + i2s_dma_tx_is_finished_t tx_isFinish; + i2s_dma_callback_t tx_callback; + i2s_dma_start_streaming_t tx_start; + i2s_dma_wait_t tx_wait; + i2s_dma_stop_t tx_stop; + size_t tx_slice_len; + + i2s_read_t read; + i2s_dma_rx_buf_t rx_buf; + i2s_dma_rx_is_finished_t rx_isFinish; + i2s_dma_callback_t rx_callback; + i2s_dma_start_streaming_t rx_start; + i2s_dma_wait_t rx_wait; + i2s_dma_stop_t rx_stop; + size_t rx_slice_len; + + DB(id_t _type); + +} I2sContext; + +typedef struct I2s +{ + I2sContext ctx; + struct I2sHardware *hw; +} I2s; + +INLINE int i2s_write(I2s *i2s, uint32_t sample) +{ + ASSERT(i2s->ctx.write); + return i2s->ctx.write(i2s, sample); +} + + +INLINE uint32_t i2s_read(I2s *i2s) +{ + ASSERT(i2s->ctx.read); + return i2s->ctx.read(i2s); +} + +/* + * Check if a dma transfer is finished. + * + * Useful for kernel-less applications. + */ +INLINE bool i2s_dmaTxIsFinished(I2s *i2s) +{ + ASSERT(i2s->ctx.tx_isFinish); + return i2s->ctx.tx_isFinish(i2s); +} + +INLINE bool i2s_dmaRxIsFinished(I2s *i2s) +{ + ASSERT(i2s->ctx.rx_isFinish); + return i2s->ctx.rx_isFinish(i2s); +} + +INLINE void i2s_dmaTxBuffer(I2s *i2s, void *buf, size_t len) +{ + ASSERT(i2s->ctx.tx_buf); + i2s->ctx.tx_buf(i2s, buf, len); +} + +INLINE void i2s_dmaRxBuffer(I2s *i2s, void *buf, size_t len) +{ + ASSERT(i2s->ctx.rx_buf); + i2s->ctx.rx_buf(i2s, buf, len); +} + + +INLINE void i2s_dmaStartTxStreaming(I2s *i2s, void *buf, size_t len, size_t slice_len, i2s_dma_callback_t callback) +{ + ASSERT(i2s->ctx.tx_start); + ASSERT(len % slice_len == 0); + ASSERT(callback); + + i2s->ctx.rx_callback = callback; + i2s->ctx.rx_slice_len = slice_len; + i2s->ctx.tx_start(i2s, buf, len, slice_len); +} + +INLINE void i2s_dmaTxStop(I2s *i2s) +{ + ASSERT(i2s->ctx.tx_stop); + i2s->ctx.tx_stop(i2s); +} + + +INLINE void i2s_dmaStartRxStreaming(I2s *i2s, void *buf, size_t len, size_t slice_len, i2s_dma_callback_t callback) +{ + ASSERT(i2s->ctx.rx_start); + ASSERT(len % slice_len == 0); + ASSERT(callback); + + i2s->ctx.rx_callback = callback; + i2s->ctx.rx_slice_len = slice_len; + i2s->ctx.rx_start(i2s, buf, len, slice_len); +} + + + +INLINE void i2s_dmaRxStop(I2s *i2s) +{ + ASSERT(i2s->ctx.rx_stop); + i2s->ctx.rx_stop(i2s); +} + +void i2s_init(I2s *i2s, int channel); + +/** \} */ //defgroup i2s +#endif /* DRV_I2S_H */