Cygnal/SiLabs C2 interface - debugging code

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:
Reply to
Matt O.
Loading thread data ...

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.