Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion apps/examples/sensor_test/sensor_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,14 @@ static void mems_teardown();

static void print_sensor_data(sensor_data_s *data)
{
// for (int i = 0; i < AIS25BA_BUFLENGTH; i++) {
// printf("x: %f, y: %f, z: %f\n", data[i].x, data[i].y, data[i].z);
// }
for (int i = 0; i < AIS25BA_BUFLENGTH; i++) {
printf("x: %f, y: %f, z: %f\n", data[i].x, data[i].y, data[i].z);
printf("%04x %04x %04x\n", data[i].samples[0], data[i].samples[1], data[i].samples[2]);
// printf("%04x %04x %04x %04x\n", data[i].samples[4], data[i].samples[5], data[i].samples[6], data[i].samples[7]);
}
printf("=======================================================================================\n");
}

static int mems_sensor_init()
Expand Down
132 changes: 92 additions & 40 deletions os/arch/arm/src/amebasmart/amebasmart_i2s.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,18 @@
#define I2S_DMA_PAGE_SIZE 8192 /* 4 ~ 16384, set to a factor of APB size */
#define I2S_DMA_PAGE_NUM 4 /* Vaild number is 2~4 */

#define I2S_TDM_DMA_PAGE_SIZE 1024 /* 4 ~ 16384, set to a factor of APB size */
#define I2S_TDM_DMA_PAGE_NUM 16 /* Vaild number is 2~8 */

static volatile bool i2s_tdm_rx = 0;
static u8 prx_int_buf[I2S_TDM_DMA_PAGE_SIZE]__attribute__((aligned(64)));
static u8 prx_ext_buf[I2S_TDM_DMA_PAGE_SIZE]__attribute__((aligned(64)));
#ifdef CONFIG_PM
static volatile bool i2s_lock_state = 0;
#endif

