mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
targets/TARGET_RENESAS/TARGET_RZ_A1XX/flash_api.c@189:f392fc9709a3, 2019-02-20 (annotated)
- Committer:
- AnnaBridge
- Date:
- Wed Feb 20 22:31:08 2019 +0000
- Revision:
- 189:f392fc9709a3
- Parent:
- 188:bcfe06ba3d64
mbed library release version 165
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AnnaBridge | 187:0387e8f68319 | 1 | /* mbed Microcontroller Library |
AnnaBridge | 187:0387e8f68319 | 2 | * Copyright (c) 2018 ARM Limited |
AnnaBridge | 187:0387e8f68319 | 3 | * |
AnnaBridge | 187:0387e8f68319 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
AnnaBridge | 187:0387e8f68319 | 5 | * you may not use this file except in compliance with the License. |
AnnaBridge | 187:0387e8f68319 | 6 | * You may obtain a copy of the License at |
AnnaBridge | 187:0387e8f68319 | 7 | * |
AnnaBridge | 187:0387e8f68319 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
AnnaBridge | 187:0387e8f68319 | 9 | * |
AnnaBridge | 187:0387e8f68319 | 10 | * Unless required by applicable law or agreed to in writing, software |
AnnaBridge | 187:0387e8f68319 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
AnnaBridge | 187:0387e8f68319 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
AnnaBridge | 187:0387e8f68319 | 13 | * See the License for the specific language governing permissions and |
AnnaBridge | 187:0387e8f68319 | 14 | * limitations under the License. |
AnnaBridge | 187:0387e8f68319 | 15 | */ |
AnnaBridge | 187:0387e8f68319 | 16 | |
AnnaBridge | 187:0387e8f68319 | 17 | #include "flash_api.h" |
AnnaBridge | 187:0387e8f68319 | 18 | #include "mbed_critical.h" |
AnnaBridge | 187:0387e8f68319 | 19 | |
AnnaBridge | 187:0387e8f68319 | 20 | #if DEVICE_FLASH |
AnnaBridge | 188:bcfe06ba3d64 | 21 | #include <string.h> |
AnnaBridge | 187:0387e8f68319 | 22 | #include "iodefine.h" |
AnnaBridge | 187:0387e8f68319 | 23 | #include "spibsc_iobitmask.h" |
AnnaBridge | 187:0387e8f68319 | 24 | #include "spibsc.h" |
AnnaBridge | 187:0387e8f68319 | 25 | #include "mbed_drv_cfg.h" |
AnnaBridge | 187:0387e8f68319 | 26 | |
AnnaBridge | 187:0387e8f68319 | 27 | /* ---- serial flash command ---- */ |
AnnaBridge | 188:bcfe06ba3d64 | 28 | #if (FLASH_SIZE > 0x1000000) |
AnnaBridge | 188:bcfe06ba3d64 | 29 | #define SPIBSC_OUTPUT_ADDR SPIBSC_OUTPUT_ADDR_32 |
AnnaBridge | 188:bcfe06ba3d64 | 30 | #define SFLASHCMD_SECTOR_ERASE (0x21u) /* SE4B 4-byte address(1bit) */ |
AnnaBridge | 188:bcfe06ba3d64 | 31 | #define SFLASHCMD_PAGE_PROGRAM (0x12u) /* PP4B 4-byte address(1bit), data(1bit) */ |
AnnaBridge | 188:bcfe06ba3d64 | 32 | #else |
AnnaBridge | 188:bcfe06ba3d64 | 33 | #define SPIBSC_OUTPUT_ADDR SPIBSC_OUTPUT_ADDR_24 |
AnnaBridge | 187:0387e8f68319 | 34 | #define SFLASHCMD_SECTOR_ERASE (0x20u) /* SE 3-byte address(1bit) */ |
AnnaBridge | 187:0387e8f68319 | 35 | #define SFLASHCMD_PAGE_PROGRAM (0x02u) /* PP 3-byte address(1bit), data(1bit) */ |
AnnaBridge | 188:bcfe06ba3d64 | 36 | #endif |
AnnaBridge | 187:0387e8f68319 | 37 | #define SFLASHCMD_READ_STATUS_REG (0x05u) /* RDSR data(1bit) */ |
AnnaBridge | 187:0387e8f68319 | 38 | #define SFLASHCMD_WRITE_ENABLE (0x06u) /* WREN */ |
AnnaBridge | 187:0387e8f68319 | 39 | /* ---- serial flash register definitions ---- */ |
AnnaBridge | 187:0387e8f68319 | 40 | #define STREG_BUSY_BIT (0x01u) /* SR.[0]BUSY Erase/Write In Progress (RO) */ |
AnnaBridge | 187:0387e8f68319 | 41 | |
AnnaBridge | 187:0387e8f68319 | 42 | /* Definition of the base address for the MMU translation table */ |
AnnaBridge | 187:0387e8f68319 | 43 | #if defined(__CC_ARM) || defined(__GNUC__) |
AnnaBridge | 187:0387e8f68319 | 44 | extern uint32_t Image$$TTB$$ZI$$Base; |
AnnaBridge | 187:0387e8f68319 | 45 | #define TTB ((uint32_t)&Image$$TTB$$ZI$$Base) /* using linker symbol */ |
AnnaBridge | 187:0387e8f68319 | 46 | #elif defined(__ICCARM__) |
AnnaBridge | 187:0387e8f68319 | 47 | #pragma section="TTB" |
AnnaBridge | 187:0387e8f68319 | 48 | #define TTB ((uint32_t)__section_begin("TTB")) |
AnnaBridge | 187:0387e8f68319 | 49 | #endif |
AnnaBridge | 187:0387e8f68319 | 50 | |
AnnaBridge | 187:0387e8f68319 | 51 | typedef struct { |
AnnaBridge | 187:0387e8f68319 | 52 | uint32_t cdb; /* bit-width : command */ |
AnnaBridge | 187:0387e8f68319 | 53 | uint32_t ocdb; /* bit-width : optional command */ |
AnnaBridge | 187:0387e8f68319 | 54 | uint32_t adb; /* bit-width : address */ |
AnnaBridge | 187:0387e8f68319 | 55 | uint32_t opdb; /* bit-width : option data */ |
AnnaBridge | 187:0387e8f68319 | 56 | uint32_t spidb; /* bit-width : data */ |
AnnaBridge | 187:0387e8f68319 | 57 | |
AnnaBridge | 187:0387e8f68319 | 58 | uint32_t cde; /* Enable : command */ |
AnnaBridge | 187:0387e8f68319 | 59 | uint32_t ocde; /* Enable : optional command */ |
AnnaBridge | 187:0387e8f68319 | 60 | uint32_t ade; /* Enable : address */ |
AnnaBridge | 187:0387e8f68319 | 61 | uint32_t opde; /* Enable : option data */ |
AnnaBridge | 187:0387e8f68319 | 62 | uint32_t spide; /* Enable : data */ |
AnnaBridge | 187:0387e8f68319 | 63 | |
AnnaBridge | 187:0387e8f68319 | 64 | uint32_t sslkp; /* SPBSSL level */ |
AnnaBridge | 187:0387e8f68319 | 65 | uint32_t spire; /* Enable data read */ |
AnnaBridge | 187:0387e8f68319 | 66 | uint32_t spiwe; /* Enable data write */ |
AnnaBridge | 187:0387e8f68319 | 67 | |
AnnaBridge | 187:0387e8f68319 | 68 | uint32_t dme; /* Enable : dummy cycle */ |
AnnaBridge | 187:0387e8f68319 | 69 | |
AnnaBridge | 187:0387e8f68319 | 70 | uint32_t addre; /* DDR enable : address */ |
AnnaBridge | 187:0387e8f68319 | 71 | uint32_t opdre; /* DDR enable : option data */ |
AnnaBridge | 187:0387e8f68319 | 72 | uint32_t spidre; /* DDR enable : data */ |
AnnaBridge | 187:0387e8f68319 | 73 | |
AnnaBridge | 187:0387e8f68319 | 74 | uint8_t dmdb; /* bit-width : dummy cycle */ |
AnnaBridge | 187:0387e8f68319 | 75 | uint8_t dmcyc; /* number of dummy cycles */ |
AnnaBridge | 187:0387e8f68319 | 76 | |
AnnaBridge | 187:0387e8f68319 | 77 | uint8_t cmd; /* command */ |
AnnaBridge | 187:0387e8f68319 | 78 | uint8_t ocmd; /* optional command */ |
AnnaBridge | 187:0387e8f68319 | 79 | uint32_t addr; /* address */ |
AnnaBridge | 187:0387e8f68319 | 80 | uint8_t opd[4]; /* option data 3/2/1/0 */ |
AnnaBridge | 187:0387e8f68319 | 81 | uint32_t smrdr[2]; /* read data */ |
AnnaBridge | 187:0387e8f68319 | 82 | uint32_t smwdr[2]; /* write data */ |
AnnaBridge | 187:0387e8f68319 | 83 | } st_spibsc_spimd_reg_t; |
AnnaBridge | 187:0387e8f68319 | 84 | |
AnnaBridge | 187:0387e8f68319 | 85 | typedef struct { |
AnnaBridge | 187:0387e8f68319 | 86 | uint32_t b0 : 1 ; /* bit 0 : - (0) */ |
AnnaBridge | 187:0387e8f68319 | 87 | uint32_t b1 : 1 ; /* bit 1 : - (1) */ |
AnnaBridge | 187:0387e8f68319 | 88 | uint32_t B : 1 ; /* bit 2 : B Memory region attribute bit */ |
AnnaBridge | 187:0387e8f68319 | 89 | uint32_t C : 1 ; /* bit 3 : C Memory region attribute bit */ |
AnnaBridge | 187:0387e8f68319 | 90 | uint32_t XN : 1 ; /* bit 4 : XN Execute-never bit */ |
AnnaBridge | 187:0387e8f68319 | 91 | uint32_t Domain : 4 ; /* bit 8-5 : Domain Domain field */ |
AnnaBridge | 187:0387e8f68319 | 92 | uint32_t b9 : 1 ; /* bit 9 : IMP IMPLEMENTATION DEFINED */ |
AnnaBridge | 187:0387e8f68319 | 93 | uint32_t AP1_0 : 2 ; /* bit 11-10 : AP[1:0] Access permissions bits:bit1-0 */ |
AnnaBridge | 187:0387e8f68319 | 94 | uint32_t TEX : 3 ; /* bit 14-12 : TEX[2:0] Memory region attribute bits */ |
AnnaBridge | 187:0387e8f68319 | 95 | uint32_t AP2 : 1 ; /* bit 15 : AP[2] Access permissions bits:bit2 */ |
AnnaBridge | 187:0387e8f68319 | 96 | uint32_t S : 1 ; /* bit 16 : S Shareable bit */ |
AnnaBridge | 187:0387e8f68319 | 97 | uint32_t nG : 1 ; /* bit 17 : nG Not global bit */ |
AnnaBridge | 187:0387e8f68319 | 98 | uint32_t b18 : 1 ; /* bit 18 : - (0) */ |
AnnaBridge | 187:0387e8f68319 | 99 | uint32_t NS : 1 ; /* bit 19 : NS Non-secure bit */ |
AnnaBridge | 187:0387e8f68319 | 100 | uint32_t base_addr : 12; /* bit 31-20 : PA[31:20] PA(physical address) bits:bit31-20 */ |
AnnaBridge | 187:0387e8f68319 | 101 | } mmu_ttbl_desc_section_t; |
AnnaBridge | 187:0387e8f68319 | 102 | |
AnnaBridge | 188:bcfe06ba3d64 | 103 | static mmu_ttbl_desc_section_t desc_tbl[(FLASH_SIZE >> 20)]; |
AnnaBridge | 187:0387e8f68319 | 104 | static volatile struct st_spibsc* SPIBSC = &SPIBSC0; |
AnnaBridge | 187:0387e8f68319 | 105 | static st_spibsc_spimd_reg_t spimd_reg; |
AnnaBridge | 188:bcfe06ba3d64 | 106 | static uint8_t write_tmp_buf[FLASH_PAGE_SIZE]; |
AnnaBridge | 187:0387e8f68319 | 107 | |
AnnaBridge | 187:0387e8f68319 | 108 | #if defined(__ICCARM__) |
AnnaBridge | 187:0387e8f68319 | 109 | #define RAM_CODE_SEC __ramfunc |
AnnaBridge | 187:0387e8f68319 | 110 | #else |
AnnaBridge | 187:0387e8f68319 | 111 | #define RAM_CODE_SEC __attribute__((section("RAM_CODE"))) |
AnnaBridge | 187:0387e8f68319 | 112 | #endif |
AnnaBridge | 187:0387e8f68319 | 113 | |
AnnaBridge | 187:0387e8f68319 | 114 | /* Global function for optimization */ |
AnnaBridge | 187:0387e8f68319 | 115 | RAM_CODE_SEC int32_t _sector_erase(uint32_t addr); |
AnnaBridge | 187:0387e8f68319 | 116 | RAM_CODE_SEC int32_t _page_program(uint32_t addr, const uint8_t * buf, int32_t size); |
AnnaBridge | 187:0387e8f68319 | 117 | |
AnnaBridge | 187:0387e8f68319 | 118 | static RAM_CODE_SEC int32_t write_enable(void); |
AnnaBridge | 187:0387e8f68319 | 119 | static RAM_CODE_SEC int32_t busy_wait(void); |
AnnaBridge | 187:0387e8f68319 | 120 | static RAM_CODE_SEC int32_t read_register(uint8_t cmd, uint8_t * status); |
AnnaBridge | 187:0387e8f68319 | 121 | static RAM_CODE_SEC int32_t data_send(uint32_t bit_width, uint32_t spbssl_level, const uint8_t * buf, int32_t size); |
AnnaBridge | 187:0387e8f68319 | 122 | static RAM_CODE_SEC void spi_mode(void); |
AnnaBridge | 187:0387e8f68319 | 123 | static RAM_CODE_SEC void ex_mode(void); |
AnnaBridge | 187:0387e8f68319 | 124 | static RAM_CODE_SEC void clear_spimd_reg(st_spibsc_spimd_reg_t * regset); |
AnnaBridge | 187:0387e8f68319 | 125 | static RAM_CODE_SEC int32_t spibsc_transfer(st_spibsc_spimd_reg_t * regset); |
AnnaBridge | 187:0387e8f68319 | 126 | static RAM_CODE_SEC uint32_t RegRead_32(volatile uint32_t * ioreg, uint32_t shift, uint32_t mask); |
AnnaBridge | 187:0387e8f68319 | 127 | static RAM_CODE_SEC void RegWwrite_32(volatile uint32_t * ioreg, uint32_t write_value, uint32_t shift, uint32_t mask); |
AnnaBridge | 187:0387e8f68319 | 128 | static RAM_CODE_SEC void change_mmu_ttbl_spibsc(uint32_t type); |
AnnaBridge | 187:0387e8f68319 | 129 | static RAM_CODE_SEC void spibsc_stop(void); |
AnnaBridge | 187:0387e8f68319 | 130 | static RAM_CODE_SEC void cache_control(void); |
AnnaBridge | 187:0387e8f68319 | 131 | |
AnnaBridge | 187:0387e8f68319 | 132 | int32_t flash_init(flash_t *obj) |
AnnaBridge | 187:0387e8f68319 | 133 | { |
AnnaBridge | 187:0387e8f68319 | 134 | return 0; |
AnnaBridge | 187:0387e8f68319 | 135 | } |
AnnaBridge | 187:0387e8f68319 | 136 | |
AnnaBridge | 187:0387e8f68319 | 137 | int32_t flash_free(flash_t *obj) |
AnnaBridge | 187:0387e8f68319 | 138 | { |
AnnaBridge | 187:0387e8f68319 | 139 | return 0; |
AnnaBridge | 187:0387e8f68319 | 140 | } |
AnnaBridge | 187:0387e8f68319 | 141 | |
AnnaBridge | 187:0387e8f68319 | 142 | int32_t flash_erase_sector(flash_t *obj, uint32_t address) |
AnnaBridge | 187:0387e8f68319 | 143 | { |
AnnaBridge | 188:bcfe06ba3d64 | 144 | return _sector_erase(address - FLASH_BASE); |
AnnaBridge | 187:0387e8f68319 | 145 | } |
AnnaBridge | 187:0387e8f68319 | 146 | |
AnnaBridge | 187:0387e8f68319 | 147 | int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size) |
AnnaBridge | 187:0387e8f68319 | 148 | { |
AnnaBridge | 188:bcfe06ba3d64 | 149 | return _page_program(address - FLASH_BASE, data, size); |
AnnaBridge | 187:0387e8f68319 | 150 | } |
AnnaBridge | 187:0387e8f68319 | 151 | |
AnnaBridge | 187:0387e8f68319 | 152 | uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) |
AnnaBridge | 187:0387e8f68319 | 153 | { |
AnnaBridge | 187:0387e8f68319 | 154 | if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) { |
AnnaBridge | 187:0387e8f68319 | 155 | return MBED_FLASH_INVALID_SIZE; |
AnnaBridge | 187:0387e8f68319 | 156 | } |
AnnaBridge | 187:0387e8f68319 | 157 | |
AnnaBridge | 187:0387e8f68319 | 158 | return FLASH_SECTOR_SIZE; |
AnnaBridge | 187:0387e8f68319 | 159 | } |
AnnaBridge | 187:0387e8f68319 | 160 | |
AnnaBridge | 187:0387e8f68319 | 161 | uint32_t flash_get_page_size(const flash_t *obj) |
AnnaBridge | 187:0387e8f68319 | 162 | { |
AnnaBridge | 188:bcfe06ba3d64 | 163 | return 8; |
AnnaBridge | 187:0387e8f68319 | 164 | } |
AnnaBridge | 187:0387e8f68319 | 165 | |
AnnaBridge | 187:0387e8f68319 | 166 | uint32_t flash_get_start_address(const flash_t *obj) |
AnnaBridge | 187:0387e8f68319 | 167 | { |
AnnaBridge | 187:0387e8f68319 | 168 | return FLASH_BASE; |
AnnaBridge | 187:0387e8f68319 | 169 | } |
AnnaBridge | 187:0387e8f68319 | 170 | |
AnnaBridge | 187:0387e8f68319 | 171 | uint32_t flash_get_size(const flash_t *obj) |
AnnaBridge | 187:0387e8f68319 | 172 | { |
AnnaBridge | 187:0387e8f68319 | 173 | return FLASH_SIZE; |
AnnaBridge | 187:0387e8f68319 | 174 | } |
AnnaBridge | 187:0387e8f68319 | 175 | |
AnnaBridge | 187:0387e8f68319 | 176 | int32_t _sector_erase(uint32_t addr) |
AnnaBridge | 187:0387e8f68319 | 177 | { |
AnnaBridge | 187:0387e8f68319 | 178 | int32_t ret; |
AnnaBridge | 187:0387e8f68319 | 179 | |
AnnaBridge | 188:bcfe06ba3d64 | 180 | core_util_critical_section_enter(); |
AnnaBridge | 187:0387e8f68319 | 181 | spi_mode(); |
AnnaBridge | 187:0387e8f68319 | 182 | |
AnnaBridge | 187:0387e8f68319 | 183 | /* ---- Write enable ---- */ |
AnnaBridge | 187:0387e8f68319 | 184 | ret = write_enable(); /* WREN Command */ |
AnnaBridge | 187:0387e8f68319 | 185 | if (ret != 0) { |
AnnaBridge | 187:0387e8f68319 | 186 | ex_mode(); |
AnnaBridge | 188:bcfe06ba3d64 | 187 | core_util_critical_section_exit(); |
AnnaBridge | 187:0387e8f68319 | 188 | return ret; |
AnnaBridge | 187:0387e8f68319 | 189 | } |
AnnaBridge | 187:0387e8f68319 | 190 | |
AnnaBridge | 187:0387e8f68319 | 191 | /* ---- spimd_reg init ---- */ |
AnnaBridge | 187:0387e8f68319 | 192 | clear_spimd_reg(&spimd_reg); |
AnnaBridge | 187:0387e8f68319 | 193 | |
AnnaBridge | 187:0387e8f68319 | 194 | /* ---- command ---- */ |
AnnaBridge | 187:0387e8f68319 | 195 | spimd_reg.cde = SPIBSC_OUTPUT_ENABLE; |
AnnaBridge | 187:0387e8f68319 | 196 | spimd_reg.cdb = SPIBSC_1BIT; |
AnnaBridge | 187:0387e8f68319 | 197 | spimd_reg.cmd = SFLASHCMD_SECTOR_ERASE; |
AnnaBridge | 187:0387e8f68319 | 198 | |
AnnaBridge | 187:0387e8f68319 | 199 | /* ---- address ---- */ |
AnnaBridge | 188:bcfe06ba3d64 | 200 | spimd_reg.ade = SPIBSC_OUTPUT_ADDR; |
AnnaBridge | 187:0387e8f68319 | 201 | spimd_reg.addre = SPIBSC_SDR_TRANS; /* SDR */ |
AnnaBridge | 187:0387e8f68319 | 202 | spimd_reg.adb = SPIBSC_1BIT; |
AnnaBridge | 187:0387e8f68319 | 203 | spimd_reg.addr = addr; |
AnnaBridge | 187:0387e8f68319 | 204 | |
AnnaBridge | 187:0387e8f68319 | 205 | ret = spibsc_transfer(&spimd_reg); |
AnnaBridge | 187:0387e8f68319 | 206 | if (ret != 0) { |
AnnaBridge | 187:0387e8f68319 | 207 | ex_mode(); |
AnnaBridge | 188:bcfe06ba3d64 | 208 | core_util_critical_section_exit(); |
AnnaBridge | 187:0387e8f68319 | 209 | return ret; |
AnnaBridge | 187:0387e8f68319 | 210 | } |
AnnaBridge | 187:0387e8f68319 | 211 | |
AnnaBridge | 187:0387e8f68319 | 212 | ret = busy_wait(); |
AnnaBridge | 187:0387e8f68319 | 213 | |
AnnaBridge | 187:0387e8f68319 | 214 | ex_mode(); |
AnnaBridge | 188:bcfe06ba3d64 | 215 | core_util_critical_section_exit(); |
AnnaBridge | 187:0387e8f68319 | 216 | return ret; |
AnnaBridge | 187:0387e8f68319 | 217 | } |
AnnaBridge | 187:0387e8f68319 | 218 | |
AnnaBridge | 187:0387e8f68319 | 219 | int32_t _page_program(uint32_t addr, const uint8_t * buf, int32_t size) |
AnnaBridge | 187:0387e8f68319 | 220 | { |
AnnaBridge | 187:0387e8f68319 | 221 | int32_t ret; |
AnnaBridge | 187:0387e8f68319 | 222 | int32_t program_size; |
AnnaBridge | 187:0387e8f68319 | 223 | int32_t remainder; |
AnnaBridge | 187:0387e8f68319 | 224 | int32_t idx = 0; |
AnnaBridge | 187:0387e8f68319 | 225 | |
AnnaBridge | 187:0387e8f68319 | 226 | while (size > 0) { |
AnnaBridge | 187:0387e8f68319 | 227 | if (size > FLASH_PAGE_SIZE) { |
AnnaBridge | 187:0387e8f68319 | 228 | program_size = FLASH_PAGE_SIZE; |
AnnaBridge | 187:0387e8f68319 | 229 | } else { |
AnnaBridge | 187:0387e8f68319 | 230 | program_size = size; |
AnnaBridge | 187:0387e8f68319 | 231 | } |
AnnaBridge | 187:0387e8f68319 | 232 | remainder = FLASH_PAGE_SIZE - (addr % FLASH_PAGE_SIZE); |
AnnaBridge | 187:0387e8f68319 | 233 | if ((remainder != 0) && (program_size > remainder)) { |
AnnaBridge | 187:0387e8f68319 | 234 | program_size = remainder; |
AnnaBridge | 187:0387e8f68319 | 235 | } |
AnnaBridge | 187:0387e8f68319 | 236 | |
AnnaBridge | 188:bcfe06ba3d64 | 237 | core_util_critical_section_enter(); |
AnnaBridge | 188:bcfe06ba3d64 | 238 | memcpy(write_tmp_buf, &buf[idx], program_size); |
AnnaBridge | 188:bcfe06ba3d64 | 239 | spi_mode(); |
AnnaBridge | 188:bcfe06ba3d64 | 240 | |
AnnaBridge | 187:0387e8f68319 | 241 | /* ---- Write enable ---- */ |
AnnaBridge | 187:0387e8f68319 | 242 | ret = write_enable(); /* WREN Command */ |
AnnaBridge | 187:0387e8f68319 | 243 | if (ret != 0) { |
AnnaBridge | 187:0387e8f68319 | 244 | ex_mode(); |
AnnaBridge | 188:bcfe06ba3d64 | 245 | core_util_critical_section_exit(); |
AnnaBridge | 187:0387e8f68319 | 246 | return ret; |
AnnaBridge | 187:0387e8f68319 | 247 | } |
AnnaBridge | 187:0387e8f68319 | 248 | |
AnnaBridge | 187:0387e8f68319 | 249 | /* ----------- 1. Command, Address ---------------*/ |
AnnaBridge | 187:0387e8f68319 | 250 | /* ---- spimd_reg init ---- */ |
AnnaBridge | 187:0387e8f68319 | 251 | clear_spimd_reg(&spimd_reg); |
AnnaBridge | 187:0387e8f68319 | 252 | |
AnnaBridge | 187:0387e8f68319 | 253 | /* ---- command ---- */ |
AnnaBridge | 187:0387e8f68319 | 254 | spimd_reg.cde = SPIBSC_OUTPUT_ENABLE; |
AnnaBridge | 187:0387e8f68319 | 255 | spimd_reg.cdb = SPIBSC_1BIT; |
AnnaBridge | 187:0387e8f68319 | 256 | spimd_reg.cmd = SFLASHCMD_PAGE_PROGRAM; |
AnnaBridge | 187:0387e8f68319 | 257 | |
AnnaBridge | 187:0387e8f68319 | 258 | /* ---- address ---- */ |
AnnaBridge | 188:bcfe06ba3d64 | 259 | spimd_reg.ade = SPIBSC_OUTPUT_ADDR; |
AnnaBridge | 187:0387e8f68319 | 260 | spimd_reg.addre = SPIBSC_SDR_TRANS; /* SDR */ |
AnnaBridge | 187:0387e8f68319 | 261 | spimd_reg.adb = SPIBSC_1BIT; |
AnnaBridge | 187:0387e8f68319 | 262 | spimd_reg.addr = addr; |
AnnaBridge | 187:0387e8f68319 | 263 | |
AnnaBridge | 187:0387e8f68319 | 264 | /* ---- Others ---- */ |
AnnaBridge | 187:0387e8f68319 | 265 | spimd_reg.sslkp = SPIBSC_SPISSL_KEEP; /* SPBSSL level */ |
AnnaBridge | 187:0387e8f68319 | 266 | |
AnnaBridge | 187:0387e8f68319 | 267 | ret = spibsc_transfer(&spimd_reg); /* Command,Address */ |
AnnaBridge | 187:0387e8f68319 | 268 | if (ret != 0) { |
AnnaBridge | 187:0387e8f68319 | 269 | ex_mode(); |
AnnaBridge | 188:bcfe06ba3d64 | 270 | core_util_critical_section_exit(); |
AnnaBridge | 187:0387e8f68319 | 271 | return ret; |
AnnaBridge | 187:0387e8f68319 | 272 | } |
AnnaBridge | 187:0387e8f68319 | 273 | |
AnnaBridge | 187:0387e8f68319 | 274 | /* ----------- 2. Data ---------------*/ |
AnnaBridge | 188:bcfe06ba3d64 | 275 | ret = data_send(SPIBSC_1BIT, SPIBSC_SPISSL_NEGATE, write_tmp_buf, program_size); |
AnnaBridge | 187:0387e8f68319 | 276 | if (ret != 0) { |
AnnaBridge | 187:0387e8f68319 | 277 | ex_mode(); |
AnnaBridge | 188:bcfe06ba3d64 | 278 | core_util_critical_section_exit(); |
AnnaBridge | 187:0387e8f68319 | 279 | return ret; |
AnnaBridge | 187:0387e8f68319 | 280 | } |
AnnaBridge | 187:0387e8f68319 | 281 | |
AnnaBridge | 187:0387e8f68319 | 282 | ret = busy_wait(); |
AnnaBridge | 187:0387e8f68319 | 283 | if (ret != 0) { |
AnnaBridge | 187:0387e8f68319 | 284 | ex_mode(); |
AnnaBridge | 188:bcfe06ba3d64 | 285 | core_util_critical_section_exit(); |
AnnaBridge | 187:0387e8f68319 | 286 | return ret; |
AnnaBridge | 187:0387e8f68319 | 287 | } |
AnnaBridge | 187:0387e8f68319 | 288 | |
AnnaBridge | 188:bcfe06ba3d64 | 289 | ex_mode(); |
AnnaBridge | 188:bcfe06ba3d64 | 290 | core_util_critical_section_exit(); |
AnnaBridge | 188:bcfe06ba3d64 | 291 | |
AnnaBridge | 187:0387e8f68319 | 292 | addr += program_size; |
AnnaBridge | 187:0387e8f68319 | 293 | idx += program_size; |
AnnaBridge | 187:0387e8f68319 | 294 | size -= program_size; |
AnnaBridge | 187:0387e8f68319 | 295 | } |
AnnaBridge | 187:0387e8f68319 | 296 | |
AnnaBridge | 187:0387e8f68319 | 297 | return ret; |
AnnaBridge | 187:0387e8f68319 | 298 | } |
AnnaBridge | 187:0387e8f68319 | 299 | |
AnnaBridge | 187:0387e8f68319 | 300 | static int32_t write_enable(void) |
AnnaBridge | 187:0387e8f68319 | 301 | { |
AnnaBridge | 187:0387e8f68319 | 302 | int32_t ret; |
AnnaBridge | 187:0387e8f68319 | 303 | |
AnnaBridge | 187:0387e8f68319 | 304 | /* ---- spimd_reg init ---- */ |
AnnaBridge | 187:0387e8f68319 | 305 | clear_spimd_reg(&spimd_reg); |
AnnaBridge | 187:0387e8f68319 | 306 | |
AnnaBridge | 187:0387e8f68319 | 307 | /* ---- command ---- */ |
AnnaBridge | 187:0387e8f68319 | 308 | spimd_reg.cde = SPIBSC_OUTPUT_ENABLE; |
AnnaBridge | 187:0387e8f68319 | 309 | spimd_reg.cdb = SPIBSC_1BIT; |
AnnaBridge | 187:0387e8f68319 | 310 | spimd_reg.cmd = SFLASHCMD_WRITE_ENABLE; |
AnnaBridge | 187:0387e8f68319 | 311 | |
AnnaBridge | 187:0387e8f68319 | 312 | ret = spibsc_transfer(&spimd_reg); |
AnnaBridge | 187:0387e8f68319 | 313 | |
AnnaBridge | 187:0387e8f68319 | 314 | return ret; |
AnnaBridge | 187:0387e8f68319 | 315 | } |
AnnaBridge | 187:0387e8f68319 | 316 | |
AnnaBridge | 187:0387e8f68319 | 317 | static int32_t busy_wait(void) |
AnnaBridge | 187:0387e8f68319 | 318 | { |
AnnaBridge | 187:0387e8f68319 | 319 | int32_t ret; |
AnnaBridge | 187:0387e8f68319 | 320 | uint8_t st_reg; |
AnnaBridge | 187:0387e8f68319 | 321 | |
AnnaBridge | 187:0387e8f68319 | 322 | while (1) { |
AnnaBridge | 187:0387e8f68319 | 323 | ret = read_register(SFLASHCMD_READ_STATUS_REG, &st_reg); |
AnnaBridge | 187:0387e8f68319 | 324 | if (ret != 0) { |
AnnaBridge | 187:0387e8f68319 | 325 | break; |
AnnaBridge | 187:0387e8f68319 | 326 | } |
AnnaBridge | 187:0387e8f68319 | 327 | if ((st_reg & STREG_BUSY_BIT) == 0) { |
AnnaBridge | 187:0387e8f68319 | 328 | break; |
AnnaBridge | 187:0387e8f68319 | 329 | } |
AnnaBridge | 187:0387e8f68319 | 330 | } |
AnnaBridge | 187:0387e8f68319 | 331 | |
AnnaBridge | 187:0387e8f68319 | 332 | return ret; |
AnnaBridge | 187:0387e8f68319 | 333 | } |
AnnaBridge | 187:0387e8f68319 | 334 | |
AnnaBridge | 187:0387e8f68319 | 335 | static int32_t read_register(uint8_t cmd, uint8_t * status) |
AnnaBridge | 187:0387e8f68319 | 336 | { |
AnnaBridge | 187:0387e8f68319 | 337 | int32_t ret; |
AnnaBridge | 187:0387e8f68319 | 338 | |
AnnaBridge | 187:0387e8f68319 | 339 | /* ---- spimd_reg init ---- */ |
AnnaBridge | 187:0387e8f68319 | 340 | clear_spimd_reg(&spimd_reg); |
AnnaBridge | 187:0387e8f68319 | 341 | |
AnnaBridge | 187:0387e8f68319 | 342 | /* ---- command ---- */ |
AnnaBridge | 187:0387e8f68319 | 343 | spimd_reg.cde = SPIBSC_OUTPUT_ENABLE; |
AnnaBridge | 187:0387e8f68319 | 344 | spimd_reg.cdb = SPIBSC_1BIT; |
AnnaBridge | 187:0387e8f68319 | 345 | spimd_reg.cmd = cmd; |
AnnaBridge | 187:0387e8f68319 | 346 | |
AnnaBridge | 187:0387e8f68319 | 347 | /* ---- Others ---- */ |
AnnaBridge | 187:0387e8f68319 | 348 | spimd_reg.sslkp = SPIBSC_SPISSL_NEGATE; /* SPBSSL level */ |
AnnaBridge | 187:0387e8f68319 | 349 | spimd_reg.spire = SPIBSC_SPIDATA_ENABLE; /* read enable/disable */ |
AnnaBridge | 187:0387e8f68319 | 350 | spimd_reg.spiwe = SPIBSC_SPIDATA_ENABLE; /* write enable/disable */ |
AnnaBridge | 187:0387e8f68319 | 351 | |
AnnaBridge | 187:0387e8f68319 | 352 | /* ---- data ---- */ |
AnnaBridge | 187:0387e8f68319 | 353 | spimd_reg.spide = SPIBSC_OUTPUT_SPID_8; /* Enable(8bit) */ |
AnnaBridge | 187:0387e8f68319 | 354 | spimd_reg.spidre = SPIBSC_SDR_TRANS; /* SDR */ |
AnnaBridge | 187:0387e8f68319 | 355 | spimd_reg.spidb = SPIBSC_1BIT; |
AnnaBridge | 187:0387e8f68319 | 356 | spimd_reg.smwdr[0] = 0x00; /* Output 0 in read status */ |
AnnaBridge | 187:0387e8f68319 | 357 | spimd_reg.smwdr[1] = 0x00; /* Output 0 in read status */ |
AnnaBridge | 187:0387e8f68319 | 358 | |
AnnaBridge | 187:0387e8f68319 | 359 | ret = spibsc_transfer(&spimd_reg); |
AnnaBridge | 187:0387e8f68319 | 360 | if (ret == 0) { |
AnnaBridge | 187:0387e8f68319 | 361 | *status = (uint8_t)(spimd_reg.smrdr[0]); /* Data[7:0] */ |
AnnaBridge | 187:0387e8f68319 | 362 | } |
AnnaBridge | 187:0387e8f68319 | 363 | |
AnnaBridge | 187:0387e8f68319 | 364 | return ret; |
AnnaBridge | 187:0387e8f68319 | 365 | } |
AnnaBridge | 187:0387e8f68319 | 366 | |
AnnaBridge | 187:0387e8f68319 | 367 | static int32_t data_send(uint32_t bit_width, uint32_t spbssl_level, const uint8_t * buf, int32_t size) |
AnnaBridge | 187:0387e8f68319 | 368 | { |
AnnaBridge | 187:0387e8f68319 | 369 | int32_t ret = 0; |
AnnaBridge | 187:0387e8f68319 | 370 | int32_t unit; |
AnnaBridge | 187:0387e8f68319 | 371 | uint8_t *buf_b; |
AnnaBridge | 187:0387e8f68319 | 372 | uint16_t *buf_s; |
AnnaBridge | 187:0387e8f68319 | 373 | uint32_t *buf_l; |
AnnaBridge | 187:0387e8f68319 | 374 | |
AnnaBridge | 187:0387e8f68319 | 375 | /* ---- spimd_reg init ---- */ |
AnnaBridge | 187:0387e8f68319 | 376 | clear_spimd_reg(&spimd_reg); |
AnnaBridge | 187:0387e8f68319 | 377 | |
AnnaBridge | 187:0387e8f68319 | 378 | /* ---- Others ---- */ |
AnnaBridge | 187:0387e8f68319 | 379 | spimd_reg.sslkp = SPIBSC_SPISSL_KEEP; /* SPBSSL level */ |
AnnaBridge | 187:0387e8f68319 | 380 | spimd_reg.spiwe = SPIBSC_SPIDATA_ENABLE; /* write enable/disable */ |
AnnaBridge | 187:0387e8f68319 | 381 | |
AnnaBridge | 187:0387e8f68319 | 382 | /* ---- data ---- */ |
AnnaBridge | 187:0387e8f68319 | 383 | spimd_reg.spidb = bit_width; |
AnnaBridge | 187:0387e8f68319 | 384 | spimd_reg.spidre= SPIBSC_SDR_TRANS; /* SDR */ |
AnnaBridge | 187:0387e8f68319 | 385 | |
AnnaBridge | 187:0387e8f68319 | 386 | if (((uint32_t)size & 0x3) == 0) { |
AnnaBridge | 187:0387e8f68319 | 387 | spimd_reg.spide = SPIBSC_OUTPUT_SPID_32; /* Enable(32bit) */ |
AnnaBridge | 187:0387e8f68319 | 388 | unit = 4; |
AnnaBridge | 187:0387e8f68319 | 389 | } else if (((uint32_t)size & 0x1) == 0) { |
AnnaBridge | 187:0387e8f68319 | 390 | spimd_reg.spide = SPIBSC_OUTPUT_SPID_16; /* Enable(16bit) */ |
AnnaBridge | 187:0387e8f68319 | 391 | unit = 2; |
AnnaBridge | 187:0387e8f68319 | 392 | } else { |
AnnaBridge | 187:0387e8f68319 | 393 | spimd_reg.spide = SPIBSC_OUTPUT_SPID_8; /* Enable(8bit) */ |
AnnaBridge | 187:0387e8f68319 | 394 | unit = 1; |
AnnaBridge | 187:0387e8f68319 | 395 | } |
AnnaBridge | 187:0387e8f68319 | 396 | |
AnnaBridge | 187:0387e8f68319 | 397 | while (size > 0) { |
AnnaBridge | 187:0387e8f68319 | 398 | if (unit == 1) { |
AnnaBridge | 187:0387e8f68319 | 399 | buf_b = (uint8_t *)buf; |
AnnaBridge | 187:0387e8f68319 | 400 | spimd_reg.smwdr[0] = (uint32_t)(((uint32_t)*buf_b) & 0x000000FF); |
AnnaBridge | 187:0387e8f68319 | 401 | } else if (unit == 2) { |
AnnaBridge | 187:0387e8f68319 | 402 | buf_s = (uint16_t *)buf; |
AnnaBridge | 187:0387e8f68319 | 403 | spimd_reg.smwdr[0] = (uint32_t)(((uint32_t)*buf_s) & 0x0000FFFF); |
AnnaBridge | 187:0387e8f68319 | 404 | } else if (unit == 4) { |
AnnaBridge | 187:0387e8f68319 | 405 | buf_l = (uint32_t *)buf; |
AnnaBridge | 187:0387e8f68319 | 406 | spimd_reg.smwdr[0] = (uint32_t)(((uint32_t)(*buf_l)) & 0xfffffffful); |
AnnaBridge | 187:0387e8f68319 | 407 | } else { |
AnnaBridge | 187:0387e8f68319 | 408 | /* Do Nothing */ |
AnnaBridge | 187:0387e8f68319 | 409 | } |
AnnaBridge | 187:0387e8f68319 | 410 | |
AnnaBridge | 187:0387e8f68319 | 411 | buf += unit; |
AnnaBridge | 187:0387e8f68319 | 412 | size -= unit; |
AnnaBridge | 187:0387e8f68319 | 413 | |
AnnaBridge | 187:0387e8f68319 | 414 | if (size <= 0) { |
AnnaBridge | 187:0387e8f68319 | 415 | spimd_reg.sslkp = spbssl_level; |
AnnaBridge | 187:0387e8f68319 | 416 | } |
AnnaBridge | 187:0387e8f68319 | 417 | |
AnnaBridge | 187:0387e8f68319 | 418 | ret = spibsc_transfer(&spimd_reg); /* Data */ |
AnnaBridge | 187:0387e8f68319 | 419 | if (ret != 0) { |
AnnaBridge | 187:0387e8f68319 | 420 | return ret; |
AnnaBridge | 187:0387e8f68319 | 421 | } |
AnnaBridge | 187:0387e8f68319 | 422 | } |
AnnaBridge | 187:0387e8f68319 | 423 | |
AnnaBridge | 187:0387e8f68319 | 424 | return ret; |
AnnaBridge | 187:0387e8f68319 | 425 | } |
AnnaBridge | 187:0387e8f68319 | 426 | |
AnnaBridge | 187:0387e8f68319 | 427 | static void spi_mode(void) |
AnnaBridge | 187:0387e8f68319 | 428 | { |
AnnaBridge | 187:0387e8f68319 | 429 | volatile uint32_t dummy_read_32; |
AnnaBridge | 187:0387e8f68319 | 430 | |
AnnaBridge | 187:0387e8f68319 | 431 | if (RegRead_32(&SPIBSC->CMNCR, SPIBSC_CMNCR_MD_SHIFT, SPIBSC_CMNCR_MD) != SPIBSC_CMNCR_MD_SPI) { |
AnnaBridge | 187:0387e8f68319 | 432 | /* ==== Change the MMU translation table SPI Multi-I/O bus space settings |
AnnaBridge | 187:0387e8f68319 | 433 | for use in SPI operating mode ==== */ |
AnnaBridge | 187:0387e8f68319 | 434 | change_mmu_ttbl_spibsc(0); |
AnnaBridge | 187:0387e8f68319 | 435 | |
AnnaBridge | 187:0387e8f68319 | 436 | /* ==== Cleaning and invalidation of cache ==== */ |
AnnaBridge | 187:0387e8f68319 | 437 | cache_control(); |
AnnaBridge | 187:0387e8f68319 | 438 | |
AnnaBridge | 187:0387e8f68319 | 439 | /* ==== Switch to SPI operating mode ==== */ |
AnnaBridge | 187:0387e8f68319 | 440 | spibsc_stop(); |
AnnaBridge | 187:0387e8f68319 | 441 | |
AnnaBridge | 187:0387e8f68319 | 442 | dummy_read_32 = SPIBSC->CMNCR; /* dummy read */ |
AnnaBridge | 187:0387e8f68319 | 443 | /* SPI Mode */ |
AnnaBridge | 187:0387e8f68319 | 444 | RegWwrite_32(&SPIBSC->CMNCR, SPIBSC_CMNCR_MD_SPI, SPIBSC_CMNCR_MD_SHIFT, SPIBSC_CMNCR_MD); |
AnnaBridge | 187:0387e8f68319 | 445 | dummy_read_32 = SPIBSC->CMNCR; /* dummy read */ |
AnnaBridge | 187:0387e8f68319 | 446 | |
AnnaBridge | 187:0387e8f68319 | 447 | } |
AnnaBridge | 187:0387e8f68319 | 448 | (void)dummy_read_32; |
AnnaBridge | 187:0387e8f68319 | 449 | } |
AnnaBridge | 187:0387e8f68319 | 450 | |
AnnaBridge | 187:0387e8f68319 | 451 | static void ex_mode(void) |
AnnaBridge | 187:0387e8f68319 | 452 | { |
AnnaBridge | 187:0387e8f68319 | 453 | volatile uint32_t dummy_read_32; |
AnnaBridge | 187:0387e8f68319 | 454 | |
AnnaBridge | 187:0387e8f68319 | 455 | if (RegRead_32(&SPIBSC->CMNCR, SPIBSC_CMNCR_MD_SHIFT, SPIBSC_CMNCR_MD) != SPIBSC_CMNCR_MD_EXTRD) { |
AnnaBridge | 187:0387e8f68319 | 456 | /* ==== Switch to external address space read mode and clear SPIBSC read cache ==== */ |
AnnaBridge | 187:0387e8f68319 | 457 | spibsc_stop(); |
AnnaBridge | 187:0387e8f68319 | 458 | |
AnnaBridge | 187:0387e8f68319 | 459 | /* Flush SPIBSC's read cache */ |
AnnaBridge | 187:0387e8f68319 | 460 | RegWwrite_32(&SPIBSC->DRCR, SPIBSC_DRCR_RCF_EXE, SPIBSC_DRCR_RCF_SHIFT, SPIBSC_DRCR_RCF); |
AnnaBridge | 187:0387e8f68319 | 461 | dummy_read_32 = SPIBSC->DRCR; /* dummy read */ |
AnnaBridge | 187:0387e8f68319 | 462 | |
AnnaBridge | 187:0387e8f68319 | 463 | /* External address space read mode */ |
AnnaBridge | 187:0387e8f68319 | 464 | RegWwrite_32(&SPIBSC->CMNCR, SPIBSC_CMNCR_MD_EXTRD, SPIBSC_CMNCR_MD_SHIFT, SPIBSC_CMNCR_MD); |
AnnaBridge | 187:0387e8f68319 | 465 | dummy_read_32 = SPIBSC->CMNCR; /* dummy read */ |
AnnaBridge | 187:0387e8f68319 | 466 | |
AnnaBridge | 187:0387e8f68319 | 467 | /* ==== Change the MMU translation table SPI Multi-I/O bus space settings |
AnnaBridge | 187:0387e8f68319 | 468 | for use in external address space read mode ==== */ |
AnnaBridge | 187:0387e8f68319 | 469 | change_mmu_ttbl_spibsc(1); |
AnnaBridge | 187:0387e8f68319 | 470 | |
AnnaBridge | 187:0387e8f68319 | 471 | /* ==== Cleaning and invalidation of cache ==== */ |
AnnaBridge | 187:0387e8f68319 | 472 | cache_control(); |
AnnaBridge | 187:0387e8f68319 | 473 | } |
AnnaBridge | 187:0387e8f68319 | 474 | (void)dummy_read_32; |
AnnaBridge | 187:0387e8f68319 | 475 | } |
AnnaBridge | 187:0387e8f68319 | 476 | |
AnnaBridge | 187:0387e8f68319 | 477 | static void clear_spimd_reg(st_spibsc_spimd_reg_t * regset) |
AnnaBridge | 187:0387e8f68319 | 478 | { |
AnnaBridge | 187:0387e8f68319 | 479 | /* ---- command ---- */ |
AnnaBridge | 187:0387e8f68319 | 480 | regset->cde = SPIBSC_OUTPUT_DISABLE; |
AnnaBridge | 187:0387e8f68319 | 481 | regset->cdb = SPIBSC_1BIT; |
AnnaBridge | 187:0387e8f68319 | 482 | regset->cmd = 0x00; |
AnnaBridge | 187:0387e8f68319 | 483 | |
AnnaBridge | 187:0387e8f68319 | 484 | /* ---- optional command ---- */ |
AnnaBridge | 187:0387e8f68319 | 485 | regset->ocde = SPIBSC_OUTPUT_DISABLE; |
AnnaBridge | 187:0387e8f68319 | 486 | regset->ocdb = SPIBSC_1BIT; |
AnnaBridge | 187:0387e8f68319 | 487 | regset->ocmd = 0x00; |
AnnaBridge | 187:0387e8f68319 | 488 | |
AnnaBridge | 187:0387e8f68319 | 489 | /* ---- address ---- */ |
AnnaBridge | 187:0387e8f68319 | 490 | regset->ade = SPIBSC_OUTPUT_DISABLE; |
AnnaBridge | 187:0387e8f68319 | 491 | regset->addre = SPIBSC_SDR_TRANS; /* SDR */ |
AnnaBridge | 187:0387e8f68319 | 492 | regset->adb = SPIBSC_1BIT; |
AnnaBridge | 187:0387e8f68319 | 493 | regset->addr = 0x00000000; |
AnnaBridge | 187:0387e8f68319 | 494 | |
AnnaBridge | 187:0387e8f68319 | 495 | /* ---- option data ---- */ |
AnnaBridge | 187:0387e8f68319 | 496 | regset->opde = SPIBSC_OUTPUT_DISABLE; |
AnnaBridge | 187:0387e8f68319 | 497 | regset->opdre = SPIBSC_SDR_TRANS; /* SDR */ |
AnnaBridge | 187:0387e8f68319 | 498 | regset->opdb = SPIBSC_1BIT; |
AnnaBridge | 187:0387e8f68319 | 499 | regset->opd[0] = 0x00; /* OPD3 */ |
AnnaBridge | 187:0387e8f68319 | 500 | regset->opd[1] = 0x00; /* OPD2 */ |
AnnaBridge | 187:0387e8f68319 | 501 | regset->opd[2] = 0x00; /* OPD1 */ |
AnnaBridge | 187:0387e8f68319 | 502 | regset->opd[3] = 0x00; /* OPD0 */ |
AnnaBridge | 187:0387e8f68319 | 503 | |
AnnaBridge | 187:0387e8f68319 | 504 | /* ---- dummy cycle ---- */ |
AnnaBridge | 187:0387e8f68319 | 505 | regset->dme = SPIBSC_DUMMY_CYC_DISABLE; |
AnnaBridge | 187:0387e8f68319 | 506 | regset->dmdb = SPIBSC_1BIT; |
AnnaBridge | 187:0387e8f68319 | 507 | regset->dmcyc = SPIBSC_DUMMY_1CYC; |
AnnaBridge | 187:0387e8f68319 | 508 | |
AnnaBridge | 187:0387e8f68319 | 509 | /* ---- data ---- */ |
AnnaBridge | 187:0387e8f68319 | 510 | regset->spide = SPIBSC_OUTPUT_DISABLE; |
AnnaBridge | 187:0387e8f68319 | 511 | regset->spidre = SPIBSC_SDR_TRANS; /* SDR */ |
AnnaBridge | 187:0387e8f68319 | 512 | regset->spidb = SPIBSC_1BIT; |
AnnaBridge | 187:0387e8f68319 | 513 | |
AnnaBridge | 187:0387e8f68319 | 514 | /* ---- Others ---- */ |
AnnaBridge | 187:0387e8f68319 | 515 | regset->sslkp = SPIBSC_SPISSL_NEGATE; /* SPBSSL level */ |
AnnaBridge | 187:0387e8f68319 | 516 | regset->spire = SPIBSC_SPIDATA_DISABLE; /* read enable/disable */ |
AnnaBridge | 187:0387e8f68319 | 517 | regset->spiwe = SPIBSC_SPIDATA_DISABLE; /* write enable/disable */ |
AnnaBridge | 187:0387e8f68319 | 518 | } |
AnnaBridge | 187:0387e8f68319 | 519 | |
AnnaBridge | 187:0387e8f68319 | 520 | static int32_t spibsc_transfer(st_spibsc_spimd_reg_t * regset) |
AnnaBridge | 187:0387e8f68319 | 521 | { |
AnnaBridge | 187:0387e8f68319 | 522 | if (RegRead_32(&SPIBSC->CMNCR, SPIBSC_CMNCR_MD_SHIFT, SPIBSC_CMNCR_MD) != SPIBSC_CMNCR_MD_SPI) { |
AnnaBridge | 187:0387e8f68319 | 523 | if (RegRead_32(&SPIBSC->CMNSR, SPIBSC_CMNSR_SSLF_SHIFT, SPIBSC_CMNSR_SSLF) != SPIBSC_SSL_NEGATE) { |
AnnaBridge | 187:0387e8f68319 | 524 | return -1; |
AnnaBridge | 187:0387e8f68319 | 525 | } |
AnnaBridge | 187:0387e8f68319 | 526 | /* SPI Mode */ |
AnnaBridge | 187:0387e8f68319 | 527 | RegWwrite_32(&SPIBSC->CMNCR, SPIBSC_CMNCR_MD_SPI, SPIBSC_CMNCR_MD_SHIFT, SPIBSC_CMNCR_MD); |
AnnaBridge | 187:0387e8f68319 | 528 | } |
AnnaBridge | 187:0387e8f68319 | 529 | |
AnnaBridge | 187:0387e8f68319 | 530 | if (RegRead_32(&SPIBSC->CMNSR, SPIBSC_CMNSR_TEND_SHIFT, SPIBSC_CMNSR_TEND) != SPIBSC_TRANS_END) { |
AnnaBridge | 187:0387e8f68319 | 531 | return -1; |
AnnaBridge | 187:0387e8f68319 | 532 | } |
AnnaBridge | 187:0387e8f68319 | 533 | |
AnnaBridge | 187:0387e8f68319 | 534 | /* ---- Command ---- */ |
AnnaBridge | 187:0387e8f68319 | 535 | /* Enable/Disable */ |
AnnaBridge | 187:0387e8f68319 | 536 | RegWwrite_32(&SPIBSC->SMENR, regset->cde, SPIBSC_SMENR_CDE_SHIFT, SPIBSC_SMENR_CDE); |
AnnaBridge | 187:0387e8f68319 | 537 | if (regset->cde != SPIBSC_OUTPUT_DISABLE) { |
AnnaBridge | 187:0387e8f68319 | 538 | /* Command */ |
AnnaBridge | 187:0387e8f68319 | 539 | RegWwrite_32(&SPIBSC->SMCMR, regset->cmd, SPIBSC_SMCMR_CMD_SHIFT, SPIBSC_SMCMR_CMD); |
AnnaBridge | 187:0387e8f68319 | 540 | /* Single/Dual/Quad */ |
AnnaBridge | 187:0387e8f68319 | 541 | RegWwrite_32(&SPIBSC->SMENR, regset->cdb, SPIBSC_SMENR_CDB_SHIFT, SPIBSC_SMENR_CDB); |
AnnaBridge | 187:0387e8f68319 | 542 | } |
AnnaBridge | 187:0387e8f68319 | 543 | |
AnnaBridge | 187:0387e8f68319 | 544 | /* ---- Option Command ---- */ |
AnnaBridge | 187:0387e8f68319 | 545 | /* Enable/Disable */ |
AnnaBridge | 187:0387e8f68319 | 546 | RegWwrite_32(&SPIBSC->SMENR, regset->ocde, SPIBSC_SMENR_OCDE_SHIFT, SPIBSC_SMENR_OCDE); |
AnnaBridge | 187:0387e8f68319 | 547 | if (regset->ocde != SPIBSC_OUTPUT_DISABLE) { |
AnnaBridge | 187:0387e8f68319 | 548 | /* Option Command */ |
AnnaBridge | 187:0387e8f68319 | 549 | RegWwrite_32(&SPIBSC->SMCMR, regset->ocmd, SPIBSC_SMCMR_OCMD_SHIFT, SPIBSC_SMCMR_OCMD); |
AnnaBridge | 187:0387e8f68319 | 550 | /* Single/Dual/Quad */ |
AnnaBridge | 187:0387e8f68319 | 551 | RegWwrite_32(&SPIBSC->SMENR, regset->ocdb, SPIBSC_SMENR_OCDB_SHIFT, SPIBSC_SMENR_OCDB); |
AnnaBridge | 187:0387e8f68319 | 552 | } |
AnnaBridge | 187:0387e8f68319 | 553 | |
AnnaBridge | 187:0387e8f68319 | 554 | /* ---- Address ---- */ |
AnnaBridge | 187:0387e8f68319 | 555 | /* Enable/Disable */ |
AnnaBridge | 187:0387e8f68319 | 556 | RegWwrite_32(&SPIBSC->SMENR, regset->ade, SPIBSC_SMENR_ADE_SHIFT, SPIBSC_SMENR_ADE); |
AnnaBridge | 187:0387e8f68319 | 557 | if (regset->ade != SPIBSC_OUTPUT_DISABLE) { |
AnnaBridge | 187:0387e8f68319 | 558 | /* Address */ |
AnnaBridge | 187:0387e8f68319 | 559 | RegWwrite_32(&SPIBSC->SMADR, regset->addr, SPIBSC_SMADR_ADR_SHIFT, SPIBSC_SMADR_ADR); |
AnnaBridge | 187:0387e8f68319 | 560 | /* Single/Dual/Quad */ |
AnnaBridge | 187:0387e8f68319 | 561 | RegWwrite_32(&SPIBSC->SMENR, regset->adb, SPIBSC_SMENR_ADB_SHIFT, SPIBSC_SMENR_ADB); |
AnnaBridge | 187:0387e8f68319 | 562 | } |
AnnaBridge | 187:0387e8f68319 | 563 | |
AnnaBridge | 187:0387e8f68319 | 564 | /* ---- Option Data ---- */ |
AnnaBridge | 187:0387e8f68319 | 565 | /* Enable/Disable */ |
AnnaBridge | 187:0387e8f68319 | 566 | RegWwrite_32(&SPIBSC->SMENR, regset->opde, SPIBSC_SMENR_OPDE_SHIFT, SPIBSC_SMENR_OPDE); |
AnnaBridge | 187:0387e8f68319 | 567 | if (regset->opde != SPIBSC_OUTPUT_DISABLE) { |
AnnaBridge | 187:0387e8f68319 | 568 | /* Option Data */ |
AnnaBridge | 187:0387e8f68319 | 569 | RegWwrite_32(&SPIBSC->SMOPR, regset->opd[0], SPIBSC_SMOPR_OPD3_SHIFT, SPIBSC_SMOPR_OPD3); |
AnnaBridge | 187:0387e8f68319 | 570 | RegWwrite_32(&SPIBSC->SMOPR, regset->opd[1], SPIBSC_SMOPR_OPD2_SHIFT, SPIBSC_SMOPR_OPD2); |
AnnaBridge | 187:0387e8f68319 | 571 | RegWwrite_32(&SPIBSC->SMOPR, regset->opd[2], SPIBSC_SMOPR_OPD1_SHIFT, SPIBSC_SMOPR_OPD1); |
AnnaBridge | 187:0387e8f68319 | 572 | RegWwrite_32(&SPIBSC->SMOPR, regset->opd[3], SPIBSC_SMOPR_OPD0_SHIFT, SPIBSC_SMOPR_OPD0); |
AnnaBridge | 187:0387e8f68319 | 573 | /* Single/Dual/Quad */ |
AnnaBridge | 187:0387e8f68319 | 574 | RegWwrite_32(&SPIBSC->SMENR, regset->opdb, SPIBSC_SMENR_OPDB_SHIFT, SPIBSC_SMENR_OPDB); |
AnnaBridge | 187:0387e8f68319 | 575 | } |
AnnaBridge | 187:0387e8f68319 | 576 | |
AnnaBridge | 187:0387e8f68319 | 577 | /* ---- Dummy ---- */ |
AnnaBridge | 187:0387e8f68319 | 578 | /* Enable/Disable */ |
AnnaBridge | 187:0387e8f68319 | 579 | RegWwrite_32(&SPIBSC->SMENR, regset->dme, SPIBSC_SMENR_DME_SHIFT, SPIBSC_SMENR_DME); |
AnnaBridge | 187:0387e8f68319 | 580 | if (regset->dme != SPIBSC_DUMMY_CYC_DISABLE) { |
AnnaBridge | 187:0387e8f68319 | 581 | RegWwrite_32(&SPIBSC->SMDMCR, regset->dmdb, SPIBSC_SMDMCR_DMDB_SHIFT, SPIBSC_SMDMCR_DMDB); |
AnnaBridge | 187:0387e8f68319 | 582 | /* Dummy Cycle */ |
AnnaBridge | 187:0387e8f68319 | 583 | RegWwrite_32(&SPIBSC->SMDMCR, regset->dmcyc, SPIBSC_SMDMCR_DMCYC_SHIFT, SPIBSC_SMDMCR_DMCYC); |
AnnaBridge | 187:0387e8f68319 | 584 | } |
AnnaBridge | 187:0387e8f68319 | 585 | |
AnnaBridge | 187:0387e8f68319 | 586 | /* ---- Data ---- */ |
AnnaBridge | 187:0387e8f68319 | 587 | /* Enable/Disable */ |
AnnaBridge | 187:0387e8f68319 | 588 | RegWwrite_32(&SPIBSC->SMENR, regset->spide, SPIBSC_SMENR_SPIDE_SHIFT, SPIBSC_SMENR_SPIDE); |
AnnaBridge | 187:0387e8f68319 | 589 | if (regset->spide != SPIBSC_OUTPUT_DISABLE) { |
AnnaBridge | 187:0387e8f68319 | 590 | if (SPIBSC_OUTPUT_SPID_8 == regset->spide) { |
AnnaBridge | 187:0387e8f68319 | 591 | if (RegRead_32(&SPIBSC0.CMNCR, SPIBSC_CMNCR_BSZ_SHIFT, SPIBSC_CMNCR_BSZ) == SPIBSC_CMNCR_BSZ_SINGLE) { |
AnnaBridge | 187:0387e8f68319 | 592 | SPIBSC->SMWDR0.UINT8[0] = (uint8_t)(regset->smwdr[0]); |
AnnaBridge | 187:0387e8f68319 | 593 | } else { |
AnnaBridge | 187:0387e8f68319 | 594 | SPIBSC->SMWDR0.UINT16[0] = (uint16_t)(regset->smwdr[0]); |
AnnaBridge | 187:0387e8f68319 | 595 | } |
AnnaBridge | 187:0387e8f68319 | 596 | } else if (regset->spide == SPIBSC_OUTPUT_SPID_16) { |
AnnaBridge | 187:0387e8f68319 | 597 | if (RegRead_32(&SPIBSC0.CMNCR, SPIBSC_CMNCR_BSZ_SHIFT, SPIBSC_CMNCR_BSZ) == SPIBSC_CMNCR_BSZ_SINGLE) { |
AnnaBridge | 187:0387e8f68319 | 598 | SPIBSC->SMWDR0.UINT16[0] = (uint16_t)(regset->smwdr[0]); |
AnnaBridge | 187:0387e8f68319 | 599 | } else { |
AnnaBridge | 187:0387e8f68319 | 600 | SPIBSC->SMWDR0.UINT32 = regset->smwdr[0]; |
AnnaBridge | 187:0387e8f68319 | 601 | } |
AnnaBridge | 187:0387e8f68319 | 602 | } else if (regset->spide == SPIBSC_OUTPUT_SPID_32) { |
AnnaBridge | 187:0387e8f68319 | 603 | if (RegRead_32(&SPIBSC0.CMNCR, SPIBSC_CMNCR_BSZ_SHIFT, SPIBSC_CMNCR_BSZ) == SPIBSC_CMNCR_BSZ_SINGLE) { |
AnnaBridge | 187:0387e8f68319 | 604 | SPIBSC->SMWDR0.UINT32 = (uint32_t)(regset->smwdr[0]); |
AnnaBridge | 187:0387e8f68319 | 605 | } else { |
AnnaBridge | 187:0387e8f68319 | 606 | SPIBSC->SMWDR0.UINT32 = (uint32_t)(regset->smwdr[0]); |
AnnaBridge | 187:0387e8f68319 | 607 | SPIBSC->SMWDR1.UINT32 = (uint32_t)(regset->smwdr[1]); /* valid in two serial-flash */ |
AnnaBridge | 187:0387e8f68319 | 608 | } |
AnnaBridge | 187:0387e8f68319 | 609 | } else { |
AnnaBridge | 187:0387e8f68319 | 610 | /* none */ |
AnnaBridge | 187:0387e8f68319 | 611 | } |
AnnaBridge | 187:0387e8f68319 | 612 | |
AnnaBridge | 187:0387e8f68319 | 613 | /* Single/Dual/Quad */ |
AnnaBridge | 187:0387e8f68319 | 614 | RegWwrite_32(&SPIBSC->SMENR, regset->spidb, SPIBSC_SMENR_SPIDB_SHIFT, SPIBSC_SMENR_SPIDB); |
AnnaBridge | 187:0387e8f68319 | 615 | } |
AnnaBridge | 187:0387e8f68319 | 616 | |
AnnaBridge | 187:0387e8f68319 | 617 | RegWwrite_32(&SPIBSC->SMCR, regset->sslkp, SPIBSC_SMCR_SSLKP_SHIFT, SPIBSC_SMCR_SSLKP); |
AnnaBridge | 187:0387e8f68319 | 618 | |
AnnaBridge | 187:0387e8f68319 | 619 | if ((regset->spidb != SPIBSC_1BIT) && (regset->spide != SPIBSC_OUTPUT_DISABLE)) { |
AnnaBridge | 187:0387e8f68319 | 620 | if ((regset->spire == SPIBSC_SPIDATA_ENABLE) && (regset->spiwe == SPIBSC_SPIDATA_ENABLE)) { |
AnnaBridge | 187:0387e8f68319 | 621 | /* not set in same time */ |
AnnaBridge | 187:0387e8f68319 | 622 | return -1; |
AnnaBridge | 187:0387e8f68319 | 623 | } |
AnnaBridge | 187:0387e8f68319 | 624 | } |
AnnaBridge | 187:0387e8f68319 | 625 | |
AnnaBridge | 187:0387e8f68319 | 626 | RegWwrite_32(&SPIBSC->SMCR, regset->spire, SPIBSC_SMCR_SPIRE_SHIFT, SPIBSC_SMCR_SPIRE); |
AnnaBridge | 187:0387e8f68319 | 627 | RegWwrite_32(&SPIBSC->SMCR, regset->spiwe, SPIBSC_SMCR_SPIWE_SHIFT, SPIBSC_SMCR_SPIWE); |
AnnaBridge | 187:0387e8f68319 | 628 | |
AnnaBridge | 187:0387e8f68319 | 629 | /* SDR Transmission/DDR Transmission Setting */ |
AnnaBridge | 187:0387e8f68319 | 630 | RegWwrite_32(&SPIBSC->SMDRENR, regset->addre, SPIBSC_SMDRENR_ADDRE_SHIFT, SPIBSC_SMDRENR_ADDRE); |
AnnaBridge | 187:0387e8f68319 | 631 | RegWwrite_32(&SPIBSC->SMDRENR, regset->opdre, SPIBSC_SMDRENR_OPDRE_SHIFT, SPIBSC_SMDRENR_OPDRE); |
AnnaBridge | 187:0387e8f68319 | 632 | RegWwrite_32(&SPIBSC->SMDRENR, regset->spidre, SPIBSC_SMDRENR_SPIDRE_SHIFT, SPIBSC_SMDRENR_SPIDRE); |
AnnaBridge | 187:0387e8f68319 | 633 | |
AnnaBridge | 187:0387e8f68319 | 634 | /* execute after setting SPNDL bit */ |
AnnaBridge | 187:0387e8f68319 | 635 | RegWwrite_32(&SPIBSC->SMCR, SPIBSC_SPI_ENABLE, SPIBSC_SMCR_SPIE_SHIFT, SPIBSC_SMCR_SPIE); |
AnnaBridge | 187:0387e8f68319 | 636 | |
AnnaBridge | 187:0387e8f68319 | 637 | /* wait for transfer-start */ |
AnnaBridge | 187:0387e8f68319 | 638 | while (RegRead_32(&SPIBSC->CMNSR, SPIBSC_CMNSR_TEND_SHIFT, SPIBSC_CMNSR_TEND) != SPIBSC_TRANS_END) { |
AnnaBridge | 187:0387e8f68319 | 639 | /* wait for transfer-end */ |
AnnaBridge | 187:0387e8f68319 | 640 | } |
AnnaBridge | 187:0387e8f68319 | 641 | |
AnnaBridge | 187:0387e8f68319 | 642 | if (SPIBSC_OUTPUT_SPID_8 == regset->spide) { |
AnnaBridge | 187:0387e8f68319 | 643 | if (RegRead_32(&SPIBSC0.CMNCR, SPIBSC_CMNCR_BSZ_SHIFT, SPIBSC_CMNCR_BSZ) == SPIBSC_CMNCR_BSZ_SINGLE) { |
AnnaBridge | 187:0387e8f68319 | 644 | regset->smrdr[0] = SPIBSC->SMRDR0.UINT8[0]; |
AnnaBridge | 187:0387e8f68319 | 645 | } else { |
AnnaBridge | 187:0387e8f68319 | 646 | regset->smrdr[0] = SPIBSC->SMRDR0.UINT16[0]; /* valid in two serial-flash */ |
AnnaBridge | 187:0387e8f68319 | 647 | } |
AnnaBridge | 187:0387e8f68319 | 648 | } else if (regset->spide == SPIBSC_OUTPUT_SPID_16) { |
AnnaBridge | 187:0387e8f68319 | 649 | if (RegRead_32(&SPIBSC0.CMNCR, SPIBSC_CMNCR_BSZ_SHIFT, SPIBSC_CMNCR_BSZ) == SPIBSC_CMNCR_BSZ_SINGLE) { |
AnnaBridge | 187:0387e8f68319 | 650 | regset->smrdr[0] = SPIBSC->SMRDR0.UINT16[0]; |
AnnaBridge | 187:0387e8f68319 | 651 | } else { |
AnnaBridge | 187:0387e8f68319 | 652 | regset->smrdr[0] = SPIBSC->SMRDR0.UINT32; /* valid in two serial-flash */ |
AnnaBridge | 187:0387e8f68319 | 653 | } |
AnnaBridge | 187:0387e8f68319 | 654 | } else if (regset->spide == SPIBSC_OUTPUT_SPID_32) { |
AnnaBridge | 187:0387e8f68319 | 655 | if (RegRead_32(&SPIBSC0.CMNCR, SPIBSC_CMNCR_BSZ_SHIFT, SPIBSC_CMNCR_BSZ) == SPIBSC_CMNCR_BSZ_SINGLE) { |
AnnaBridge | 187:0387e8f68319 | 656 | regset->smrdr[0] = SPIBSC->SMRDR0.UINT32; |
AnnaBridge | 187:0387e8f68319 | 657 | } else { |
AnnaBridge | 187:0387e8f68319 | 658 | regset->smrdr[0] = SPIBSC->SMRDR0.UINT32; /* valid in two serial-flash */ |
AnnaBridge | 187:0387e8f68319 | 659 | regset->smrdr[1] = SPIBSC->SMRDR1.UINT32; |
AnnaBridge | 187:0387e8f68319 | 660 | } |
AnnaBridge | 187:0387e8f68319 | 661 | } else { |
AnnaBridge | 187:0387e8f68319 | 662 | /* none */ |
AnnaBridge | 187:0387e8f68319 | 663 | } |
AnnaBridge | 187:0387e8f68319 | 664 | |
AnnaBridge | 187:0387e8f68319 | 665 | return 0; |
AnnaBridge | 187:0387e8f68319 | 666 | } |
AnnaBridge | 187:0387e8f68319 | 667 | |
AnnaBridge | 187:0387e8f68319 | 668 | static uint32_t RegRead_32(volatile uint32_t * ioreg, uint32_t shift, uint32_t mask) |
AnnaBridge | 187:0387e8f68319 | 669 | { |
AnnaBridge | 187:0387e8f68319 | 670 | uint32_t reg_value; |
AnnaBridge | 187:0387e8f68319 | 671 | |
AnnaBridge | 187:0387e8f68319 | 672 | reg_value = *ioreg; /* Read from register */ |
AnnaBridge | 187:0387e8f68319 | 673 | reg_value = (reg_value & mask) >> shift; /* Clear other bit and Bit shift */ |
AnnaBridge | 187:0387e8f68319 | 674 | |
AnnaBridge | 187:0387e8f68319 | 675 | return reg_value; |
AnnaBridge | 187:0387e8f68319 | 676 | } |
AnnaBridge | 187:0387e8f68319 | 677 | |
AnnaBridge | 187:0387e8f68319 | 678 | static void RegWwrite_32(volatile uint32_t * ioreg, uint32_t write_value, uint32_t shift, uint32_t mask) |
AnnaBridge | 187:0387e8f68319 | 679 | { |
AnnaBridge | 187:0387e8f68319 | 680 | uint32_t reg_value; |
AnnaBridge | 187:0387e8f68319 | 681 | |
AnnaBridge | 187:0387e8f68319 | 682 | reg_value = *ioreg; /* Read from register */ |
AnnaBridge | 187:0387e8f68319 | 683 | reg_value = (reg_value & (~mask)) | (write_value << shift); /* Modify value */ |
AnnaBridge | 187:0387e8f68319 | 684 | *ioreg = reg_value; /* Write to register */ |
AnnaBridge | 187:0387e8f68319 | 685 | } |
AnnaBridge | 187:0387e8f68319 | 686 | |
AnnaBridge | 187:0387e8f68319 | 687 | static void change_mmu_ttbl_spibsc(uint32_t type) |
AnnaBridge | 187:0387e8f68319 | 688 | { |
AnnaBridge | 187:0387e8f68319 | 689 | uint32_t index; /* Loop variable: table index */ |
AnnaBridge | 187:0387e8f68319 | 690 | mmu_ttbl_desc_section_t desc; /* Loop variable: descriptor */ |
AnnaBridge | 187:0387e8f68319 | 691 | mmu_ttbl_desc_section_t * table = (mmu_ttbl_desc_section_t *)TTB; |
AnnaBridge | 187:0387e8f68319 | 692 | |
AnnaBridge | 187:0387e8f68319 | 693 | /* ==== Modify SPI Multi-I/O bus space settings in the MMU translation table ==== */ |
AnnaBridge | 188:bcfe06ba3d64 | 694 | for (index = (FLASH_BASE >> 20); index < ((FLASH_BASE + FLASH_SIZE) >> 20); index++) { |
AnnaBridge | 187:0387e8f68319 | 695 | /* Modify memory attribute descriptor */ |
AnnaBridge | 187:0387e8f68319 | 696 | if (type == 0) { /* Spi */ |
AnnaBridge | 187:0387e8f68319 | 697 | desc = table[index]; |
AnnaBridge | 188:bcfe06ba3d64 | 698 | desc_tbl[index - (FLASH_BASE >> 20)] = desc; |
AnnaBridge | 187:0387e8f68319 | 699 | desc.AP1_0 = 0x0u; /* AP[2:0] = b'000 (No access) */ |
AnnaBridge | 187:0387e8f68319 | 700 | desc.AP2 = 0x0u; |
AnnaBridge | 187:0387e8f68319 | 701 | desc.XN = 0x1u; /* XN = 1 (Execute never) */ |
AnnaBridge | 187:0387e8f68319 | 702 | } else { /* Xip */ |
AnnaBridge | 188:bcfe06ba3d64 | 703 | desc = desc_tbl[index - (FLASH_BASE >> 20)]; |
AnnaBridge | 187:0387e8f68319 | 704 | } |
AnnaBridge | 187:0387e8f68319 | 705 | /* Write descriptor back to translation table */ |
AnnaBridge | 187:0387e8f68319 | 706 | table[index] = desc; |
AnnaBridge | 187:0387e8f68319 | 707 | } |
AnnaBridge | 187:0387e8f68319 | 708 | } |
AnnaBridge | 187:0387e8f68319 | 709 | |
AnnaBridge | 187:0387e8f68319 | 710 | static void spibsc_stop(void) |
AnnaBridge | 187:0387e8f68319 | 711 | { |
AnnaBridge | 187:0387e8f68319 | 712 | if (((SPIBSC->DRCR & SPIBSC_DRCR_RBE) != 0) && |
AnnaBridge | 187:0387e8f68319 | 713 | ((SPIBSC->DRCR & SPIBSC_DRCR_SSLE) != 0)) { |
AnnaBridge | 187:0387e8f68319 | 714 | RegWwrite_32(&SPIBSC->DRCR, 1, SPIBSC_DRCR_SSLN_SHIFT, SPIBSC_DRCR_SSLN); |
AnnaBridge | 187:0387e8f68319 | 715 | } |
AnnaBridge | 187:0387e8f68319 | 716 | |
AnnaBridge | 187:0387e8f68319 | 717 | while (RegRead_32(&SPIBSC->CMNSR, SPIBSC_CMNSR_SSLF_SHIFT, SPIBSC_CMNSR_SSLF) != SPIBSC_SSL_NEGATE) { |
AnnaBridge | 187:0387e8f68319 | 718 | ; |
AnnaBridge | 187:0387e8f68319 | 719 | } |
AnnaBridge | 187:0387e8f68319 | 720 | |
AnnaBridge | 187:0387e8f68319 | 721 | while (RegRead_32(&SPIBSC->CMNSR, SPIBSC_CMNSR_TEND_SHIFT, SPIBSC_CMNSR_TEND) != SPIBSC_TRANS_END) { |
AnnaBridge | 187:0387e8f68319 | 722 | ; |
AnnaBridge | 187:0387e8f68319 | 723 | } |
AnnaBridge | 187:0387e8f68319 | 724 | } |
AnnaBridge | 187:0387e8f68319 | 725 | |
AnnaBridge | 187:0387e8f68319 | 726 | static void cache_control(void) |
AnnaBridge | 187:0387e8f68319 | 727 | { |
AnnaBridge | 187:0387e8f68319 | 728 | unsigned int assoc; |
AnnaBridge | 187:0387e8f68319 | 729 | |
AnnaBridge | 187:0387e8f68319 | 730 | /* ==== Cleaning and invalidation of the L1 data cache ==== */ |
AnnaBridge | 187:0387e8f68319 | 731 | L1C_CleanInvalidateDCacheAll(); |
AnnaBridge | 187:0387e8f68319 | 732 | __DSB(); |
AnnaBridge | 187:0387e8f68319 | 733 | |
AnnaBridge | 187:0387e8f68319 | 734 | /* ==== Cleaning and invalidation of the L2 cache ==== */ |
AnnaBridge | 187:0387e8f68319 | 735 | if (L2C_310->AUX_CNT & (1U << 16U)) { |
AnnaBridge | 187:0387e8f68319 | 736 | assoc = 16U; |
AnnaBridge | 187:0387e8f68319 | 737 | } else { |
AnnaBridge | 187:0387e8f68319 | 738 | assoc = 8U; |
AnnaBridge | 187:0387e8f68319 | 739 | } |
AnnaBridge | 187:0387e8f68319 | 740 | L2C_310->CLEAN_INV_WAY = (1U << assoc) - 1U; |
AnnaBridge | 187:0387e8f68319 | 741 | while (L2C_310->CLEAN_INV_WAY & ((1U << assoc) - 1U)); // poll invalidate |
AnnaBridge | 187:0387e8f68319 | 742 | L2C_310->CACHE_SYNC = 0x0; |
AnnaBridge | 187:0387e8f68319 | 743 | |
AnnaBridge | 187:0387e8f68319 | 744 | /* ==== Invalidate all TLB entries ==== */ |
AnnaBridge | 187:0387e8f68319 | 745 | __set_TLBIALL(0); |
AnnaBridge | 187:0387e8f68319 | 746 | __DSB(); // ensure completion of the invalidation |
AnnaBridge | 187:0387e8f68319 | 747 | __ISB(); // ensure instruction fetch path sees new state |
AnnaBridge | 187:0387e8f68319 | 748 | |
AnnaBridge | 187:0387e8f68319 | 749 | /* ==== Invalidate the L1 instruction cache ==== */ |
AnnaBridge | 187:0387e8f68319 | 750 | __set_ICIALLU(0); |
AnnaBridge | 187:0387e8f68319 | 751 | __DSB(); // ensure completion of the invalidation |
AnnaBridge | 187:0387e8f68319 | 752 | __ISB(); // ensure instruction fetch path sees new I cache state |
AnnaBridge | 187:0387e8f68319 | 753 | } |
AnnaBridge | 189:f392fc9709a3 | 754 | |
AnnaBridge | 189:f392fc9709a3 | 755 | uint8_t flash_get_erase_value(const flash_t *obj) |
AnnaBridge | 189:f392fc9709a3 | 756 | { |
AnnaBridge | 189:f392fc9709a3 | 757 | (void)obj; |
AnnaBridge | 189:f392fc9709a3 | 758 | |
AnnaBridge | 189:f392fc9709a3 | 759 | return 0xFF; |
AnnaBridge | 189:f392fc9709a3 | 760 | } |
AnnaBridge | 189:f392fc9709a3 | 761 | |
AnnaBridge | 187:0387e8f68319 | 762 | #endif |