示例#1
0
/**
 * \brief Writes data on the At45 at the specified address. Only one page of
 * data is written that way; if the address is not at the beginning of the
 * page, the data is written starting from this address and wraps around to
 * the beginning of the page.
 * \param pAt45  Pointer to an AT45 driver instance.
 * \param pBuffer  Data buffer.
 * \param size  Number of bytes to write.
 * \param address  Destination address on the At45.
 */
void AT45D_Write(
    At45 *pAt45,
    uint8_t *pBuffer,
    uint32_t size,
    uint32_t address)
{
    uint8_t error;

    SANITY_CHECK(pAt45);
    SANITY_CHECK(pBuffer);
    SANITY_CHECK(size <= pAt45->pDesc->pageSize);

    /* Issue a page write through buffer 1 command. */
    error = AT45_SendCommand(pAt45, AT45_PAGE_WRITE_BUF1, 4, pBuffer, size, address, 0, 0);
    ASSERT(!error, "-F- AT45_Write: Could not issue command.\n\r");

    /* Wait until the command is sent. */
    while (AT45_IsBusy(pAt45)) {

        AT45D_Wait(pAt45);
    }

    /* Wait until the At45 becomes ready again.*/
    AT45D_WaitReady(pAt45);
}
示例#2
0
文件: at45d.c 项目: gstroe/Arm
//------------------------------------------------------------------------------
/// Wait for transfer to finish calling the SPI driver ISR (interrupts are
/// disabled).
/// \param pAt45  Pointer to an AT45 driver instance.
//------------------------------------------------------------------------------
static void AT45D_Wait(At45 *pAt45)
{
	SANITY_CHECK(pAt45);

	// Wait for transfer to finish
	while (AT45_IsBusy(pAt45))
		SPID_Handler(pAt45->pSpid);
}
示例#3
0
/**
 * \brief Wait for transfer to finish calling the SPI driver ISR (interrupts are
 * disabled).
 *
 * \param pAt45  Pointer to an AT45 driver instance.
 */
