Reposting this here since my e-mail reply didn't get copied to the forum...
I didn't use the timer interrupt at all. The ADV7511 demo seems to work without it. As far as I can tell, the timer is just used for the HAL_DelayMS and HAL_GetCurrentMSCount functions, and I didn't implement HAL_DelayMS because the demo doesn't seem to need it. This is what I have in my replacement for platform.c. I based the i2c functions on the reference code for Avnet's FMC-IMAGEON card (fmc_iic_sw from here). My HAL_GetCurrentMSCount doesn't deal with counter wrap-around, but it is only used in the demo to determine whether to run the ADIAPI_TransmitterMain() function within the polling loop. It's by no means perfect but it works well enough for me at the moment.
(Forum text editor messed up all the formatting)
#include "xiic.h"
#include "xil_types.h"
#include "xtmrctr.h"
#include "string.h"
#include <stdarg.h>
typedef unsigned char UCHAR; /* unsigned 8-bit */
typedef unsigned short UINT16; /* unsigned 16-bit */
typedef unsigned long UINT32; /* unsigned 32-bit */
typedef short int INT16;
typedef long int INT32;
typedef char CHAR;
#define UINT8 UCHAR
UINT32 HAL_GetCurrentMsCount(void);
UCHAR HAL_I2CReadByte (UCHAR Dev, UCHAR Reg, UCHAR *Data);
UCHAR HAL_I2CWriteByte (UCHAR Dev, UCHAR Reg, UCHAR Data);
UINT16 HAL_I2CReadBlock (UCHAR Dev, UCHAR Reg, UCHAR *Data, UINT16 NumberBytes);
UINT16 HAL_I2CWriteBlock (UCHAR Dev, UCHAR Reg, UCHAR *Data, UINT16 NumberBytes);
UINT16 HAL_I2C16ReadBlock8 (UCHAR Dev, UINT16 Reg, UCHAR* Data, UINT16 NumberBytes);
UINT16 HAL_I2C16WriteBlock8 (UCHAR Dev, UINT16 Reg, UCHAR* Data, UINT16 NumberBytes);
UCHAR HAL_SetRxChipSelect(UCHAR DevIdx);
void WaitMilliSec(unsigned int msec);
void DBG_Printf(const char *data, ...);
#if 1
#define debug_iic(...)
#else
#define debug_iic xil_printf
#endif
static u32 g_iic_base;
static XTmrCtr g_tmr_inst;
static u32 g_tmr_freq;
{
va_list argptr;
va_start(argptr, data);
xil_printf(data, argptr);
va_end(argptr);
}
void adi_memcpy(void *dst,void* src, UINT32 count)
{
memcpy(dst, src, count);
}
void adi_memset(void *dst,UINT8 data, UINT32 count)
{
memset(dst, data, count);
}
// HAL functions
///////////////////////////////////////////////////////////////////////////
/*===========================================================================
* not used
*==========================================================================*/
void HAL_DelayMs (UINT16 Counter)
{
WaitMilliSec(Counter);
}
/*===========================================================================
*
*==========================================================================*/
UINT32 HAL_GetCurrentMsCount(void)
{
u32 v;
v = XTmrCtr_GetValue(&g_tmr_inst, 0);
return ((double) v)*1000/((double) g_tmr_freq);
}
///////////////////////////////////////////////////////////////////////////
int axi_iic_init(u32 BaseAddress)
{
XStatus Status;
Xuint8 StatusReg;
Xuint32 timeout = 10000;
g_iic_base = BaseAddress;
Status = XIic_DynInit(g_iic_base);
if(Status != XST_SUCCESS) {
xil_printf("Failed to initialize I2C chain\n\r" );
return 0;
}
/*
* Check to see if the core was initialized successfully
*/
do{
StatusReg = Xil_In8(g_iic_base + XIIC_SR_REG_OFFSET);
StatusReg = StatusReg & (XIIC_SR_RX_FIFO_EMPTY_MASK |
XIIC_SR_TX_FIFO_EMPTY_MASK |
XIIC_SR_BUS_BUSY_MASK);
} while ( (timeout-- > 0) &&
(StatusReg != (XIIC_SR_RX_FIFO_EMPTY_MASK | XIIC_SR_TX_FIFO_EMPTY_MASK)) );
return 1;
}
///////////////////////////////////////////////////////////////////////////
void timer_init(u16 tmrctr_dev_id, u32 tmrctr_freq_hz)
{
int status;
status = XTmrCtr_Initialize(&g_tmr_inst, tmrctr_dev_id);
if (status != XST_SUCCESS) {
xil_printf("ERROR: XTmrCtr_Initialize failed.\r\n");
return;
}
XTmrCtr_SetResetValue(&g_tmr_inst, 0, 0);
XTmrCtr_SetOptions(&g_tmr_inst, 0,
XTmrCtr_GetOptions(&g_tmr_inst, 0) |
XTC_AUTO_RELOAD_OPTION);
XTmrCtr_Start(&g_tmr_inst, 0);
g_tmr_freq = tmrctr_freq_hz;
}
/*===========================================================================
*
*==========================================================================*/
void HAL_PlatformInit_MB(UINT32 i2cBaseAddr,
UINT16 timerDevId,
UINT32 timerFreq)
{
axi_iic_init(i2cBaseAddr);
timer_init(timerDevId, timerFreq);
}
/*===========================================================================
*
*==========================================================================*/
UINT16 HAL_I2CReadBlock (UCHAR Dev, UCHAR Reg, UCHAR *Data, UINT16 NofBytes)
{
Xuint8 ReceivedByteCount = 0;
Xuint8 SentByteCount = 0;
Xuint8 StatusReg;
int cnt = 0;
debug_iic("RB %02x %02x %d", Dev, Reg, NofBytes);
#if 1
// Make sure all the Fifo's are cleared and Bus is Not busy.
do {
StatusReg = Xil_In8(g_iic_base + XIIC_SR_REG_OFFSET);
StatusReg = StatusReg & (XIIC_SR_RX_FIFO_EMPTY_MASK |
XIIC_SR_TX_FIFO_EMPTY_MASK |
XIIC_SR_BUS_BUSY_MASK);
} while (StatusReg != (XIIC_SR_RX_FIFO_EMPTY_MASK |
XIIC_SR_TX_FIFO_EMPTY_MASK));
#endif
// Position the Read pointer to specific location.
do {
StatusReg = Xil_In8(g_iic_base + XIIC_SR_REG_OFFSET);
if(!(StatusReg & XIIC_SR_BUS_BUSY_MASK)) {
SentByteCount = XIic_DynSend(g_iic_base, Dev>>1, (Xuint8 *)&Reg, 1,
XIIC_REPEATED_START);
}
cnt++;
} while(SentByteCount != 1 && (cnt < 100));
// Error writing chip address so return SentByteCount
if (SentByteCount < 1) { return SentByteCount; }
// Receive the data.
ReceivedByteCount = XIic_DynRecv(g_iic_base, Dev>>1, Data, (u8) NofBytes);
debug_iic(" (%d)\r\n", ReceivedByteCount);
// Return the number of bytes received.
return ReceivedByteCount;
}
///////////////////////////////////////////////////////////////////////////
UINT16 I2C_WriteByte(UCHAR Dev, UCHAR Reg, UCHAR *Data)
{
u8 SentByteCount;
u8 WriteBuffer[2];
u8 i;
u8 StatusReg;
int NumBytes = 1;
// xil_printf(" WByte %02x %02x\r\n", Dev, Reg);
#if 1
// Make sure all the Fifo's are cleared and Bus is Not busy.
do {
StatusReg = Xil_In8(g_iic_base + XIIC_SR_REG_OFFSET);
StatusReg = StatusReg & (XIIC_SR_RX_FIFO_EMPTY_MASK |
XIIC_SR_TX_FIFO_EMPTY_MASK |
XIIC_SR_BUS_BUSY_MASK);
} while (StatusReg != (XIIC_SR_RX_FIFO_EMPTY_MASK |
XIIC_SR_TX_FIFO_EMPTY_MASK));
#endif
/*
* A temporary write buffer must be used which contains both the address
* and the data to be written, put the address in first
*/
WriteBuffer[0] = Reg;
/*
* Put the data in the write buffer following the address.
*/
for (i = 0; i < NumBytes; i++) {
WriteBuffer[i + 1] = Data[i];
}
/*
* Write data at the specified address.
*/
SentByteCount = XIic_DynSend(g_iic_base, Dev>>1, WriteBuffer,
NumBytes + 1, XIIC_STOP);
if (SentByteCount < 1) { SentByteCount = 1; }
return SentByteCount - 1;
}
/*===========================================================================
*
*==========================================================================*/
UINT16 HAL_I2CWriteBlock (UCHAR Dev, UCHAR Reg, UCHAR *Data, UINT16 NumberBytes)
{
int i;
int n = 0;
debug_iic("WB %02x %02x %d", Dev, Reg, NumberBytes);
// Multi-byte writes seem to get stuck in XIic_Dynsend, so writing one
// byte at a time.
for (i = 0; i < NumberBytes; i++) {
n += I2C_WriteByte(Dev, Reg++, Data++);
}
debug_iic(" (%d)\r\n", n);
return n;
}
/*===========================================================================
*
*==========================================================================*/
UCHAR HAL_I2CReadByte (UCHAR Dev, UCHAR Reg, UCHAR *Data)
{
return (UCHAR) HAL_I2CReadBlock(Dev, Reg, Data, 1);
}
/*===========================================================================
*
*==========================================================================*/
UCHAR HAL_I2CWriteByte (UCHAR Dev, UCHAR Reg, UCHAR Data)
{
return (UCHAR) HAL_I2CWriteBlock(Dev, Reg, &Data, 1);
}
/*===========================================================================
* not used
*==========================================================================*/
UCHAR HAL_SetRxChipSelect(UCHAR DevIdx)
{
return 1;
}
///////////////////////////////////////////////////////////////////////////
// Functions required for linking with atv_common.o
UINT16 HAL_I2C16ReadBlock8 (UCHAR Dev, UINT16 Reg, UCHAR* Data, UINT16 NumberBytes)
{
return 1;
}
UINT16 HAL_I2C16WriteBlock8 (UCHAR Dev, UINT16 Reg, UCHAR* Data, UINT16 NumberBytes)
{
return 1;
}
/*===========================================================================
* only by HAL_DelayMs above
*==========================================================================*/
/**
* Wait for passed number of milli-seconds
*/
void WaitMilliSec(unsigned int msec)
{
}