Important update: Arm Announces End of Life Timeline for Mbed. This site will be archived in July 2026. Read the full announcement.
Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
ADAU1701
![](/media/cache/profiles/5f4f25d269af35abf542f09062624683.jpg.16x16_q85_crop-center.jpg)
I found the example SigmaStudioFW.h
SigmaStudioFW.h
/* * File: SigmaStudioFW.h * * Description: SigmaStudio System Framwork macro definitions. These * macros should be implemented for your system's software. * * This software is distributed in the hope that it will be useful, * but is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * This software may only be used to program products purchased from * Analog Devices for incorporation by you into audio products that * are intended for resale to audio product end users. This software * may not be distributed whole or in any part to third parties. * * Copyright © 2008 Analog Devices, Inc. All rights reserved. */ #ifndef __SIGMASTUDIOFW_H__ #define __SIGMASTUDIOFW_H__ /* * TODO: Update for your system's data type */ typedef unsigned short ADI_DATA_U16; typedef unsigned char ADI_REG_TYPE; extern vu16 Tx_Idx, Rx_Idx; extern vu16 NextBufferEnd, ThisBufferSize; extern u8 I2C1_Buffer_Tx[]; #define Address_Length 2 void SIGMA_WRITE_REGISTER_BLOCK(int devAddress, int address, int length, ADI_REG_TYPE *pData); void SIGMA_WRITE_DELAY(int devAddress, int length, ADI_REG_TYPE *pData ); /* * Parameter data format */ #define SIGMASTUDIOTYPE_FIXPOINT 0 #define SIGMASTUDIOTYPE_INTEGER 1 /* * Write to a single Device register */ #define SIGMA_WRITE_REGISTER( devAddress, address, dataLength, data ) {/*TODO: implement macro or define as function*/} /* * TODO: CUSTOM MACRO IMPLEMENTATION * Write to multiple Device registers */ void SIGMA_WRITE_REGISTER_BLOCK(int devAddress, int address, int length, ADI_REG_TYPE *pData ) { int ii = 0; int zz = 0; Tx_Idx = 0; /*----- Transmission Phase -----*/ ThisBufferSize = Address_Length + length; I2C1_Buffer_Tx[0] = (address & 0xFF00)>>8; I2C1_Buffer_Tx[1] = address & 0x00FF; for(zz=0;zz<length;zz++) { I2C1_Buffer_Tx [zz + Address_Length] = pData[zz]; } Tx_Idx = 0; for(ii =0;ii < ThisBufferSize;ii++) { NextBufferEnd = ThisBufferSize;//I2C1_numbytes[ii]; if(ii == 0) I2C_GenerateSTART(I2C1, ENABLE); /* Send data */ while(Tx_Idx < NextBufferEnd) { } } } void SIGMA_WRITE_DELAY(int devAddress, int length, ADI_REG_TYPE *pData ) { // int cnt=0; int nCount=0; //int data_length = length - Address_Length; // ADI_REG_TYPE data[4]={0x05, 0xF5, 0xE1, 0x00}; // for(cnt=0; cnt<data_length; cnt++) // { // nCount &= pData[cnt] >> (8*cnt); // } // for(cnt=0; cnt<4; cnt++) // { // nCount += data[cnt]; // nCount = nCount<<(8); // // } //nCount=0xFFFFFF; //nCount=0x15752A00; //5 secs approx //nCount=0x05F5E100; //5 secs approx nCount=0xFFFFF; for(; nCount != 0; nCount--); } /* * Read device registers */ #define SIGMA_READ_REGISTER( devAddress, address, length, pData ) {/*TODO: implement macro or define as function*/} /* * Set a register field's value */ #define SIGMA_SET_REGSITER_FIELD( regVal, fieldVal, fieldMask, fieldShift ) \ { (regVal) = (((regVal) & (~(fieldMask))) | (((fieldVal) << (fieldShift)) && (fieldMask))) } /* * Get the value of a register field */ #define SIGMA_GET_REGSITER_FIELD( regVal, fieldMask, fieldShift ) \ { ((regVal) & (fieldMask)) >> (fieldShift) } /* * Convert a floating-point value to SigmaDSP (5.23) fixed point format * This optional macro is intended for systems having special implementation * requirements (for example: limited memory size or endianness) */ #define SIGMASTUDIOTYPE_FIXPOINT_CONVERT( _value ) {/*TODO: IMPLEMENT MACRO*/} /* * Convert integer data to system compatible format * This optional macro is intended for systems having special implementation * requirements (for example: limited memory size or endianness) */ #define SIGMASTUDIOTYPE_INTEGER_CONVERT( _value ) {/*TODO: IMPLEMENT MACRO*/} #endif
I am trying to port the file over to mbed. I don't know if this is right but I changed this:
extern vu16 Tx_Idx, Rx_Idx; extern vu16 NextBufferEnd, ThisBufferSize; extern u8 I2C1_Buffer_Tx[];
to this:
mbed
extern uint16_t Tx_Idx, Rx_Idx; extern uint16_t NextBufferEnd, ThisBufferSize; extern uint8_t I2C1_Buffer_Tx[];
I figured the data types of vu16 = unsigned int 16
I did generate a compile error:
Error: Expected an identifier in "SigmaStudioFW.h", Line: 41, Col: 6
Error: Expected a ";" in "SigmaStudioFW.h", Line: 41, Col: 6
Error: Expected an identifier in "SigmaStudioFW.h", Line: 44, Col: 6
Error: Expected a ";" in "SigmaStudioFW.h", Line: 44, Col: 6
SigmaStudioFW.h
41 void SIGMA_WRITE_REGISTER_BLOCK(int devAddress, int address, int length, ADI_REG_TYPE *pData); . . . 44 void SIGMA_WRITE_REGISTER_BLOCK(int devAddress, int address, int length, ADI_REG_TYPE *pData ) {...}
mbed_SigmaStudioFW.h
#ifndef __SIGMASTUDIOFW_H__ #define __SIGMASTUDIOFW_H__ #include "mbed.h" #define I2C_ADDR_ADAU1701 0x68 /* * TODO: Update for your system's data type */ typedef unsigned short ADI_DATA_U16; typedef unsigned char ADI_REG_TYPE; //void SIGMA_WRITE_REGISTER_BLOCK(int, int, int, char); /* * Parameter data format */ #define SIGMASTUDIOTYPE_FIXPOINT 0 #define SIGMASTUDIOTYPE_INTEGER 1 /* * Write to a single Device register */ #define SIGMA_WRITE_REGISTER( devAddress, address, dataLength, data ) {/*TODO: implement macro or define as function*/} /* * TODO: CUSTOM MACRO IMPLEMENTATION * Write to multiple Device registers */ #define SIGMA_WRITE_REGISTER_BLOCK( devAddress, address, length, pData ) {/*TODO: implement macro or define as function*/} /* * TODO: CUSTOM MACRO IMPLEMENTATION * Writes delay (in ms) */ extern uint16_t Tx_Idx, Rx_Idx; extern uint16_t NextBufferEnd, ThisBufferSize; extern uint8_t I2C1_Buffer_Tx[]; #define Address_Length 2 void SIGMA_WRITE_REGISTER_BLOCK(int devAddress, int address, int length, ADI_REG_TYPE *pData); void SIGMA_WRITE_DELAY(int devAddress, int length, ADI_REG_TYPE *pData ); void SIGMA_WRITE_REGISTER_BLOCK(int devAddress, int address, int length, ADI_REG_TYPE *pData ) { int ii = 0; int zz = 0; Tx_Idx = 0; /*----- Transmission Phase -----*/ ThisBufferSize = Address_Length + length; I2C1_Buffer_Tx[0] = (address & 0xFF00)>>8; I2C1_Buffer_Tx[1] = address & 0x00FF; for(zz=0;zz<length;zz++) { I2C1_Buffer_Tx [zz + Address_Length] = pData[zz]; } Tx_Idx = 0; for(ii =0;ii < ThisBufferSize;ii++) { NextBufferEnd = ThisBufferSize;//I2C1_numbytes[ii]; if(ii == 0) { I2C_GenerateSTART(I2C1, ENABLE); } /* Send data */ while(Tx_Idx < NextBufferEnd) { } } } void SIGMA_WRITE_DELAY(int devAddress, int length, ADI_REG_TYPE *pData ) { // int cnt=0; int nCount=0; //int data_length = length - Address_Length; // ADI_REG_TYPE data[4]={0x05, 0xF5, 0xE1, 0x00}; // for(cnt=0; cnt<data_length; cnt++) // { // nCount &= pData[cnt] >> (8*cnt); // } // for(cnt=0; cnt<4; cnt++) // { // nCount += data[cnt]; // nCount = nCount<<(8); // // } //nCount=0xFFFFFF; //nCount=0x15752A00; //5 secs approx //nCount=0x05F5E100; //5 secs approx nCount=0xFFFFF; for(; nCount != 0; nCount--); } /* * Read device registers */ #define SIGMA_READ_REGISTER( devAddress, address, length, pData ) {/*TODO: implement macro or define as function*/} /* * Set a register field's value */ #define SIGMA_SET_REGSITER_FIELD( regVal, fieldVal, fieldMask, fieldShift ) \ { (regVal) = (((regVal) & (~(fieldMask))) | (((fieldVal) << (fieldShift)) && (fieldMask))) } /* * Get the value of a register field */ #define SIGMA_GET_REGSITER_FIELD( regVal, fieldMask, fieldShift ) \ { ((regVal) & (fieldMask)) >> (fieldShift) } /* * Convert a floating-point value to SigmaDSP (5.23) fixed point format * This optional macro is intended for systems having special implementation * requirements (for example: limited memory size or endianness) */ #define SIGMASTUDIOTYPE_FIXPOINT_CONVERT( _value ) {/*TODO: IMPLEMENT MACRO*/} /* * Convert integer data to system compatible format * This optional macro is intended for systems having special implementation * requirements (for example: limited memory size or endianness) */ #define SIGMASTUDIOTYPE_INTEGER_CONVERT( _value ) {/*TODO: IMPLEMENT MACRO*/} #endif
Well, I have fixed the errors listed above, however it seems I traded them for other errors. !! Yikes. First: I forgot to delete the
#define SIGMA_WRITE_REGISTER_BLOCK( devAddress, address, length, pData ) {/*TODO: implement macro or define as function*/}
once deleted I stopped getting Error: Expected an identifier in "SigmaStudioFW.h", Line: 41, Col: 6
Next I defined the I2C pin in the SigmaStudioFW.h
mbed_SigmaStudioFW.h
#ifndef __SIGMASTUDIOFW_H__ #define __SIGMASTUDIOFW_H__ #include "mbed.h" I2C i2c(p28,p29); #define I2C_ADDR_ADAU1701 0x68 /* * TODO: Update for your system's data type */ typedef unsigned short ADI_DATA_U16; typedef unsigned char ADI_REG_TYPE; extern uint16_t Tx_Idx, Rx_Idx; extern uint16_t NextBufferEnd, ThisBufferSize; extern uint8_t I2C1_Buffer_Tx[]; #define Address_Length 2 void SIGMA_WRITE_REGISTER_BLOCK(int devAddress, int address, int length, ADI_REG_TYPE *pData); void SIGMA_WRITE_DELAY(int devAddress, int length, ADI_REG_TYPE *pData ); /* * Parameter data format */ #define SIGMASTUDIOTYPE_FIXPOINT 0 #define SIGMASTUDIOTYPE_INTEGER 1 /* * Write to a single Device register */ #define SIGMA_WRITE_REGISTER( devAddress, address, dataLength, data ) {/*TODO: implement macro or define as function*/} /* * TODO: CUSTOM MACRO IMPLEMENTATION * Write to multiple Device registers */ void SIGMA_WRITE_REGISTER_BLOCK(int devAddress, int address, int length, ADI_REG_TYPE *pData ) { int ii = 0; int zz = 0; Tx_Idx = 0; /*----- Transmission Phase -----*/ ThisBufferSize = Address_Length + length; I2C1_Buffer_Tx[0] = (address & 0xFF00)>>8; I2C1_Buffer_Tx[1] = address & 0x00FF; for(zz=0;zz<length;zz++) { I2C1_Buffer_Tx [zz + Address_Length] = pData[zz]; } Tx_Idx = 0; for(ii =0;ii < ThisBufferSize;ii++) { NextBufferEnd = ThisBufferSize;//I2C1_numbytes[ii]; if(ii == 0) { i2c.start(); } /* Send data */ while(Tx_Idx < NextBufferEnd) { } } } void SIGMA_WRITE_DELAY(int devAddress, int length, ADI_REG_TYPE *pData ) { // int cnt=0; int nCount=0; //int data_length = length - Address_Length; // ADI_REG_TYPE data[4]={0x05, 0xF5, 0xE1, 0x00}; // for(cnt=0; cnt<data_length; cnt++) // { // nCount &= pData[cnt] >> (8*cnt); // } // for(cnt=0; cnt<4; cnt++) // { // nCount += data[cnt]; // nCount = nCount<<(8); // // } //nCount=0xFFFFFF; //nCount=0x15752A00; //5 secs approx //nCount=0x05F5E100; //5 secs approx nCount=0xFFFFF; for(; nCount != 0; nCount--); } /* * Read device registers */ #define SIGMA_READ_REGISTER( devAddress, address, length, pData ) {/*TODO: implement macro or define as function*/} /* * Set a register field's value */ #define SIGMA_SET_REGSITER_FIELD( regVal, fieldVal, fieldMask, fieldShift ) \ { (regVal) = (((regVal) & (~(fieldMask))) | (((fieldVal) << (fieldShift)) && (fieldMask))) } /* * Get the value of a register field */ #define SIGMA_GET_REGSITER_FIELD( regVal, fieldMask, fieldShift ) \ { ((regVal) & (fieldMask)) >> (fieldShift) } /* * Convert a floating-point value to SigmaDSP (5.23) fixed point format * This optional macro is intended for systems having special implementation * requirements (for example: limited memory size or endianness) */ #define SIGMASTUDIOTYPE_FIXPOINT_CONVERT( _value ) {/*TODO: IMPLEMENT MACRO*/} /* * Convert integer data to system compatible format * This optional macro is intended for systems having special implementation * requirements (for example: limited memory size or endianness) */ #define SIGMASTUDIOTYPE_INTEGER_CONVERT( _value ) {/*TODO: IMPLEMENT MACRO*/} #endif
I have a main, and its simple.
main
#include "mbed.h" #include "SigmaStudioFW.h" #include "Design_1_IC_1.h" #include "Design_1_IC_1_PARAM.h" #include "Design_1_IC_1_REG.h" int main() { //void default_download_IC_1(); }
And the error I get now is: Error: Undefined symbol I2C1_Buffer_Tx (referred from main.cpp.LPC1768.o) Error: Undefined symbol NextBufferEnd (referred from main.cpp.LPC1768.o) Error: Undefined symbol ThisBufferSize (referred from main.cpp.LPC1768.o) Error: Undefined symbol Tx_Idx (referred from main.cpp.LPC1768.o)
looks like I'm using the extern variables wrong?
extern var
extern uint16_t Tx_Idx, Rx_Idx; extern uint16_t NextBufferEnd, ThisBufferSize; extern uint8_t I2C1_Buffer_Tx[];
Another update, I initialized the exern variables = 0 and the errors went away, I am able to compile. Im testing now to see if I can generate I2C data for the default_download() function generated by SigmaStudio
default_download()
void default_download_IC_1() { SIGMA_WRITE_REGISTER_BLOCK( DEVICE_ADDR_IC_1, REG_COREREGISTER_IC_1_ADDR, REG_COREREGISTER_IC_1_BYTE, R0_COREREGISTER_IC_1_Default ); SIGMA_WRITE_REGISTER_BLOCK( DEVICE_ADDR_IC_1, PROGRAM_ADDR_IC_1, PROGRAM_SIZE_IC_1, Program_Data_IC_1 ); SIGMA_WRITE_REGISTER_BLOCK( DEVICE_ADDR_IC_1, PARAM_ADDR_IC_1, PARAM_SIZE_IC_1, Param_Data_IC_1 ); SIGMA_WRITE_REGISTER_BLOCK( DEVICE_ADDR_IC_1, REG_COREREGISTER_IC_1_ADDR , R3_HWCONFIGURATION_IC_1_SIZE, R3_HWCONFIGURATION_IC_1_Default ); SIGMA_WRITE_REGISTER_BLOCK( DEVICE_ADDR_IC_1, REG_COREREGISTER_IC_1_ADDR, REG_COREREGISTER_IC_1_BYTE, R4_COREREGISTER_IC_1_Default ); }
I have revised this code yet again and I have been able to send I2C data to the DSP, Although it's more a bit-bang method then the Sigma_Write_Register_Block() above. I do receive an ACK. Tomorrow I will try to write to a register and change some values. Today I was just playing around with getting the sequence and .h files in order. Still more work is needed to implement the block read function properly.
Is there a real reason why you can't just use the standard mbed I2C functions in those blocks? It needs to be changed a bit of course, but I assume it should be possible.
it might be possible, Im still exploring the function. but the main problem is... the number of bytes changes per register. For example, the volume control register might require 3 bytes of data and a mute switch might require 2 bytes. This might not be a problem for the mbed I2C function, and I have been able to bit-bang I2C and recive an ACK from the DSP. Tomorrow I am going to explore more and I'll post an updated code.
I guess I am trying to keep everything as close to the example as possible, trying to make this a portable solution, using the mbed to understand how to send the data... I think that will make changing ucontrollers a lot easier in the future. Maybe Im over complicating this.. a little sleep and Ill hit it again tomorrow. Thanks for showing interest in my project Erik.
As it turns out, I was assuming the I2C communication was a standard PIC based method. instead the example is written for an ARM3 which uses an interrupt style I2C method. I revised my code again and now I am able to setup the DSP. I also wrote a little function to toggle a mute switch. I just wanted to prove I could control the DSP in real time, although ugly, it works.
I do have a problem. When I load the DSP with default_download(), the function never completes. I assume I am only writing a portion of the program to the DSP as default_download() is a function of 5 SIGMA_WRITE_REGISTER_BLOCK(...)
default_download( )
#define DEFAULT_DOWNLOAD_SIZE_IC_1 5 void default_download_IC_1() { SIGMA_WRITE_REGISTER_BLOCK( DEVICE_ADDR_IC_1, REG_COREREGISTER_IC_1_ADDR, REG_COREREGISTER_IC_1_BYTE, R0_COREREGISTER_IC_1_Default ); SIGMA_WRITE_REGISTER_BLOCK( DEVICE_ADDR_IC_1, PROGRAM_ADDR_IC_1, PROGRAM_SIZE_IC_1, Program_Data_IC_1 ); SIGMA_WRITE_REGISTER_BLOCK( DEVICE_ADDR_IC_1, PARAM_ADDR_IC_1, PARAM_SIZE_IC_1, Param_Data_IC_1 ); SIGMA_WRITE_REGISTER_BLOCK( DEVICE_ADDR_IC_1, REG_COREREGISTER_IC_1_ADDR , R3_HWCONFIGURATION_IC_1_SIZE, R3_HWCONFIGURATION_IC_1_Default ); SIGMA_WRITE_REGISTER_BLOCK( DEVICE_ADDR_IC_1, REG_COREREGISTER_IC_1_ADDR, REG_COREREGISTER_IC_1_BYTE, R4_COREREGISTER_IC_1_Default ); }
My revised code looks like this for the SigmaStudioFW.h block write function:
SIGMA_WRITE_BLOCK(...)
void SIGMA_WRITE_REGISTER_BLOCK(int devAddress, int address, int length, ADI_REG_TYPE *pData ) { int ii = 0; int zz = 0; Tx_Idx = 0; // connect to DSP address //int deviceI2CAddress = (devAddress >> 1); //DEVICE_ADDR_IC_1 found in *_IC_1.h needs to be shifted right 1 bit /*----- Transmission Phase -----*/ ThisBufferSize = Address_Length + length; I2C1_Buffer_Tx[0] = (address & 0xFF00)>>8; I2C1_Buffer_Tx[1] = address & 0x00FF; for(zz=0;zz<length;zz++) { I2C1_Buffer_Tx[zz + Address_Length] = pData[zz]; } Tx_Idx = 0; for(ii =0;ii < ThisBufferSize;ii++) { NextBufferEnd = ThisBufferSize;//I2C1_numbytes[ii]; if(ii == 0) i2c.write(devAddress, I2C1_Buffer_Tx, ThisBufferSize, true); /* Send data */ } }
this is really the only change, although I dont understand what kind of stop condition to look for... I think a while loop is in order. ??
if(ii == 0) i2c.write(devAddress, I2C1_Buffer_Tx, ThisBufferSize, true);
For starters I don't really understand what that loop is supposed to do exactly. Also why do you use 'true' as last argument? That prevents a stop condition from being sent at the end of the write sequence.
I have modified the code and everything works a treat. One problem I was having, the DEV board Im using defaults the ADAU1701 to load in Self Boot mode by pulling up pin6. I verified I was sending correct I2C data with my logic analyzer. I also have an ADAU144xx dev Board that lets me toggle the Self Boot/ucontroller mode via a dip-switch. The SIGMA_WRITE_REGISTER(...) function works great.
SIGMA_WRITE_REGISTER_BLOCK(...)
void SIGMA_WRITE_REGISTER_BLOCK(int devAddress, int address, int length, ADI_REG_TYPE *pData ) { int zz = 0; //counter defined /*----- Transmission Phase -----*/ ThisBufferSize = Address_Length + length; //2 bytes for the address + the length of the data packet I2C1_Buffer_Tx[0] = (address & 0xFF00)>>8; //mask the upper 8 bits of the address then put into unique variable I2C1_Buffer_Tx[1] = address & 0x00FF; //mask the lower 8 bits of the address then put into unique variable //fil the buffer array with the data (still leaving room for the address) for(zz=0;zz<length;zz++) { I2C1_Buffer_Tx[zz + Address_Length] = pData[zz]; //start fill buffer location after address } // begin transmission and request acknowledgement i2c.write(devAddress, I2C1_Buffer_Tx, ThisBufferSize, false); //send it out the port }
So I am working on a project useing Analog devices ADAU1701 DSP. Its a great chip but I'm new to the world of DSP and could use a little help. First let me give you a brief overview of what the ADAU1701 is and how I plain to use it. I hope to keep this discussion as an informal build log, later I will write some code and an example for the mbed community.
I am making a simple DSP that can interface with a webserver. The DSP will output to an amplifier and pramaters will be configurable over wifi.
Anyway, the ADAU1701 is a DSP solution. It is used to process audio and it takes a lot of the hard work and MATH out of DSP design. SigmaStudio is the software used to configure the ADAU1701. It is a free graphical, drag-&-drop style editor. You configure a system, complete with filters, volume control, and GPIO. SigmaStudio generates a few .h files with defined register address and parameter values. It also generates a .hex that gets loaded into the ADAU1701. (The chip can operate in standalone mode, loading an EEPROM with the HEX and setting the ADAU1701 in selfboot mode is all thats needed) However I am using the DSP in control mode. I am using the med to control the device over I2C.
SigmaStudio provides a SigmaStudioFW.h file that the user needs to first configure in order for the other .h files to work. In the SigmaStudioFW.h a macro that needs to be written is the SIGMA_WRITE_REGISTER_BLOCK(); This is where I need to define the mbeds I2C communication. You can see the code below; its the 'default' code
SigmaStudioFW.h
SigmaStudio provides an example of the SIGMA_WRITE_REGISTER_BLOCK(); in the example project an ARM Cortex M3 ucontroller is used. the code is below:
example
The I2C transmission the DSP is expecting is not very complex. Its the standard I2C scheme, almost.
-Device Address--Reg_Address_High Byte--Reg_Address_Low_Byte--Data-some parts of this I don't understand. is NextBufferEnd & ThisBufferSize a defined thing or an Arm 3 register?
I have done a lot of work setting up the DSP but now Im stuck on defining the I2C macro.. :( I feel stupid!