static void AT45D_Wait( At45* pAt45 )
{
    assert( pAt45 != NULL ) ;

    /* Wait for transfer to finish */
    while ( AT45_IsBusy( pAt45 ) )
    {
        SPID_Handler( pAt45->pSpid ) ;
    }
}
示例#4
0
//------------------------------------------------------------------------------
/// Sends a command to the dataflash through the SPI. The command is identified
/// by its command code and the number of bytes to transfer (1 + number of
/// address bytes + number of dummy bytes). If data needs to be received, then
/// a data buffer must be provided.
/// This function does not block; its optional callback will be invoked when
/// the transfer completes.
/// \param pAt45  Pointer to an At45 driver instance.
/// \param cmd  Command code.
/// \param cmdSize  Size of command code + address bytes + dummy bytes.
/// \param pData  Data buffer.
/// \param dataSize  Number of data bytes to send/receive.
/// \param address  Address at which the command is performed if meaningful.
/// \param callback  Optional callback to invoke at end of transfer.
/// \param pArgument  Optional parameter to the callback function.
//------------------------------------------------------------------------------
unsigned char AT45_SendCommand(
    At45 *pAt45,
    unsigned char cmd,
    unsigned char cmdSize,
    unsigned char *pData,
    unsigned int dataSize,
    unsigned int address,
    SpidCallback callback,
    void *pArgument)
{
    SpidCmd *pCommand;
    const At45Desc *pDesc = pAt45->pDesc;
    unsigned int dfAddress = 0;

    // Sanity checks
    ASSERT(pAt45, "AT45_Command: pAt45 is 0.\n\r");
    ASSERT(pDesc || (cmd == AT45_STATUS_READ),
           "AT45_Command: Device has no descriptor, only STATUS_READ command allowed\n\r");

    // Check if the SPI driver is available
    if (AT45_IsBusy(pAt45)) {

        return AT45_ERROR_LOCK;
    }

    // Compute command pattern
    pAt45->pCmdBuffer[0] = cmd;

    // Add address bytes if necessary
    if (cmdSize > 1) {

        ASSERT(pDesc, "AT45_Command: No descriptor for dataflash.\n\r");
        if (!configuredBinaryPage) {
            dfAddress =
                ((address / (pDesc->pageSize)) << pDesc->pageOffset)
                 + (address % (pDesc->pageSize));
        }
        else {
            dfAddress = address;
        }
        // Write address bytes
        if (pDesc->pageNumber >= 16384) {

            pAt45->pCmdBuffer[1] = ((dfAddress & 0x0F000000) >> 24);
            pAt45->pCmdBuffer[2] = ((dfAddress & 0x00FF0000) >> 16);
            pAt45->pCmdBuffer[3] = ((dfAddress & 0x0000FF00) >> 8);
            pAt45->pCmdBuffer[4] = ((dfAddress & 0x000000FF) >> 0);

            if ((cmd != AT45_CONTINUOUS_READ) && (cmd != AT45_PAGE_READ)) {

                cmdSize++;
            }
        }
示例#5
0
/**
 * \brief Sends a command to the dataflash through the SPI.
 * The command is identified by its command code and the number of bytes to transfer
 * (1 + number of address bytes + number of dummy bytes).If data needs to be received,
 * then a data buffer must be provided.
 * \note This function does not block; its optional callback will be invoked when
 * the transfer completes.
 * \param pAt45  Pointer to the At45 instance to initialize.
 * \param cmd  Command code.
 * \param cmdSize  Size of command code + address bytes + dummy bytes.
 * \param pData  Data buffer.
 * \param dataSize  Number of data bytes to send/receive.
 * \param address  Address at which the command is performed if meaningful.
 * \param callback  Optional callback to invoke at end of transfer.
 * \param pArgument  Optional parameter to the callback function.
 * \return  0.
 */
extern uint32_t AT45_SendCommand( At45* pAt45, 
                                  uint8_t ucCmd, 
                                  uint8_t ucCmdSize, 
                                  uint8_t *pucData, 
                                  uint32_t dwDataSize,
                                  uint32_t dwAddress, 
                                  SpidCallback pCallback, 
                                  void *pArgument )
{
    SpidCmd *pCommand ;
    const At45Desc *pDesc = pAt45->pDesc ;
    uint32_t dfAddress = 0 ;

    /* Sanity checks */
   // assert( pDesc || (ucCmd == AT45_STATUS_READ) ) ;

    /* Check if the SPI driver is available*/
    if ( AT45_IsBusy( pAt45 ) )
    {
        return AT45_ERROR_LOCK ;
    }

    /* Compute command pattern*/
    pAt45->pCmdBuffer[0] = ucCmd ;

    /* Add address bytes if necessary*/
    if ( ucCmdSize > 1 )
    {
        assert( pDesc != NULL ) ;
        if ( !configuredBinaryPage )
        {
            dfAddress = ((dwAddress / (pDesc->pageSize)) << pDesc->pageOffset)
                        + (dwAddress % (pDesc->pageSize));
        }
        else
        {
            dfAddress = dwAddress ;
        }

        /* Write address bytes */
        if ( pDesc->pageNumber >= 16384 )
        {
            pAt45->pCmdBuffer[1] = ((dfAddress & 0x0F000000) >> 24);
            pAt45->pCmdBuffer[2] = ((dfAddress & 0x00FF0000) >> 16);
            pAt45->pCmdBuffer[3] = ((dfAddress & 0x0000FF00) >> 8);
            pAt45->pCmdBuffer[4] = ((dfAddress & 0x000000FF) >> 0);

            if ( (ucCmd != AT45_CONTINUOUS_READ) && (ucCmd != AT45_PAGE_READ) )
            {
                ucCmdSize++ ;
            }
        }
示例#6
0
/**
 * \brief Retrieves and returns the At45 current status, or 0 if an error happened.
 *
 * \param pAt45  Pointer to an AT45 driver instance.
 */
uint8_t AT45D_GetStatus(At45 *pAt45)
{
    uint8_t error;
    uint8_t status;

    SANITY_CHECK(pAt45);

    /* Issue a status register read command*/
    error = AT45_SendCommand(pAt45, AT45_STATUS_READ, 1, &status, 1, 0, 0, 0);
    ASSERT(!error, "-F- AT45_GetStatus: Failed to issue command.\n\r");

    /* Wait for command to terminate*/
    while (AT45_IsBusy(pAt45)) {
        AT45D_Wait(pAt45);
    }
    return status;
}
示例#7
0
/**
 * \brief Reads data from the At45 inside the provided buffer. Since a continuous
 * read command is used, there is no restriction on the buffer size and read address.
 *
 * \param pAt45  Pointer to an AT45 driver instance.
 * \param pBuffer  Data buffer.
 * \param size  Number of bytes to read.
 * \param address  Address at which data shall be read.
 */
extern void AT45D_Read( At45* pAt45, uint8_t* pucBuffer, uint32_t dwSize, uint32_t dwAddress )
{
    uint32_t dwError ;

    assert( pAt45 != NULL ) ;
    assert( pucBuffer != NULL ) ;

    /* Issue a continuous read array command. */
    dwError = AT45_SendCommand( pAt45, AT45_CONTINUOUS_READ_LEG, 8, pucBuffer, dwSize, dwAddress, 0, 0 ) ;
    assert( !dwError ) ;

    /* Wait for the read command to execute. */
    while ( AT45_IsBusy( pAt45 ) )
    {
        AT45D_Wait( pAt45 ) ;
    }
}
示例#8
0
文件: at45d.c 项目: gstroe/Arm
//------------------------------------------------------------------------------
/// Erases a page of data at the given address in the At45.
/// \param pAt45  Pointer to a At45 driver instance.
/// \param address  Address of page to erase.
//------------------------------------------------------------------------------
void AT45D_Erase(At45 *pAt45, unsigned int address)
{
	unsigned char error;

	SANITY_CHECK(pAt45);

	// Issue a page erase command.
	error = AT45_SendCommand(pAt45, AT45_PAGE_ERASE, 4, 0, 0, address, 0, 0);
	ASSERT(!error, "-F- AT45_Erase: Could not issue command.\n\r");

	// Wait for end of transfer
	while (AT45_IsBusy(pAt45))
		AT45D_Wait(pAt45);

	// Poll until the At45 has completed the erase operation
	AT45D_WaitReady(pAt45);
}
示例#9
0
文件: at45d.c 项目: gstroe/Arm
//------------------------------------------------------------------------------
/// Retrieves and returns the At45 current status, or 0 if an error
/// happened.
/// \param pAt45  Pointer to a At45 driver instance.
//------------------------------------------------------------------------------
unsigned char AT45D_GetStatus(At45 *pAt45)
{
	unsigned char error;
	unsigned char status;

	SANITY_CHECK(pAt45);

	// Issue a status register read command
	error = AT45_SendCommand(pAt45, AT45_STATUS_READ, 1, &status, 1, 0, 0, 0);
	ASSERT(!error, "-F- AT45_GetStatus: Failed to issue command.\n\r");

	// Wait for command to terminate
	while (AT45_IsBusy(pAt45))

		AT45D_Wait(pAt45);

	return status;
}
示例#10
0
/**
 * \brief Erases a page of data at the given address in the At45.
 *
 * \param pAt45  Pointer to an AT45 driver instance.
 * \param dwAddress  Address of page to erase.
 */
extern void AT45D_Erase( At45* pAt45, uint32_t dwAddress )
{
    uint32_t dwError ;

    assert( pAt45 != NULL ) ;

    /* Issue a page erase command. */
    dwError = AT45_SendCommand( pAt45, AT45_PAGE_ERASE, 4, 0, 0, dwAddress, 0, 0 ) ;
    assert( !dwError ) ;

    /* Wait for end of transfer. */
    while ( AT45_IsBusy(pAt45 ) )
    {
        AT45D_Wait( pAt45 ) ;
    }

    /* Poll until the At45 has completed the erase operation. */
    AT45D_WaitReady( pAt45 ) ;
}
示例#11
0
/**
 * \brief Retrieves and returns the At45 current status, or 0 if an error happened.
 *
 * \param pAt45  Pointer to an AT45 driver instance.
 */
extern uint32_t AT45D_GetStatus( At45* pAt45 )
{
    uint32_t dwError ;
    uint8_t ucStatus ;

    assert( pAt45 != NULL ) ;

    /* Issue a status register read command */
    dwError = AT45_SendCommand( pAt45, AT45_STATUS_READ, 1, &ucStatus, 1, 0, 0, 0 ) ;
    assert( !dwError ) ;

    /* Wait for command to terminate */
    while ( AT45_IsBusy( pAt45 ) )
    {
        AT45D_Wait( pAt45 ) ;
    }

    return ucStatus ;
}
示例#12
0
/**
 * \brief Erases a page of data at the given address in the At45.
 *
 * \param pAt45  Pointer to an AT45 driver instance.
 * \param address  Address of page to erase.
 */
void AT45D_Erase(At45 *pAt45, uint32_t address)
{
    uint8_t error;

    SANITY_CHECK(pAt45);

    /* Issue a page erase command. */
    error = AT45_SendCommand(pAt45, AT45_PAGE_ERASE, 4, 0, 0, address, 0, 0);
    ASSERT(!error, "-F- AT45_Erase: Could not issue command.\n\r");

    /* Wait for end of transfer. */
    while (AT45_IsBusy(pAt45)) {

        AT45D_Wait(pAt45);
    }

    /* Poll until the At45 has completed the erase operation.*/
    AT45D_WaitReady(pAt45);
}
示例#13
0
/**
 * \brief Configure power-of-2 binary page size in the At45.
 *
 * \param pAt45  Pointer to an AT45 driver instance.
 */
extern void AT45D_BinaryPage( At45* pAt45 )
{
    uint8_t dwError ;
    uint8_t opcode[3]= {AT45_BINARY_PAGE};
    assert( pAt45 != NULL ) ;

    /* Issue a binary page command. */

    dwError = AT45_SendCommand( pAt45, AT45_BINARY_PAGE_FIRST_OPCODE, 1, opcode, 3, 0, 0, 0 ) ;

    assert( !dwError ) ;

    /* Wait for end of transfer.*/
    while ( AT45_IsBusy( pAt45 ) )
    {
        AT45D_Wait( pAt45 ) ;
    }

    /* Wait until the At45 becomes ready again.*/
    AT45D_WaitReady( pAt45 ) ;
}
示例#14
0
/**
 * \brief Writes data on the At45 at the specified address. Only one page of
 * data is written that way; if the address is not at the beginning of the
 * page, the data is written starting from this address and wraps around to
 * the beginning of the page.
 *
 * \param pAt45  Pointer to an AT45 driver instance.
 * \param pucBuffer  Data buffer.
 * \param dwSize  Number of bytes to write.
 * \param dwAddress  Destination address on the At45.
 */
extern void AT45D_Write( At45* pAt45, uint8_t *pucBuffer, uint32_t dwSize, uint32_t dwAddress )
{
    uint8_t dwError ;

    assert( pAt45 != NULL ) ;
    assert( pucBuffer != NULL ) ;
    assert( dwSize <= pAt45->pDesc->pageSize ) ;

    /* Issue a page write through buffer 1 command. */
    dwError = AT45_SendCommand( pAt45, AT45_PAGE_WRITE_BUF1, 4, pucBuffer, dwSize, dwAddress, 0, 0 ) ;
    assert( !dwError ) ;

    /* Wait until the command is sent. */
    while ( AT45_IsBusy( pAt45 ) )
    {
        AT45D_Wait( pAt45 ) ;
    }

    /* Wait until the At45 becomes ready again.*/
    AT45D_WaitReady( pAt45 ) ;
}
示例#15
0
/**
 * \brief Reads data from the At45 inside the provided buffer. Since a continuous
 * read command is used, there is no restriction on the buffer size and read address.
 *
 * \param pAt45  Pointer to an AT45 driver instance.
 * \param pBuffer  Data buffer.
 * \param size  Number of bytes to read.
 * \param address  Address at which data shall be read.
 */
void AT45D_Read(
    At45 *pAt45,
    uint8_t *pBuffer,
    uint32_t size,
    uint32_t address)
{
    uint8_t error;

    SANITY_CHECK(pAt45);
    SANITY_CHECK(pBuffer);

    /* Issue a continuous read array command.*/
    error = AT45_SendCommand(pAt45, AT45_CONTINUOUS_READ_LEG, 8, pBuffer, size, address, 0, 0);
    ASSERT(!error, "-F- AT45_Read: Failed to issue command\n\r");

    /* Wait for the read command to execute.*/
    while (AT45_IsBusy(pAt45)) {

        AT45D_Wait(pAt45);
    }
}
示例#16
0
文件: at45d.c 项目: gstroe/Arm
void AT45D_BinaryPage(At45 *pAt45)
{
	unsigned char error;
	unsigned char opcode[3] = {AT45_BINARY_PAGE};
	SANITY_CHECK(pAt45);

	// Issue a binary page command.

	error = AT45_SendCommand(
				pAt45, AT45_BINARY_PAGE_FIRST_OPCODE, 1, opcode, 3, 0, 0, 0);

	ASSERT(!error, "-F- AT45_Erase: Could not issue command.\n\r");

	// Wait for end of transfer
	while (AT45_IsBusy(pAt45))

		AT45D_Wait(pAt45);

	// Wait until the At45 becomes ready again
	AT45D_WaitReady(pAt45);
}
示例#17
0
文件: at45d.c 项目: gstroe/Arm
//------------------------------------------------------------------------------
/// Reads data from the At45 inside the provided buffer. Since a continuous
/// read command is used, there is no restriction on the buffer size and read
/// address.
/// \param pAt45  Pointer to a At45 driver instance.
/// \param pBuffer  Data buffer.
/// \param size  Number of bytes to read.
/// \param address  Address at which data shall be read.
//------------------------------------------------------------------------------
void AT45D_Read(
	At45 *pAt45,
	unsigned char *pBuffer,
	unsigned int size,
	unsigned int address)
{
	unsigned char error;

	SANITY_CHECK(pAt45);
	SANITY_CHECK(pBuffer);

	// Issue a continuous read array command
	error = AT45_SendCommand(
				pAt45, AT45_CONTINUOUS_READ_LEG, 8, pBuffer, size, address, 0, 0);
	ASSERT(!error, "-F- AT45_Read: Failed to issue command\n\r");

	// Wait for the read command to execute
	while (AT45_IsBusy(pAt45))

		AT45D_Wait(pAt45);
}
示例#18
0
/**
 * \brief Configure power-of-2 binary page size in the At45.
 *
 * \param pAt45  Pointer to an AT45 driver instance.
 */
void AT45D_BinaryPage(At45 *pAt45)
{
    uint8_t error;
    uint8_t opcode[3]= {AT45_BINARY_PAGE};
    SANITY_CHECK(pAt45);

    /* Issue a binary page command. */

    error = AT45_SendCommand(pAt45, AT45_BINARY_PAGE_FIRST_OPCODE, 1, opcode, 3, 0, 0, 0);

    ASSERT(!error, "-F- AT45_Erase: Could not issue command.\n\r");

    /* Wait for end of transfer.*/
    while (AT45_IsBusy(pAt45)) {

        AT45D_Wait(pAt45);
    }

    /* Wait until the At45 becomes ready again.*/
    AT45D_WaitReady(pAt45);
}
示例#19
0
文件: at45d.c 项目: gstroe/Arm
//------------------------------------------------------------------------------
/// Writes data on the At45 at the specified address. Only one page of
/// data is written that way; if the address is not at the beginning of the
/// page, the data is written starting from this address and wraps around to
/// the beginning of the page.
/// \param pAt45  Pointer to a At45 driver instance.
/// \param pBuffer  Buffer containing the data to write.
/// \param size  Number of bytes to write.
/// \param address  Destination address on the At45.
//------------------------------------------------------------------------------
void AT45D_Write(
	At45 *pAt45,
	unsigned char *pBuffer,
	unsigned int size,
	unsigned int address)
{
	unsigned char error;

	SANITY_CHECK(pAt45);
	SANITY_CHECK(pBuffer);
	SANITY_CHECK(size <= pAt45->pDesc->pageSize);

	// Issue a page write through buffer 1 command
	error = AT45_SendCommand(
				pAt45, AT45_PAGE_WRITE_BUF1, 4, pBuffer, size, address, 0, 0);
	ASSERT(!error, "-F- AT45_Write: Could not issue command.\n\r");

	// Wait until the command is sent
	while (AT45_IsBusy(pAt45))
		AT45D_Wait(pAt45);

	// Wait until the At45 becomes ready again
	AT45D_WaitReady(pAt45);
}