Cygnal/SiLabs C2 interface - debugging code

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

While searching on Google I've read a few requests on this newsgroup for
information on how to perform debugging tasks via Cygnal's C2 interface.  So
I though I'd share some code.  I won't post my 1000+ line source code
(available upon request), but below is the meat of the code.  For anyone
trying debug the C2 interface itself, I've also got a Perl script that can
read a logic analyzer trace (comma-separated) and decode the register
accesses (how do other people debug serial interfaces?).

Matt
(see sig for address)

Sorry it's so long:

// C2 Registers useful for flashing & debugging (c8051F330.h defines the rest)
// To access 0x00-0x02, I've only used C2_ReadReg & C2_WriteReg.
// To access 0x20-0x33, you must used C2_ReadRegBlock & C2_WriteRegBlock.
// To access 0x80-0xFF, you can use either method.
#define DEVICEID 0x00   // fixed device ID value
#define REVID    0x01   // fixed revision ID (I've only seen 0x00)
#define FPCTL    0x02   // Flash Programming Control (also for debugging)
#define PCL_COPY 0x20   // copy of Program Counter, low byte, while debugging
#define PCH_COPY 0x21   // copy of Program Counter, high byte, while debugging
#define PSW_COPY 0x23   // copy of PSW while debugging
#define R0_COPY  0x24   // copy of R0 (bank 0) while debugging
#define R1_COPY  0x25   // copy of R1 (bank 0) while debugging
#define R2_COPY  0x26   // copy of R2 (bank 0) while debugging
#define XRAMD    0x84   // XRAM Data (address auto-increments)
#define BRKP0L   0x85   // Breakpoint 0, low byte
#define BRKP0H   0x86   // Breakpoint 0, high byte
#define BRKP1L   0xAB   // Breakpoint 1, low byte
#define BRKP1H   0xAC   // Breakpoint 1, high byte
#define XRAMAL   0xAD   // XRAM Address, low byte (address auto-increments)
#define FPDAT    0xB4   // Flash Programming Data (also for debugging)
#define XRAMAH   0xC7   // XRAM Address, high byte (address auto-increments)
#define BRKP2L   0xCE   // Breakpoint 2, low byte
#define BRKP2H   0xCF   // Breakpoint 2, high byte
#define BRKP3L   0xD2   // Breakpoint 3, low byte
#define BRKP3H   0xD3   // Breakpoint 3, high byte

// FPCTL codes
#define INIT_KEY1   0x02        // first key
#define INIT_KEY2   0x01        // second key
#define RESUME_EXEC 0x08        // resume code execution

// FPDAT commands
#define UNKNOWN1     0x01
#define UNKNOWN2     0x02
#define DEVICE_ERASE 0x03
#define FLASH_READ   0x06
#define FLASH_WRITE  0x07
#define PAGE_ERASE   0x08
#define REG_READ     0x09
#define REG_WRITE    0x0A
#define RAM_READ     0x0B
#define RAM_WRITE    0x0C

// C2_ReadData, C2_WriteData, C2_ReadAddr, C2_WriteAddr are just the
// basic C2 functions, so I won't repeat them here.

U8 C2_ReadReg(U8 reg)
{
   C2_WriteAddr(reg);
   return C2_ReadData();
}
void C2_WriteReg(U8 reg, U8 val)
{
   C2_WriteAddr(reg);
   C2_WriteData(val);
}

void C2_SetBreakpoint0(U16 Addr)
{
   C2_WriteReg(BRKP0L, (U8)(Addr >> 8));
   C2_WriteReg(BRKP0H, (U8)Addr | 0x80);
}
void C2_ClearBreakpoint0(void)
{
   C2_WriteReg(BRKP0L, 0x00);
}
void C2_RunUntilBreakpoint(void)
{
   // This function resumes code execution on the 'F331 and waits until
   // a breakpoint it hit.  To indicate it hit a breakpoint, the 'F331 causes
   // a short reset pulse (~116ns when running at 24.5MHz).  I really should
   // use an interrupt to detect the reset pulse, but this is sample code.

   C2_WriteReg(FPCTL,RESUME_EXEC);

   C2CK_DriverOff();        // stop driving C2CK so we can listen for the /RST
   while (READ_C2CK());     // wait for /RST to go low (this could take a while)
   while (!READ_C2CK());    // OK, now wait for /RST to go high (very quick)
   C2CK_DriverOn();         // back to normal C2 operation
}
void C2_RunFor20ms(void)
{
   C2_WriteReg(FPCTL,RESUME_EXEC);
   WaitXms(20);
   StrobeC2CK();            // stop the 'F331
}

// this e-mail's getting long, I'll try to compress these functions
U8 C2_ReadRegBlock(U8 BlockStart, U8 BlockSize, U8 *BufPtr)
{
   C2_WriteReg(FPDAT, REG_READ);
   WaitForInReady();
   WaitForOutReady();
   if (C2_ReadData() != COMMAND_OK)
     return 1;
   C2_WriteData(BlockStart);
   WaitForInReady();
   C2_WriteData(BlockSize);
   WaitForInReady();
   do
   {
     WaitForOutReady();
     *BufPtr++ = C2_ReadData();
   } while (--BlockSize);
   return 0;
}

U8 C2_WriteRegBlock(U8 BlockStart, U8 BlockSize, U8 *BufPtr)
{
   C2_WriteReg(FPDAT, REG_WRITE);
   WaitForInReady();
   WaitForOutReady();
   if (C2_ReadData() != COMMAND_OK)
     return 1;
   C2_WriteData(BlockStart);
   WaitForInReady();
   C2_WriteData(BlockSize);
   WaitForInReady();
   do
   {
     WaitForOutReady();
     C2_WriteData(*BufPtr++);
   } while (--BlockSize);
   return 0;
}

// C2_ReadRAMBlock and C2_WriteRAMBlock work just
// like C2_ReadRegBlock and C2_WriteRegBlock

void C2_ReadXRAMBlock(U16 BlockStart, U16 BlockSize, U8 *BufPtr)
{
   C2_WriteReg(XRAMAL, (U8)BlockStart);
   C2_WriteReg(XRAMAH, (U8)(BlockStart >> 8));

   // read repeatedly from XRAMD, the address in XRAMA will auto-increment
   C2_WriteAddr(XRAMD);
   do
   {
     *BufPtr++ = C2_ReadData();
   } while (--BlockSize);
}

// C2_WriteXRAMBlock is just like C2_ReadXRAMBlock,
// just change the C2_ReadData line to use C2_WriteData

--
To e-mail me, send an e-mail to:
<this newsgroup name> <at> <klox.net>


Site Timeline