📄 df.c
字号:
//! The memory check failed -> KO
//!/
bit df_mem_check (void)
{
//# DF memory check.
for(df_select=0; df_select<DF_NB_MEM; df_select++)
{
df_chipselect_current();
Spi_write_data(DF_RD_STATUS); /* Send the read status register cmd
+ 1st step to clear the SPIF bit */
Spi_write_dummy(); /* dummy write that:
(.) finalize the clear of the SPIF bit (access to SPDR)
(.) get status register
(.) does the 1st step to clear the SPIF bit */
/* Following Spi_read_data() finalize the clear of SPIF by accessing SPDR. */
// Check the DF density.
if ((Spi_read_data() & DF_MSK_DENSITY) != DF_DENSITY)
{ // Unexpected value.
Df_desel_all();
return (KO);
}
Df_desel_all();
}
return OK;
}
//!
//! @brief This function waits until the DataFlash is not busy.
//!
//! @warning Code:?? bytes (function code length)
//!
//! @param None
//!
//! @return None
//!/
static void df_wait_busy (void)
{
// Read the status register until the DataFlash is not busy.
df_chipselect_current();
Spi_write_data(DF_RD_STATUS); /* Send the read status register cmd
+ 1st step to clear the SPIF bit */
Spi_write_dummy(); /* dummy write that:
(.) finalize the clear of the SPIF bit (access to SPDR)
(.) get status register
(.) does the 1st step to clear the SPIF bit */
// Following Spi_read_data() finalize the clear of SPIF by accessing SPDR
while ((Spi_read_data() & DF_MSK_BIT_BUSY) == DF_MEM_BUSY)
{
Spi_write_dummy(); /* dummy write to get new status
+ 1st step to clear the SPIF bit */
}
Df_desel_all(); /* unselect memory to leave STATUS request mode */
Spi_ack_write(); /* Final step to clear the SPIF bit. */
}
//!
//! @brief This function opens a DF memory in read mode at a given sector address.
//!
//! NOTE: Address may not be synchronized on the beginning of a page (depending on the DF page size).
//!
//! @warning Code:?? bytes (function code length)
//!
//! @param pos Logical sector address
//!
//! @return bit
//! The open succeeded -> OK
//!/
bit df_read_open (Uint32 pos)
{
// Set the global memory ptr at a Byte address.
gl_ptr_mem = df_translate_addr(pos);
// Select the DF that memory "pos" points to (the "df_select" variable will be updated)
df_chipselect_memzone(LSB0(pos));
// If the DF memory is busy, wait until it's not.
if (is_df_busy(df_select))
{
df_release_busy(df_select);
df_wait_busy(); /* wait end of programming */
}
// Physically assert the selected dataflash
df_chipselect_current();
//#
//# Initiate a page read at a given sector address.
//#
// Send read main command, + first step to clear the SPIF bit
Spi_write_data(DF_RD_MAIN);
// Final step to clear the SPIF bit will be done on the next write
// Send the three address Bytes made of:
// (.) the page-address(first xbits),
// (.) the Byte-address within the page(last ybits).
// (x and y depending on the DF type).
// NOTE: the bits of gl_ptr_mem above the 24bits are not useful for the local
// DF addressing. They are used for DF discrimination when there are several
// DFs.
Spi_write_data((MSB1(gl_ptr_mem) << DF_SHFT_B1) | (MSB2(gl_ptr_mem) >> DF_SHFT_B2));
Spi_write_data(((MSB2(gl_ptr_mem) & ~DF_PAGE_MASK) << DF_SHFT_B1) | (MSB2(gl_ptr_mem) & DF_PAGE_MASK));
Spi_write_data(MSB3(gl_ptr_mem));
// Final step to clear the SPIF bit will be done on the next write
// 4 dummy writes for reading delay
Spi_write_data(0xFF);
Spi_write_data(0xFF);
Spi_write_data(0xFF);
Spi_write_data(0xFF); /* Tx 0xFF, first step to clear the SPIF bit */
Spi_ack_write(); /* Final step to clear the SPIF bit. */
return OK;
}
//!
//! @brief This function unselects the current DF memory.
//!
//! @warning Code:?? bytes (function code length)
//!
//! @param None
//!
//! @return None
//!/
void df_read_close (void)
{
Df_desel_all(); /* Unselect memory */
}
//!
//! @brief This function is optimized and writes nb-sector * 512 Bytes from
//! DataFlash memory to USB controller
//!
//! DATA FLOW is: DF => USB
//!
//!
//! NOTE:
//! - First call must be preceded by a call to the df_read_open() function,
//! - The USB EPIN must have been previously selected,
//! - USB ping-pong buffers are free,
//! - As 512 is always a sub-multiple of page size, there is no need to check
//! page end for each Bytes,
//! - Interrupts are disabled during transfer to avoid timer interrupt,
//! - nb_sector always >= 1, cannot be zero.
//!
//! @warning code:?? bytes (function code length)
//!
//! @param nb_sector number of contiguous sectors to read [IN]
//!
//! @return bit
//! The read succeeded -> OK
//!/
bit df_read_sector (Uint16 nb_sector)
{
U8 i;
do
{
for (i = 8; i != 0; i--)
{
Disable_interrupt(); // Global disable.
// Principle: send any Byte to get a Byte.
// Spi_write_dummy(): send any Byte + 1st step to clear the SPIF bit.
// Spi_read_data(): get the Byte + final step to clear the SPIF bit.
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
Spi_write_dummy(); Usb_write_byte(Spi_read_data());
//# Send the USB FIFO IN content to the USB Host.
Usb_send_in(); // Send the FIFO IN content to the USB Host.
Enable_interrupt(); // Global interrupt re-enable.
// Wait until the tx is done so that we may write to the FIFO IN again.
while(Is_usb_write_enabled()==FALSE);
}
gl_ptr_mem += 512; // increment global address pointer
nb_sector--; // 1 more sector read
#if (DF_NB_MEM == 1) // end of page ?
#if (DF_PAGE_SIZE == 512)
Df_desel_all();
if (nb_sector != 0)
df_read_open(gl_ptr_mem>>9);
#else
if ((MSB2(gl_ptr_mem) & DF_PAGE_MASK) == 0x00)
{
Df_desel_all();
if (nb_sector != 0)
df_read_open(gl_ptr_mem>>9);
}
#endif
#endif
}
while (nb_sector != 0);
return OK; // Read done.
}
//!
//! @brief This function opens a DF memory in write mode at a given sector
//! address.
//!
//! NOTE: If page buffer > 512 bytes, page content is first loaded in buffer to
//! be partially updated by write_byte or write64 functions.
//!
//! @warning Code:?? bytes (function code length)
//!
//! @param pos Sector address
//!
//! @return bit
//! The open succeeded -> OK
//!/
bit df_write_open (Uint32 pos)
{
// Set the global memory ptr at a Byte address.
gl_ptr_mem = df_translate_addr(pos);
// Select the DF that memory "pos" points to
df_chipselect_memzone(LSB0(pos));
// If the DF memory is busy, wait until it's not.
if (is_df_busy(df_select))
{
df_release_busy(df_select);
df_wait_busy(); /* wait end of programming */
}
#if DF_PAGE_SIZE > 512
// Physically assert the selected dataflash
df_chipselect_current();
//#
//# Transfer the current page content in buffer1.
//#
// Send Main Mem page to Buffer1 command, + first step to clear the SPIF bit
Spi_write_data(DF_TF_BUF_1);
// Final step to clear the SPIF bit will be done on the next write
// Send the three address Bytes made of:
// (.) the page-address(first xbits),
// (.) remaining don't care bits(last ybits).
// (x and y depending on the DF type).
// NOTE: the bits of gl_ptr_mem above the 24bits are not useful for the local
// DF addressing. They are used for DF discrimination when there are several
// DFs.
Spi_write_data((MSB1(gl_ptr_mem) << DF_SHFT_B1) | (MSB2(gl_ptr_mem) >> DF_SHFT_B2));
Spi_write_data(MSB2(gl_ptr_mem) << DF_SHFT_B1);
Spi_write_dummy(); // Remaining don't care bits.
Spi_ack_write(); // Final step to clear the SPIF bit.
Df_desel_all(); // Unselect memory to validate the command
df_wait_busy(); // Wait end of page transfer
#endif
// Physically assert the selected dataflash
df_chipselect_current();
//#
//# Initiate a page write at a given sector address.
//#
// Send Main Memory Page Program Through Buffer1 command,
// + first step to clear the SPIF bit
Spi_write_data(DF_PG_BUF_1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -