Skip to content

CurieI2S library #156

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 2, 2016
Merged
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
54 changes: 54 additions & 0 deletions libraries/CurieI2S/examples/I2S_RxCallback/I2S_RxCallback.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* A simple sketch to test the rx channel of the i2s interface.
* A callback function is used to fill up a buffer whenever data is received
*
* To test this sketch you will need a second Arduino/Genuino 101 board with the I2S_TxCallback sketch uploaded
*
* Connection:
* I2S_RSCK(pin 8) -> I2S_TSCK(pin 2)
* I2S_RWS(pin 3) -> I2S_TWS(pin 4)
* I2S_RXD(pin 5) -> I2S_TXD(pin 7)
*
**/
#include <CurieI2S.h>

uint32_t dataBuff[256];
volatile int count = 0;

void setup()
{
// put your setup code here, to run once:
Serial.begin(115200);
while(!Serial);
Serial.println("CurieI2S Rx Callback Example");
CurieI2S.begin(I2S_44K, I2S_32bit);
CurieI2S.setI2SMode(PHILIPS_MODE);
CurieI2S.attachRxInterrupt(rxDataReceived);
CurieI2S.initRX();
CurieI2S.startRX();

}

void loop()
{
if(count>0)
{
for(int i =0; i < count; i++)
{
Serial.print("data: ");
Serial.println(dataBuff[i], HEX);
}
count = 0;
}
delay(500);
}

//This function is called inside an ISR so it is important to make this as atomic/fast as possible
void rxDataReceived()
{
while(CurieI2S.available())
{
dataBuff[count++] = CurieI2S.requestdword();
count %= 256; //prevent buffer overflow and just write data in front of the buffer.
}
}
56 changes: 56 additions & 0 deletions libraries/CurieI2S/examples/I2S_TxCallback/I2S_TxCallback.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include <CurieI2S.h>

//I2S_TX -> Pin 7
//I2S_TSK -> Pin 4
//I2S_TSCK -> pin 2

void setup()
{
Serial.begin(115200);
while(!Serial);
Serial.println("CurieI2S Tx Callback");
CurieI2S.begin(I2S_44K, I2S_32bit);
CurieI2S.setI2SMode(PHILIPS_MODE);
CurieI2S.attachTxEmptyInterrupt(doneTX);
CurieI2S.attachTxInterrupt(fillTxBuffer);
CurieI2S.initTX();
}

void loop()
{
Serial.println("+++");

//start filling the tx buffer
CurieI2S.pushData(0xFFFFFFFF);
CurieI2S.pushData(0x00000000);
CurieI2S.pushData(0xDEADFACE);
CurieI2S.pushData(0x10101010);
Serial.println("start transmitting");
//Start Transmission
CurieI2S.startTX();
for(int i = 0; i < 40; i++)
{
//keep filling the buffer
while(!CurieI2S.pushData(0xFFFFFFFF));
while(!CurieI2S.pushData(0x00000000));
while(!CurieI2S.pushData(0xDEADFACE));
while(!CurieI2S.pushData(0x10101010));
}
//Tx is automatically stopped after the tx buffer is emptied

delay(500);
Serial.println("+++");
}

void doneTX()
{
Serial.println("done transmitting");
}

void fillTxBuffer()
{
//you can fill the tx buffer here if you want
//CurieI2S.pushData(0xDEADDEAD);
//CurieI2S.pushData(0xDEADFACE);
}

48 changes: 48 additions & 0 deletions libraries/CurieI2S/keywords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#######################################
# Syntax Coloring Map For CurieI2S
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

Curie_I2S KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

begin KEYWORD2
start KEYWORD2
stop KEYWORD2
begin KEYWORD2
enableRX KEYWORD2
enableTX KEYWORD2
startRX KEYWORD2
startTX KEYWORD2
stopRX KEYWORD2
stopTX KEYWORD2
setI2SMode KEYWORD2
setResolution KEYWORD2
initRX KEYWORD2
initTX KEYWORD2
end KEYWORD2
pushData KEYWORD2
fastPushData KEYWORD2
write KEYWORD2
pullData KEYWORD2
read KEYWORD2
requestdword KEYWORD2
available KEYWORD2
availableTx KEYWORD2
attachRxInterrupt KEYWORD2
detachRxInterrupt KEYWORD2
attachTxInterrupt KEYWORD2
detachTxInterrupt KEYWORD2
#######################################
# Instances (KEYWORD2)
#######################################
CurieI2S KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
11 changes: 11 additions & 0 deletions libraries/CurieI2S/library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name=CurieI2S
version=1.0
author=Intel
maintainer=Intel
[email protected]
sentence=Curie I2S Library for Arduino/Genuino 101
paragraph=
category=Communication
url=http://makers.intel.com
architectures=arc32
core-dependencies=arduino (>=1.6.3)
675 changes: 675 additions & 0 deletions libraries/CurieI2S/src/CurieI2S.cpp

Large diffs are not rendered by default.

237 changes: 237 additions & 0 deletions libraries/CurieI2S/src/CurieI2S.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
//***************************************************************
//
// Copyright (c) 2016 Intel Corporation. All rights reserved.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
//***************************************************************

//CurieI2S.h

#ifndef __CurieI2S_H__
#define __CurieI2S_H__

#include <Arduino.h>

//I2S Modes
#define PHILIPS_MODE 0b001000001000
#define RIGHT_JST_MODE 0b010010010010
#define LEFT_JST_MODE 0b011010011010
#define DSP_MODE 0b101000101000

//Sample Rate I2S_SRR Values
#define I2S_48K 0x000A000A
#define I2S_44K 0x000F000F
#define I2S_24K 0x001C001C
#define I2S_22K 0x001E001E
#define I2S_12K 0x00530053
#define I2S_8K 0x007D007D

//Resolution I2S_SRR Values
#define I2S_32bit 0xF800F800
#define I2S_24bit 0xB800B800
#define I2S_16bit 0x78007800

//Registers
#define I2S_CTRL (uint32_t *)0xB0003800 //I2S Control Register
#define I2S_STAT (volatile uint32_t *)0xB0003804 //I2S Status Register
#define I2S_SRR (uint32_t *)0xB0003808 //I2S Channels Sample Rate & Resolution Configuration Register
#define I2S_CID_CTRL (uint32_t *)0xB000380C //Clock, Interrupt and DMA Control Register
#define I2S_TFIFO_STAT (volatile uint32_t *)0xB0003810 //Transmit FIFO Status Register
#define I2S_RFIFO_STAT (volatile uint32_t *)0xB0003814 //Receive FIFO Status Register
#define I2S_TFIFO_CTRL (uint32_t *)0xB0003818 //Transmit FIFO Control Register
#define I2S_RFIFO_CTRL (uint32_t *)0xB000381C //Receive FIFO Control Register
#define I2S_DEV_CONF (uint32_t *)0xB0003820 //Device Configuration Register
#define I2S_DATA_REG (volatile uint32_t *)0xB0003850 //Data Register
#define I2S_MASK_INT (uint32_t *)0xB0800468 //Host Processor Interrupt Routing Mask 7
#define CLK_GATE_CTL (uint32_t *)0xB0800018 //CLK_GATE_CTL register

//DMA
//#define DMA_CTL_L0 (uint32_t *))0xB0700000
//#define DMA_BUFFER_SIZE 128


//Masks
#define I2S_SAMPLERATE_MASK 0xF800F800
#define I2S_RESOLUTION_MASK 0x07FF07FF


//I2S Arduino Pins
#define I2S_TXD 7
#define I2S_TWS 4
#define I2S_TSCK 2
#define I2S_RXD 5
#define I2S_RWS 3
#define I2S_RSCK 8

