/******************************************************************************* * DISCLAIMER * This software is supplied by Renesas Electronics Corporation and is only * intended for use with Renesas products. No other uses are authorized. This * software is owned by Renesas Electronics Corporation and is protected under * all applicable laws, including copyright laws. * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT * LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. * TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS * ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE * FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR * ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * Renesas reserves the right, without notice, to make changes to this software * and to discontinue the availability of this software. By using this software, * you agree to the additional terms and conditions found by accessing the * following link: * http://www.renesas.com/disclaimer * Copyright 2015-2022 Renesas Electronics Corporation All rights reserved. *******************************************************************************/ /******************************************************************************* * DESCRIPTION : RPC driver for QSPI Flash ******************************************************************************/ /****************************************************************************** * @file rpcqspidrv.c * - Version : 0.07 * @brief RPC driver for QSPI Flash. * . *****************************************************************************/ /****************************************************************************** * History : DD.MM.YYYY Version Description * : 15.10.2021 0.01 First Release * : 16.02.2022 0.02 Modify how to write to RPC_WRBUF register. * : 15.03.2022 0.03 Modify to use inline function in mem_io.h * : when access to register. * : 18.03.2022 0.04 Modify to read modify write when write to * : register. * : 23.03.2022 0.05 Modify command for QSPI Flash to refer to * : command table. * : 01.04.2022 0.06 Modify magic number to definition. * : 09.11.2022 0.07 License notation change. *****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include "dma2.h" static uint32_t read_register_qspi_flash(uint32_t cmd, uint32_t *readData); void init_rpc_qspi_flash_4fastread_ext_mode(void) { uint32_t reg; reg = mem_read32(RPC_PHYCNT); reg |= (RPC_PHYCNT_STRTIM3 | RPC_PHYCNT_STRTIM2 | RPC_PHYCNT_STRTIM1 | RPC_PHYCNT_STRTIM0); reg &= ~(RPC_PHYCNT_HS | RPC_PHYCNT_WBUF2 | RPC_PHYCNT_WBUF | RPC_PHYCNT_PHYMEM_HYP); mem_write32(RPC_PHYCNT, reg); reg |= RPC_PHYCNT_CAL; mem_write32(RPC_PHYCNT, reg); reg = mem_read32(RPC_CMNCR); reg &= ~(CMNCR_MD_MANUAL /* External address space read mode */ | CMNCR_BSZ_MASK); /* Data Bus Size: Serial flash memory x 1*/ reg |= (CMNCR_MOIIO3_HIZ | CMNCR_MOIIO2_HIZ | CMNCR_MOIIO1_HIZ | CMNCR_MOIIO0_HIZ | CMNCR_IO0FV_HIZ); mem_write32(RPC_CMNCR, reg); /* bit31 MD = 0 : External address space read mode */ /* bit1-0 BSZ[1:0] = 00 : QSPI Flash x 1 */ reg = mem_read32(RPC_DRCR); reg &= ~(DRCR_SSLN | DRCR_RCF | DRCR_SSLE); reg |= (DRCR_RBURST_32UNITS | DRCR_RBE_BURST); mem_write32(RPC_DRCR, reg); /* bit20-16 RBURST[4:0] = 11111 : 32 continuous data unit */ /* bit8 RBE = 1 : Burst read */ reg = mem_read32(RPC_DRCMR); reg &= ~(DRCMR_CMD_MASK | DRCMR_OCMD_MASK); reg |= ((gp_qspi_cmd_tbl -> read_fast) << DRCMR_SMCMR_CMD_SHIFT); mem_write32(RPC_DRCMR, reg); /* bit23-16 CMD[7:0] = 0x0C : 4FAST_READ 0Ch Command 4-byte address command */ reg = mem_read32(RPC_DREAR); reg &= ~(DREAR_EAV_MASK | DREAR_EAC_MASK); reg |= DREAR_EAC_26BITS; mem_write32(RPC_DREAR, reg); /* bit23-16 EAV[7:0] = 0 : ADR[32:26] output set0 */ /* bit2-0 EAC[2:0] = 001 : ADR[25:0 ] Enable */ reg = mem_read32(RPC_DRENR); reg &= ~(DRENR_CDB_MASK | DRENR_OCDB_MASK | DRENR_ADB_MASK | DRENR_OPDB_MASK | DRENR_DRDB_MASK | DRENR_OCDE_EN | DRENR_ADE_MASK | DRENR_OPDE_MASK); reg |= (DRENR_DME_EN | DRENR_CDE_EN | DRENR_ADE_ONE_SERIAL); mem_write32(RPC_DRENR, reg); /* bit31-30 CDB[1:0] = 00 : 1bit width command (QSPI0_MOSI) */ /* bit25-24 ADB[1:0] = 00 : 1bit width address (QSPI0_MOSI) */ /* bit17-16 DRDB[1:0] = 00 : 1bit width transfer data (QSPI0_IO0) */ /* bit15 DME = 1 : dummy cycle enable */ /* bit14 CDE = 1 : Command enable */ /* bit11-8 ADE[3:0] = 1111 : ADR[31:0] output (32 Bit Address) */ reg = mem_read32(RPC_DRDMCR); reg &= ~(DRDMCR_DMCYC_MASK); reg |= DRDMCR_DMCYC_8; mem_write32(RPC_DRDMCR, reg); /* bit2-0 DMCYC[2:0] = 111 : 8 cycle dummy wait */ reg = mem_read32(RPC_DRDRENR); reg &= ~(DRDRENR_HYPE_MASK | DRDRENR_ADDRE | DRDRENR_OPDRE | DRDRENR_DRDRE); mem_write32(RPC_DRDRENR, reg); /* bit8 ADDRE = 0 : Address SDR transfer */ /* bit0 DRDRE = 0 : DATA SDR transfer */ } /* End of function init_rpc_qspi_flash_4fastread_ext_mode */ void init_rpc_qspi_flash(void) { uint32_t reg; power_on_rpc(); set_rpc_clock_mode(RPC_CLK_80M); reset_rpc(); set_rpc_ssl_delay(); reg = mem_read32(RPC_OFFSET1); reg &= ~(PHYOFFSET1_MASK); reg |= PHYOFFSET1_DMA_QSPI; mem_write32(RPC_OFFSET1, reg); } /* End of function init_rpc_qspi_flash */ /* 4SE DCh 4-byte address */ void sector_erase_4byte_qspi_flash(uint32_t sector_addr) { uint32_t reg; reg = mem_read32(RPC_PHYCNT); reg |= (RPC_PHYCNT_CAL | RPC_PHYCNT_STRTIM3 | RPC_PHYCNT_STRTIM2 | RPC_PHYCNT_STRTIM1 | RPC_PHYCNT_STRTIM0); reg &= ~(RPC_PHYCNT_HS | RPC_PHYCNT_WBUF2 | RPC_PHYCNT_WBUF | RPC_PHYCNT_PHYMEM_HYP); mem_write32(RPC_PHYCNT, reg); /* bit31 CAL = 1 : PHY calibration */ /* bit1-0 PHYMEM[1:0] = 00 : QSPI-SDR */ reg = mem_read32(RPC_CMNCR); reg &= ~(CMNCR_BSZ_MASK); reg |= (CMNCR_MD_MANUAL | CMNCR_MOIIO3_HIZ | CMNCR_MOIIO2_HIZ | CMNCR_MOIIO1_HIZ | CMNCR_MOIIO0_HIZ | CMNCR_IO0FV_HIZ); mem_write32(RPC_CMNCR, reg); /* bit31 MD = 1 : Manual mode */ /* bit1-0 BSZ[1:0] = 00 : QSPI Flash x 1 */ reg = mem_read32(RPC_SMCMR); reg &= ~(SMCMR_CMD_MASK | SMCMR_OCMD_MASK); reg |= ((gp_qspi_cmd_tbl -> sector_erase_4byte_addr) << DRCMR_SMCMR_CMD_SHIFT); mem_write32(RPC_SMCMR, reg); /* bit23-16 CMD[7:0] = 0xDC : Sector Erase 4-byte address command */ mem_write32(RPC_SMADR, sector_addr); reg = mem_read32(RPC_SMDRENR); reg &= ~(SMDRENR_HYPE_MASK | SMDRENR_ADDRE | SMDRENR_OPDRE | SMDRENR_SPIDRE); mem_write32(RPC_SMDRENR, reg); /* bit8 ADDRE = 0 : Address SDR transfer */ /* bit0 SPIDRE = 0 : DATA SDR transfer */ reg = mem_read32(RPC_SMENR); reg &= ~(SMENR_CDB_MASK | SMENR_OCDB_MASK | SMENR_ADB_MASK | SMENR_OPDB_MASK | SMENR_SPIDB_MASK | SMENR_DME_EN | SMENR_OCDE_EN | SMENR_ADE_MASK | SMENR_OPDE_MASK | SMENR_SPIDE_MASK); reg |= (SMENR_CDE_EN | SMENR_ADE_SERIAL_31); mem_write32(RPC_SMENR, reg); /* bit31-30 CDB[1:0] = 00 : 1bit width command (QSPI0_MOSI) */ /* bit25-24 ADB[1:0] = 00 : 1bit width address (QSPI0_MOSI) */ /* bit17-16 SPIDB[1:0] = 00 : 1bit width transfer data (QSPI0_MISO) */ /* bit15 DME = 0 : No dummy cycle */ /* bit14 CDE = 1 : Command enable */ /* bit11-8 ADE[3:0] = 1111 : ADR[31:0] output (32 Bit Address) */ /* bit3-0 SPIDE[3:0] = 0000 : No transfer */ reg = mem_read32(RPC_SMCR); reg &= ~(SMCR_SSLKP | SMCR_SPIRE | SMCR_SPIWE); reg |= SMCR_SPIE; mem_write32(RPC_SMCR, reg); /* bit2 SPIRE = 0 : Data read disable */ /* bit1 SPIWE = 0 : Data write disable */ /* bit0 SPIE = 1 : SPI transfer start */ wait_rpc_tx_end(); } /* End of function sector_erase_4byte_qspi_flash */ /* 4P4E 21h 4-byte address */ void parameter_sector_erase_4kb_qspi_flash(uint32_t sector_addr) { uint32_t reg; reg = mem_read32(RPC_PHYCNT); reg |= (RPC_PHYCNT_CAL | RPC_PHYCNT_STRTIM3 | RPC_PHYCNT_STRTIM2 | RPC_PHYCNT_STRTIM1 | RPC_PHYCNT_STRTIM0); reg &= ~(RPC_PHYCNT_HS | RPC_PHYCNT_WBUF2 | RPC_PHYCNT_WBUF | RPC_PHYCNT_PHYMEM_HYP); mem_write32(RPC_PHYCNT, reg); /* bit31 CAL = 1 : PHY calibration */ /* bit1-0 PHYMEM[1:0] = 00 : QSPI-SDR */ reg = mem_read32(RPC_CMNCR); reg &= ~(CMNCR_BSZ_MASK); reg |= (CMNCR_MD_MANUAL | CMNCR_MOIIO3_HIZ | CMNCR_MOIIO2_HIZ | CMNCR_MOIIO1_HIZ | CMNCR_MOIIO0_HIZ | CMNCR_IO0FV_HIZ); mem_write32(RPC_CMNCR, reg); /* bit31 MD = 1 : Manual mode */ /* bit1-0 BSZ[1:0] = 00 : QSPI Flash x 1 */ reg = mem_read32(RPC_SMCMR); reg &= ~(SMCMR_CMD_MASK | SMCMR_OCMD_MASK); reg |= ((gp_qspi_cmd_tbl -> parameter_4kbyte_erase) << DRCMR_SMCMR_CMD_SHIFT); mem_write32(RPC_SMCMR, reg); /* bit23-16 CMD[7:0] = 0x21 : Parameter 4-kB Sector Erasecommand */ mem_write32(RPC_SMADR, sector_addr); reg = mem_read32(RPC_SMDRENR); reg &= ~(SMDRENR_HYPE_MASK | SMDRENR_ADDRE | SMDRENR_OPDRE | SMDRENR_SPIDRE); mem_write32(RPC_SMDRENR, reg); /* bit8 ADDRE = 0 : Address SDR transfer */ /* bit0 SPIDRE = 0 : DATA SDR transfer */ reg = mem_read32(RPC_SMENR); reg &= ~(SMENR_CDB_MASK | SMENR_OCDB_MASK | SMENR_ADB_MASK | SMENR_OPDB_MASK | SMENR_SPIDB_MASK | SMENR_DME_EN | SMENR_OCDE_EN | SMENR_ADE_MASK | SMENR_OPDE_MASK | SMENR_SPIDE_MASK); reg |= (SMENR_CDE_EN | SMENR_ADE_SERIAL_31); mem_write32(RPC_SMENR, reg); /* bit31-30 CDB[1:0] = 00 : 1bit width command (QSPI0_MOSI) */ /* bit25-24 ADB[1:0] = 00 : 1bit width address (QSPI0_MOSI) */ /* bit17-16 SPIDB[1:0] = 00 : 1bit width transfer data (QSPI0_MISO) */ /* bit15 DME = 0 : No dummy cycle */ /* bit14 CDE = 1 : Command enable */ /* bit11-8 ADE[3:0] = 1111 : ADR[31:0] output (32 Bit Address) */ /* bit3-0 SPIDE[3:0] = 0000 : No transfer */ reg = mem_read32(RPC_SMCR); reg &= ~(SMCR_SSLKP | SMCR_SPIRE | SMCR_SPIWE); reg |= SMCR_SPIE; mem_write32(RPC_SMCR, reg); /* bit2 SPIRE = 0 : Data read disable */ /* bit1 SPIWE = 0 : Data write disable */ /* bit0 SPIE = 1 : SPI transfer start */ wait_rpc_tx_end(); } /* End of function parameter_sector_erase_4kb_qspi_flash */ /* Page Program (4PP:12h) 4-byte address */ void write_data_4pp_with_buf_qspi_flash(uint32_t addr, uint32_t source_addr) { uintptr_t i=0; uint32_t reg; reg = mem_read32(RPC_DRCR); reg |= (DRCR_SSLN | DRCR_RBURST_32UNITS | DRCR_RCF | DRCR_RBE_BURST | DRCR_SSLE); mem_write32(RPC_DRCR, reg); /* bit9 RCF = 1 : Read Cache Clear */ reg = mem_read32(RPC_PHYCNT); reg |= (RPC_PHYCNT_CAL | RPC_PHYCNT_STRTIM3 | RPC_PHYCNT_STRTIM2 | RPC_PHYCNT_STRTIM1 | RPC_PHYCNT_STRTIM0 | RPC_PHYCNT_WBUF2 | RPC_PHYCNT_WBUF); reg &= ~(RPC_PHYCNT_HS | RPC_PHYCNT_PHYMEM_HYP); mem_write32(RPC_PHYCNT, reg); /* bit31 CAL = 1 : PHY calibration */ /* bit2 WBUF = 1 : Write Buffer Enable */ /* bit1-0 PHYMEM[1:0] = 00 : QSPI-SDR */ for(i = 0; i < RPC_WRITE_BUF_SIZE; i = i + TRANS_SIZE_64BYTE) { dma2_start_xbyte(RPC_WRBUF_PHYS+i, source_addr+i, TRANS_SIZE_64BYTE, TRANS_UNIT_64BYTES); dma2_end(); // dma_trans_start(RPC_WRBUF_PHYS+i, source_addr+i, TRANS_SIZE_64BYTE); // dma_trans_end_check(); } reg = mem_read32(RPC_CMNCR); reg &= ~(CMNCR_BSZ_MASK); reg |= (CMNCR_MD_MANUAL | CMNCR_MOIIO3_HIZ | CMNCR_MOIIO2_HIZ | CMNCR_MOIIO1_HIZ | CMNCR_MOIIO0_HIZ | CMNCR_IO0FV_HIZ); mem_write32(RPC_CMNCR, reg); /* bit31 MD = 1 : Manual mode */ /* bit1-0 BSZ[1:0] = 00 : QSPI Flash x 1 */ reg = mem_read32(RPC_SMCMR); reg &= ~(SMCMR_CMD_MASK | SMCMR_OCMD_MASK); reg |= ((gp_qspi_cmd_tbl -> pp_4byte_addr) << DRCMR_SMCMR_CMD_SHIFT); mem_write32(RPC_SMCMR, reg); /* bit23-16 CMD[7:0] = 0x12 : Page Program 4-byte address */ mem_write32(RPC_SMADR, addr); reg = mem_read32(RPC_SMDRENR); reg &= ~(SMDRENR_HYPE_MASK | SMDRENR_ADDRE | SMDRENR_OPDRE | SMDRENR_SPIDRE); mem_write32(RPC_SMDRENR, reg); /* bit8 ADDRE = 0 : Address SDR transfer */ /* bit0 SPIDRE = 0 : DATA SDR transfer */ reg = mem_read32(RPC_SMENR); reg &= ~(SMENR_CDB_MASK | SMENR_OCDB_MASK | SMENR_ADB_MASK | SMENR_OPDB_MASK | SMENR_SPIDB_MASK | SMENR_DME_EN | SMENR_OCDE_EN | SMENR_ADE_MASK | SMENR_OPDE_MASK | SMENR_SPIDE_MASK); reg |= (SMENR_CDE_EN | SMENR_ADE_SERIAL_31 | SMENR_SPIDE_SPI_32); mem_write32(RPC_SMENR, reg); /* bit31-30 CDB[1:0] = 00 : 1bit width command (QSPI0_MOSI) */ /* bit25-24 ADB[1:0] = 00 : 1bit width address (QSPI0_MOSI) */ /* bit17-16 SPIDB[1:0] = 00 : 1bit width transfer data (QSPI0_MISO) */ /* bit15 DME = 0 : No dummy cycle */ /* bit14 CDE = 1 : Command enable */ /* bit11-8 ADE[3:0] = 1111 : ADR[31:0] is output */ /* bit3-0 SPIDE[3:0] = 1111 : 32bit transfer */ reg = mem_read32(RPC_SMCR); reg &= ~(SMCR_SSLKP | SMCR_SPIRE); reg |= (SMCR_SPIWE | SMCR_SPIE); mem_write32(RPC_SMCR, reg); /* bit2 SPIRE = 0 : Data read disable */ /* bit1 SPIWE = 1 : Data write enable */ /* bit0 SPIE = 1 : SPI transfer start */ wait_rpc_tx_end(); reg = mem_read32(RPC_PHYCNT); reg |= (RPC_PHYCNT_STRTIM3 | RPC_PHYCNT_STRTIM2 | RPC_PHYCNT_STRTIM1 | RPC_PHYCNT_STRTIM0 | RPC_PHYCNT_WBUF2); reg &= ~(RPC_PHYCNT_HS | RPC_PHYCNT_WBUF | RPC_PHYCNT_PHYMEM_HYP); mem_write32(RPC_PHYCNT, reg); /* bit31 CAL = 0 : No PHY calibration */ /* bit2 WBUF = 0 : Write Buffer Disable */ /* bit1-0 PHYMEM[1:0] = 00 : QSPI-SDR */ reg = mem_read32(RPC_DRCR); reg |= (DRCR_SSLN | DRCR_RBURST_32UNITS | DRCR_RCF | DRCR_RBE_BURST | DRCR_SSLE); mem_write32(RPC_DRCR, reg); /* bit9 RCF = 1 : Read Cache Clear */ } /* End of function write_data_4pp_with_buf_qspi_flash */ /* OnBoard QspiFlash(MT25QU01GB) */ uint32_t read_wip_status_register(uint32_t *readData) /* for QSPIx1ch */ { return read_register_qspi_flash(gp_qspi_cmd_tbl -> read_any_register, readData); } #define RDCR_cmd 0x15 uint32_t read_configuration_register(uint32_t *readData) /* for QSPIx1ch */ { return read_register_qspi_flash(RDCR_cmd, readData); } #define WRSR_cmd 0x01 void write_status_register(uint16_t stat_conf) { uint32_t reg; reg = mem_read32(RPC_PHYCNT); reg |= (RPC_PHYCNT_CAL | RPC_PHYCNT_STRTIM3 | RPC_PHYCNT_STRTIM2 | RPC_PHYCNT_STRTIM1 | RPC_PHYCNT_STRTIM0); reg &= ~(RPC_PHYCNT_HS | RPC_PHYCNT_WBUF2 | RPC_PHYCNT_WBUF | RPC_PHYCNT_PHYMEM_HYP); mem_write32(RPC_PHYCNT, reg); /* bit31 CAL = 1 : PHY calibration */ /* bit1-0 PHYMEM[1:0] = 00 : QSPI-SDR */ reg = mem_read32(RPC_CMNCR); reg &= ~(CMNCR_BSZ_MASK); reg |= (CMNCR_MD_MANUAL | CMNCR_MOIIO3_HIZ | CMNCR_MOIIO2_HIZ | CMNCR_MOIIO1_HIZ | CMNCR_MOIIO0_HIZ | CMNCR_IO0FV_HIZ); mem_write32(RPC_CMNCR, reg); /* bit31 MD = 1 : Manual mode */ /* bit1-0 BSZ[1:0] = 00 : QSPI Flash x 1 */ reg = mem_read32(RPC_SMCMR); reg &= ~(SMCMR_CMD_MASK | SMCMR_OCMD_MASK); reg |= ((WRSR_cmd) << DRCMR_SMCMR_CMD_SHIFT); mem_write32(RPC_SMCMR, reg); /* bit23-16 CMD[7:0] = 0x01 : write status/configuration register command */ reg = mem_read32(RPC_SMENR); reg &= ~(SMENR_CDB_MASK | SMENR_OCDB_MASK | SMENR_ADB_MASK | SMENR_OPDB_MASK | SMENR_SPIDB_MASK | SMENR_DME_EN | SMENR_OCDE_EN | SMENR_ADE_MASK | SMENR_OPDE_MASK | SMENR_SPIDE_MASK); reg |= (SMENR_CDE_EN | SMENR_SPIDE_SPI_16); mem_write32(RPC_SMENR, reg); /* bit31-30 CDB[1:0] = 00 : 1bit width command (QSPI0_MOSI) */ /* bit25-24 ADB[1:0] = 00 : 1bit width address (QSPI0_MOSI) */ /* bit17-16 SPIDB[1:0] = 00 : 1bit width transfer data (QSPI0_MISO) */ /* bit15 DME = 0 : No dummy cycle */ /* bit14 CDE = 1 : Command enable */ /* bit11-8 ADE[3:0] = 0000 : Address output disable */ /* bit3-0 SPIDE[3:0] = 1100 : 16bit transfer */ mem_write16(RPC_SMWDR0, stat_conf); reg = mem_read32(RPC_SMCR); reg &= ~(SMCR_SSLKP | SMCR_SPIRE); reg |= (SMCR_SPIWE | SMCR_SPIE); mem_write32(RPC_SMCR, reg); /* bit2 SPIRE = 0 : Data read disable */ /* bit1 SPIWE = 1 : Data write enable */ /* bit0 SPIE = 1 : SPI transfer start */ wait_rpc_tx_end(); } void set_rpc_clock_mode(uint32_t mode) { uint32_t dataL=0; uint32_t reg; if(mode == RPC_CLK_160M){ dataL = RPCCKCR_RPCFC_160M; /* RPC clock 160MHz */ }else if(mode == RPC_CLK_80M){ dataL = RPCCKCR_RPCFC_80M; /* RPC clock 80MHz */ }else{ dataL = RPCCKCR_RPCFC_40M; /* RPC clock 40MHz */ } reg = mem_read32(CPG_RPCCKCR); reg &= ~(RPCCKCR_RPCFC_MASK); dataL |= reg; mem_write32(CPG_CPGWPR, ~dataL); mem_write32(CPG_RPCCKCR, dataL); (void)mem_read32(CPG_RPCCKCR); /* dummy read */ } /* End of function set_rpc_clock_mode */ void wait_rpc_tx_end(void) { uint32_t dataL=0; while(1) { wdt_restart(); dataL = mem_read32(RPC_CMNSR); if(dataL & BIT0) break; /* Wait for TEND = 1 */ } } /* End of function wait_rpc_tx_end */ void reset_rpc(void) { mem_write32(CPG_CPGWPR, ~BIT29); mem_write32(CPG_SRCR6, BIT29); /* wait: tRLRH Reset# low pulse width 10us */ micro_wait(20); /* wait 20us */ mem_write32(CPG_CPGWPR, ~BIT29); mem_write32(CPG_SRSTCLR6, BIT29); /* wait: tREADY1(35us) - tRHSL(10us) = 25us */ micro_wait(40); /* wait 40us */ } /* End of function reset_rpc */ void set_rpc_ssl_delay(void) { uint32_t reg; reg = mem_read32(RPC_SSLDR); reg |= SSLDR_SLNDL; mem_write32(RPC_SSLDR, reg); /* bit10-8 SLNDL[2:0] = 100 : 5.5 cycles of QSPIn_SPCLK */ } /* End of function set_rpc_ssl_delay */ void power_on_rpc(void) { uint32_t dataL=0; dataL = mem_read32(CPG_MSTPSR6); if(dataL & BIT29){ /* case RPC(QSPI) Standby */ dataL &= ~BIT29; mem_write32(CPG_CPGWPR, ~dataL); mem_write32(CPG_MSTPCR6, dataL); while( BIT29 & mem_read32(CPG_MSTPSR6) ); /* wait bit=0 */ } } /* End of function power_on_rpc */ uint32_t read_qspi_flash_id(uint32_t *readData) /* for QSPIx1ch */ { return read_register_qspi_flash(FLASH_CMD_READ_ID, readData); } uint32_t read_status_qspi_flash(uint32_t *readData) { return read_register_qspi_flash(gp_qspi_cmd_tbl -> read_stts_register, readData); } static uint32_t read_register_qspi_flash(uint32_t cmd, uint32_t *readData) /* for QSPIx1ch */ { uint32_t reg; reg = mem_read32(RPC_PHYCNT); reg |= (RPC_PHYCNT_STRTIM3 | RPC_PHYCNT_STRTIM2 | RPC_PHYCNT_STRTIM1 | RPC_PHYCNT_STRTIM0); reg &= ~(RPC_PHYCNT_HS | RPC_PHYCNT_WBUF2 | RPC_PHYCNT_WBUF | RPC_PHYCNT_PHYMEM_HYP); mem_write32(RPC_PHYCNT, reg); reg |= RPC_PHYCNT_CAL; mem_write32(RPC_PHYCNT, reg); /* bit31 CAL = 1 : PHY calibration */ /* bit1-0 PHYMEM[1:0] = 00 : QSPI-SDR */ reg = mem_read32(RPC_CMNCR); reg &= ~(CMNCR_BSZ_MASK); reg |= (CMNCR_MD_MANUAL | CMNCR_MOIIO3_HIZ | CMNCR_MOIIO2_HIZ | CMNCR_MOIIO1_HIZ | CMNCR_MOIIO0_HIZ | CMNCR_IO0FV_HIZ); mem_write32(RPC_CMNCR, reg); /* bit31 MD = 1 : Manual mode */ /* bit1-0 BSZ[1:0] = 00 : QSPI Flash x 1 */ reg = mem_read32(RPC_SMCMR); reg &= ~(SMCMR_CMD_MASK | SMCMR_OCMD_MASK); reg |= ((cmd) << DRCMR_SMCMR_CMD_SHIFT); mem_write32(RPC_SMCMR, reg); /* bit23-16 CMD[7:0] = 0x05 : Status Read command (for Palladium QSPI model) */ reg = mem_read32(RPC_SMDRENR); reg &= ~(SMDRENR_HYPE_MASK | SMDRENR_ADDRE | SMDRENR_OPDRE | SMDRENR_SPIDRE); mem_write32(RPC_SMDRENR, reg); /* bit8 ADDRE = 0 : Address SDR transfer */ /* bit0 SPIDRE = 0 : DATA SDR transfer */ reg = mem_read32(RPC_SMENR); reg &= ~(SMENR_CDB_MASK | SMENR_OCDB_MASK | SMENR_ADB_MASK | SMENR_OPDB_MASK | SMENR_SPIDB_MASK | SMENR_DME_EN | SMENR_OCDE_EN | SMENR_ADE_MASK | SMENR_OPDE_MASK | SMENR_SPIDE_MASK); reg |= (SMENR_CDE_EN | SMENR_SPIDE_SPI_32); mem_write32(RPC_SMENR, reg); /* bit31-30 CDB[1:0] = 00 : 1bit width command (QSPI0_MOSI) */ /* bit25-24 ADB[1:0] = 00 : 1bit width address (QSPI0_MOSI) */ /* bit17-16 SPIDB[1:0] = 00 : 1bit width transfer data (QSPI0_MISO) */ /* bit15 DME = 0 : No dummy cycle */ /* bit14 CDE = 1 : Command enable */ /* bit11-8 ADE[3:0] = 0000 : Address output disable */ /* bit3-0 SPIDE[3:0] = 1111 : 32bit transfer */ reg = mem_read32(RPC_SMCR); reg &= ~(SMCR_SSLKP | SMCR_SPIWE); reg |= (SMCR_SPIRE | SMCR_SPIE); mem_write32(RPC_SMCR, reg); /* bit2 SPIRE = 1 : Data read enable */ /* bit1 SPIWE = 0 : Data write disable */ /* bit0 SPIE = 1 : SPI transfer start */ wait_rpc_tx_end(); readData[0] = mem_read32(RPC_SMRDR0); /* read data[31:0] */ return(readData[0]); } /* End of function read_register_qspi_flash */ void write_command_qspi_flash(uint32_t command) /* for QSPIx1ch */ { uint32_t reg; reg = mem_read32(RPC_PHYCNT); reg |= (RPC_PHYCNT_CAL | RPC_PHYCNT_STRTIM3 | RPC_PHYCNT_STRTIM2 | RPC_PHYCNT_STRTIM1 | RPC_PHYCNT_STRTIM0); reg &= ~(RPC_PHYCNT_HS | RPC_PHYCNT_WBUF2 | RPC_PHYCNT_WBUF | RPC_PHYCNT_PHYMEM_HYP); mem_write32(RPC_PHYCNT, reg); /* bit31 CAL = 1 : PHY calibration */ /* bit1-0 PHYMEM[1:0] = 00 : QSPI-SDR */ reg = mem_read32(RPC_CMNCR); reg &= ~(CMNCR_BSZ_MASK); reg |= (CMNCR_MD_MANUAL | CMNCR_MOIIO3_HIZ | CMNCR_MOIIO2_HIZ | CMNCR_MOIIO1_HIZ | CMNCR_MOIIO0_HIZ | CMNCR_IO0FV_HIZ); mem_write32(RPC_CMNCR, reg); /* bit31 MD = 1 : Manual mode */ /* bit1-0 BSZ[1:0] = 00 : QSPI Flash x 1 */ reg = mem_read32(RPC_SMCMR); reg &= ~(SMCMR_CMD_MASK | SMCMR_OCMD_MASK); reg |= (command & (SMCMR_CMD_MASK | SMCMR_OCMD_MASK)); mem_write32(RPC_SMCMR, reg); /* bit23-16 CMD[7:0] : command */ reg = mem_read32(RPC_SMDRENR); reg &= ~(SMDRENR_HYPE_MASK | SMDRENR_ADDRE | SMDRENR_OPDRE | SMDRENR_SPIDRE); mem_write32(RPC_SMDRENR, reg); /* bit8 ADDRE = 0 : Address SDR transfer */ /* bit0 SPIDRE = 0 : DATA SDR transfer */ reg = mem_read32(RPC_SMENR); reg &= ~(SMENR_CDB_MASK | SMENR_OCDB_MASK | SMENR_ADB_MASK | SMENR_OPDB_MASK | SMENR_SPIDB_MASK | SMENR_DME_EN | SMENR_OCDE_EN | SMENR_ADE_MASK | SMENR_ADE_MASK | SMENR_OPDE_MASK | SMENR_SPIDE_MASK); reg |= SMENR_CDE_EN; mem_write32(RPC_SMENR, reg); /* bit31-30 CDB[1:0] = 00 : 1bit width command (QSPI0_MOSI) */ /* bit25-24 ADB[1:0] = 00 : 1bit width address (QSPI0_MOSI) */ /* bit17-16 SPIDB[1:0] = 00 : 1bit width transfer data (QSPI0_MISO) */ /* bit15 DME = 0 : No dummy cycle */ /* bit14 CDE = 1 : Command enable */ /* bit11-8 ADE[3:0] = 0000 : Address output disable */ /* bit3-0 SPIDE[3:0] = 0000 : No transfer */ reg = mem_read32(RPC_SMCR); reg &= ~(SMCR_SSLKP | SMCR_SPIRE | SMCR_SPIWE); reg |= SMCR_SPIE; mem_write32(RPC_SMCR, reg); /* bit2 SPIRE = 0 : Data read disable */ /* bit1 SPIWE = 0 : Data write disable */ /* bit0 SPIE = 1 : SPI transfer start */ wait_rpc_tx_end(); } /* End of function write_command_qspi_flash */