Skip to content
Permalink
4d2bdd9d79
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
895 lines (712 sloc) 33.8 KB
/******************************************************************************
* File Name: memory_driver.c
*
* Description: This is the source code for the XMC MCU: SPI QSPI Flash
* Example for ModusToolbox. This file includes the function
* definitions for interfacing the on-board N25Q03 memory chip
* in the XMC4700 Relax kit V1 and XMC4800 Relax EtherCAT kit V1,
* the on-board S25FL032P0XMFI01 memory chip in the XMC4500 Relax
* kit V1 or the on-board SST26VF032BT-104I/SM memory chip
* in the XMC4400 Platform2Go kit.
*
* Related Document: See README.md
*
******************************************************************************
*
* Copyright (c) 2015-2022, Infineon Technologies AG
* All rights reserved.
*
* Boost Software License - Version 1.0 - August 17th, 2003
*
* Permission is hereby granted, free of charge, to any person or organization
* obtaining a copy of the software and accompanying documentation covered by
* this license (the "Software") to use, reproduce, display, distribute,
* execute, and transmit the Software, and to prepare derivative works of the
* Software, and to permit third-parties to whom the Software is furnished to
* do so, all subject to the following:
*
* The copyright notices in the Software and this entire statement, including
* the above license grant, this restriction and the following disclaimer,
* must be included in all copies of the Software, in whole or in part, and
* all derivative works of the Software, unless such copies or derivative
* works are solely in the form of machine-executable object code generated by
* a source language processor.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#include "memory_driver.h"
#include "spi_master.h"
#include "cycfg_peripherals.h"
/* N25Q03 / S25FL032P / SST26VF032BT-104I-SM flash chip command definitions */
#define MEMORY_CM_READ 0x03
#define MEMORY_CM_READ_FAST 0x0B
#define MEMORY_CM_QUAL_READ 0x3B
#define MEMORY_CM_QUAD_READ 0x6B
#define MEMORY_CM_ID_READ 0x9F
#define MEMORY_CM_WRITE_EN 0x06
#define MEMORY_CM_WRITE_DIS 0x04
/* Global Block Protection Unlock for KIT_XMC_PLT2GO_XMC4400 */
#define MEMORY_CM_WRITE_PROT_DIS 0x98
/* 4KB sector */
#define MEMORY_CM_ERASE_P4E 0x20
/* 8KB sector */
#if (UC_SERIES == XMC44)
#define MEMORY_CM_ERASE_P8E 0xD8
#else
#define MEMORY_CM_ERASE_P8E 0x40
#endif
/* 64KB sector */
#define MEMORY_CM_ERASE_SE 0xD8
/* programming commands */
#define MEMORY_CM_PROG_PAGE 0x02
#define MEMORY_CM_PROG_QPAGE 0x32
/* write status and configure register */
#define MEMORY_CM_REG_WRITE 0x01
/* read status register */
#define MEMORY_CM_REG_READ_ST 0x05
/* read configure register */
#if (UC_SERIES == XMC44) || (UC_SERIES == XMC45)
#define MEMORY_CM_REG_READ_CFG 0x35
#endif
#if (UC_SERIES == XMC47) || (UC_SERIES == XMC48)
#define MEMORY_CM_REG_READ_CFG 0xB5
#endif
/* reset the erase and program fall flag */
#define MEMORY_CM_REG_RESET 0x30
#define SINGLE_WORD 1
#define SECTOR_24_ADDR_MSK 0x00FF0000
#define SECTOR_16_ADDR_MSK 0x0000FF00
#define SECTOR_8_ADDR_MSK 0x000000FF
#define RIGHT_SHIFT_16_POS 16
#define RIGHT_SHIFT_8_POS 8
#define RIGHT_SHIFT_0_POS 0
#define DATA_LENGTH 256
#define BIT8_FRAME 8
#define BIT16_FRAME 16
#define BIT32_FRAME 32
#define BIT64_FRAME 64
/*******************************************************************************
* Function Name: memory_status_read
********************************************************************************
* Summary:
* This function sends read status register command to SPI flash chip
* and returns Status register value
*
* Parameters:
* none
*
* Return:
* uint16_t - SPI Flash status register value
*
*******************************************************************************/
uint16_t memory_status_read(void)
{
uint8_t tmp;
uint8_t data = 0;
uint32_t status1 = 0;
uint32_t status2 = 0;
/* Change SPI Channel configuration */
SPI_MASTER_SetMode(&SPI_MASTER_0, XMC_SPI_CH_MODE_STANDARD);
/* Set the number of bits in a frame */
XMC_USIC_CH_SetFrameLength(SPI_CHANNEL_HW, BIT16_FRAME);
/* Enable slave select */
SPI_MASTER_EnableSlaveSelectSignal(&SPI_MASTER_0,
SPI_MASTER_0.config->slave_select_pin_config[0]->slave_select_ch);
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Load the command */
data = MEMORY_CM_REG_READ_ST;
/* Send the read status register command to SPI flash chip */
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Receive the status command from the SPI flash chip */
SPI_MASTER_Receive(&SPI_MASTER_0, &tmp, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->rx_busy);
/* Disable the Slave Select Line */
SPI_MASTER_DisableSlaveSelectSignal(&SPI_MASTER_0);
return tmp;
}
/*******************************************************************************
* Function Name: memory_sector_erase
********************************************************************************
* Summary:
* This function sends sector erase command to SPI flash chip
*
* Parameters:
* uint32_t address - sector address to be erased
*
* Return:
* void
*
*******************************************************************************/
void memory_sector_erase(uint32_t address)
{
uint8_t data;
uint32_t status1 = 0;
uint32_t status2 = 0;
/* Change SPI Channel configuration */
SPI_MASTER_SetMode(&SPI_MASTER_0, XMC_SPI_CH_MODE_STANDARD);
/* Set the number of bits in a frame */
XMC_USIC_CH_SetFrameLength(SPI_CHANNEL_HW, BIT32_FRAME);
/* Enable slave select */
SPI_MASTER_EnableSlaveSelectSignal(&SPI_MASTER_0, SPI_MASTER_0.config->slave_select_pin_config[0]->slave_select_ch);
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Load the command */
data = MEMORY_CM_ERASE_SE;
/* Send the command to SPI flash chip */
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Send 3rd byte of 24bit address */
data = ((address & SECTOR_24_ADDR_MSK) >> RIGHT_SHIFT_16_POS);
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Send 2nd byte of 24bit address */
data = ((address & SECTOR_16_ADDR_MSK) >> RIGHT_SHIFT_8_POS);
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Send 1st byte of 24bit address */
data =((address & SECTOR_8_ADDR_MSK) >> RIGHT_SHIFT_0_POS);
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Disable the Slave Select Line */
SPI_MASTER_DisableSlaveSelectSignal(&SPI_MASTER_0);
}
/*******************************************************************************
* Function Name: memory_write_enable
********************************************************************************
* Summary:
* This function sends the write enable command to SPI flash chip
*
* Parameters:
* void
*
* Return:
* void
*
*******************************************************************************/
void memory_write_enable(void)
{
uint8_t data = 0;
uint32_t status1 = 0;
uint32_t status2 = 0;
/* Change SPI Channel configuration */
SPI_MASTER_SetMode(&SPI_MASTER_0, XMC_SPI_CH_MODE_STANDARD);
/* Set the number of bits in a frame */
XMC_USIC_CH_SetFrameLength(SPI_CHANNEL_HW, BIT8_FRAME);
/* Enable slave select */
SPI_MASTER_EnableSlaveSelectSignal(&SPI_MASTER_0, SPI_MASTER_0.config->slave_select_pin_config[0]->slave_select_ch);
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Write Enable command */
data = MEMORY_CM_WRITE_EN;
/* Send Write Enable command */
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Disable the Slave Select Line */
SPI_MASTER_DisableSlaveSelectSignal(&SPI_MASTER_0);
}
/*******************************************************************************
* Function Name: memory_write_protection
********************************************************************************
* Summary:
* This function sends the write protection command to SPI flash chip
*
* Parameters:
* void
*
* Return:
* void
*
*******************************************************************************/
void memory_write_protection(void)
{
uint8_t data = 0;
uint32_t status1 = 0;
uint32_t status2 = 0;
/* Change SPI Channel configuration */
SPI_MASTER_SetMode(&SPI_MASTER_0, XMC_SPI_CH_MODE_STANDARD);
/* Set the number of bits in a frame */
XMC_USIC_CH_SetFrameLength(SPI_CHANNEL_HW, BIT8_FRAME);
/* Enable slave select */
SPI_MASTER_EnableSlaveSelectSignal(&SPI_MASTER_0, SPI_MASTER_0.config->slave_select_pin_config[0]->slave_select_ch);
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Write Enable command */
data = MEMORY_CM_WRITE_PROT_DIS;
/* Send Write Enable command */
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Disable the Slave Select Line */
SPI_MASTER_DisableSlaveSelectSignal(&SPI_MASTER_0);
}
/*******************************************************************************
* Function Name: memory_quad_read_page
********************************************************************************
* Summary:
* This function reads 256 bytes of data from the given sector to the buffer
* provided
*
* Parameters:
* - uint32_t address - Memory address to be read
* - uint8_t *p_spi_receive_data - pointer to receive buffer
*
* Return:
* void
*
*******************************************************************************/
void memory_quad_read_page(uint32_t address, uint8_t *p_spi_receive_data)
{
uint8_t data = 0;
uint32_t status1 = 0;
uint32_t status2 = 0;
/* Configure the channel with given configuration */
SPI_MASTER_SetMode(&SPI_MASTER_0, XMC_SPI_CH_MODE_QUAD);
/* Set the number of bits in a frame */
XMC_USIC_CH_SetFrameLength(SPI_CHANNEL_HW, BIT64_FRAME);
/* Enable slave select */
SPI_MASTER_EnableSlaveSelectSignal(&SPI_MASTER_0, SPI_MASTER_0.config->slave_select_pin_config[0]->slave_select_ch);
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Quad read command */
data = MEMORY_CM_QUAD_READ;
/*Send the command in quad mode*/
SPI_MASTER_0.runtime->spi_master_mode = XMC_SPI_CH_MODE_QUAD;
/* Send Quad read command */
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Send 3rd byte of 24 bit address */
data = ((address & SECTOR_24_ADDR_MSK) >> RIGHT_SHIFT_16_POS);
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Send 2nd byte of 24 bit address */
data = ((address & SECTOR_16_ADDR_MSK) >> RIGHT_SHIFT_8_POS);
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Send 1st byte of 24 bit address */
data = ((address & SECTOR_8_ADDR_MSK) >> RIGHT_SHIFT_0_POS);
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Send dummy byte */
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
SPI_MASTER_0.runtime->spi_master_mode = XMC_SPI_CH_MODE_QUAD;
/* Send 255 Dummy data to receive data from SPI Flash */
SPI_MASTER_Receive(&SPI_MASTER_0, p_spi_receive_data, DATA_LENGTH);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->rx_busy);
/* Disable the Slave Select Line */
SPI_MASTER_DisableSlaveSelectSignal(&SPI_MASTER_0);
}
/*******************************************************************************
* Function Name: memory_quad_write_page
********************************************************************************
* Summary:
* This function writes 256 bytes of data from given buffer to the
* sector starting from 0x00000000
*
* Parameters:
* - uint32_t address - Memory address to write to
* - uint8_t *p_spi_receive_data - pointer to transmit buffer
*
* Return:
* void
*
*******************************************************************************/
void memory_quad_write_page(uint32_t address, uint8_t *p_spi_send_data)
{
uint8_t data = 0;
uint32_t status1 = 0;
uint32_t status2 = 0;
/* Configure SPI Channel */
SPI_MASTER_SetMode(&SPI_MASTER_0, XMC_SPI_CH_MODE_QUAD);
/* Set the number of bits in a frame */
XMC_USIC_CH_SetFrameLength(SPI_CHANNEL_HW, BIT64_FRAME);
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Enable the Slave Select Line */
SPI_MASTER_EnableSlaveSelectSignal(&SPI_MASTER_0, SPI_MASTER_0.config->slave_select_pin_config[0]->slave_select_ch);
/* Program Quad page command */
data = MEMORY_CM_PROG_QPAGE;
/* Send the command in quad mode */
SPI_MASTER_0.runtime->spi_master_mode = XMC_SPI_CH_MODE_QUAD;
/* Send Quad write command */
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Send 3rd byte of 24 bit address */
data = ((address & SECTOR_24_ADDR_MSK) >> RIGHT_SHIFT_16_POS);
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Send 2rd byte of 24 bit address */
data = ((address & SECTOR_24_ADDR_MSK) >> RIGHT_SHIFT_8_POS);
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Send 1nd byte of 24 bit address */
data = ((address & SECTOR_8_ADDR_MSK) >> RIGHT_SHIFT_0_POS);
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Send 255 bytes of Data in Quad SPI mode */
SPI_MASTER_0.runtime->spi_master_mode = XMC_SPI_CH_MODE_QUAD;
SPI_MASTER_Transmit(&SPI_MASTER_0, p_spi_send_data, DATA_LENGTH);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till the last dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Disable the Slave Select Line */
SPI_MASTER_DisableSlaveSelectSignal(&SPI_MASTER_0);
}
/*******************************************************************************
* Function Name: memory_read_page
********************************************************************************
* Summary:
* This function sends read page command and reads out 256 bytes of data
* from sector specified to the given buffer
*
* Parameters:
* - uint32_t address - Memory address to read from
* - uint8_t *p_spi_receive_data - pointer to receive buffer
*
* Return:
* void
*
*******************************************************************************/
void memory_read_page(uint32_t address, uint8_t *p_spi_receive_data)
{
uint8_t data = 0;
uint32_t status1;
uint32_t status2;
/* Configure SPI channel */
SPI_MASTER_SetMode(&SPI_MASTER_0, XMC_SPI_CH_MODE_STANDARD);
/* Set the number of bits in a frame */
XMC_USIC_CH_SetFrameLength(SPI_CHANNEL_HW, BIT64_FRAME);
/* Enable the Slave Select Line */
SPI_MASTER_EnableSlaveSelectSignal(&SPI_MASTER_0, SPI_MASTER_0.config->slave_select_pin_config[0]->slave_select_ch);
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* read page command */
data = MEMORY_CM_READ;
/* Send read page command */
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till the last dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Send 3rd byte of 24bit start address */
data = ((address & SECTOR_24_ADDR_MSK) >> RIGHT_SHIFT_16_POS);
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till the last dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Send 2nd byte of 24bit start address */
data = ((address & SECTOR_16_ADDR_MSK) >> RIGHT_SHIFT_8_POS);
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till the last dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while((status1 == 0) && (status2 == 0));
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Send 1st byte of 24bit start address */
data = ((address & SECTOR_8_ADDR_MSK) >> RIGHT_SHIFT_0_POS);
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till the last dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Receive the 256 bytes */
SPI_MASTER_Receive(&SPI_MASTER_0, p_spi_receive_data, DATA_LENGTH);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->rx_busy);
/* Disable the Slave Select Line */
SPI_MASTER_DisableSlaveSelectSignal(&SPI_MASTER_0);
}
/*******************************************************************************
* Function Name: memory_program_page
********************************************************************************
* Summary:
* This function sends read page command and reads out 256 bytes of data
* from sector specified to the given buffer
*
* Parameters:
* - uint32_t address - Memory address to program
* - uint8_t *p_spi_send_data - pointer to transmit buffer
*
* Return:
* void
*
*******************************************************************************/
void memory_program_page( uint32_t address, uint8_t *p_spi_send_data)
{
uint8_t data;
uint32_t status1;
uint32_t status2;
/* Configure SPI channel */
SPI_MASTER_SetMode(&SPI_MASTER_0, XMC_SPI_CH_MODE_STANDARD);
/* Set the number of bits in a frame */
XMC_USIC_CH_SetFrameLength(SPI_CHANNEL_HW, BIT64_FRAME);
/* Enable the Slave Select Line */
SPI_MASTER_EnableSlaveSelectSignal(&SPI_MASTER_0, SPI_MASTER_0.config->slave_select_pin_config[0]->slave_select_ch);
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Write program page data */
data = MEMORY_CM_PROG_PAGE;
/* Send program page write command */
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Send 3rd byte of 24bit address of sector */
data = ((address & SECTOR_24_ADDR_MSK) >> RIGHT_SHIFT_16_POS);
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Send 2nd byte of 24bit address of sector */
data = ((address & SECTOR_16_ADDR_MSK) >> 8);
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Send 1st byte of 24bit address of sector */
data = ((address & SECTOR_8_ADDR_MSK) >> RIGHT_SHIFT_0_POS);
SPI_MASTER_Transmit(&SPI_MASTER_0, &data, SINGLE_WORD);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Send 256 bytes of data to be programmed */
SPI_MASTER_Transmit(&SPI_MASTER_0, p_spi_send_data, DATA_LENGTH);
/* Wait while SPI master is busy */
while(SPI_MASTER_0.runtime->tx_busy);
/* Clear the flags */
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
SPI_MASTER_ClearFlag(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
/* Wait till dummy data is received from flash chip */
do
{
status1 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
status2 = SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION);
} while(((status1 == 0) && (status2 == 0)));
/* Disable the Slave Select Line */
SPI_MASTER_DisableSlaveSelectSignal(&SPI_MASTER_0);
}
/* [] END OF FILE */