Recently, I've been trying to implement hardware I2C volume control using the sw_usb_audio_8.1.0 reference design on the XMOS xcore.ai XU316 platform.
I referenced the suggestions from MaximLiadov and infiniteimprobability to enable I2C volume adjustment at sw_usb_audio_8.1.0\lib_xua\lib_xua\src\core\endpoint0\xua_ep0_uacreqs.xc. (or audiorequests.xc)
However, the specific problem I'm facing is that when I insert the I2C code after the updateVol point, the XU316 chip gets stuck and sometimes fails to enumerate properly.
(By the way, my Audio runs on tile 0, the I2C port is on tile 0, and the USB runs on tile 1.)
Here are the I2C definitions in my user_main.h:
Code: Select all
extern unsafe client interface i2c_master_if i_i2c_client;
extern void interface_saver(client interface i2c_master_if i);
extern void board_setup();
/* I2C interface ports */
extern port p_i2c; //on tile0 <Port Location="XS1_PORT_4E" Name="PORT_I2C"/>
#define USER_MAIN_DECLARATIONS \
interface i2c_master_if i2c[1];
#define USER_MAIN_CORES on tile[0]: {\
board_setup();\
i2c_master_single_port(i2c, 1, p_i2c, 80, 2, 3, 0);\
}\
on tile[1]: {\
unsafe\
{\
i_i2c_client = i2c[0];\
}\
}
I referenced app_usb_aud_xk_316_mc and inserted the following I2C code in xua_ep0_uacreqs.xc:
Code: Select all
#include "user_main.h"
#include "xassert.h"
#include "i2c.h"
unsafe client interface i2c_master_if i_i2c_client;
i2c_regop_res_t i2c_reg_write(uint8_t device_addr, uint8_t reg, uint8_t data)
{
uint8_t a_data[2] = {reg, data};
size_t n;
unsafe
{
i_i2c_client.write(device_addr, a_data, 2, n, 1);
}
if (n == 0)
{
return I2C_REGOP_DEVICE_NACK;
}
if (n < 2)
{
return I2C_REGOP_INCOMPLETE;
}
return I2C_REGOP_SUCCESS;
}
void WriteRegs(int deviceAddr, int regAddr, int regData)
{
i2c_regop_res_t result;
unsafe
{
result = i2c_reg_write(deviceAddr, regAddr, regData);
}
assert(result == I2C_REGOP_SUCCESS && msg("I2C write reg failed"));
}
In int AudioClassRequests_2 at FU_USBOUT, I disabled the updateVol and inserted the I2C code (in xua_ep0_uacreqs.xc):
Code: Select all
/*at line 573*/
if(unitID == FU_USBOUT) {
if ((sp.wValue & 0xff) <= NUM_USB_CHAN_OUT) {
volsOut[sp.wValue & 0xff] = (buffer, unsigned char[])[0] | (((int)(signed char)(buffer, unsigned char[])[1]) << 8);
// updateVol(unitID, (sp.wValue & 0xff), c_mix_ctl);
/* I2C test here */
WriteRegs(0x20, 125, 0x00);
return XUD_DoSetRequestStatus(ep0_in);
}
}
What could be the problem? I would greatly appreciate any suggestions you might have!
Here is the reference link:
https://www.xcore.com/viewtopic.php?t=7181&start=12
https://www.xcore.com/viewtopic.php?t=5761&start=10
https://www.xcore.com/viewtopic.php?p=2 ... OUT#p25929