Hi,
we are using power sequencer UCD9080 of TI in our system to provide power supply. UCD9080 is programmed through IIC by 8-bit host controller (Atmel ATmega).
In process of debugging our system with UCD9080 and three daughter's power modules, we've got a state of UCD9080 that isn't described in datasheet SLVS692E:
1) UCD9080 communicates with host-controller through IIC;
2) UCD9080 answers to IIC commands as described and, for example, returns a non-zero value of "VERSION" register;
3) UCD9080 is configurable; I mean that it writes configuration data into it's flash and reads configuration back; the process of verification (in host controller) is completed successful,
however,
4) registers RAILxL and RAILxH are read equal to 0 regardless of voltage on MONx pin;
5) the state ENx pin is always non-active regardless voltage on parent MONx-pin is in thresholds (UnderVoltageThresholds - OverVoltageThreshold) or not;
6) value of STATUS register is always equal to 0x20, bit NVERRLOG = 1, but in current revision of the datasheet (E May 2008) this bit is described as "reserved for future use"; all other bits in this register are equal to 0;
7) value of ERROR register is always equal to 0.
UCD9080 is programmed in way, described in datasheet: host controller writes all 512 bytes of configuration memory. Unused bytes are exactly match table 2 of datasheet.
Program a default configuration doesn't solve the problem.
Is there a way to return UCD9080 to normal state? What is the reason of this abnormal work of UCD9080?
Thank you,
Kirill
P.S. I try to attach an example code to my message, sample.c is main function, eedata.h - is a default config of UCD9080.
#define F_CPU 3.6864E6
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "eeprom.h"
#include "TWI_Master.h"
#include "ucd9080.h"
#define nop() {asm("nop");}
unsigned char res;
unsigned char ucTryCnt;
unsigned int idx;
unsigned char buf[16];
unsigned char register_map[512];
unsigned int param_address, param_value;
unsigned char version, status;
unsigned int rail_volts[8];
TError LastError;
unsigned char GetLastError(void);
unsigned char GetRailVoltages(void);
int main(void)
{
TWI_Master_Initialise();
sei();
_delay_ms(1000);
config_start:
bzero(&config_memory[0], CONFIG_MEMORY_SIZE);
EEPROM_read_buffer(&def_config_memory[0], &config_memory[0], CONFIG_MEMORY_SIZE);// ���������� ��������� �������� �� EEPROM!
/* Prepare configuration of power sequencer */
/* SequenceEventParameters */
config_memory[0x0080] = 0xD0;// Sequence is triggered after parent rail is achieves voltage regulation
config_memory[0x0081] = 0xD1;
config_memory[0x0082] = 0xD2;
config_memory[0x0083] = 0xD3;
config_memory[0x0084] = 0xD4;
/* SequenceEventLink*/
config_memory[0x008c] = 0x40;//0x40;//Sequence after shut down
config_memory[0x008d] = 0x41;//0x41;
config_memory[0x008e] = 0x42;//0x42;
config_memory[0x008f] = 0x43;//0x43;
config_memory[0x0090] = 0x44;//0x44;
/* SequenceEventData*/
config_memory[0x0098] = 0x10;// delay 16 ms after volatge regulation
config_memory[0x0099] = 0xa0;//0xa0
config_memory[0x009a] = 0x10;
config_memory[0x009b] = 0xa0;//0xa0
config_memory[0x009c] = 0x10;
config_memory[0x009d] = 0xa0;//0xa0
config_memory[0x009e] = 0x10;
config_memory[0x009f] = 0xa0;//0xa0
config_memory[0x00a0] = 0x64;// delay 100 ms after voltage regulation
config_memory[0x00a1] = 0xa0;//0xa0
/* DependencyMasks*/
config_memory[0x0100] = 0x1F;
config_memory[0x0101] = 0x08;
config_memory[0x0102] = 0x1E;//0x1E
config_memory[0x0103] = 0x08;
config_memory[0x0104] = 0x1C;//0x1C
config_memory[0x0105] = 0x00;
config_memory[0x0106] = 0x18;//0x18
config_memory[0x0107] = 0x00;
config_memory[0x0108] = 0x10;//0x10
config_memory[0x0109] = 0x00;
/* UnderVoltageThresholds*/
config_memory[0x011e] = 0xe7;
config_memory[0x011f] = 0x01;
config_memory[0x011c] = 0x33;
config_memory[0x011d] = 0x01;
config_memory[0x011a] = 0x26;
config_memory[0x011b] = 0x01;
config_memory[0x0118] = 0x61;
config_memory[0x0119] = 0x01;
config_memory[0x0116] = 0xe7;
config_memory[0x0117] = 0x01;
/* OverVoltageThresholds*/
config_memory[0x012e] = 0x18;
config_memory[0x012f] = 0x02;
config_memory[0x012c] = 0x90;
config_memory[0x012d] = 0x01;
config_memory[0x012a] = 0x45;
config_memory[0x012b] = 0x01;
config_memory[0x0128] = 0x86;
config_memory[0x0129] = 0x01;
config_memory[0x0126] = 0x18;
config_memory[0x0127] = 0x02;
config_memory[0x0124] = 0x07;
config_memory[0x0125] = 0x01;
/* RampTime*/
config_memory[0x0130] = 0x00;//RampTime = 512 ms
config_memory[0x0131] = 0x02;
config_memory[0x0132] = 0x00;
config_memory[0x0133] = 0x02;
config_memory[0x0134] = 0x00;
config_memory[0x0135] = 0x02;
config_memory[0x0136] = 0x00;
config_memory[0x0137] = 0x02;
config_memory[0x0138] = 0x00;
config_memory[0x0139] = 0x02;
/* OutOfRegulationWidth */
/* UnsequenceTime*/
config_memory[0x0150] = 0x14;//20 ms
config_memory[0x0151] = 0xa0;//0xa0
config_memory[0x0152] = 0x10;//16 ms
config_memory[0x0153] = 0xa0;//0xa0
config_memory[0x0154] = 0x0c;//12 ms
config_memory[0x0155] = 0xa0;//0xa0
config_memory[0x0156] = 0x08;// 8 ms
config_memory[0x0157] = 0xa0;//0xa0
config_memory[0x0158] = 0x04;// 4 ms
config_memory[0x0159] = 0xa0;//0xa0
/* EnablePolarity*/
config_memory[0x0168] = 0x04;
config_memory[0x0169] = 0x20;//active-low
config_memory[0x016a] = 0x08;
config_memory[0x016b] = 0x20;//active-low
config_memory[0x016c] = 0x04;
config_memory[0x016d] = 0x18;//active-low
config_memory[0x016e] = 0x02;
config_memory[0x016f] = 0x18;//active-low
config_memory[0x0170] = 0x08;
config_memory[0x0171] = 0x98;//active-high
/* LastUnusedSeq*/
config_memory[0x018E] = 0xFF;
config_memory[0x018F] = 0x08;
/* FAN_ON_P */
config_memory[0x008B] = 0x4B;
config_memory[0x0097] = 0;
config_memory[0x00AE] = 0x00;
config_memory[0x00AF] = 0x04;
config_memory[0x017E] = 0x80;
config_memory[0x017F] = 0xA0;
/* Save config_memory to register_map */
memcpy(®ister_map[0], &config_memory[0], CONFIG_MEMORY_SIZE);
/* Configure power sequencer */
ucTryCnt = 3;
do{
res = ucd9080_config_store();
_delay_ms(100);
}while((!res) && (--ucTryCnt));
if (!res)
{
while(1)
{
nop();
}
}
bzero(&config_memory[0], CONFIG_MEMORY_SIZE);
/* Verifying configuration*/
/* Load configuration back */
ucTryCnt = 3;
do{
res = ucd9080_config_load();
_delay_ms(100);
}while((!res) && (--ucTryCnt));
if (!res)
{
while(1);
}
res = true;
for (idx = 0; idx < CONFIG_MEMORY_SIZE; idx++)
{
if (config_memory[idx] != register_map[idx])
{
res = false;
break;
}
}
if (!res)
{
goto config_start;
}
res = ucd9080_read_byte(STATUS, &status);
ucTryCnt = 3;
do{
res = ucd9080_write_byte(RESTART, 0);
_delay_ms(100);
}while((!res) && (--ucTryCnt));
if (!res)
{
while(1);
}
while(1)
{
//TODO:: Please write your application code
res = ucd9080_read_byte(STATUS, &status);
res = GetLastError();
res = GetRailVoltages();
_delay_ms(1000);
}
}
unsigned char GetRailVoltages(void)
{
unsigned char icx;
bool res;
for(icx = 0; icx < 16; icx++)
{
res = ucd9080_read_byte(icx+RAIL1H, &buf[icx]);
if (!res)
return false;
}
bzero(&rail_volts[0], 16);
for(icx = 0; icx < 7; icx++)
{
rail_volts[icx] = (buf[2*icx] << 8) + buf[2*icx+1];
}
return true;
}
unsigned char GetLastError(void)
{
unsigned char icx;
bool res;
for(icx = 0; icx < 7; icx++)
{
res = ucd9080_read_byte(icx+ERROR1, &buf[idx]);
if (!res)
return 0;
}
LastError.error_code = (buf[0] & 0xe0) >> 5;
LastError.rail = (buf[0] & 0x1c) >> 2;
LastError.error_data = ((buf[0] & 0x03) << 8) | (buf[1]);
LastError.time.hh = buf[2];
LastError.time.mm = buf[3];
LastError.time.ss = (buf[4] & 0xfc) >> 2;
LastError.time.ms = ((buf[4] & 0x03) << 8) | (buf[5]);
return LastError.error_code;
}