static volatile bool i2s_tx_enabled = 0;
static volatile bool i2s_rx_enabled = 0;
struct amebasmart_buffer_s {
struct amebasmart_buffer_s *flink; /* Supports a singly linked list */
i2s_callback_t callback; /* Function to call when the transfer completes */
Expand Down Expand Up @@ -196,8 +203,8 @@ struct amebasmart_i2s_s {
#endif

#if defined(I2S_HAVE_RX) && (0 < I2S_HAVE_RX)
uint8_t i2s_rx_buf[(I2S_DMA_PAGE_NUM + 1) * I2S_DMA_PAGE_SIZE]__attribute__((aligned(64))); /* Allocate buffer for use in RX, must I2S_DMA_PAGE_NUM+1 for zero buffer */
uint8_t i2s_rx_buf_ext[(I2S_DMA_PAGE_NUM + 1) * I2S_DMA_PAGE_SIZE]__attribute__((aligned(64))); /* Allocate buffer for use in RX, must I2S_DMA_PAGE_NUM+1 for zero buffer */
uint8_t i2s_rx_buf[(I2S_TDM_DMA_PAGE_NUM + 1) * I2S_TDM_DMA_PAGE_SIZE]__attribute__((aligned(64))); /* Allocate buffer for use in RX, must I2S_DMA_PAGE_NUM+1 for zero buffer */
uint8_t i2s_rx_buf_ext[(I2S_TDM_DMA_PAGE_NUM + 1) * I2S_TDM_DMA_PAGE_SIZE]__attribute__((aligned(64))); /* Allocate buffer for use in RX, must I2S_DMA_PAGE_NUM+1 for zero buffer */
//uint8_t* i2s_rx_buf;
i2s_irq_handler rx_isr_handler;
#if defined(I2S_HAVE_TDM) && (0 < I2S_HAVE_TDM)
Expand Down Expand Up @@ -288,7 +295,7 @@ static const struct amebasmart_i2s_config_s amebasmart_i2s2_tdm_config = {
.rxenab = 1,
.txenab = 0,
.tdmenab = 1,
.data_format = SP_DF_I2S
.data_format = SP_DF_LEFT
};
#endif

Expand Down Expand Up @@ -888,11 +895,10 @@ static int i2s_rxdma_prep(struct amebasmart_i2s_s *priv, struct amebasmart_buffe
#if defined(I2S_HAVE_TDM) && (0 < I2S_HAVE_TDM)
if (priv->tdmenab) {
i2sinfo("tdm: set dma buffer! rxbuf: %p\n", priv->i2s_rx_buf);

i2s_tdm_set_dma_buffer(priv->i2s_object, NULL, (char *)priv->i2s_rx_buf, I2S_DMA_PAGE_NUM, I2S_DMA_PAGE_SIZE, GDMA_INT, apb->nmaxbytes);
i2s_tdm_set_dma_buffer(priv->i2s_object, NULL, (char *)priv->i2s_rx_buf, I2S_TDM_DMA_PAGE_NUM, I2S_TDM_DMA_PAGE_SIZE/2, GDMA_INT, apb->nmaxbytes);
if (priv->i2s_object->fifo_num >= SP_RX_FIFO8) {
i2sinfo("tdm: set dma buffer for EXT! rxbuf1: %p\n", priv->i2s_rx_buf);
i2s_tdm_set_dma_buffer(priv->i2s_object, NULL, (char *)priv->i2s_rx_buf_ext, I2S_DMA_PAGE_NUM, I2S_DMA_PAGE_SIZE, GDMA_EXT, apb->nmaxbytes);
i2sinfo("tdm: set dma buffer for EXT! rxbuf1: %p\n", priv->i2s_rx_buf_ext);
i2s_tdm_set_dma_buffer(priv->i2s_object, NULL, (char *)priv->i2s_rx_buf_ext, I2S_TDM_DMA_PAGE_NUM, I2S_TDM_DMA_PAGE_SIZE/2, GDMA_EXT, apb->nmaxbytes);
}
} else
#else
Expand Down Expand Up @@ -930,11 +936,15 @@ static int i2s_rx_start(struct amebasmart_i2s_s *priv)
/* Add the container to the list of active DMAs */
sq_addlast((sq_entry_t *)bfcontainer, &priv->rx.act);
#if defined(I2S_HAVE_TDM) && (0 < I2S_HAVE_TDM)
if(priv->tdmenab == 0)
#endif
{
i2s_recv_page(priv->i2s_object);
/* resume the clockgen if master, GDMA-SPORT ISR will trigger the callback to pass memory to app layer */
if (priv->i2s_object->role == MASTER) {
i2s_tdm_rx = 1;
if (!i2s_rx_enabled) {
i2s_tdm_enable(priv->i2s_object);
i2s_rx_enabled = 1;
}
}
#endif
}
leave_critical_section(flags);

Expand Down Expand Up @@ -1229,19 +1239,14 @@ static int i2s_tdm_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb, i2s_c
bsp_pm_domain_control(BSP_I2S_DRV, 1);
#endif

/* Prepare DMA microcode (CHANGE THIS! THIS SHOULD SETUP DMA BUFFERS BEFORE CLOCK STARTS) */
i2s_rxdma_prep(priv, bfcontainer);

flags = enter_critical_section();
sq_addlast((sq_entry_t *)bfcontainer, &priv->rx.pend);
leave_critical_section(flags);
/* Start transfer */

ret = i2s_rx_start(priv);

/* resume the clockgen if master, GDMA-SPORT ISR will trigger the callback to pass memory to app layer */
if (priv->i2s_object->role == MASTER) {
ameba_i2s_tdm_resume(priv->i2s_object);
}

i2s_exclsem_give(priv);
i2sinfo("RX Exclusive Exit\n");
Expand All @@ -1261,21 +1266,21 @@ static int i2s_tdm_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb, i2s_c
* @param base pointer.
* @param handle Pointer to the sai_handle_t structure.
*/
extern volatile uint8_t DMA_Done, DMA_Done_1;
void i2s_transfer_rx_handleirq(void *data, char *pbuf)
{
struct amebasmart_i2s_s *priv = (struct amebasmart_i2s_s *)data;
i2s_t *obj = priv->i2s_object;

#if defined(I2S_HAVE_TDM) && (0 < I2S_HAVE_TDM)
if (!i2s_tdm_rx) {
return;
}
if (priv->tdmenab) {
/* this callback will be called twice if 2 DMA channels are used, only allow processing when both completion flags are true */
if (obj->fifo_num >= SP_RX_FIFO8) {
if (DMA_Done && DMA_Done_1) {
//dbg("rx complete 8CH! stopping clockgen! APB: %p\n", priv->apb_rx);

/* stop clockgen */
ameba_i2s_tdm_pause(obj);
#if 0
#else
if (sp_get_ready_rx_page() && sp_get_ready_rx_page_ext() ) {

/* INTERNAL channel will have SLOT 1,2 followed by 5,6 */
/* EXTERNAL channel will have SLOT 3,4 followed by 7,8 */
Expand All @@ -1290,11 +1295,11 @@ void i2s_transfer_rx_handleirq(void *data, char *pbuf)
}
if (word_size == sizeof(u16)) {
u16 *dst_buf = (u16 *)priv->apb_rx->samp;
u16 *dma1 = (u16 *)priv->i2s_rx_buf;
u16 *dma2 = (u16 *)priv->i2s_rx_buf_ext;
lldbg("@@@@@@@@ DST BUF SIZE: %d |||| DMA PAGE SIZE: %d\n", priv->apb_rx->nmaxbytes, I2S_DMA_PAGE_SIZE);
// lib_dumpbuffer("Int", dma1, 512);
// lib_dumpbuffer("Ext", dma2, 512);

sp_read_rx_page((u8 *)prx_int_buf, priv->apb_rx->nmaxbytes / 2);
sp_read_rx_page_ext((u8 *)prx_ext_buf, priv->apb_rx->nmaxbytes / 2);
u16 *dma1 = (u16 *)prx_int_buf;
u16 *dma2 = (u16 *)prx_ext_buf;
u32 count = 0;
u32 dma1_idx = 0, dma2_idx = 0, sample_idx = 0;
while (count < priv->apb_rx->nmaxbytes) {
Expand Down Expand Up @@ -1349,14 +1354,18 @@ void i2s_transfer_rx_handleirq(void *data, char *pbuf)
dst_buf[i + 7] = rx_ext[j + 3]; // slot 8
}
}


i2s_tdm_rx = 0;
/* call upper layer callback */
i2s_rxdma_callback(priv, OK);
}
} else {
if (DMA_Done) {
/* stop clockgen */
ameba_i2s_tdm_pause(obj);
}
#endif
else {
if (sp_get_ready_rx_page()) {
/* stop DMA, but retain clockgen */
ameba_i2s_tdm_pause(obj, ENABLE);

/* copy DMA contents into buffer container ? */
// TODO: for single channel DMA populate the buffer

Expand Down Expand Up @@ -1692,7 +1701,7 @@ static int i2s_pause(struct i2s_dev_s *dev, i2s_ch_dir_t dir)
if (dir == I2S_TX && priv->txenab) {
#if defined(I2S_HAVE_TDM) && (0 < I2S_HAVE_TDM)
if (priv->tdmenab) {
ameba_i2s_tdm_pause(priv->i2s_object);
ameba_i2s_tdm_pause(priv->i2s_object, DISABLE);
} else {
ameba_i2s_pause(priv->i2s_object);
}
Expand All @@ -1707,7 +1716,8 @@ static int i2s_pause(struct i2s_dev_s *dev, i2s_ch_dir_t dir)
if (dir == I2S_RX && priv->rxenab) {
#if defined(I2S_HAVE_TDM) && (0 < I2S_HAVE_TDM)
if (priv->tdmenab) {
ameba_i2s_tdm_pause(priv->i2s_object);
ameba_i2s_tdm_pause(priv->i2s_object, DISABLE);
i2s_rx_enabled = 0;
} else {
ameba_i2s_pause(priv->i2s_object);
}
Expand Down Expand Up @@ -1743,7 +1753,7 @@ static int i2s_resume(struct i2s_dev_s *dev, i2s_ch_dir_t dir)
#if defined(I2S_HAVE_TDM) && (0 < I2S_HAVE_TDM)
if (dir == I2S_TX && priv->txenab) {
if (priv->tdmenab) {
ameba_i2s_tdm_resume(priv->i2s_object);
i2s_tdm_enable(priv->i2s_object);
} else {
ameba_i2s_resume(priv->i2s_object);
}
Expand All @@ -1760,7 +1770,8 @@ static int i2s_resume(struct i2s_dev_s *dev, i2s_ch_dir_t dir)
#if defined(I2S_HAVE_TDM) && (0 < I2S_HAVE_TDM)
if (dir == I2S_RX && priv->rxenab) {
if (priv->tdmenab) {
ameba_i2s_tdm_resume(priv->i2s_object);
i2s_tdm_enable(priv->i2s_object);
i2s_rx_enabled = 1;
} else {
ameba_i2s_resume(priv->i2s_object);
}
Expand Down Expand Up @@ -1797,7 +1808,7 @@ static int i2s_stop_transfer(struct i2s_dev_s *dev, i2s_ch_dir_t dir)
#if defined(I2S_HAVE_TX) && (0 < I2S_HAVE_TX)
#if defined(I2S_HAVE_TDM) && (0 < I2S_HAVE_TDM)
if (dir == I2S_TX && priv->tdmenab) {
ameba_i2s_tdm_pause(priv->i2s_object);
ameba_i2s_tdm_pause(priv->i2s_object, DISABLE);
} else {
ameba_i2s_pause(priv->i2s_object);
}
Expand All @@ -1812,7 +1823,9 @@ static int i2s_stop_transfer(struct i2s_dev_s *dev, i2s_ch_dir_t dir)
#if defined(I2S_HAVE_RX) && (0 < I2S_HAVE_RX)
#if defined(I2S_HAVE_TDM) && (0 < I2S_HAVE_TDM)
if (dir == I2S_RX && priv->tdmenab) {
ameba_i2s_tdm_pause(priv->i2s_object);
ameba_i2s_tdm_pause(priv->i2s_object, DISABLE);
i2s_rx_enabled = 0;

} else {
ameba_i2s_pause(priv->i2s_object);
}
Expand Down Expand Up @@ -1899,6 +1912,40 @@ static int i2s_stop(struct i2s_dev_s *dev, i2s_ch_dir_t dir)
}
}
#endif
#if defined(I2S_HAVE_TDM) && (0 < I2S_HAVE_TDM)
if (dir == I2S_RX) {
i2s_tdm_disable(priv->i2s_object, 0);
i2s_rx_enabled = 0;
i2s_tdm_set_dma_buffer(priv->i2s_object, NULL, (char *)priv->i2s_rx_buf, I2S_TDM_DMA_PAGE_NUM, I2S_TDM_DMA_PAGE_SIZE/2, GDMA_INT,I2S_TDM_DMA_PAGE_SIZE/2);
if (priv->i2s_object->fifo_num >= SP_RX_FIFO8) {
lldbg("tdm: set dma buffer for EXT! rxbuf1: %p\n", priv->i2s_rx_buf_ext);
i2s_tdm_set_dma_buffer(priv->i2s_object, NULL, (char *)priv->i2s_rx_buf_ext, I2S_TDM_DMA_PAGE_NUM, I2S_TDM_DMA_PAGE_SIZE/2, GDMA_EXT,I2S_TDM_DMA_PAGE_SIZE/2);
}
amebasmart_i2s_tdm_isr_initialize(priv); // TDM
while (sq_peek(&priv->rx.pend) != NULL) {
flags = enter_critical_section();
bfcontainer = (struct amebasmart_buffer_s *)sq_remfirst(&priv->rx.pend);
leave_critical_section(flags);
apb_free(bfcontainer->apb);
i2s_buf_rx_free(priv, bfcontainer);
}

while (sq_peek(&priv->rx.act) != NULL) {
flags = enter_critical_section();
bfcontainer = (struct amebasmart_buffer_s *)sq_remfirst(&priv->rx.act);
leave_critical_section(flags);
apb_free(bfcontainer->apb);
i2s_buf_rx_free(priv, bfcontainer);
}

while (sq_peek(&priv->rx.done) != NULL) {
flags = enter_critical_section();
bfcontainer = (struct amebasmart_buffer_s *)sq_remfirst(&priv->rx.done);
leave_critical_section(flags);
i2s_buf_rx_free(priv, bfcontainer);
}
}
#endif

i2s_exclsem_give(priv);

Expand Down Expand Up @@ -1967,6 +2014,7 @@ int amebasmart_i2s_tdm_isr_initialize(struct amebasmart_i2s_s *priv)
#endif
#if defined(I2S_HAVE_RX) && (0 < I2S_HAVE_RX)
i2s_tdm_rx_irq_handler(priv->i2s_object, (i2s_irq_handler)priv->rx_isr_handler, (uint32_t)priv);
ameba_i2s_tdm_init_dma(priv->i2s_object);
#endif
return 0;
}
Expand Down Expand Up @@ -2336,6 +2384,11 @@ struct i2s_dev_s *amebasmart_i2s_tdm_initialize(uint16_t port, bool is_reinit)

#if defined(I2S_HAVE_TDM) && (0 < I2S_HAVE_TDM)
priv->rx_isr_handler_ext = (i2s_irq_handler)&i2s_transfer_rx_handleirq;
i2s_tdm_set_dma_buffer(priv->i2s_object, NULL, (char *)priv->i2s_rx_buf, I2S_TDM_DMA_PAGE_NUM, I2S_TDM_DMA_PAGE_SIZE/2, GDMA_INT,I2S_TDM_DMA_PAGE_SIZE/2);
if (priv->i2s_object->fifo_num >= SP_RX_FIFO8) {
lldbg("tdm: set dma buffer for EXT! rxbuf1: %p\n", priv->i2s_rx_buf_ext);
i2s_tdm_set_dma_buffer(priv->i2s_object, NULL, (char *)priv->i2s_rx_buf_ext, I2S_TDM_DMA_PAGE_NUM, I2S_TDM_DMA_PAGE_SIZE/2, GDMA_EXT,I2S_TDM_DMA_PAGE_SIZE/2);
}
#endif

#endif
Expand All @@ -2348,7 +2401,6 @@ struct i2s_dev_s *amebasmart_i2s_tdm_initialize(uint16_t port, bool is_reinit)
#endif

#endif

ret = amebasmart_i2s_tdm_isr_initialize(priv); // TDM
if (ret != OK) {
i2serr("I2S initialize (TDM): isr fails\n");
Expand Down
Loading