I2C Demo
```language
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include "UART.h"
#include "osa.h"
#include "I2C.h"
#define sdk_uart_printf(fmt, args...) do { fatal_printf("[sdk]"fmt, ##args); } while(0)
#define _TASK_STACK_SIZE 1280*2
static UINT32 _task_stack[_TASK_STACK_SIZE/sizeof(UINT32)];
static OSTaskRef _task_ref = NULL;
static OSATimerRef _timer_ref = NULL;
static OSFlagRef _flag_ref = NULL;
#define TASK_TIMER_CHANGE_FLAG_BIT 0x01
static void _timer_callback(UINT32 tmrId);
static void _task(void *ptr);
static I2C_ReturnCode nau8810_reg_read(UINT8 RegAddr, UINT16 *value);
static I2C_ReturnCode nau8810_reg_write(UINT8 RegAddr, UINT16 RegData);
static I2C_ReturnCode nau8810_update_bit(UINT8 RegAddr, UINT16 mask, UINT16 value);
static int codec_nau8810_init(void);
// Device bootup hook before Phase1Inits.
// If you have some work to be init, you may implete it here.
// ex: you may start your task here. or do some initialize here.
extern void Phase1Inits_enter(void);
// Device bootup hook after Phase1Inits.
// If you have some work to be init, you may implete it here.
// ex: you may start your task here. or do some initialize here.
extern void Phase1Inits_exit(void);
// Device bootup hook before Phase2Inits.
// If you have some work to be init, you may implete it here.
// ex: you may start your task here. or do some initialize here.
extern void Phase2Inits_enter(void);
// Device bootup hook after Phase2Inits.
// If you have some work to be init, you may implete it here.
// ex: you may start your task here. or do some initialize here.
extern void Phase2Inits_exit(void);
void Phase1Inits_enter(void)
{
}
void Phase1Inits_exit(void)
{
}
void Phase2Inits_enter(void)
{
}
void Phase2Inits_exit(void)
{
int ret;
codec_nau8810_init();
ret = OSAFlagCreate(&_flag_ref);
ASSERT(ret == OS_SUCCESS);
ret = OSATimerCreate(&_timer_ref);
ASSERT(ret == OS_SUCCESS);
ret = OSATaskCreate(&_task_ref, _task_stack, _TASK_STACK_SIZE, 20, "test-task", _task, NULL);
ASSERT(ret == OS_SUCCESS);
sdk_uart_printf("Phase2Inits_exit OSATimerStart\n");
OSATimerStart(_timer_ref, 10 * 200, 10 * 200, _timer_callback, 0); // 10 seconds timer
}
static void _timer_callback(UINT32 tmrId)
{
OSAFlagSet(_flag_ref, TASK_TIMER_CHANGE_FLAG_BIT, OSA_FLAG_OR);
}
static void _task(void *ptr)
{
OSA_STATUS status;
UINT32 flag_value;
UINT32 flag_mask = TASK_TIMER_CHANGE_FLAG_BIT;
UINT32 value;
I2C_ReturnCode I2Cstatus = I2C_RC_NOT_OK;
while(1) {
status = OSAFlagWait(_flag_ref, flag_mask, OSA_FLAG_OR_CLEAR, &flag_value, OSA_SUSPEND);
ASSERT(status == OS_SUCCESS);
if (flag_value & TASK_TIMER_CHANGE_FLAG_BIT) {
static int count = 0;
count++;
sdk_uart_printf("_task: count: %d\n", count);
I2Cstatus = nau8810_reg_write(0x01, 0x1d);
if(I2C_RC_OK != I2Cstatus){
sdk_uart_printf("nau8810_reg_write status 0x%x\n", status);
}
I2Cstatus = nau8810_reg_read(0x01, &value);
if(I2C_RC_OK != I2Cstatus){
sdk_uart_printf("nau8810_reg_read status 0x%x\n", status);
}
sdk_uart_printf("nau8810_reg_read value 0x%x\n", value);
if (count > 10) {
CPUartLogPrintf("_task: stop timer\n");
OSATimerStop(_timer_ref);
}
}
}
}
#define NAU8810_I2C_SLAVE_ADDR 0x34 //7-MSB bits: 0011_010
#define NAU8810_SLAVE_WRITE_ADDR 0x34
#define NAU8810_SLAVE_READ_ADDR 0x35
static I2C_ReturnCode nau8810_reg_read(UINT8 RegAddr, UINT16 *value)
{
I2C_ReturnCode status = I2C_RC_NOT_OK;
UINT8 temp_buf[2];
UINT8 retry_count = 5;
UINT8 nau_reg = (RegAddr << 1) & 0xFE;
do {
status = CI2CMasterReceiveDataDirect(&nau_reg,
1 /*cmd lenght*/,
NAU8810_SLAVE_WRITE_ADDR,
FALSE /*not protected*/,
temp_buf,
2,
NAU8810_SLAVE_READ_ADDR);
if (status != I2C_RC_OK)
{
sdk_uart_printf("status: 0x%lx", status);
}
else
{
*value = (((UINT16)temp_buf[0]) << 8) | temp_buf[1];
break;
}
} while (--retry_count);
return status;
}
static I2C_ReturnCode nau8810_reg_write(UINT8 RegAddr, UINT16 RegData)
{
I2C_ReturnCode status = I2C_RC_NOT_OK;
UINT8 param_data[3] = {0x00};
UINT8 retry_count = 5;
param_data[0] = ((RegAddr<<1) & 0xFE) | ((RegData >> 8) & 0x01);
param_data[1] = (UINT8)(RegData & 0xFF);
do {
status = CI2CMasterSendDataDirect (param_data , 2 , NAU8810_SLAVE_WRITE_ADDR , FALSE , 0);
if (status != I2C_RC_OK)
{
sdk_uart_printf("status:0x%lx, RegAddr:0x%lx, RegData:0x%lx, retry_count:0x%lx",status, RegAddr,RegData, retry_count);
}
else
break;
} while (--retry_count);
return status;
}
static I2C_ReturnCode nau8810_update_bit(UINT8 RegAddr, UINT16 mask, UINT16 value)
{
I2C_ReturnCode status = I2C_RC_NOT_OK;
UINT16 orig;
UINT16 tmp;
status = nau8810_reg_read(RegAddr, &orig);
if (status != I2C_RC_OK)
{
sdk_uart_printf("status: 0x%lx", status);
}
else
{
tmp = orig & (~mask);
tmp |= (value & mask);
if (tmp != orig)
{
status = nau8810_reg_write(RegAddr, tmp);
if (status != I2C_RC_OK)
{
sdk_uart_printf("status: 0x%lx", status);
}
}
}
return status;
}
int codec_nau8810_init(void)
{
static UINT8 nau8810_init_ok = 0;
UINT16 value = 0;
if(0 == nau8810_init_ok){
Ci2C_PINMUX_INIT();
/* check if has codec nau8810*/
if(I2C_RC_OK == nau8810_reg_read(0x3F, &value)
&& (NAU8810_I2C_SLAVE_ADDR >> 1) == value ){
nau8810_reg_write(0, 0x00);
nau8810_init_ok = 1;
}
}
return !nau8810_init_ok;
}
```