#define I2S_BUFFER_SIZE 256

//#define I2S_DEBUG

#ifdef I2S_DEBUG
#define I2S_DEBUG_PIN 12
#endif

struct i2s_ring_buffer
{
volatile uint32_t data[I2S_BUFFER_SIZE];
volatile int head = 0;
volatile int tail= 0;
volatile bool lock = false;
};

class Curie_I2S
{
private:
uint32_t clock;

int frameDelay = 0;

bool useDMA;

// initializes i2s interface
void init();

// mux/demux the i2s rx pins into i2s mode
void muxRX(bool enable);

// mux/demux the i2s tx pins into i2s mode
void muxTX(bool enable);

// enables/disables the i2s rx channel
void enableRXChannel(bool enable);

// enables/disables the i2s tx channel
void enableTXChannel(bool enable);

// rx sync unit
void syncTX(bool sync);

// tx sync unit
void syncRX(bool sync);

// resets RX FIFO pointer
void resetRXFIFO();

// resets TX FIFO pointer
void resetTXFIFO();

//enables i2s interrupts
void enableInterrupts();

void (*i2s_rxCB)();

void (*i2s_txCB)();

void (*i2s_txEmptyCB)();

public:
Curie_I2S();

//
void begin(uint32_t sampleRate, uint32_t resolution);

// enables rx channel
void enableRX();

// enables tx channel
void enableTX();

// starts listening to the rx channel
void startRX();

// starts transmission of data to the tx channel
void startTX();

// stops listening on rx channel
void stopRX();

// stops transmission on tx channel
void stopTX();

// sets the mode of operation for the i2s interface
void setI2SMode(uint32_t mode);

// sets sample rate bor both i2s channels
void setSampleRate(uint32_t dividerValues);

// sets the bit resolution for both i2s cahnnels
void setResolution(uint32_t resolution);

// Initializes the i2s rx channel
void initRX();

// Initializes the i2s tx channel
void initTX();

void end();

// Pushes a dword into the TX buffer
int pushData(uint32_t data);

// Pushes a dword into the TX FIFO
void fastPushData(uint32_t data);

void write();

// Pulls a dword directly from the RX FIFO
uint32_t pullData();

// Pulls a dword from the tail of the rx buffer
uint32_t read() {return requestdword(); };

// Pulls a dword from the tail of the rx buffer
uint32_t requestdword();

// Returns number of dword avaialable in the rx buffer
uint16_t available();

// Returns the number of space available in the tx buffer;
uint16_t availableTx();

uint8_t getTxFIFOLength();

uint8_t getRxFIFOLength();

void lastFrameDelay();

// Attach user callback that is triggered when there is data pushed into the rx buffer from the RX_FIFO
void attachRxInterrupt(void (*userCallBack)());

void detachRxInterrupt(void) { return attachTxInterrupt(NULL); };

// Attach user callback that is triggered when that gets called when TX_FIFO is empty(transmission done);
void attachTxEmptyInterrupt(void (*userCallBack)());

void detachTxEmptyInterrupt(void) { return attachTxEmptyInterrupt(NULL); };

// Attach user callback that is triggered when that gets called when TX_FIFO has available space;
void attachTxInterrupt(void (*userCallBack)());

void detachTxInterrupt(void) { return attachTxInterrupt(NULL); };

//rx callback
void i2s_rx_callback(void);

//tx callback
void i2s_tx_callback(void);

//tx empty callback
void i2s_tx_empty_callback(void);
};

extern Curie_I2S CurieI2S;

#endif
5 changes: 5 additions & 0 deletions variants/arduino_101/variant.h
Original file line number Diff line number Diff line change
@@ -78,6 +78,11 @@ extern "C"{
*/
#define SPI_MUX_MODE QRK_PMUX_SEL_MODEB

/*
* I2S
*/
#define I2S_MUX_MODE QRK_PMUX_SEL_MODEB

/*
* GPIO
*/