Flash access library for GR-Boards.

Committer:
dkato
Date:
Tue Nov 28 06:46:10 2017 +0000
Revision:
1:652a093cf264
Parent:
0:5a74eeaefb5d
Text update

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dkato 0:5a74eeaefb5d 1 /*******************************************************************************
dkato 0:5a74eeaefb5d 2 * DISCLAIMER
dkato 0:5a74eeaefb5d 3 * This software is supplied by Renesas Electronics Corporation and is only
dkato 0:5a74eeaefb5d 4 * intended for use with Renesas products. No other uses are authorized. This
dkato 0:5a74eeaefb5d 5 * software is owned by Renesas Electronics Corporation and is protected under
dkato 0:5a74eeaefb5d 6 * all applicable laws, including copyright laws.
dkato 0:5a74eeaefb5d 7 * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
dkato 0:5a74eeaefb5d 8 * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
dkato 0:5a74eeaefb5d 9 * LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
dkato 0:5a74eeaefb5d 10 * AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
dkato 0:5a74eeaefb5d 11 * TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
dkato 0:5a74eeaefb5d 12 * ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
dkato 0:5a74eeaefb5d 13 * FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
dkato 0:5a74eeaefb5d 14 * ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
dkato 0:5a74eeaefb5d 15 * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
dkato 0:5a74eeaefb5d 16 * Renesas reserves the right, without notice, to make changes to this software
dkato 0:5a74eeaefb5d 17 * and to discontinue the availability of this software. By using this software,
dkato 0:5a74eeaefb5d 18 * you agree to the additional terms and conditions found by accessing the
dkato 0:5a74eeaefb5d 19 * following link:
dkato 0:5a74eeaefb5d 20 * http://www.renesas.com/disclaimer
dkato 0:5a74eeaefb5d 21 *
dkato 0:5a74eeaefb5d 22 * Copyright (C) 2017 Renesas Electronics Corporation. All rights reserved.
dkato 0:5a74eeaefb5d 23 *******************************************************************************/
dkato 0:5a74eeaefb5d 24
dkato 0:5a74eeaefb5d 25 #include "mbed.h"
dkato 0:5a74eeaefb5d 26 #include "FlashAccess.h"
dkato 0:5a74eeaefb5d 27
dkato 0:5a74eeaefb5d 28 /* ---- serial flash command ---- */
dkato 0:5a74eeaefb5d 29 #define SFLASHCMD_SECTOR_ERASE (0x20u) /* SE 3-byte address(1bit) */
dkato 0:5a74eeaefb5d 30 #define SFLASHCMD_PAGE_PROGRAM (0x02u) /* PP 3-byte address(1bit), data(1bit) */
dkato 0:5a74eeaefb5d 31 #define SFLASHCMD_READ (0x03u) /* READ 3-byte address(1bit), data(1bit) */
dkato 0:5a74eeaefb5d 32 #define SFLASHCMD_READ_STATUS_REG (0x05u) /* RDSR data(1bit) */
dkato 0:5a74eeaefb5d 33 #define SFLASHCMD_WRITE_ENABLE (0x06u) /* WREN */
dkato 0:5a74eeaefb5d 34 /* ---- serial flash register definitions ---- */
dkato 0:5a74eeaefb5d 35 #define STREG_BUSY_BIT (0x01u) /* SR.[0]BUSY Erase/Write In Progress (RO) */
dkato 0:5a74eeaefb5d 36
dkato 0:5a74eeaefb5d 37 /* Definition of the base address for the MMU translation table */
dkato 0:5a74eeaefb5d 38 #if defined(__CC_ARM) || defined(__GNUC__)
dkato 0:5a74eeaefb5d 39 extern uint32_t Image$$TTB$$ZI$$Base;
dkato 0:5a74eeaefb5d 40 #define TTB ((uint32_t)&Image$$TTB$$ZI$$Base) /* using linker symbol */
dkato 0:5a74eeaefb5d 41 #elif defined(__ICCARM__)
dkato 0:5a74eeaefb5d 42 #pragma section="TTB"
dkato 0:5a74eeaefb5d 43 #define TTB ((uint32_t)__section_begin("TTB"))
dkato 0:5a74eeaefb5d 44 #endif
dkato 0:5a74eeaefb5d 45
dkato 0:5a74eeaefb5d 46 /** public **/
dkato 0:5a74eeaefb5d 47
dkato 0:5a74eeaefb5d 48 FlashAccess::FlashAccess() : SPIBSC(&SPIBSC0) {
dkato 0:5a74eeaefb5d 49 }
dkato 0:5a74eeaefb5d 50
dkato 0:5a74eeaefb5d 51 bool FlashAccess::SectorErase(uint32_t addr) {
dkato 0:5a74eeaefb5d 52 bool ret;
dkato 0:5a74eeaefb5d 53 #if defined (__ICCARM__)
dkato 0:5a74eeaefb5d 54 int was_masked = __disable_irq_iar();
dkato 0:5a74eeaefb5d 55 #else
dkato 0:5a74eeaefb5d 56 int was_masked = __disable_irq();
dkato 0:5a74eeaefb5d 57 #endif
dkato 0:5a74eeaefb5d 58 spi_mode();
dkato 0:5a74eeaefb5d 59 ret = _SectorErase(addr);
dkato 0:5a74eeaefb5d 60 ex_mode();
dkato 0:5a74eeaefb5d 61 if (0 == was_masked) {
dkato 0:5a74eeaefb5d 62 __enable_irq();
dkato 0:5a74eeaefb5d 63 }
dkato 0:5a74eeaefb5d 64 return ret;
dkato 0:5a74eeaefb5d 65 }
dkato 0:5a74eeaefb5d 66
dkato 0:5a74eeaefb5d 67 bool FlashAccess::PageProgram(uint32_t addr, uint8_t * buf, int32_t size) {
dkato 0:5a74eeaefb5d 68 bool ret;
dkato 0:5a74eeaefb5d 69 #if defined (__ICCARM__)
dkato 0:5a74eeaefb5d 70 int was_masked = __disable_irq_iar();
dkato 0:5a74eeaefb5d 71 #else
dkato 0:5a74eeaefb5d 72 int was_masked = __disable_irq();
dkato 0:5a74eeaefb5d 73 #endif
dkato 0:5a74eeaefb5d 74 spi_mode();
dkato 0:5a74eeaefb5d 75 ret = _PageProgram(addr, buf, size);
dkato 0:5a74eeaefb5d 76 ex_mode();
dkato 0:5a74eeaefb5d 77 if (0 == was_masked) {
dkato 0:5a74eeaefb5d 78 __enable_irq();
dkato 0:5a74eeaefb5d 79 }
dkato 0:5a74eeaefb5d 80 return ret;
dkato 0:5a74eeaefb5d 81 }
dkato 0:5a74eeaefb5d 82
dkato 0:5a74eeaefb5d 83 bool FlashAccess::Read(uint32_t addr, uint8_t * buf, int32_t size) {
dkato 0:5a74eeaefb5d 84 bool ret;
dkato 0:5a74eeaefb5d 85 #if defined (__ICCARM__)
dkato 0:5a74eeaefb5d 86 int was_masked = __disable_irq_iar();
dkato 0:5a74eeaefb5d 87 #else
dkato 0:5a74eeaefb5d 88 int was_masked = __disable_irq();
dkato 0:5a74eeaefb5d 89 #endif
dkato 0:5a74eeaefb5d 90 spi_mode();
dkato 0:5a74eeaefb5d 91 ret = _Read(addr, buf, size);
dkato 0:5a74eeaefb5d 92 ex_mode();
dkato 0:5a74eeaefb5d 93 if (0 == was_masked) {
dkato 0:5a74eeaefb5d 94 __enable_irq();
dkato 0:5a74eeaefb5d 95 }
dkato 0:5a74eeaefb5d 96 return ret;
dkato 0:5a74eeaefb5d 97 }
dkato 0:5a74eeaefb5d 98
dkato 0:5a74eeaefb5d 99 /** protected **/
dkato 0:5a74eeaefb5d 100
dkato 0:5a74eeaefb5d 101 bool FlashAccess::_SectorErase(uint32_t addr) {
dkato 0:5a74eeaefb5d 102 bool ret;
dkato 0:5a74eeaefb5d 103
dkato 0:5a74eeaefb5d 104 /* ---- Write enable ---- */
dkato 0:5a74eeaefb5d 105 ret = _WriteEnable(); /* WREN Command */
dkato 0:5a74eeaefb5d 106 if (ret == false) {
dkato 0:5a74eeaefb5d 107 return ret;
dkato 0:5a74eeaefb5d 108 }
dkato 0:5a74eeaefb5d 109
dkato 0:5a74eeaefb5d 110 /* ---- spimd_reg init ---- */
dkato 0:5a74eeaefb5d 111 clear_spimd_reg(&spimd_reg);
dkato 0:5a74eeaefb5d 112
dkato 0:5a74eeaefb5d 113 /* ---- command ---- */
dkato 0:5a74eeaefb5d 114 spimd_reg.cde = SPIBSC_OUTPUT_ENABLE;
dkato 0:5a74eeaefb5d 115 spimd_reg.cdb = SPIBSC_1BIT;
dkato 0:5a74eeaefb5d 116 spimd_reg.cmd = SFLASHCMD_SECTOR_ERASE;
dkato 0:5a74eeaefb5d 117
dkato 0:5a74eeaefb5d 118 /* ---- address ---- */
dkato 0:5a74eeaefb5d 119 spimd_reg.ade = SPIBSC_OUTPUT_ADDR_24;
dkato 0:5a74eeaefb5d 120 spimd_reg.addre = SPIBSC_SDR_TRANS; /* SDR */
dkato 0:5a74eeaefb5d 121 spimd_reg.adb = SPIBSC_1BIT;
dkato 0:5a74eeaefb5d 122 spimd_reg.addr = addr;
dkato 0:5a74eeaefb5d 123
dkato 0:5a74eeaefb5d 124 ret = spibsc_transfer(&spimd_reg);
dkato 0:5a74eeaefb5d 125 if (ret == false) {
dkato 0:5a74eeaefb5d 126 return ret;
dkato 0:5a74eeaefb5d 127 }
dkato 0:5a74eeaefb5d 128
dkato 0:5a74eeaefb5d 129 ret = _busy_wait();
dkato 0:5a74eeaefb5d 130
dkato 0:5a74eeaefb5d 131 return ret;
dkato 0:5a74eeaefb5d 132 }
dkato 0:5a74eeaefb5d 133
dkato 0:5a74eeaefb5d 134 bool FlashAccess::_PageProgram(uint32_t addr, uint8_t * buf, int32_t size) {
dkato 0:5a74eeaefb5d 135 bool ret;
dkato 0:5a74eeaefb5d 136
dkato 0:5a74eeaefb5d 137 /* ---- Write enable ---- */
dkato 0:5a74eeaefb5d 138 ret = _WriteEnable(); /* WREN Command */
dkato 0:5a74eeaefb5d 139 if (ret == false) {
dkato 0:5a74eeaefb5d 140 return ret;
dkato 0:5a74eeaefb5d 141 }
dkato 0:5a74eeaefb5d 142
dkato 0:5a74eeaefb5d 143 /* ----------- 1. Command, Address ---------------*/
dkato 0:5a74eeaefb5d 144 /* ---- spimd_reg init ---- */
dkato 0:5a74eeaefb5d 145 clear_spimd_reg(&spimd_reg);
dkato 0:5a74eeaefb5d 146
dkato 0:5a74eeaefb5d 147 /* ---- command ---- */
dkato 0:5a74eeaefb5d 148 spimd_reg.cde = SPIBSC_OUTPUT_ENABLE;
dkato 0:5a74eeaefb5d 149 spimd_reg.cdb = SPIBSC_1BIT;
dkato 0:5a74eeaefb5d 150 spimd_reg.cmd = SFLASHCMD_PAGE_PROGRAM;
dkato 0:5a74eeaefb5d 151
dkato 0:5a74eeaefb5d 152 /* ---- address ---- */
dkato 0:5a74eeaefb5d 153 spimd_reg.ade = SPIBSC_OUTPUT_ADDR_24;
dkato 0:5a74eeaefb5d 154 spimd_reg.addre = SPIBSC_SDR_TRANS; /* SDR */
dkato 0:5a74eeaefb5d 155 spimd_reg.adb = SPIBSC_1BIT;
dkato 0:5a74eeaefb5d 156 spimd_reg.addr = addr;
dkato 0:5a74eeaefb5d 157
dkato 0:5a74eeaefb5d 158 /* ---- Others ---- */
dkato 0:5a74eeaefb5d 159 spimd_reg.sslkp = SPIBSC_SPISSL_KEEP; /* SPBSSL level */
dkato 0:5a74eeaefb5d 160
dkato 0:5a74eeaefb5d 161 ret = spibsc_transfer(&spimd_reg); /* Command,Address */
dkato 0:5a74eeaefb5d 162 if (ret == false) {
dkato 0:5a74eeaefb5d 163 return ret;
dkato 0:5a74eeaefb5d 164 }
dkato 0:5a74eeaefb5d 165
dkato 0:5a74eeaefb5d 166 /* ----------- 2. Data ---------------*/
dkato 0:5a74eeaefb5d 167 ret = data_send(SPIBSC_1BIT, SPIBSC_SPISSL_NEGATE, buf, size);
dkato 0:5a74eeaefb5d 168 if (ret == false) {
dkato 0:5a74eeaefb5d 169 return ret;
dkato 0:5a74eeaefb5d 170 }
dkato 0:5a74eeaefb5d 171
dkato 0:5a74eeaefb5d 172 ret = _busy_wait();
dkato 0:5a74eeaefb5d 173
dkato 0:5a74eeaefb5d 174 return ret;
dkato 0:5a74eeaefb5d 175 }
dkato 0:5a74eeaefb5d 176
dkato 0:5a74eeaefb5d 177 bool FlashAccess::_Read(uint32_t addr, uint8_t * buf, int32_t size) {
dkato 0:5a74eeaefb5d 178 bool ret;
dkato 0:5a74eeaefb5d 179
dkato 0:5a74eeaefb5d 180 /* ----------- 1. Command, Address ---------------*/
dkato 0:5a74eeaefb5d 181 /* ---- spimd_reg init ---- */
dkato 0:5a74eeaefb5d 182 clear_spimd_reg(&spimd_reg);
dkato 0:5a74eeaefb5d 183
dkato 0:5a74eeaefb5d 184 /* ---- command ---- */
dkato 0:5a74eeaefb5d 185 spimd_reg.cde = SPIBSC_OUTPUT_ENABLE;
dkato 0:5a74eeaefb5d 186 spimd_reg.cdb = SPIBSC_1BIT;
dkato 0:5a74eeaefb5d 187 spimd_reg.cmd = SFLASHCMD_READ;
dkato 0:5a74eeaefb5d 188
dkato 0:5a74eeaefb5d 189 /* ---- address ---- */
dkato 0:5a74eeaefb5d 190 spimd_reg.ade = SPIBSC_OUTPUT_ADDR_24;
dkato 0:5a74eeaefb5d 191 spimd_reg.addre = SPIBSC_SDR_TRANS; /* SDR */
dkato 0:5a74eeaefb5d 192 spimd_reg.adb = SPIBSC_1BIT;
dkato 0:5a74eeaefb5d 193 spimd_reg.addr = addr;
dkato 0:5a74eeaefb5d 194
dkato 0:5a74eeaefb5d 195 /* ---- Others ---- */
dkato 0:5a74eeaefb5d 196 spimd_reg.sslkp = SPIBSC_SPISSL_KEEP; /* SPBSSL level */
dkato 0:5a74eeaefb5d 197
dkato 0:5a74eeaefb5d 198 ret = spibsc_transfer(&spimd_reg); /* Command,Address */
dkato 0:5a74eeaefb5d 199 if (ret == false) {
dkato 0:5a74eeaefb5d 200 return ret;
dkato 0:5a74eeaefb5d 201 }
dkato 0:5a74eeaefb5d 202
dkato 0:5a74eeaefb5d 203 /* ----------- 2. Data ---------------*/
dkato 0:5a74eeaefb5d 204 ret = data_recv(SPIBSC_1BIT, SPIBSC_SPISSL_NEGATE, buf, size);
dkato 0:5a74eeaefb5d 205
dkato 0:5a74eeaefb5d 206 return ret;
dkato 0:5a74eeaefb5d 207 }
dkato 0:5a74eeaefb5d 208
dkato 0:5a74eeaefb5d 209 bool FlashAccess::_WriteEnable(void) {
dkato 0:5a74eeaefb5d 210 bool ret;
dkato 0:5a74eeaefb5d 211
dkato 0:5a74eeaefb5d 212 /* ---- spimd_reg init ---- */
dkato 0:5a74eeaefb5d 213 clear_spimd_reg(&spimd_reg);
dkato 0:5a74eeaefb5d 214
dkato 0:5a74eeaefb5d 215 /* ---- command ---- */
dkato 0:5a74eeaefb5d 216 spimd_reg.cde = SPIBSC_OUTPUT_ENABLE;
dkato 0:5a74eeaefb5d 217 spimd_reg.cdb = SPIBSC_1BIT;
dkato 0:5a74eeaefb5d 218 spimd_reg.cmd = SFLASHCMD_WRITE_ENABLE;
dkato 0:5a74eeaefb5d 219
dkato 0:5a74eeaefb5d 220 ret = spibsc_transfer(&spimd_reg);
dkato 0:5a74eeaefb5d 221
dkato 0:5a74eeaefb5d 222 return ret;
dkato 0:5a74eeaefb5d 223 }
dkato 0:5a74eeaefb5d 224
dkato 0:5a74eeaefb5d 225 bool FlashAccess::_busy_wait(void) {
dkato 0:5a74eeaefb5d 226 bool ret;
dkato 0:5a74eeaefb5d 227 uint8_t st_reg;
dkato 0:5a74eeaefb5d 228
dkato 0:5a74eeaefb5d 229 while (1) {
dkato 0:5a74eeaefb5d 230 ret = _read_register(SFLASHCMD_READ_STATUS_REG, &st_reg);
dkato 0:5a74eeaefb5d 231 if (ret == false) {
dkato 0:5a74eeaefb5d 232 break;
dkato 0:5a74eeaefb5d 233 }
dkato 0:5a74eeaefb5d 234 if ((st_reg & STREG_BUSY_BIT) == 0) {
dkato 0:5a74eeaefb5d 235 break;
dkato 0:5a74eeaefb5d 236 }
dkato 0:5a74eeaefb5d 237 }
dkato 0:5a74eeaefb5d 238
dkato 0:5a74eeaefb5d 239 return ret;
dkato 0:5a74eeaefb5d 240 }
dkato 0:5a74eeaefb5d 241
dkato 0:5a74eeaefb5d 242 bool FlashAccess::_read_register(uint8_t cmd, uint8_t * status) {
dkato 0:5a74eeaefb5d 243 bool ret;
dkato 0:5a74eeaefb5d 244
dkato 0:5a74eeaefb5d 245 /* ---- spimd_reg init ---- */
dkato 0:5a74eeaefb5d 246 clear_spimd_reg(&spimd_reg);
dkato 0:5a74eeaefb5d 247
dkato 0:5a74eeaefb5d 248 /* ---- command ---- */
dkato 0:5a74eeaefb5d 249 spimd_reg.cde = SPIBSC_OUTPUT_ENABLE;
dkato 0:5a74eeaefb5d 250 spimd_reg.cdb = SPIBSC_1BIT;
dkato 0:5a74eeaefb5d 251 spimd_reg.cmd = cmd;
dkato 0:5a74eeaefb5d 252
dkato 0:5a74eeaefb5d 253 /* ---- Others ---- */
dkato 0:5a74eeaefb5d 254 spimd_reg.sslkp = SPIBSC_SPISSL_NEGATE; /* SPBSSL level */
dkato 0:5a74eeaefb5d 255 spimd_reg.spire = SPIBSC_SPIDATA_ENABLE; /* read enable/disable */
dkato 0:5a74eeaefb5d 256 spimd_reg.spiwe = SPIBSC_SPIDATA_ENABLE; /* write enable/disable */
dkato 0:5a74eeaefb5d 257
dkato 0:5a74eeaefb5d 258 /* ---- data ---- */
dkato 0:5a74eeaefb5d 259 spimd_reg.spide = SPIBSC_OUTPUT_SPID_8; /* Enable(8bit) */
dkato 0:5a74eeaefb5d 260 spimd_reg.spidre = SPIBSC_SDR_TRANS; /* SDR */
dkato 0:5a74eeaefb5d 261 spimd_reg.spidb = SPIBSC_1BIT;
dkato 0:5a74eeaefb5d 262 spimd_reg.smwdr[0] = 0x00; /* Output 0 in read status */
dkato 0:5a74eeaefb5d 263 spimd_reg.smwdr[1] = 0x00; /* Output 0 in read status */
dkato 0:5a74eeaefb5d 264
dkato 0:5a74eeaefb5d 265 ret = spibsc_transfer(&spimd_reg);
dkato 0:5a74eeaefb5d 266 if (ret != false) {
dkato 0:5a74eeaefb5d 267 *status = (uint8_t)(spimd_reg.smrdr[0]); /* Data[7:0] */
dkato 0:5a74eeaefb5d 268 }
dkato 0:5a74eeaefb5d 269
dkato 0:5a74eeaefb5d 270 return ret;
dkato 0:5a74eeaefb5d 271 }
dkato 0:5a74eeaefb5d 272
dkato 0:5a74eeaefb5d 273 bool FlashAccess::data_send(uint32_t bit_width, uint32_t spbssl_level, uint8_t * buf, int32_t size) {
dkato 0:5a74eeaefb5d 274 bool ret = true;
dkato 0:5a74eeaefb5d 275 int32_t unit;
dkato 0:5a74eeaefb5d 276 uint8_t *buf_b;
dkato 0:5a74eeaefb5d 277 uint16_t *buf_s;
dkato 0:5a74eeaefb5d 278 uint32_t *buf_l;
dkato 0:5a74eeaefb5d 279
dkato 0:5a74eeaefb5d 280 /* ---- spimd_reg init ---- */
dkato 0:5a74eeaefb5d 281 clear_spimd_reg(&spimd_reg);
dkato 0:5a74eeaefb5d 282
dkato 0:5a74eeaefb5d 283 /* ---- Others ---- */
dkato 0:5a74eeaefb5d 284 spimd_reg.sslkp = SPIBSC_SPISSL_KEEP; /* SPBSSL level */
dkato 0:5a74eeaefb5d 285 spimd_reg.spiwe = SPIBSC_SPIDATA_ENABLE; /* write enable/disable */
dkato 0:5a74eeaefb5d 286
dkato 0:5a74eeaefb5d 287 /* ---- data ---- */
dkato 0:5a74eeaefb5d 288 spimd_reg.spidb = bit_width;
dkato 0:5a74eeaefb5d 289 spimd_reg.spidre= SPIBSC_SDR_TRANS; /* SDR */
dkato 0:5a74eeaefb5d 290
dkato 0:5a74eeaefb5d 291 if (((uint32_t)size & 0x3) == 0) {
dkato 0:5a74eeaefb5d 292 spimd_reg.spide = SPIBSC_OUTPUT_SPID_32; /* Enable(32bit) */
dkato 0:5a74eeaefb5d 293 unit = 4;
dkato 0:5a74eeaefb5d 294 } else if (((uint32_t)size & 0x1) == 0) {
dkato 0:5a74eeaefb5d 295 spimd_reg.spide = SPIBSC_OUTPUT_SPID_16; /* Enable(16bit) */
dkato 0:5a74eeaefb5d 296 unit = 2;
dkato 0:5a74eeaefb5d 297 } else {
dkato 0:5a74eeaefb5d 298 spimd_reg.spide = SPIBSC_OUTPUT_SPID_8; /* Enable(8bit) */
dkato 0:5a74eeaefb5d 299 unit = 1;
dkato 0:5a74eeaefb5d 300 }
dkato 0:5a74eeaefb5d 301
dkato 0:5a74eeaefb5d 302 while (size > 0) {
dkato 0:5a74eeaefb5d 303 if (unit == 1) {
dkato 0:5a74eeaefb5d 304 buf_b = (uint8_t *)buf;
dkato 0:5a74eeaefb5d 305 spimd_reg.smwdr[0] = (uint32_t)(((uint32_t)*buf_b) & 0x000000FF);
dkato 0:5a74eeaefb5d 306 } else if (unit == 2) {
dkato 0:5a74eeaefb5d 307 buf_s = (uint16_t *)buf;
dkato 0:5a74eeaefb5d 308 spimd_reg.smwdr[0] = (uint32_t)(((uint32_t)*buf_s) & 0x0000FFFF);
dkato 0:5a74eeaefb5d 309 } else if (unit == 4) {
dkato 0:5a74eeaefb5d 310 buf_l = (uint32_t *)buf;
dkato 0:5a74eeaefb5d 311 spimd_reg.smwdr[0] = (uint32_t)(((uint32_t)(*buf_l)) & 0xfffffffful);
dkato 0:5a74eeaefb5d 312 } else {
dkato 0:5a74eeaefb5d 313 /* Do Nothing */
dkato 0:5a74eeaefb5d 314 }
dkato 0:5a74eeaefb5d 315
dkato 0:5a74eeaefb5d 316 buf += unit;
dkato 0:5a74eeaefb5d 317 size -= unit;
dkato 0:5a74eeaefb5d 318
dkato 0:5a74eeaefb5d 319 if (size <= 0) {
dkato 0:5a74eeaefb5d 320 spimd_reg.sslkp = spbssl_level;
dkato 0:5a74eeaefb5d 321 }
dkato 0:5a74eeaefb5d 322
dkato 0:5a74eeaefb5d 323 ret = spibsc_transfer(&spimd_reg); /* Data */
dkato 0:5a74eeaefb5d 324 if (ret == false) {
dkato 0:5a74eeaefb5d 325 return ret;
dkato 0:5a74eeaefb5d 326 }
dkato 0:5a74eeaefb5d 327 }
dkato 0:5a74eeaefb5d 328
dkato 0:5a74eeaefb5d 329 return ret;
dkato 0:5a74eeaefb5d 330 }
dkato 0:5a74eeaefb5d 331
dkato 0:5a74eeaefb5d 332 bool FlashAccess::data_recv(uint32_t bit_width, uint32_t spbssl_level, uint8_t * buf, int32_t size) {
dkato 0:5a74eeaefb5d 333 bool ret = true;
dkato 0:5a74eeaefb5d 334 int32_t unit;
dkato 0:5a74eeaefb5d 335 uint8_t *buf_b;
dkato 0:5a74eeaefb5d 336 uint16_t *buf_s;
dkato 0:5a74eeaefb5d 337 uint32_t *buf_l;
dkato 0:5a74eeaefb5d 338
dkato 0:5a74eeaefb5d 339 /* ---- spimd_reg init ---- */
dkato 0:5a74eeaefb5d 340 clear_spimd_reg(&spimd_reg);
dkato 0:5a74eeaefb5d 341
dkato 0:5a74eeaefb5d 342 /* ---- Others ---- */
dkato 0:5a74eeaefb5d 343 spimd_reg.sslkp = SPIBSC_SPISSL_KEEP; /* SPBSSL level */
dkato 0:5a74eeaefb5d 344 spimd_reg.spire = SPIBSC_SPIDATA_ENABLE; /* read enable/disable */
dkato 0:5a74eeaefb5d 345
dkato 0:5a74eeaefb5d 346 /* ---- data ---- */
dkato 0:5a74eeaefb5d 347 spimd_reg.spidb = bit_width;
dkato 0:5a74eeaefb5d 348 spimd_reg.spidre = SPIBSC_SDR_TRANS; /* SDR */
dkato 0:5a74eeaefb5d 349
dkato 0:5a74eeaefb5d 350 if (((uint32_t)size & 0x3) == 0) {
dkato 0:5a74eeaefb5d 351 spimd_reg.spide = SPIBSC_OUTPUT_SPID_32; /* Enable(32bit) */
dkato 0:5a74eeaefb5d 352 unit = 4;
dkato 0:5a74eeaefb5d 353 } else if (((uint32_t)size & 0x1) == 0) {
dkato 0:5a74eeaefb5d 354 spimd_reg.spide = SPIBSC_OUTPUT_SPID_16; /* Enable(16bit) */
dkato 0:5a74eeaefb5d 355 unit = 2;
dkato 0:5a74eeaefb5d 356 } else {
dkato 0:5a74eeaefb5d 357 spimd_reg.spide = SPIBSC_OUTPUT_SPID_8; /* Enable(8bit) */
dkato 0:5a74eeaefb5d 358 unit = 1;
dkato 0:5a74eeaefb5d 359 }
dkato 0:5a74eeaefb5d 360
dkato 0:5a74eeaefb5d 361 while (size > 0) {
dkato 0:5a74eeaefb5d 362 if (unit >= size) {
dkato 0:5a74eeaefb5d 363 spimd_reg.sslkp = spbssl_level;
dkato 0:5a74eeaefb5d 364 }
dkato 0:5a74eeaefb5d 365
dkato 0:5a74eeaefb5d 366 ret = spibsc_transfer(&spimd_reg); /* Data */
dkato 0:5a74eeaefb5d 367 if (ret == false) {
dkato 0:5a74eeaefb5d 368 return ret;
dkato 0:5a74eeaefb5d 369 }
dkato 0:5a74eeaefb5d 370
dkato 0:5a74eeaefb5d 371 if (unit == 1) {
dkato 0:5a74eeaefb5d 372 buf_b = (uint8_t *)buf;
dkato 0:5a74eeaefb5d 373 *buf_b = (uint8_t)((spimd_reg.smrdr[0]) & 0x000000fful);
dkato 0:5a74eeaefb5d 374 } else if (unit == 2) {
dkato 0:5a74eeaefb5d 375 buf_s = (uint16_t *)buf;
dkato 0:5a74eeaefb5d 376 *buf_s = (uint16_t)((spimd_reg.smrdr[0]) & 0x0000fffful);
dkato 0:5a74eeaefb5d 377 } else if (unit == 4) {
dkato 0:5a74eeaefb5d 378 buf_l = (uint32_t *)buf;
dkato 0:5a74eeaefb5d 379 *buf_l = (uint32_t)((spimd_reg.smrdr[0]) & 0xfffffffful);
dkato 0:5a74eeaefb5d 380 } else {
dkato 0:5a74eeaefb5d 381 /* Do Nothing */
dkato 0:5a74eeaefb5d 382 }
dkato 0:5a74eeaefb5d 383
dkato 0:5a74eeaefb5d 384 buf += unit;
dkato 0:5a74eeaefb5d 385 size -= unit;
dkato 0:5a74eeaefb5d 386 }
dkato 0:5a74eeaefb5d 387
dkato 0:5a74eeaefb5d 388 return ret;
dkato 0:5a74eeaefb5d 389 }
dkato 0:5a74eeaefb5d 390
dkato 0:5a74eeaefb5d 391 void FlashAccess::spi_mode(void) {
dkato 0:5a74eeaefb5d 392 volatile uint32_t dummy_read_32;
dkato 0:5a74eeaefb5d 393
dkato 0:5a74eeaefb5d 394 if (RegRead_32(&SPIBSC->CMNCR, SPIBSC_CMNCR_MD_SHIFT, SPIBSC_CMNCR_MD) != SPIBSC_CMNCR_MD_SPI) {
dkato 0:5a74eeaefb5d 395 /* ==== Change the MMU translation table SPI Multi-I/O bus space settings
dkato 0:5a74eeaefb5d 396 for use in SPI operating mode ==== */
dkato 0:5a74eeaefb5d 397 change_mmu_ttbl_spibsc(0);
dkato 0:5a74eeaefb5d 398
dkato 0:5a74eeaefb5d 399 /* ==== Cleaning and invalidation of cache ==== */
dkato 0:5a74eeaefb5d 400 cache_control();
dkato 0:5a74eeaefb5d 401
dkato 0:5a74eeaefb5d 402 /* ==== Switch to SPI operating mode ==== */
dkato 0:5a74eeaefb5d 403 spibsc_stop();
dkato 0:5a74eeaefb5d 404
dkato 0:5a74eeaefb5d 405 dummy_read_32 = SPIBSC->CMNCR; /* dummy read */
dkato 0:5a74eeaefb5d 406 /* SPI Mode */
dkato 0:5a74eeaefb5d 407 RegWwrite_32(&SPIBSC->CMNCR, SPIBSC_CMNCR_MD_SPI, SPIBSC_CMNCR_MD_SHIFT, SPIBSC_CMNCR_MD);
dkato 0:5a74eeaefb5d 408 dummy_read_32 = SPIBSC->CMNCR; /* dummy read */
dkato 0:5a74eeaefb5d 409
dkato 0:5a74eeaefb5d 410 }
dkato 0:5a74eeaefb5d 411 (void)dummy_read_32;
dkato 0:5a74eeaefb5d 412 }
dkato 0:5a74eeaefb5d 413
dkato 0:5a74eeaefb5d 414 void FlashAccess::ex_mode(void) {
dkato 0:5a74eeaefb5d 415 volatile uint32_t dummy_read_32;
dkato 0:5a74eeaefb5d 416
dkato 0:5a74eeaefb5d 417 if (RegRead_32(&SPIBSC->CMNCR, SPIBSC_CMNCR_MD_SHIFT, SPIBSC_CMNCR_MD) != SPIBSC_CMNCR_MD_EXTRD) {
dkato 0:5a74eeaefb5d 418 /* ==== Switch to external address space read mode and clear SPIBSC read cache ==== */
dkato 0:5a74eeaefb5d 419 spibsc_stop();
dkato 0:5a74eeaefb5d 420
dkato 0:5a74eeaefb5d 421 /* Flush SPIBSC's read cache */
dkato 0:5a74eeaefb5d 422 RegWwrite_32(&SPIBSC->DRCR, SPIBSC_DRCR_RCF_EXE, SPIBSC_DRCR_RCF_SHIFT, SPIBSC_DRCR_RCF);
dkato 0:5a74eeaefb5d 423 dummy_read_32 = SPIBSC->DRCR; /* dummy read */
dkato 0:5a74eeaefb5d 424
dkato 0:5a74eeaefb5d 425 /* External address space read mode */
dkato 0:5a74eeaefb5d 426 RegWwrite_32(&SPIBSC->CMNCR, SPIBSC_CMNCR_MD_EXTRD, SPIBSC_CMNCR_MD_SHIFT, SPIBSC_CMNCR_MD);
dkato 0:5a74eeaefb5d 427 dummy_read_32 = SPIBSC->CMNCR; /* dummy read */
dkato 0:5a74eeaefb5d 428
dkato 0:5a74eeaefb5d 429 /* ==== Change the MMU translation table SPI Multi-I/O bus space settings
dkato 0:5a74eeaefb5d 430 for use in external address space read mode ==== */
dkato 0:5a74eeaefb5d 431 change_mmu_ttbl_spibsc(1);
dkato 0:5a74eeaefb5d 432
dkato 0:5a74eeaefb5d 433 /* ==== Cleaning and invalidation of cache ==== */
dkato 0:5a74eeaefb5d 434 cache_control();
dkato 0:5a74eeaefb5d 435 }
dkato 0:5a74eeaefb5d 436 (void)dummy_read_32;
dkato 0:5a74eeaefb5d 437 }
dkato 0:5a74eeaefb5d 438
dkato 0:5a74eeaefb5d 439 void FlashAccess::clear_spimd_reg(st_spibsc_spimd_reg_t * regset) {
dkato 0:5a74eeaefb5d 440 /* ---- command ---- */
dkato 0:5a74eeaefb5d 441 regset->cde = SPIBSC_OUTPUT_DISABLE;
dkato 0:5a74eeaefb5d 442 regset->cdb = SPIBSC_1BIT;
dkato 0:5a74eeaefb5d 443 regset->cmd = 0x00;
dkato 0:5a74eeaefb5d 444
dkato 0:5a74eeaefb5d 445 /* ---- optional command ---- */
dkato 0:5a74eeaefb5d 446 regset->ocde = SPIBSC_OUTPUT_DISABLE;
dkato 0:5a74eeaefb5d 447 regset->ocdb = SPIBSC_1BIT;
dkato 0:5a74eeaefb5d 448 regset->ocmd = 0x00;
dkato 0:5a74eeaefb5d 449
dkato 0:5a74eeaefb5d 450 /* ---- address ---- */
dkato 0:5a74eeaefb5d 451 regset->ade = SPIBSC_OUTPUT_DISABLE;
dkato 0:5a74eeaefb5d 452 regset->addre = SPIBSC_SDR_TRANS; /* SDR */
dkato 0:5a74eeaefb5d 453 regset->adb = SPIBSC_1BIT;
dkato 0:5a74eeaefb5d 454 regset->addr = 0x00000000;
dkato 0:5a74eeaefb5d 455
dkato 0:5a74eeaefb5d 456 /* ---- option data ---- */
dkato 0:5a74eeaefb5d 457 regset->opde = SPIBSC_OUTPUT_DISABLE;
dkato 0:5a74eeaefb5d 458 regset->opdre = SPIBSC_SDR_TRANS; /* SDR */
dkato 0:5a74eeaefb5d 459 regset->opdb = SPIBSC_1BIT;
dkato 0:5a74eeaefb5d 460 regset->opd[0] = 0x00; /* OPD3 */
dkato 0:5a74eeaefb5d 461 regset->opd[1] = 0x00; /* OPD2 */
dkato 0:5a74eeaefb5d 462 regset->opd[2] = 0x00; /* OPD1 */
dkato 0:5a74eeaefb5d 463 regset->opd[3] = 0x00; /* OPD0 */
dkato 0:5a74eeaefb5d 464
dkato 0:5a74eeaefb5d 465 /* ---- dummy cycle ---- */
dkato 0:5a74eeaefb5d 466 regset->dme = SPIBSC_DUMMY_CYC_DISABLE;
dkato 0:5a74eeaefb5d 467 regset->dmdb = SPIBSC_1BIT;
dkato 0:5a74eeaefb5d 468 regset->dmcyc = SPIBSC_DUMMY_1CYC;
dkato 0:5a74eeaefb5d 469
dkato 0:5a74eeaefb5d 470 /* ---- data ---- */
dkato 0:5a74eeaefb5d 471 regset->spide = SPIBSC_OUTPUT_DISABLE;
dkato 0:5a74eeaefb5d 472 regset->spidre = SPIBSC_SDR_TRANS; /* SDR */
dkato 0:5a74eeaefb5d 473 regset->spidb = SPIBSC_1BIT;
dkato 0:5a74eeaefb5d 474
dkato 0:5a74eeaefb5d 475 /* ---- Others ---- */
dkato 0:5a74eeaefb5d 476 regset->sslkp = SPIBSC_SPISSL_NEGATE; /* SPBSSL level */
dkato 0:5a74eeaefb5d 477 regset->spire = SPIBSC_SPIDATA_DISABLE; /* read enable/disable */
dkato 0:5a74eeaefb5d 478 regset->spiwe = SPIBSC_SPIDATA_DISABLE; /* write enable/disable */
dkato 0:5a74eeaefb5d 479 }
dkato 0:5a74eeaefb5d 480
dkato 0:5a74eeaefb5d 481 bool FlashAccess::spibsc_transfer(st_spibsc_spimd_reg_t * regset) {
dkato 0:5a74eeaefb5d 482 if (RegRead_32(&SPIBSC->CMNCR, SPIBSC_CMNCR_MD_SHIFT, SPIBSC_CMNCR_MD) != SPIBSC_CMNCR_MD_SPI) {
dkato 0:5a74eeaefb5d 483 if (RegRead_32(&SPIBSC->CMNSR, SPIBSC_CMNSR_SSLF_SHIFT, SPIBSC_CMNSR_SSLF) != SPIBSC_SSL_NEGATE) {
dkato 0:5a74eeaefb5d 484 return false;
dkato 0:5a74eeaefb5d 485 }
dkato 0:5a74eeaefb5d 486 /* SPI Mode */
dkato 0:5a74eeaefb5d 487 RegWwrite_32(&SPIBSC->CMNCR, SPIBSC_CMNCR_MD_SPI, SPIBSC_CMNCR_MD_SHIFT, SPIBSC_CMNCR_MD);
dkato 0:5a74eeaefb5d 488 }
dkato 0:5a74eeaefb5d 489
dkato 0:5a74eeaefb5d 490 if (RegRead_32(&SPIBSC->CMNSR, SPIBSC_CMNSR_TEND_SHIFT, SPIBSC_CMNSR_TEND) != SPIBSC_TRANS_END) {
dkato 0:5a74eeaefb5d 491 return false;
dkato 0:5a74eeaefb5d 492 }
dkato 0:5a74eeaefb5d 493
dkato 0:5a74eeaefb5d 494 /* ---- Command ---- */
dkato 0:5a74eeaefb5d 495 /* Enable/Disable */
dkato 0:5a74eeaefb5d 496 RegWwrite_32(&SPIBSC->SMENR, regset->cde, SPIBSC_SMENR_CDE_SHIFT, SPIBSC_SMENR_CDE);
dkato 0:5a74eeaefb5d 497 if (regset->cde != SPIBSC_OUTPUT_DISABLE) {
dkato 0:5a74eeaefb5d 498 /* Command */
dkato 0:5a74eeaefb5d 499 RegWwrite_32(&SPIBSC->SMCMR, regset->cmd, SPIBSC_SMCMR_CMD_SHIFT, SPIBSC_SMCMR_CMD);
dkato 0:5a74eeaefb5d 500 /* Single/Dual/Quad */
dkato 0:5a74eeaefb5d 501 RegWwrite_32(&SPIBSC->SMENR, regset->cdb, SPIBSC_SMENR_CDB_SHIFT, SPIBSC_SMENR_CDB);
dkato 0:5a74eeaefb5d 502 }
dkato 0:5a74eeaefb5d 503
dkato 0:5a74eeaefb5d 504 /* ---- Option Command ---- */
dkato 0:5a74eeaefb5d 505 /* Enable/Disable */
dkato 0:5a74eeaefb5d 506 RegWwrite_32(&SPIBSC->SMENR, regset->ocde, SPIBSC_SMENR_OCDE_SHIFT, SPIBSC_SMENR_OCDE);
dkato 0:5a74eeaefb5d 507 if (regset->ocde != SPIBSC_OUTPUT_DISABLE) {
dkato 0:5a74eeaefb5d 508 /* Option Command */
dkato 0:5a74eeaefb5d 509 RegWwrite_32(&SPIBSC->SMCMR, regset->ocmd, SPIBSC_SMCMR_OCMD_SHIFT, SPIBSC_SMCMR_OCMD);
dkato 0:5a74eeaefb5d 510 /* Single/Dual/Quad */
dkato 0:5a74eeaefb5d 511 RegWwrite_32(&SPIBSC->SMENR, regset->ocdb, SPIBSC_SMENR_OCDB_SHIFT, SPIBSC_SMENR_OCDB);
dkato 0:5a74eeaefb5d 512 }
dkato 0:5a74eeaefb5d 513
dkato 0:5a74eeaefb5d 514 /* ---- Address ---- */
dkato 0:5a74eeaefb5d 515 /* Enable/Disable */
dkato 0:5a74eeaefb5d 516 RegWwrite_32(&SPIBSC->SMENR, regset->ade, SPIBSC_SMENR_ADE_SHIFT, SPIBSC_SMENR_ADE);
dkato 0:5a74eeaefb5d 517 if (regset->ade != SPIBSC_OUTPUT_DISABLE) {
dkato 0:5a74eeaefb5d 518 /* Address */
dkato 0:5a74eeaefb5d 519 RegWwrite_32(&SPIBSC->SMADR, regset->addr, SPIBSC_SMADR_ADR_SHIFT, SPIBSC_SMADR_ADR);
dkato 0:5a74eeaefb5d 520 /* Single/Dual/Quad */
dkato 0:5a74eeaefb5d 521 RegWwrite_32(&SPIBSC->SMENR, regset->adb, SPIBSC_SMENR_ADB_SHIFT, SPIBSC_SMENR_ADB);
dkato 0:5a74eeaefb5d 522 }
dkato 0:5a74eeaefb5d 523
dkato 0:5a74eeaefb5d 524 /* ---- Option Data ---- */
dkato 0:5a74eeaefb5d 525 /* Enable/Disable */
dkato 0:5a74eeaefb5d 526 RegWwrite_32(&SPIBSC->SMENR, regset->opde, SPIBSC_SMENR_OPDE_SHIFT, SPIBSC_SMENR_OPDE);
dkato 0:5a74eeaefb5d 527 if (regset->opde != SPIBSC_OUTPUT_DISABLE) {
dkato 0:5a74eeaefb5d 528 /* Option Data */
dkato 0:5a74eeaefb5d 529 RegWwrite_32(&SPIBSC->SMOPR, regset->opd[0], SPIBSC_SMOPR_OPD3_SHIFT, SPIBSC_SMOPR_OPD3);
dkato 0:5a74eeaefb5d 530 RegWwrite_32(&SPIBSC->SMOPR, regset->opd[1], SPIBSC_SMOPR_OPD2_SHIFT, SPIBSC_SMOPR_OPD2);
dkato 0:5a74eeaefb5d 531 RegWwrite_32(&SPIBSC->SMOPR, regset->opd[2], SPIBSC_SMOPR_OPD1_SHIFT, SPIBSC_SMOPR_OPD1);
dkato 0:5a74eeaefb5d 532 RegWwrite_32(&SPIBSC->SMOPR, regset->opd[3], SPIBSC_SMOPR_OPD0_SHIFT, SPIBSC_SMOPR_OPD0);
dkato 0:5a74eeaefb5d 533 /* Single/Dual/Quad */
dkato 0:5a74eeaefb5d 534 RegWwrite_32(&SPIBSC->SMENR, regset->opdb, SPIBSC_SMENR_OPDB_SHIFT, SPIBSC_SMENR_OPDB);
dkato 0:5a74eeaefb5d 535 }
dkato 0:5a74eeaefb5d 536
dkato 0:5a74eeaefb5d 537 /* ---- Dummy ---- */
dkato 0:5a74eeaefb5d 538 /* Enable/Disable */
dkato 0:5a74eeaefb5d 539 RegWwrite_32(&SPIBSC->SMENR, regset->dme, SPIBSC_SMENR_DME_SHIFT, SPIBSC_SMENR_DME);
dkato 0:5a74eeaefb5d 540 if (regset->dme != SPIBSC_DUMMY_CYC_DISABLE) {
dkato 0:5a74eeaefb5d 541 RegWwrite_32(&SPIBSC->SMDMCR, regset->dmdb, SPIBSC_SMDMCR_DMDB_SHIFT, SPIBSC_SMDMCR_DMDB);
dkato 0:5a74eeaefb5d 542 /* Dummy Cycle */
dkato 0:5a74eeaefb5d 543 RegWwrite_32(&SPIBSC->SMDMCR, regset->dmcyc, SPIBSC_SMDMCR_DMCYC_SHIFT, SPIBSC_SMDMCR_DMCYC);
dkato 0:5a74eeaefb5d 544 }
dkato 0:5a74eeaefb5d 545
dkato 0:5a74eeaefb5d 546 /* ---- Data ---- */
dkato 0:5a74eeaefb5d 547 /* Enable/Disable */
dkato 0:5a74eeaefb5d 548 RegWwrite_32(&SPIBSC->SMENR, regset->spide, SPIBSC_SMENR_SPIDE_SHIFT, SPIBSC_SMENR_SPIDE);
dkato 0:5a74eeaefb5d 549 if (regset->spide != SPIBSC_OUTPUT_DISABLE) {
dkato 0:5a74eeaefb5d 550 if (SPIBSC_OUTPUT_SPID_8 == regset->spide) {
dkato 0:5a74eeaefb5d 551 if (RegRead_32(&SPIBSC0.CMNCR, SPIBSC_CMNCR_BSZ_SHIFT, SPIBSC_CMNCR_BSZ) == SPIBSC_CMNCR_BSZ_SINGLE) {
dkato 0:5a74eeaefb5d 552 SPIBSC->SMWDR0.UINT8[0] = (uint8_t)(regset->smwdr[0]);
dkato 0:5a74eeaefb5d 553 } else {
dkato 0:5a74eeaefb5d 554 SPIBSC->SMWDR0.UINT16[0] = (uint16_t)(regset->smwdr[0]);
dkato 0:5a74eeaefb5d 555 }
dkato 0:5a74eeaefb5d 556 } else if (regset->spide == SPIBSC_OUTPUT_SPID_16) {
dkato 0:5a74eeaefb5d 557 if (RegRead_32(&SPIBSC0.CMNCR, SPIBSC_CMNCR_BSZ_SHIFT, SPIBSC_CMNCR_BSZ) == SPIBSC_CMNCR_BSZ_SINGLE) {
dkato 0:5a74eeaefb5d 558 SPIBSC->SMWDR0.UINT16[0] = (uint16_t)(regset->smwdr[0]);
dkato 0:5a74eeaefb5d 559 } else {
dkato 0:5a74eeaefb5d 560 SPIBSC->SMWDR0.UINT32 = regset->smwdr[0];
dkato 0:5a74eeaefb5d 561 }
dkato 0:5a74eeaefb5d 562 } else if (regset->spide == SPIBSC_OUTPUT_SPID_32) {
dkato 0:5a74eeaefb5d 563 if (RegRead_32(&SPIBSC0.CMNCR, SPIBSC_CMNCR_BSZ_SHIFT, SPIBSC_CMNCR_BSZ) == SPIBSC_CMNCR_BSZ_SINGLE) {
dkato 0:5a74eeaefb5d 564 SPIBSC->SMWDR0.UINT32 = (uint32_t)(regset->smwdr[0]);
dkato 0:5a74eeaefb5d 565 } else {
dkato 0:5a74eeaefb5d 566 SPIBSC->SMWDR0.UINT32 = (uint32_t)(regset->smwdr[0]);
dkato 0:5a74eeaefb5d 567 SPIBSC->SMWDR1.UINT32 = (uint32_t)(regset->smwdr[1]); /* valid in two serial-flash */
dkato 0:5a74eeaefb5d 568 }
dkato 0:5a74eeaefb5d 569 } else {
dkato 0:5a74eeaefb5d 570 /* none */
dkato 0:5a74eeaefb5d 571 }
dkato 0:5a74eeaefb5d 572
dkato 0:5a74eeaefb5d 573 /* Single/Dual/Quad */
dkato 0:5a74eeaefb5d 574 RegWwrite_32(&SPIBSC->SMENR, regset->spidb, SPIBSC_SMENR_SPIDB_SHIFT, SPIBSC_SMENR_SPIDB);
dkato 0:5a74eeaefb5d 575 }
dkato 0:5a74eeaefb5d 576
dkato 0:5a74eeaefb5d 577 RegWwrite_32(&SPIBSC->SMCR, regset->sslkp, SPIBSC_SMCR_SSLKP_SHIFT, SPIBSC_SMCR_SSLKP);
dkato 0:5a74eeaefb5d 578
dkato 0:5a74eeaefb5d 579 if ((regset->spidb != SPIBSC_1BIT) && (regset->spide != SPIBSC_OUTPUT_DISABLE)) {
dkato 0:5a74eeaefb5d 580 if ((regset->spire == SPIBSC_SPIDATA_ENABLE) && (regset->spiwe == SPIBSC_SPIDATA_ENABLE)) {
dkato 0:5a74eeaefb5d 581 /* not set in same time */
dkato 0:5a74eeaefb5d 582 return false;
dkato 0:5a74eeaefb5d 583 }
dkato 0:5a74eeaefb5d 584 }
dkato 0:5a74eeaefb5d 585
dkato 0:5a74eeaefb5d 586 RegWwrite_32(&SPIBSC->SMCR, regset->spire, SPIBSC_SMCR_SPIRE_SHIFT, SPIBSC_SMCR_SPIRE);
dkato 0:5a74eeaefb5d 587 RegWwrite_32(&SPIBSC->SMCR, regset->spiwe, SPIBSC_SMCR_SPIWE_SHIFT, SPIBSC_SMCR_SPIWE);
dkato 0:5a74eeaefb5d 588
dkato 0:5a74eeaefb5d 589 /* SDR Transmission/DDR Transmission Setting */
dkato 0:5a74eeaefb5d 590 RegWwrite_32(&SPIBSC->SMDRENR, regset->addre, SPIBSC_SMDRENR_ADDRE_SHIFT, SPIBSC_SMDRENR_ADDRE);
dkato 0:5a74eeaefb5d 591 RegWwrite_32(&SPIBSC->SMDRENR, regset->opdre, SPIBSC_SMDRENR_OPDRE_SHIFT, SPIBSC_SMDRENR_OPDRE);
dkato 0:5a74eeaefb5d 592 RegWwrite_32(&SPIBSC->SMDRENR, regset->spidre, SPIBSC_SMDRENR_SPIDRE_SHIFT, SPIBSC_SMDRENR_SPIDRE);
dkato 0:5a74eeaefb5d 593
dkato 0:5a74eeaefb5d 594 /* execute after setting SPNDL bit */
dkato 0:5a74eeaefb5d 595 RegWwrite_32(&SPIBSC->SMCR, SPIBSC_SPI_ENABLE, SPIBSC_SMCR_SPIE_SHIFT, SPIBSC_SMCR_SPIE);
dkato 0:5a74eeaefb5d 596
dkato 0:5a74eeaefb5d 597 /* wait for transfer-start */
dkato 0:5a74eeaefb5d 598 while (RegRead_32(&SPIBSC->CMNSR, SPIBSC_CMNSR_TEND_SHIFT, SPIBSC_CMNSR_TEND) != SPIBSC_TRANS_END) {
dkato 0:5a74eeaefb5d 599 /* wait for transfer-end */
dkato 0:5a74eeaefb5d 600 }
dkato 0:5a74eeaefb5d 601
dkato 0:5a74eeaefb5d 602 if (SPIBSC_OUTPUT_SPID_8 == regset->spide) {
dkato 0:5a74eeaefb5d 603 if (RegRead_32(&SPIBSC0.CMNCR, SPIBSC_CMNCR_BSZ_SHIFT, SPIBSC_CMNCR_BSZ) == SPIBSC_CMNCR_BSZ_SINGLE) {
dkato 0:5a74eeaefb5d 604 regset->smrdr[0] = SPIBSC->SMRDR0.UINT8[0];
dkato 0:5a74eeaefb5d 605 } else {
dkato 0:5a74eeaefb5d 606 regset->smrdr[0] = SPIBSC->SMRDR0.UINT16[0]; /* valid in two serial-flash */
dkato 0:5a74eeaefb5d 607 }
dkato 0:5a74eeaefb5d 608 } else if (regset->spide == SPIBSC_OUTPUT_SPID_16) {
dkato 0:5a74eeaefb5d 609 if (RegRead_32(&SPIBSC0.CMNCR, SPIBSC_CMNCR_BSZ_SHIFT, SPIBSC_CMNCR_BSZ) == SPIBSC_CMNCR_BSZ_SINGLE) {
dkato 0:5a74eeaefb5d 610 regset->smrdr[0] = SPIBSC->SMRDR0.UINT16[0];
dkato 0:5a74eeaefb5d 611 } else {
dkato 0:5a74eeaefb5d 612 regset->smrdr[0] = SPIBSC->SMRDR0.UINT32; /* valid in two serial-flash */
dkato 0:5a74eeaefb5d 613 }
dkato 0:5a74eeaefb5d 614 } else if (regset->spide == SPIBSC_OUTPUT_SPID_32) {
dkato 0:5a74eeaefb5d 615 if (RegRead_32(&SPIBSC0.CMNCR, SPIBSC_CMNCR_BSZ_SHIFT, SPIBSC_CMNCR_BSZ) == SPIBSC_CMNCR_BSZ_SINGLE) {
dkato 0:5a74eeaefb5d 616 regset->smrdr[0] = SPIBSC->SMRDR0.UINT32;
dkato 0:5a74eeaefb5d 617 } else {
dkato 0:5a74eeaefb5d 618 regset->smrdr[0] = SPIBSC->SMRDR0.UINT32; /* valid in two serial-flash */
dkato 0:5a74eeaefb5d 619 regset->smrdr[1] = SPIBSC->SMRDR1.UINT32;
dkato 0:5a74eeaefb5d 620 }
dkato 0:5a74eeaefb5d 621 } else {
dkato 0:5a74eeaefb5d 622 /* none */
dkato 0:5a74eeaefb5d 623 }
dkato 0:5a74eeaefb5d 624
dkato 0:5a74eeaefb5d 625 return true;
dkato 0:5a74eeaefb5d 626 }
dkato 0:5a74eeaefb5d 627
dkato 0:5a74eeaefb5d 628 uint32_t FlashAccess::RegRead_32(volatile uint32_t * ioreg, uint32_t shift, uint32_t mask) {
dkato 0:5a74eeaefb5d 629 uint32_t reg_value;
dkato 0:5a74eeaefb5d 630
dkato 0:5a74eeaefb5d 631 reg_value = *ioreg; /* Read from register */
dkato 0:5a74eeaefb5d 632 reg_value = (reg_value & mask) >> shift; /* Clear other bit and Bit shift */
dkato 0:5a74eeaefb5d 633
dkato 0:5a74eeaefb5d 634 return reg_value;
dkato 0:5a74eeaefb5d 635 }
dkato 0:5a74eeaefb5d 636
dkato 0:5a74eeaefb5d 637 void FlashAccess::RegWwrite_32(volatile uint32_t * ioreg, uint32_t write_value, uint32_t shift, uint32_t mask) {
dkato 0:5a74eeaefb5d 638 uint32_t reg_value;
dkato 0:5a74eeaefb5d 639
dkato 0:5a74eeaefb5d 640 reg_value = *ioreg; /* Read from register */
dkato 0:5a74eeaefb5d 641 reg_value = (reg_value & (~mask)) | (write_value << shift); /* Modify value */
dkato 0:5a74eeaefb5d 642 *ioreg = reg_value; /* Write to register */
dkato 0:5a74eeaefb5d 643 }
dkato 0:5a74eeaefb5d 644
dkato 0:5a74eeaefb5d 645 /** private **/
dkato 0:5a74eeaefb5d 646
dkato 0:5a74eeaefb5d 647 void FlashAccess::change_mmu_ttbl_spibsc(uint32_t type) {
dkato 0:5a74eeaefb5d 648 uint32_t index; /* Loop variable: table index */
dkato 0:5a74eeaefb5d 649 mmu_ttbl_desc_section_t desc; /* Loop variable: descriptor */
dkato 0:5a74eeaefb5d 650 mmu_ttbl_desc_section_t * table = (mmu_ttbl_desc_section_t *)TTB;
dkato 0:5a74eeaefb5d 651
dkato 0:5a74eeaefb5d 652 /* ==== Modify SPI Multi-I/O bus space settings in the MMU translation table ==== */
dkato 0:5a74eeaefb5d 653 for (index = (SPIBSC_ADDR_START >> 20); index <= (SPIBSC_ADDR_END >> 20); index++) {
dkato 0:5a74eeaefb5d 654 /* Modify memory attribute descriptor */
dkato 0:5a74eeaefb5d 655 if (type == 0) { /* Spi */
dkato 0:5a74eeaefb5d 656 desc = table[index];
dkato 0:5a74eeaefb5d 657 desc_tbl[index - (SPIBSC_ADDR_START >> 20)] = desc;
dkato 0:5a74eeaefb5d 658 desc.AP1_0 = 0x0u; /* AP[2:0] = b'000 (No access) */
dkato 0:5a74eeaefb5d 659 desc.AP2 = 0x0u;
dkato 0:5a74eeaefb5d 660 desc.XN = 0x1u; /* XN = 1 (Execute never) */
dkato 0:5a74eeaefb5d 661 } else { /* Xip */
dkato 0:5a74eeaefb5d 662 desc = desc_tbl[index - (SPIBSC_ADDR_START >> 20)];
dkato 0:5a74eeaefb5d 663 }
dkato 0:5a74eeaefb5d 664 /* Write descriptor back to translation table */
dkato 0:5a74eeaefb5d 665 table[index] = desc;
dkato 0:5a74eeaefb5d 666 }
dkato 0:5a74eeaefb5d 667 }
dkato 0:5a74eeaefb5d 668
dkato 0:5a74eeaefb5d 669 void FlashAccess::spibsc_stop(void) {
dkato 0:5a74eeaefb5d 670 if (((SPIBSC->DRCR & SPIBSC_DRCR_RBE) != 0) &&
dkato 0:5a74eeaefb5d 671 ((SPIBSC->DRCR & SPIBSC_DRCR_SSLE) != 0)) {
dkato 0:5a74eeaefb5d 672 RegWwrite_32(&SPIBSC->DRCR, 1, SPIBSC_DRCR_SSLN_SHIFT, SPIBSC_DRCR_SSLN);
dkato 0:5a74eeaefb5d 673 }
dkato 0:5a74eeaefb5d 674
dkato 0:5a74eeaefb5d 675 while (RegRead_32(&SPIBSC->CMNSR, SPIBSC_CMNSR_SSLF_SHIFT, SPIBSC_CMNSR_SSLF) != SPIBSC_SSL_NEGATE) {
dkato 0:5a74eeaefb5d 676 ;
dkato 0:5a74eeaefb5d 677 }
dkato 0:5a74eeaefb5d 678
dkato 0:5a74eeaefb5d 679 while (RegRead_32(&SPIBSC->CMNSR, SPIBSC_CMNSR_TEND_SHIFT, SPIBSC_CMNSR_TEND) != SPIBSC_TRANS_END) {
dkato 0:5a74eeaefb5d 680 ;
dkato 0:5a74eeaefb5d 681 }
dkato 0:5a74eeaefb5d 682 }
dkato 0:5a74eeaefb5d 683
dkato 0:5a74eeaefb5d 684 #ifndef __STATIC_FORCEINLINE
dkato 0:5a74eeaefb5d 685 #if defined ( __CC_ARM )
dkato 0:5a74eeaefb5d 686 #define __STATIC_FORCEINLINE static __forceinline
dkato 0:5a74eeaefb5d 687 #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
dkato 0:5a74eeaefb5d 688 #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline
dkato 0:5a74eeaefb5d 689 #elif defined ( __GNUC__ )
dkato 0:5a74eeaefb5d 690 #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline
dkato 0:5a74eeaefb5d 691 #elif defined ( __ICCARM__ )
dkato 0:5a74eeaefb5d 692 #define __STATIC_FORCEINLINE _Pragma("inline=forced") static inline
dkato 0:5a74eeaefb5d 693 #endif
dkato 0:5a74eeaefb5d 694 #endif
dkato 0:5a74eeaefb5d 695
dkato 0:5a74eeaefb5d 696 #if defined ( __CC_ARM )
dkato 0:5a74eeaefb5d 697 __STATIC_FORCEINLINE __ASM void L1C_CleanInvalidateCache_sforce(uint32_t op) {
dkato 0:5a74eeaefb5d 698 ARM
dkato 0:5a74eeaefb5d 699
dkato 0:5a74eeaefb5d 700 PUSH {R4-R11}
dkato 0:5a74eeaefb5d 701
dkato 0:5a74eeaefb5d 702 MRC p15, 1, R6, c0, c0, 1 // Read CLIDR
dkato 0:5a74eeaefb5d 703 ANDS R3, R6, #0x07000000 // Extract coherency level
dkato 0:5a74eeaefb5d 704 MOV R3, R3, LSR #23 // Total cache levels << 1
dkato 0:5a74eeaefb5d 705 BEQ Finished // If 0, no need to clean
dkato 0:5a74eeaefb5d 706
dkato 0:5a74eeaefb5d 707 MOV R10, #0 // R10 holds current cache level << 1
dkato 0:5a74eeaefb5d 708 Loop1 ADD R2, R10, R10, LSR #1 // R2 holds cache "Set" position
dkato 0:5a74eeaefb5d 709 MOV R1, R6, LSR R2 // Bottom 3 bits are the Cache-type for this level
dkato 0:5a74eeaefb5d 710 AND R1, R1, #7 // Isolate those lower 3 bits
dkato 0:5a74eeaefb5d 711 CMP R1, #2
dkato 0:5a74eeaefb5d 712 BLT Skip // No cache or only instruction cache at this level
dkato 0:5a74eeaefb5d 713
dkato 0:5a74eeaefb5d 714 MCR p15, 2, R10, c0, c0, 0 // Write the Cache Size selection register
dkato 0:5a74eeaefb5d 715 ISB // ISB to sync the change to the CacheSizeID reg
dkato 0:5a74eeaefb5d 716 MRC p15, 1, R1, c0, c0, 0 // Reads current Cache Size ID register
dkato 0:5a74eeaefb5d 717 AND R2, R1, #7 // Extract the line length field
dkato 0:5a74eeaefb5d 718 ADD R2, R2, #4 // Add 4 for the line length offset (log2 16 bytes)
dkato 0:5a74eeaefb5d 719 LDR R4, =0x3FF
dkato 0:5a74eeaefb5d 720 ANDS R4, R4, R1, LSR #3 // R4 is the max number on the way size (right aligned)
dkato 0:5a74eeaefb5d 721 CLZ R5, R4 // R5 is the bit position of the way size increment
dkato 0:5a74eeaefb5d 722 LDR R7, =0x7FFF
dkato 0:5a74eeaefb5d 723 ANDS R7, R7, R1, LSR #13 // R7 is the max number of the index size (right aligned)
dkato 0:5a74eeaefb5d 724
dkato 0:5a74eeaefb5d 725 Loop2 MOV R9, R4 // R9 working copy of the max way size (right aligned)
dkato 0:5a74eeaefb5d 726
dkato 0:5a74eeaefb5d 727 Loop3 ORR R11, R10, R9, LSL R5 // Factor in the Way number and cache number into R11
dkato 0:5a74eeaefb5d 728 ORR R11, R11, R7, LSL R2 // Factor in the Set number
dkato 0:5a74eeaefb5d 729 CMP R0, #0
dkato 0:5a74eeaefb5d 730 BNE Dccsw
dkato 0:5a74eeaefb5d 731 MCR p15, 0, R11, c7, c6, 2 // DCISW. Invalidate by Set/Way
dkato 0:5a74eeaefb5d 732 B cont
dkato 0:5a74eeaefb5d 733 Dccsw CMP R0, #1
dkato 0:5a74eeaefb5d 734 BNE Dccisw
dkato 0:5a74eeaefb5d 735 MCR p15, 0, R11, c7, c10, 2 // DCCSW. Clean by Set/Way
dkato 0:5a74eeaefb5d 736 B cont
dkato 0:5a74eeaefb5d 737 Dccisw MCR p15, 0, R11, c7, c14, 2 // DCCISW. Clean and Invalidate by Set/Way
dkato 0:5a74eeaefb5d 738 cont SUBS R9, R9, #1 // Decrement the Way number
dkato 0:5a74eeaefb5d 739 BGE Loop3
dkato 0:5a74eeaefb5d 740 SUBS R7, R7, #1 // Decrement the Set number
dkato 0:5a74eeaefb5d 741 BGE Loop2
dkato 0:5a74eeaefb5d 742 Skip ADD R10, R10, #2 // Increment the cache number
dkato 0:5a74eeaefb5d 743 CMP R3, R10
dkato 0:5a74eeaefb5d 744 BGT Loop1
dkato 0:5a74eeaefb5d 745
dkato 0:5a74eeaefb5d 746 Finished
dkato 0:5a74eeaefb5d 747 DSB
dkato 0:5a74eeaefb5d 748 POP {R4-R11}
dkato 0:5a74eeaefb5d 749 BX lr
dkato 0:5a74eeaefb5d 750 }
dkato 0:5a74eeaefb5d 751
dkato 0:5a74eeaefb5d 752 #elif (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) || defined ( __GNUC__ )
dkato 0:5a74eeaefb5d 753 __STATIC_FORCEINLINE void L1C_CleanInvalidateCache_sforce(uint32_t op) {
dkato 0:5a74eeaefb5d 754 __ASM volatile(
dkato 0:5a74eeaefb5d 755 " PUSH {R4-R11} \n"
dkato 0:5a74eeaefb5d 756
dkato 0:5a74eeaefb5d 757 " MRC p15, 1, R6, c0, c0, 1 \n" // Read CLIDR
dkato 0:5a74eeaefb5d 758 " ANDS R3, R6, #0x07000000 \n" // Extract coherency level
dkato 0:5a74eeaefb5d 759 " MOV R3, R3, LSR #23 \n" // Total cache levels << 1
dkato 0:5a74eeaefb5d 760 " BEQ Finished \n" // If 0, no need to clean
dkato 0:5a74eeaefb5d 761
dkato 0:5a74eeaefb5d 762 " MOV R10, #0 \n" // R10 holds current cache level << 1
dkato 0:5a74eeaefb5d 763 "Loop1: ADD R2, R10, R10, LSR #1 \n" // R2 holds cache "Set" position
dkato 0:5a74eeaefb5d 764 " MOV R1, R6, LSR R2 \n" // Bottom 3 bits are the Cache-type for this level
dkato 0:5a74eeaefb5d 765 " AND R1, R1, #7 \n" // Isolate those lower 3 bits
dkato 0:5a74eeaefb5d 766 " CMP R1, #2 \n"
dkato 0:5a74eeaefb5d 767 " BLT Skip \n" // No cache or only instruction cache at this level
dkato 0:5a74eeaefb5d 768
dkato 0:5a74eeaefb5d 769 " MCR p15, 2, R10, c0, c0, 0 \n" // Write the Cache Size selection register
dkato 0:5a74eeaefb5d 770 " ISB \n" // ISB to sync the change to the CacheSizeID reg
dkato 0:5a74eeaefb5d 771 " MRC p15, 1, R1, c0, c0, 0 \n" // Reads current Cache Size ID register
dkato 0:5a74eeaefb5d 772 " AND R2, R1, #7 \n" // Extract the line length field
dkato 0:5a74eeaefb5d 773 " ADD R2, R2, #4 \n" // Add 4 for the line length offset (log2 16 bytes)
dkato 0:5a74eeaefb5d 774 " LDR R4, =0x3FF \n"
dkato 0:5a74eeaefb5d 775 " ANDS R4, R4, R1, LSR #3 \n" // R4 is the max number on the way size (right aligned)
dkato 0:5a74eeaefb5d 776 " CLZ R5, R4 \n" // R5 is the bit position of the way size increment
dkato 0:5a74eeaefb5d 777 " LDR R7, =0x7FFF \n"
dkato 0:5a74eeaefb5d 778 " ANDS R7, R7, R1, LSR #13 \n" // R7 is the max number of the index size (right aligned)
dkato 0:5a74eeaefb5d 779
dkato 0:5a74eeaefb5d 780 "Loop2: MOV R9, R4 \n" // R9 working copy of the max way size (right aligned)
dkato 0:5a74eeaefb5d 781
dkato 0:5a74eeaefb5d 782 "Loop3: ORR R11, R10, R9, LSL R5 \n" // Factor in the Way number and cache number into R11
dkato 0:5a74eeaefb5d 783 " ORR R11, R11, R7, LSL R2 \n" // Factor in the Set number
dkato 0:5a74eeaefb5d 784 " CMP R0, #0 \n"
dkato 0:5a74eeaefb5d 785 " BNE Dccsw \n"
dkato 0:5a74eeaefb5d 786 " MCR p15, 0, R11, c7, c6, 2 \n" // DCISW. Invalidate by Set/Way
dkato 0:5a74eeaefb5d 787 " B cont \n"
dkato 0:5a74eeaefb5d 788 "Dccsw: CMP R0, #1 \n"
dkato 0:5a74eeaefb5d 789 " BNE Dccisw \n"
dkato 0:5a74eeaefb5d 790 " MCR p15, 0, R11, c7, c10, 2 \n" // DCCSW. Clean by Set/Way
dkato 0:5a74eeaefb5d 791 " B cont \n"
dkato 0:5a74eeaefb5d 792 "Dccisw: MCR p15, 0, R11, c7, c14, 2 \n" // DCCISW. Clean and Invalidate by Set/Way
dkato 0:5a74eeaefb5d 793 "cont: SUBS R9, R9, #1 \n" // Decrement the Way number
dkato 0:5a74eeaefb5d 794 " BGE Loop3 \n"
dkato 0:5a74eeaefb5d 795 " SUBS R7, R7, #1 \n" // Decrement the Set number
dkato 0:5a74eeaefb5d 796 " BGE Loop2 \n"
dkato 0:5a74eeaefb5d 797 "Skip: ADD R10, R10, #2 \n" // Increment the cache number
dkato 0:5a74eeaefb5d 798 " CMP R3, R10 \n"
dkato 0:5a74eeaefb5d 799 " BGT Loop1 \n"
dkato 0:5a74eeaefb5d 800
dkato 0:5a74eeaefb5d 801 "Finished: \n"
dkato 0:5a74eeaefb5d 802 " DSB \n"
dkato 0:5a74eeaefb5d 803 " POP {R4-R11} "
dkato 0:5a74eeaefb5d 804 );
dkato 0:5a74eeaefb5d 805 }
dkato 0:5a74eeaefb5d 806
dkato 0:5a74eeaefb5d 807 #else
dkato 0:5a74eeaefb5d 808 __STATIC_FORCEINLINE void __L1C_MaintainDCacheSetWay_sforce(uint32_t level, uint32_t maint) {
dkato 0:5a74eeaefb5d 809 register volatile uint32_t Dummy;
dkato 0:5a74eeaefb5d 810 register volatile uint32_t ccsidr;
dkato 0:5a74eeaefb5d 811 uint32_t num_sets;
dkato 0:5a74eeaefb5d 812 uint32_t num_ways;
dkato 0:5a74eeaefb5d 813 uint32_t shift_way;
dkato 0:5a74eeaefb5d 814 uint32_t log2_linesize;
dkato 0:5a74eeaefb5d 815 uint32_t log2_num_ways;
dkato 0:5a74eeaefb5d 816
dkato 0:5a74eeaefb5d 817 Dummy = level << 1;
dkato 0:5a74eeaefb5d 818 /* set csselr, select ccsidr register */
dkato 0:5a74eeaefb5d 819 __set_CCSIDR(Dummy);
dkato 0:5a74eeaefb5d 820 /* get current ccsidr register */
dkato 0:5a74eeaefb5d 821 ccsidr = __get_CCSIDR();
dkato 0:5a74eeaefb5d 822 num_sets = ((ccsidr & 0x0FFFE000) >> 13) + 1;
dkato 0:5a74eeaefb5d 823 num_ways = ((ccsidr & 0x00001FF8) >> 3) + 1;
dkato 0:5a74eeaefb5d 824 log2_linesize = (ccsidr & 0x00000007) + 2 + 2;
dkato 0:5a74eeaefb5d 825 log2_num_ways = log2_up(num_ways);
dkato 0:5a74eeaefb5d 826 shift_way = 32 - log2_num_ways;
dkato 0:5a74eeaefb5d 827 for (int way = num_ways-1; way >= 0; way--) {
dkato 0:5a74eeaefb5d 828 for (int set = num_sets-1; set >= 0; set--) {
dkato 0:5a74eeaefb5d 829 Dummy = (level << 1) | (set << log2_linesize) | (way << shift_way);
dkato 0:5a74eeaefb5d 830 switch (maint) {
dkato 0:5a74eeaefb5d 831 case 0:
dkato 0:5a74eeaefb5d 832 // DCISW. Invalidate by Set/Way
dkato 0:5a74eeaefb5d 833 __ASM volatile("MCR p15, 0, %0, c7, c6, 2" : : "r"(Dummy) : "memory");
dkato 0:5a74eeaefb5d 834 break;
dkato 0:5a74eeaefb5d 835 case 1:
dkato 0:5a74eeaefb5d 836 // DCCSW. Clean by Set/Way
dkato 0:5a74eeaefb5d 837 __ASM volatile("MCR p15, 0, %0, c7, c10, 2" : : "r"(Dummy) : "memory");
dkato 0:5a74eeaefb5d 838 break;
dkato 0:5a74eeaefb5d 839 default:
dkato 0:5a74eeaefb5d 840 // DCCISW. Clean and Invalidate by Set/Way
dkato 0:5a74eeaefb5d 841 __ASM volatile("MCR p15, 0, %0, c7, c14, 2" : : "r"(Dummy) : "memory");
dkato 0:5a74eeaefb5d 842 break;
dkato 0:5a74eeaefb5d 843 }
dkato 0:5a74eeaefb5d 844 }
dkato 0:5a74eeaefb5d 845 }
dkato 0:5a74eeaefb5d 846 __DMB();
dkato 0:5a74eeaefb5d 847 }
dkato 0:5a74eeaefb5d 848
dkato 0:5a74eeaefb5d 849 __STATIC_FORCEINLINE void L1C_CleanInvalidateCache_sforce(uint32_t op) {
dkato 0:5a74eeaefb5d 850 register volatile uint32_t clidr;
dkato 0:5a74eeaefb5d 851 uint32_t cache_type;
dkato 0:5a74eeaefb5d 852 clidr = __get_CLIDR();
dkato 0:5a74eeaefb5d 853 for (uint32_t i = 0; i<7; i++) {
dkato 0:5a74eeaefb5d 854 cache_type = (clidr >> i*3) & 0x7UL;
dkato 0:5a74eeaefb5d 855 if ((cache_type >= 2) && (cache_type <= 4)) {
dkato 0:5a74eeaefb5d 856 __L1C_MaintainDCacheSetWay_sforce(i, op);
dkato 0:5a74eeaefb5d 857 }
dkato 0:5a74eeaefb5d 858 }
dkato 0:5a74eeaefb5d 859 }
dkato 0:5a74eeaefb5d 860 #endif
dkato 0:5a74eeaefb5d 861
dkato 0:5a74eeaefb5d 862 #ifdef MBED_VERSION
dkato 0:5a74eeaefb5d 863
dkato 0:5a74eeaefb5d 864 void FlashAccess::cache_control(void) {
dkato 0:5a74eeaefb5d 865 unsigned int assoc;
dkato 0:5a74eeaefb5d 866
dkato 0:5a74eeaefb5d 867 /* ==== Cleaning and invalidation of the L1 data cache ==== */
dkato 0:5a74eeaefb5d 868 L1C_CleanInvalidateCache_sforce(2);
dkato 0:5a74eeaefb5d 869 __DSB();
dkato 0:5a74eeaefb5d 870
dkato 0:5a74eeaefb5d 871 /* ==== Cleaning and invalidation of the L2 cache ==== */
dkato 0:5a74eeaefb5d 872 if (PL310->AUX_CNT & (1<<16)) {
dkato 0:5a74eeaefb5d 873 assoc = 16;
dkato 0:5a74eeaefb5d 874 } else {
dkato 0:5a74eeaefb5d 875 assoc = 8;
dkato 0:5a74eeaefb5d 876 }
dkato 0:5a74eeaefb5d 877 PL310->INV_WAY = (1 << assoc) - 1;
dkato 0:5a74eeaefb5d 878 while(PL310->INV_WAY & ((1 << assoc) - 1)); // poll invalidate
dkato 0:5a74eeaefb5d 879 PL310->CACHE_SYNC = 0x0;
dkato 0:5a74eeaefb5d 880
dkato 0:5a74eeaefb5d 881 /* ==== Invalidate all TLB entries ==== */
dkato 0:5a74eeaefb5d 882 __ca9u_inv_tlb_all();
dkato 0:5a74eeaefb5d 883
dkato 0:5a74eeaefb5d 884 /* ==== Invalidate the L1 instruction cache ==== */
dkato 0:5a74eeaefb5d 885 __v7_inv_icache_all();
dkato 0:5a74eeaefb5d 886 __DSB();
dkato 0:5a74eeaefb5d 887 __ISB();
dkato 0:5a74eeaefb5d 888 }
dkato 0:5a74eeaefb5d 889
dkato 0:5a74eeaefb5d 890 #else // mbed-os 5.6.4
dkato 0:5a74eeaefb5d 891
dkato 0:5a74eeaefb5d 892 void FlashAccess::cache_control(void) {
dkato 0:5a74eeaefb5d 893 unsigned int assoc;
dkato 0:5a74eeaefb5d 894
dkato 0:5a74eeaefb5d 895 /* ==== Cleaning and invalidation of the L1 data cache ==== */
dkato 0:5a74eeaefb5d 896 L1C_CleanInvalidateCache_sforce(2);
dkato 0:5a74eeaefb5d 897 __DSB();
dkato 0:5a74eeaefb5d 898
dkato 0:5a74eeaefb5d 899 /* ==== Cleaning and invalidation of the L2 cache ==== */
dkato 0:5a74eeaefb5d 900 if (L2C_310->AUX_CNT & (1U << 16U)) {
dkato 0:5a74eeaefb5d 901 assoc = 16U;
dkato 0:5a74eeaefb5d 902 } else {
dkato 0:5a74eeaefb5d 903 assoc = 8U;
dkato 0:5a74eeaefb5d 904 }
dkato 0:5a74eeaefb5d 905 L2C_310->CLEAN_INV_WAY = (1U << assoc) - 1U;
dkato 0:5a74eeaefb5d 906 while (L2C_310->CLEAN_INV_WAY & ((1U << assoc) - 1U)); // poll invalidate
dkato 0:5a74eeaefb5d 907 L2C_310->CACHE_SYNC = 0x0;
dkato 0:5a74eeaefb5d 908
dkato 0:5a74eeaefb5d 909 /* ==== Invalidate all TLB entries ==== */
dkato 0:5a74eeaefb5d 910 __set_TLBIALL(0);
dkato 0:5a74eeaefb5d 911 __DSB(); // ensure completion of the invalidation
dkato 0:5a74eeaefb5d 912 __ISB(); // ensure instruction fetch path sees new state
dkato 0:5a74eeaefb5d 913
dkato 0:5a74eeaefb5d 914 /* ==== Invalidate the L1 instruction cache ==== */
dkato 0:5a74eeaefb5d 915 __set_ICIALLU(0);
dkato 0:5a74eeaefb5d 916 __DSB(); // ensure completion of the invalidation
dkato 0:5a74eeaefb5d 917 __ISB(); // ensure instruction fetch path sees new I cache state
dkato 0:5a74eeaefb5d 918 }
dkato 0:5a74eeaefb5d 919 #endif