diff --git a/libraries/CurieI2S/examples/I2SDMA_RXCallBack/I2SDMA_RXCallBack.ino b/libraries/CurieI2S/examples/I2SDMA_RXCallBack/I2SDMA_RXCallBack.ino index 97ab8163..6992bf56 100644 --- a/libraries/CurieI2S/examples/I2SDMA_RXCallBack/I2SDMA_RXCallBack.ino +++ b/libraries/CurieI2S/examples/I2SDMA_RXCallBack/I2SDMA_RXCallBack.ino @@ -25,7 +25,7 @@ uint32_t dataBuff[BUFF_SIZE+OFFSET]; // extra 2 buffer is for the padding zero uint8_t start_flag = 0; uint8_t done_flag = 0; uint32_t loop_count = 0; - +uint32_t shift_count = 0; void setup() { Serial.begin(115200); @@ -46,32 +46,45 @@ void setup() void loop() { - int status = CurieI2SDMA.transRX(dataBuff,sizeof(dataBuff)); + int status = CurieI2SDMA.transRX(dataBuff,sizeof(dataBuff),sizeof(uint32_t)); if(status) return; + // find out first non-zero + shift_count = 0; + for(uint32_t i = 0;i <= OFFSET;++i) + { + if(dataBuff[i] == 0) + shift_count++; + else + break; + } + if(shift_count > OFFSET) + return; + if(start_flag) { - if((dataBuff[OFFSET]>>16) != loop_count+1) + if((dataBuff[shift_count]>>16) != loop_count+1) Serial.println("+++ loop_count jump +++"); } else { start_flag = 1; } - loop_count = (dataBuff[OFFSET] >> 16); - + loop_count = (dataBuff[shift_count] >> 16); + + // check data done_flag = 1; for(uint32_t i = 0 ;i < BUFF_SIZE;++i) { - //Serial.println(dataBuff[i+OFFSET],HEX); - if ((dataBuff[i+OFFSET] & 0XFFFF0000) == (loop_count <<16) - && (dataBuff[i+OFFSET] & 0XFFFF) == (i+1)) + //Serial.println(dataBuff[i+shift_count],HEX); + if ((dataBuff[i+shift_count] & 0XFFFF0000) == (loop_count <<16) + && (dataBuff[i+shift_count] & 0XFFFF) == (i+1)) ; else { done_flag = 0; - Serial.println(dataBuff[i+OFFSET],HEX); + Serial.println(dataBuff[i+shift_count],HEX); Serial.println("ERROR"); break; } diff --git a/libraries/CurieI2S/examples/I2SDMA_TXCallBack/I2SDMA_TXCallBack.ino b/libraries/CurieI2S/examples/I2SDMA_TXCallBack/I2SDMA_TXCallBack.ino index fe27ab2e..d39bea36 100644 --- a/libraries/CurieI2S/examples/I2SDMA_TXCallBack/I2SDMA_TXCallBack.ino +++ b/libraries/CurieI2S/examples/I2SDMA_TXCallBack/I2SDMA_TXCallBack.ino @@ -38,7 +38,7 @@ void loop() dataBuff[i] = i + 1 + (loop_count<<16); } loop_count++; - int status = CurieI2SDMA.transTX(dataBuff,sizeof(dataBuff)); + int status = CurieI2SDMA.transTX(dataBuff,sizeof(dataBuff),sizeof(uint32_t)); if(status) return; diff --git a/libraries/CurieI2S/src/CurieI2SDMA.cpp b/libraries/CurieI2S/src/CurieI2SDMA.cpp index 4ef36428..9ac8de50 100644 --- a/libraries/CurieI2S/src/CurieI2SDMA.cpp +++ b/libraries/CurieI2S/src/CurieI2SDMA.cpp @@ -36,10 +36,11 @@ volatile uint8_t txerror_flag = 0; volatile uint8_t rxdone_flag = 0; volatile uint8_t rxerror_flag = 0; - +uint8_t frameDelay = 0; static void txi2s_done(void* x) { + CurieI2SDMA.lastFrameDelay(); txdone_flag = 1; return; @@ -76,6 +77,11 @@ Curie_I2SDMA::Curie_I2SDMA() { } +void Curie_I2SDMA::lastFrameDelay() +{ + delay(frameDelay); +} + int Curie_I2SDMA::iniTX() { muxTX(1); @@ -154,8 +160,8 @@ int Curie_I2SDMA::beginTX(uint16_t sample_rate,uint8_t resolution,uint8_t master txcfg.cb_err = txi2s_err; txdone_flag = 0; txerror_flag = 0; + frameDelay = 5; soc_i2s_config(I2S_CHANNEL_TX, &txcfg); - return I2S_DMA_OK; } @@ -195,10 +201,11 @@ int Curie_I2SDMA::beginRX(uint16_t sample_rate,uint8_t resolution,uint8_t master return I2S_DMA_OK; } -int Curie_I2SDMA::transTX(uint32_t* buf_TX,uint32_t len) +int Curie_I2SDMA::transTX(void* buf_TX,uint32_t len,uint32_t len_per_data) { - soc_i2s_stream(buf_TX, len,0); - + int status = soc_i2s_stream(buf_TX, len,len_per_data,0); + if(status) + return I2S_DMA_FAIL; while (1) { // check the DMA and I2S status @@ -215,9 +222,11 @@ int Curie_I2SDMA::transTX(uint32_t* buf_TX,uint32_t len) } } -int Curie_I2SDMA::transRX(uint32_t* buf_RX,uint32_t len) +int Curie_I2SDMA::transRX(void* buf_RX,uint32_t len,uint32_t len_per_data) { - soc_i2s_listen(buf_RX, len ,0); + int status = soc_i2s_listen(buf_RX, len ,len_per_data,0); + if(status) + return I2S_DMA_FAIL; while (1) { @@ -248,28 +257,66 @@ void Curie_I2SDMA::stopRX() muxRX(0); } -int Curie_I2SDMA::mergeData(uint32_t* buf_left,uint32_t* buf_right,uint32_t* buf_TX) +int Curie_I2SDMA::mergeData(void* buf_left,void* buf_right,void* buf_TX,uint32_t length_TX,uint32_t len_per_data) { - int length = (int)(sizeof(buf_left) / sizeof(buf_left[0])); - for(int i = 0; i < length;++i) + if(len_per_data == 1) { - buf_TX[2*i] = buf_left[i]; - buf_TX[2*i+1] = buf_right[i]; + for(uint32_t i = 0; i < length_TX/2;++i) + { + *((uint8_t *)buf_TX+2*i) = *((uint8_t *)buf_left+i); + *((uint8_t *)buf_TX+2*i+1) = *((uint8_t *)buf_right+i); + } } + else if(len_per_data == 2) + { + for(uint32_t i = 0; i < length_TX/2;++i) + { + *((uint16_t *)buf_TX+2*i) = *((uint16_t *)buf_left+i); + *((uint16_t *)buf_TX+2*i+1) = *((uint16_t *)buf_right+i); + } + } + else if(len_per_data == 4) + { + for(uint32_t i = 0; i < length_TX/2;++i) + { + *((uint32_t *)buf_TX+2*i) = *((uint32_t *)buf_left+i); + *((uint32_t *)buf_TX+2*i+1) = *((uint32_t *)buf_right+i); + } + } + else + return I2S_DMA_FAIL; - return I2S_DMA_OK; + return I2S_DMA_OK; } -int Curie_I2SDMA::separateData(uint32_t* buf_left,uint32_t* buf_right,uint32_t* buf_RX) -{ - int length1 = (int)( sizeof(buf_RX) / sizeof(buf_RX[0])/2 ); - int length2 = (int)( sizeof(buf_left) / sizeof(buf_left[0]) ); - int length = length1 < length2 ? length1 : length2; - - for(int i = 0; i < length;++i) +int Curie_I2SDMA::separateData(void* buf_left,void* buf_right,void* buf_RX,uint32_t length_RX,uint32_t len_per_data) +{ + if(len_per_data == 1) + { + for(uint32_t i = 0; i < length_RX/2;++i) + { + *((uint8_t *)buf_left+i) = *((uint8_t *)buf_RX+2*i); + *((uint8_t *)buf_right+i) = *((uint8_t *)buf_RX+2*i+1); + } + } + else if(len_per_data == 2) { - buf_left[i] = buf_RX[2*i]; - buf_right[i] = buf_RX[2*i+1]; + for(uint32_t i = 0; i < length_RX/2;++i) + { + *((uint16_t *)buf_left+i) = *((uint16_t *)buf_RX+2*i); + *((uint16_t *)buf_right+i) = *((uint16_t *)buf_RX+2*i+1); + } } - return I2S_DMA_OK; + else if(len_per_data == 4) + { + for(uint32_t i = 0; i < length_RX/2;++i) + { + *((uint32_t *)buf_left+i) = *((uint32_t *)buf_RX+2*i); + *((uint32_t *)buf_right+i) = *((uint32_t *)buf_RX+2*i+1); + } + } + else + return I2S_DMA_FAIL; + + return I2S_DMA_OK; } diff --git a/libraries/CurieI2S/src/CurieI2SDMA.h b/libraries/CurieI2S/src/CurieI2SDMA.h index a1707123..3f026ef8 100644 --- a/libraries/CurieI2S/src/CurieI2SDMA.h +++ b/libraries/CurieI2S/src/CurieI2SDMA.h @@ -47,6 +47,8 @@ class Curie_I2SDMA public: Curie_I2SDMA(); + void lastFrameDelay(); + // int beginTX(uint16_t sample_rate,uint8_t resolution,uint8_t master,uint8_t mode); // @@ -58,16 +60,16 @@ class Curie_I2SDMA int iniRX(); // starts transmission of data to the tx channel - int transTX(uint32_t* buf_TX,uint32_t len); + int transTX(void* buf_TX,uint32_t len,uint32_t len_per_data); // starts listening to the rx channel - int transRX(uint32_t* buf_RX,uint32_t len); + int transRX(void* buf_RX,uint32_t len,uint32_t len_per_data); // merge data of left and right channel into one buffer - int mergeData(uint32_t* buf_left,uint32_t* buf_right,uint32_t* buf_TX); + int mergeData(void* buf_left,void* buf_right,void* buf_TX,uint32_t length_TX,uint32_t len_per_data); // seperate the data to left and right channl - int separateData(uint32_t* buf_left,uint32_t* buf_right,uint32_t* buf_RX); + int separateData(void* buf_left,void* buf_right,void* buf_RX,uint32_t length_RX,uint32_t len_per_data); // void stopTX(); diff --git a/system/libarc32_arduino101/drivers/soc_i2s.c b/system/libarc32_arduino101/drivers/soc_i2s.c index 70b51429..114ce764 100644 --- a/system/libarc32_arduino101/drivers/soc_i2s.c +++ b/system/libarc32_arduino101/drivers/soc_i2s.c @@ -57,11 +57,11 @@ static void i2s_disable(uint8_t channel); static void i2s_isr(void); DRIVER_API_RC soc_i2s_config(uint8_t channel, struct soc_i2s_cfg *cfg); DRIVER_API_RC soc_i2s_deconfig(uint8_t channel); -DRIVER_API_RC soc_i2s_read(uint32_t *buf, uint32_t len); -DRIVER_API_RC soc_i2s_listen(uint32_t *buf, uint32_t len, uint8_t num_bufs); +DRIVER_API_RC soc_i2s_read(void *buf, uint32_t len, uint32_t len_per_data); +DRIVER_API_RC soc_i2s_listen(void *buf, uint32_t len, uint32_t len_per_data, uint8_t num_bufs); DRIVER_API_RC soc_i2s_stop_listen(void); -DRIVER_API_RC soc_i2s_write(uint32_t *buf, uint32_t len); -DRIVER_API_RC soc_i2s_stream(uint32_t *buf, uint32_t len, uint32_t num_bufs); +DRIVER_API_RC soc_i2s_write(void *buf, uint32_t len, uint32_t len_per_data); +DRIVER_API_RC soc_i2s_stream(void *buf, uint32_t len, uint32_t len_per_data, uint32_t num_bufs); DRIVER_API_RC soc_i2s_stop_stream(void); DRIVER_API_RC soc_i2s_init(); @@ -196,19 +196,12 @@ static void i2s_dma_cb_done(void *num) if(channel == I2S_CHANNEL_TX) { - if((0x00200000 & MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, SOC_I2S_CTRL)) - && !(0x18000000 & MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, SOC_I2S_CTRL))) - { - for(int i = 0; i < 4; ++i) - MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, SOC_I2S_DATA_REG) = 0x0; - } - do { reg = MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].fifo_stat); - } while(reg & 0x000000FF); + } while(reg & 0x000000FF); } - + if (i2s_info->cfg[channel].cb_done) { i2s_info->cfg[channel].cb_done(i2s_info->cfg[channel].cb_done_arg); @@ -294,13 +287,13 @@ DRIVER_API_RC soc_i2s_deconfig(uint8_t channel) return DRV_RC_OK; } -DRIVER_API_RC soc_i2s_read(uint32_t *buf, uint32_t len) +DRIVER_API_RC soc_i2s_read(void *buf, uint32_t len, uint32_t len_per_data) { // Calling listen with 0 buffers is the same as a onetime read of the whole buffer - return soc_i2s_listen(buf, len, 0); + return soc_i2s_listen(buf, len, len_per_data, 0); } -DRIVER_API_RC soc_i2s_listen(uint32_t *buf, uint32_t len, uint8_t num_bufs) +DRIVER_API_RC soc_i2s_listen(void *buf, uint32_t len, uint32_t len_per_data, uint8_t num_bufs) { DRIVER_API_RC ret; uint8_t channel = I2S_CHANNEL_RX; @@ -347,10 +340,26 @@ DRIVER_API_RC soc_i2s_listen(uint32_t *buf, uint32_t len, uint8_t num_bufs) i2s_info->dma_cfg[channel].src_step_count = 0; i2s_info->dma_cfg[channel].xfer.dest.delta = SOC_DMA_DELTA_INCR; - i2s_info->dma_cfg[channel].xfer.dest.width = SOC_DMA_WIDTH_32; i2s_info->dma_cfg[channel].xfer.src.delta = SOC_DMA_DELTA_NONE; - i2s_info->dma_cfg[channel].xfer.src.width = SOC_DMA_WIDTH_32; i2s_info->dma_cfg[channel].xfer.src.addr = (void *)(SOC_I2S_BASE + SOC_I2S_DATA_REG); + + if(len_per_data == 1) + { + i2s_info->dma_cfg[channel].xfer.dest.width = SOC_DMA_WIDTH_8; + i2s_info->dma_cfg[channel].xfer.src.width = SOC_DMA_WIDTH_8; + } + else if(len_per_data == 2) + { + i2s_info->dma_cfg[channel].xfer.dest.width = SOC_DMA_WIDTH_16; + i2s_info->dma_cfg[channel].xfer.src.width = SOC_DMA_WIDTH_16; + } + else if(len_per_data == 4) + { + i2s_info->dma_cfg[channel].xfer.dest.width = SOC_DMA_WIDTH_32; + i2s_info->dma_cfg[channel].xfer.src.width = SOC_DMA_WIDTH_32; + } + else + return DRV_RC_FAIL; if (num_bufs == 0) { @@ -383,8 +392,8 @@ DRIVER_API_RC soc_i2s_listen(uint32_t *buf, uint32_t len, uint8_t num_bufs) } } - dma_list->dest.addr = (void *)(&(buf[i * (len_per_buf / sizeof(uint32_t))])); - dma_list->size = len_per_buf / sizeof(uint32_t); + dma_list->dest.addr = (void *)(uint8_t *)(buf+i * len_per_buf ); + dma_list->size = len_per_buf / len_per_data; } // Create a circular list if we are doing circular buffering @@ -443,13 +452,13 @@ DRIVER_API_RC soc_i2s_stop_listen(void) return DRV_RC_OK; } -DRIVER_API_RC soc_i2s_write(uint32_t *buf, uint32_t len) +DRIVER_API_RC soc_i2s_write(void *buf, uint32_t len, uint32_t len_per_data) { // Calling stream with 0 buffers is the same as a onetime write of the whole buffer - return soc_i2s_stream(buf, len, 0); + return soc_i2s_stream(buf, len, len_per_data, 0); } -DRIVER_API_RC soc_i2s_stream(uint32_t *buf, uint32_t len, uint32_t num_bufs) +DRIVER_API_RC soc_i2s_stream(void *buf, uint32_t len, uint32_t len_per_data, uint32_t num_bufs) { DRIVER_API_RC ret; uint8_t channel = I2S_CHANNEL_TX; @@ -496,11 +505,27 @@ DRIVER_API_RC soc_i2s_stream(uint32_t *buf, uint32_t len, uint32_t num_bufs) i2s_info->dma_cfg[channel].src_step_count = 0; i2s_info->dma_cfg[channel].xfer.dest.delta = SOC_DMA_DELTA_NONE; - i2s_info->dma_cfg[channel].xfer.dest.width = SOC_DMA_WIDTH_32; i2s_info->dma_cfg[channel].xfer.dest.addr = (void *)(SOC_I2S_BASE + SOC_I2S_DATA_REG); i2s_info->dma_cfg[channel].xfer.src.delta = SOC_DMA_DELTA_INCR; - i2s_info->dma_cfg[channel].xfer.src.width = SOC_DMA_WIDTH_32; + if(len_per_data == 1) + { + i2s_info->dma_cfg[channel].xfer.dest.width = SOC_DMA_WIDTH_8; + i2s_info->dma_cfg[channel].xfer.src.width = SOC_DMA_WIDTH_8; + } + else if(len_per_data == 2) + { + i2s_info->dma_cfg[channel].xfer.dest.width = SOC_DMA_WIDTH_16; + i2s_info->dma_cfg[channel].xfer.src.width = SOC_DMA_WIDTH_16; + } + else if(len_per_data == 4) + { + i2s_info->dma_cfg[channel].xfer.dest.width = SOC_DMA_WIDTH_32; + i2s_info->dma_cfg[channel].xfer.src.width = SOC_DMA_WIDTH_32; + } + else + return DRV_RC_FAIL;; + if (num_bufs == 0) { i2s_info->dma_cfg[channel].cb_done = i2s_dma_cb_done; @@ -532,8 +557,8 @@ DRIVER_API_RC soc_i2s_stream(uint32_t *buf, uint32_t len, uint32_t num_bufs) } } - dma_list->src.addr = (void *)(&(buf[i * (len_per_buf / sizeof(uint32_t))])); - dma_list->size = len_per_buf / sizeof(uint32_t); + dma_list->src.addr = (void *)(uint8_t *)(buf+i * len_per_buf ); + dma_list->size = len_per_buf / len_per_data; } // Create a circular list if we are doing circular buffering @@ -643,30 +668,3 @@ DRIVER_API_RC soc_i2s_init() return DRV_RC_OK; } -DRIVER_API_RC soc_i2s_reset(uint8_t channel) -{ - i2s_info->en[channel] = 0; - i2s_info->cfgd[channel] = 0; - i2s_info->cfg[channel].cb_done = NULL; - i2s_info->cfg[channel].cb_err = NULL; - - i2s_info->cfg[channel].cb_done_arg = NULL; - i2s_info->cfg[channel].cb_err_arg = NULL; - - - i2s_info->dma_ch[channel].active = 0; - i2s_info->dma_ch[channel].id = 0; - i2s_info->dma_ch[channel].ll = NULL; - i2s_info->dma_ch[channel].curr = NULL; - - i2s_info->dma_cfg[channel].cb_done_arg = NULL; - i2s_info->dma_cfg[channel].cb_done = NULL; - i2s_info->dma_cfg[channel].cb_block_arg= NULL; - i2s_info->dma_cfg[channel].cb_block = NULL; - i2s_info->dma_cfg[channel].cb_err_arg = NULL; - i2s_info->dma_cfg[channel].cb_err = NULL; - - soc_i2s_config(channel, &(i2s_info->cfg[channel])); - - return DRV_RC_OK; -} diff --git a/system/libarc32_arduino101/drivers/soc_i2s.h b/system/libarc32_arduino101/drivers/soc_i2s.h index 5a14f5f9..61692103 100644 --- a/system/libarc32_arduino101/drivers/soc_i2s.h +++ b/system/libarc32_arduino101/drivers/soc_i2s.h @@ -143,7 +143,7 @@ DRIVER_API_RC soc_i2s_deconfig(uint8_t channel); * - DRV_RC_OK on success * - DRV_RC_FAIL otherwise */ -DRIVER_API_RC soc_i2s_write(uint32_t *buf, uint32_t len); +DRIVER_API_RC soc_i2s_write(void *buf, uint32_t len, uint32_t len_per_data); /** * Function to continuously transmit blocks of audio data @@ -157,7 +157,7 @@ DRIVER_API_RC soc_i2s_write(uint32_t *buf, uint32_t len); * - DRV_RC_OK on success * - DRV_RC_FAIL otherwise */ -DRIVER_API_RC soc_i2s_stream(uint32_t *buf, uint32_t len, uint32_t num_bufs); +DRIVER_API_RC soc_i2s_stream(void *buf, uint32_t len, uint32_t len_per_data, uint32_t num_bufs); /** * Function to stop a continuous audio data write @@ -178,7 +178,7 @@ DRIVER_API_RC soc_i2s_stop_stream(void); * - DRV_RC_OK on success * - DRV_RC_FAIL otherwise */ -DRIVER_API_RC soc_i2s_read(uint32_t *buf, uint32_t len); +DRIVER_API_RC soc_i2s_read(void *buf, uint32_t len, uint32_t len_per_data); /** * Function to continuously receive blocks of audio data @@ -192,7 +192,7 @@ DRIVER_API_RC soc_i2s_read(uint32_t *buf, uint32_t len); * - DRV_RC_OK on success * - DRV_RC_FAIL otherwise */ -DRIVER_API_RC soc_i2s_listen(uint32_t *buf, uint32_t len, uint8_t num_bufs); +DRIVER_API_RC soc_i2s_listen(void *buf, uint32_t len, uint32_t len_per_data, uint8_t num_bufs); /** * Function to stop a continuous audio data read