📄 an027.c
字号:
Poll_InBusy; // Wait for input acknowledge
C2_WriteDR(NUM_BYTES); // Send block size
Poll_InBusy; // Wait for input acknolwedge
// Check status before writing FLASH block
Poll_OutReady; // Wait for status information
status = C2_ReadDR(); // Read FLASH programming interface status
if (status != COMMAND_OK)
return 0; // Exit and indicate error
// Write FLASH block
for (i=0;i<NUM_BYTES;i++)
{
C2_WriteDR(*C2_PTR++); // Write data to the FPDAT register
Poll_InBusy; // Wait for input acknowledge
}
Poll_OutReady; // Wait for last FLASH write to complete
return 1; // Exit and indicate success
}
//-----------------------------------------------------------------------------------
// C2_PageErase()
//-----------------------------------------------------------------------------------
// - Erases a 512-byte FLASH page
// - Targets the FLASH page containing the address <FLASH_ADDR>
// - Assumes that FLASH accesses via C2 have been enabled prior to the function call
// - Function call returns a '1' if successful; returns a '0' if unsuccessful
//
char C2_PageErase()
{
unsigned char page; // Target FLASH page
unsigned char status; // FPI status information holder
page = (unsigned char)(FLASH_ADDR >> 9);
// <page> is the 512-byte sector containing
// the target <FLASH_ADDR>.
if (page >= NUM_PAGES - 1) // Check that target page is within range
// (NUM_PAGES minus 1 for reserved area)
return 0; // Indicate error if out of range
C2_WriteAR(FPDAT); // Select the FLASH Programming Data register
// for C2 Data register accesses
C2_WriteDR(PAGE_ERASE); // Send FLASH page erase command
Poll_InBusy; // Wait for input acknowledge
// Check status before starting FLASH access sequence
Poll_OutReady; // Wait for status information
status = C2_ReadDR(); // Read FLASH programming interface status
if (status != COMMAND_OK)
return 0; // Exit and indicate error
C2_WriteDR(page); // Send FLASH page number
Poll_InBusy; // Wait for input acknowledge
Poll_OutReady; // Wait for ready indicator
status = C2_ReadDR(); // Read FLASH programming interface status
if (status != COMMAND_OK)
return 0; // Exit and indicate error
C2_WriteDR(0x00); // Dummy write to initiate erase
Poll_InBusy; // Wait for input acknowledge
Poll_OutReady; // Wait for erase operation to complete
return 1; // Exit and indicate success
}
//-----------------------------------------------------------------------------------
// C2_Device_Erase()
//-----------------------------------------------------------------------------------
// - Erases the entire FLASH memory space
// - Assumes that FLASH accesses via C2 have been enabled prior to the function call
// - Function call returns a '1' if successful; returns a '0' if unsuccessful
//
char C2_DeviceErase()
{
unsigned char status; // FPI status information holder
C2_WriteAR(FPDAT); // Select the FLASH Programming Data register
// for C2 Data register accesses
C2_WriteDR(DEVICE_ERASE); // Send Device Erase command
Poll_InBusy; // Wait for input acknowledge
// Check status before starting FLASH access sequence
Poll_OutReady; // Wait for status information
status = C2_ReadDR(); // Read FLASH programming interface status
if (status != COMMAND_OK)
return 0; // Exit and indicate error
// Send a three-byte arming sequence to enable the device erase. If the sequence
// is not received correctly, the command will be ignored.
// Sequence: 0xDE, 0xAD, 0xA5.
C2_WriteDR(0xDE); // Arming sequence command 1
Poll_InBusy; // Wait for input acknowledge
C2_WriteDR(0xAD); // Arming sequence command 2
Poll_InBusy; // Wait for input acknowledge
C2_WriteDR(0xA5); // Arming sequence command 3
Poll_InBusy; // Wait for input acknowledge
Poll_OutReady; // Wait for erase operation to complete
return 1; // Exit and indicate success
}
//-----------------------------------------------------------------------------------
// Primitive C2 Command Routines
//-----------------------------------------------------------------------------------
//
// These routines perform the low-level C2 commands:
// 1. Address Read
// 2. Address Write
// 3. Data Read
// 4. Data Write
// 5. Device Reset
//-----------------------------------------------------------------------------------
// C2_ReadAR()
//-----------------------------------------------------------------------------------
// - Performs a C2 Address register read
// - Returns the 8-bit register content
//
unsigned char C2_ReadAR()
{
unsigned char i; // Bit counter
unsigned char addr; // Address register read content
// START field
StrobeC2CK; // Strobe C2CK with C2D driver disabled
// INS field (10b, LSB first)
C2D = LOW;
C2D_DriverOn; // Enable C2D driver (output)
StrobeC2CK;
C2D = HIGH;
StrobeC2CK;
C2D_DriverOff; // Disable C2D driver (input)
// ADDRESS field
addr = 0;
for (i=0;i<8;i++) // Shift in 8 bit ADDRESS field
{ // LSB-first
addr >>= 1;
StrobeC2CK;
if (C2D)
addr |= 0x80;
}
// STOP field
StrobeC2CK; // Strobe C2CK with C2D driver disabled
return addr; // Return Address register read value
}
//-----------------------------------------------------------------------------------
// C2_WriteAR()
//-----------------------------------------------------------------------------------
// - Performs a C2 Address register write (writes the <addr> input
// to Address register)
//
void C2_WriteAR(unsigned char addr)
{
unsigned char i; // Bit counter
// START field
StrobeC2CK; // Strobe C2CK with C2D driver disabled
// INS field (11b, LSB first)
C2D = HIGH;
C2D_DriverOn; // Enable C2D driver (output)
StrobeC2CK;
C2D = HIGH;
StrobeC2CK;
// ADDRESS field
for(i=0;i<8;i++) // Shift out 8-bit ADDRESS field
{
C2D = (addr & 0x01);
StrobeC2CK;
addr >>= 1;
}
// STOP field
C2D_DriverOff; // Disable C2D driver
StrobeC2CK; // Strobe C2CK with C2D driver disabled
return;
}
//-----------------------------------------------------------------------------------
// C2_ReadDR()
//-----------------------------------------------------------------------------------
// - Performs a C2 Data register read
// - Returns the 8-bit register content
//
unsigned char C2_ReadDR()
{
unsigned char i; // Bit counter
unsigned char dat; // Data register read content
// START field
StrobeC2CK; // Strobe C2CK with C2D driver disabled
// INS field (00b, LSB first)
C2D = LOW;
C2D_DriverOn; // Enable C2D driver (output)
StrobeC2CK;
C2D = LOW;
StrobeC2CK;
// LENGTH field (00b -> 1 byte)
C2D = LOW;
StrobeC2CK;
C2D = LOW;
StrobeC2CK;
// WAIT field
C2D_DriverOff; // Disable C2D driver for input
do
{
StrobeC2CK;
}
while (!C2D); // Strobe C2CK until target transmits a '1'
// DATA field
dat = 0;
for (i=0;i<8;i++) // Shift in 8-bit DATA field
{ // LSB-first
dat >>= 1;
StrobeC2CK;
if (C2D)
dat |= 0x80;
}
// STOP field
StrobeC2CK; // Strobe C2CK with C2D driver disabled
return dat;
}
//-----------------------------------------------------------------------------------
// C2_WriteDR()
//-----------------------------------------------------------------------------------
// - Performs a C2 Data register write (writes <dat> input to data register)
//
void C2_WriteDR(unsigned char dat)
{
unsigned char i; // Bit counter
// START field
StrobeC2CK; // Strobe C2CK with C2D driver disabled
// INS field (01b, LSB first)
C2D = HIGH;
C2D_DriverOn; // Enable C2D driver
StrobeC2CK;
C2D = LOW;
StrobeC2CK;
// LENGTH field (00b -> 1 byte)
C2D = LOW;
StrobeC2CK;
C2D = LOW;
StrobeC2CK;
// DATA field
for (i=0;i<8;i++) // Shift out 8-bit DATA field
{ // LSB-first
C2D = (dat & 0x01);
StrobeC2CK;
dat >>= 1;
}
// WAIT field
C2D_DriverOff; // Disable C2D driver for input
do
{
StrobeC2CK; // Strobe C2CK until target transmits a '1'
}
while (!C2D);
// STOP field
StrobeC2CK; // Strobe C2CK with C2D driver disabled
return;
}
//-----------------------------------------------------------------------------------
// C2_Reset()
//-----------------------------------------------------------------------------------
// - Performs a target device reset by pulling the C2CK pin low for >20us
//
void C2_Reset()
{
C2CK = LOW; // Put target device in reset state by pulling
Timer3us(20); // C2CK low for >20us
C2CK = HIGH; // Release target device from reset
}
//-----------------------------------------------------------------------------------
// Initialization / Utility Routines
//-----------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------
// Timer3us
//-----------------------------------------------------------------------------------
// - Uses Timer3 to delay <us> micro-seconds.
//
void Timer3us(unsigned int us)
{
unsigned int i; // usec counter
TMR3CN = 0 ; // Stop Timer3 and clear interrupt-pending flag
TMR3CN |= 0x02; // Select SYSCLK as timebase
TMR3RL = (-SYSCLK/1000000); // Set Timer3 to overflow in 1us
TMR3 = TMR3RL; // Initialize Timer3 for first overflow
for (i = 0; i < us; i++) // Count <us> overflows
{
TMR3CN |= 0x04; // START Timer3
while (!(TMR3CN & 0x80)); // Wait for overflow
TMR3CN &= ~0x04; // STOP Timer3
TMR3CN &= ~(0x80); // Clear overflow indicator
}
}
//-----------------------------------------------------------------------------------
// Port_Init()
//-----------------------------------------------------------------------------------
// - Configures Port I/O for C2 functions
//
void Port_Init()
{
XBR0 = 0x00; // No peripherals routed through Crossbar
XBR1 = 0x00; // Crossbar
XBR2 = 0x40; // Enable Crossbar (for GPIO)
PRT1CF = 0x01; // Initialize C2CK to push-pull
// and C2D to open-drain (driver disabled)
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -