esp_psram_impl_quad.c 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175
  1. /*
  2. Driver bits for PSRAM chips (at the moment only the ESP-PSRAM32 chip).
  3. */
  4. /*
  5. * SPDX-FileCopyrightText: 2013-2023 Espressif Systems (Shanghai) CO LTD
  6. *
  7. * SPDX-License-Identifier: Apache-2.0
  8. */
  9. #include "sdkconfig.h"
  10. #include "string.h"
  11. #include "esp_attr.h"
  12. #include "esp_err.h"
  13. #include "esp_types.h"
  14. #include "esp_bit_defs.h"
  15. #include "esp_log.h"
  16. #include "../esp_psram_impl.h"
  17. #include "esp32/rom/spi_flash.h"
  18. #include "esp32/rom/cache.h"
  19. #include "esp32/rom/efuse.h"
  20. #include "esp_rom_efuse.h"
  21. #include "soc/dport_reg.h"
  22. #include "soc/efuse_periph.h"
  23. #include "soc/soc_caps.h"
  24. #include "soc/spi_periph.h"
  25. #include "soc/chip_revision.h"
  26. #include "driver/gpio.h"
  27. #include "hal/efuse_hal.h"
  28. #include "hal/gpio_hal.h"
  29. #include "esp_private/spi_common_internal.h"
  30. #include "esp_private/periph_ctrl.h"
  31. #include "bootloader_common.h"
  32. #include "esp_rom_gpio.h"
  33. #include "bootloader_flash_config.h"
  34. #include "esp_private/esp_gpio_reserve.h"
  35. #if CONFIG_SPIRAM
  36. #include "soc/rtc.h"
  37. //Commands for PSRAM chip
  38. #define PSRAM_READ 0x03
  39. #define PSRAM_FAST_READ 0x0B
  40. #define PSRAM_FAST_READ_DUMMY 0x3
  41. #define PSRAM_FAST_READ_QUAD 0xEB
  42. #define PSRAM_FAST_READ_QUAD_DUMMY 0x5
  43. #define PSRAM_WRITE 0x02
  44. #define PSRAM_QUAD_WRITE 0x38
  45. #define PSRAM_ENTER_QMODE 0x35
  46. #define PSRAM_EXIT_QMODE 0xF5
  47. #define PSRAM_RESET_EN 0x66
  48. #define PSRAM_RESET 0x99
  49. #define PSRAM_SET_BURST_LEN 0xC0
  50. #define PSRAM_DEVICE_ID 0x9F
  51. typedef enum {
  52. PSRAM_CLK_MODE_NORM = 0, /*!< Normal SPI mode */
  53. PSRAM_CLK_MODE_DCLK = 1, /*!< Two extra clock cycles after CS is set high level */
  54. } psram_clk_mode_t;
  55. #define PSRAM_ID_KGD_M 0xff
  56. #define PSRAM_ID_KGD_S 8
  57. #define PSRAM_ID_KGD 0x5d
  58. #define PSRAM_ID_EID_M 0xff
  59. #define PSRAM_ID_EID_S 16
  60. // Use the [7:5](bit7~bit5) of EID to distinguish the psram size:
  61. //
  62. // BIT7 | BIT6 | BIT5 | SIZE(MBIT)
  63. // -------------------------------------
  64. // 0 | 0 | 0 | 16
  65. // 0 | 0 | 1 | 32
  66. // 0 | 1 | 0 | 64
  67. #define PSRAM_EID_SIZE_M 0x07
  68. #define PSRAM_EID_SIZE_S 5
  69. typedef enum {
  70. PSRAM_EID_SIZE_16MBITS = 0,
  71. PSRAM_EID_SIZE_32MBITS = 1,
  72. PSRAM_EID_SIZE_64MBITS = 2,
  73. } psram_eid_size_t;
  74. #define PSRAM_KGD(id) (((id) >> PSRAM_ID_KGD_S) & PSRAM_ID_KGD_M)
  75. #define PSRAM_EID(id) (((id) >> PSRAM_ID_EID_S) & PSRAM_ID_EID_M)
  76. #define PSRAM_SIZE_ID(id) ((PSRAM_EID(id) >> PSRAM_EID_SIZE_S) & PSRAM_EID_SIZE_M)
  77. #define PSRAM_IS_VALID(id) (PSRAM_KGD(id) == PSRAM_ID_KGD)
  78. // For the old version 32Mbit psram, using the spicial driver */
  79. #define PSRAM_IS_32MBIT_VER0(id) (PSRAM_EID(id) == 0x20)
  80. #define PSRAM_IS_64MBIT_TRIAL(id) (PSRAM_EID(id) == 0x26)
  81. // IO-pins for PSRAM.
  82. // WARNING: PSRAM shares all but the CS and CLK pins with the flash, so these defines
  83. // hardcode the flash pins as well, making this code incompatible with either a setup
  84. // that has the flash on non-standard pins or ESP32s with built-in flash.
  85. #define PSRAM_SPIQ_SD0_IO 7
  86. #define PSRAM_SPID_SD1_IO 8
  87. #define PSRAM_SPIWP_SD3_IO 10
  88. #define PSRAM_SPIHD_SD2_IO 9
  89. #define FLASH_HSPI_CLK_IO 14
  90. #define FLASH_HSPI_CS_IO 15
  91. #define PSRAM_HSPI_SPIQ_SD0_IO 12
  92. #define PSRAM_HSPI_SPID_SD1_IO 13
  93. #define PSRAM_HSPI_SPIWP_SD3_IO 2
  94. #define PSRAM_HSPI_SPIHD_SD2_IO 4
  95. // PSRAM clock and cs IO should be configured based on hardware design.
  96. // For ESP32-WROVER or ESP32-WROVER-B module, the clock IO is IO17, the cs IO is IO16,
  97. // they are the default value for these two configs.
  98. #define D0WD_PSRAM_CLK_IO CONFIG_D0WD_PSRAM_CLK_IO // Default value is 17
  99. #define D0WD_PSRAM_CS_IO CONFIG_D0WD_PSRAM_CS_IO // Default value is 16
  100. #define D2WD_PSRAM_CLK_IO CONFIG_D2WD_PSRAM_CLK_IO // Default value is 9
  101. #define D2WD_PSRAM_CS_IO CONFIG_D2WD_PSRAM_CS_IO // Default value is 10
  102. // There is no reason to change the pin of an embedded psram.
  103. // So define the number of pin directly, instead of configurable.
  104. #define D0WDR2_V3_PSRAM_CLK_IO 6
  105. #define D0WDR2_V3_PSRAM_CS_IO 16
  106. // For ESP32-PICO chip, the psram share clock with flash. The flash clock pin is fixed, which is IO6.
  107. #define PICO_PSRAM_CLK_IO 6
  108. #define PICO_PSRAM_CS_IO CONFIG_PICO_PSRAM_CS_IO // Default value is 10
  109. #define PICO_V3_02_PSRAM_CLK_IO 10
  110. #define PICO_V3_02_PSRAM_CS_IO 9
  111. typedef enum {
  112. PSRAM_CACHE_F80M_S40M = 0,
  113. PSRAM_CACHE_F40M_S40M,
  114. PSRAM_CACHE_F80M_S80M,
  115. PSRAM_CACHE_MAX,
  116. } psram_cache_speed_t;
  117. #if CONFIG_SPIRAM_SPEED_40M && CONFIG_ESPTOOLPY_FLASHFREQ_40M
  118. #define PSRAM_SPEED PSRAM_CACHE_F40M_S40M
  119. #define PSRAM_CS_HOLD_TIME 0
  120. #elif CONFIG_SPIRAM_SPEED_40M && CONFIG_ESPTOOLPY_FLASHFREQ_80M
  121. #define PSRAM_SPEED PSRAM_CACHE_F80M_S40M
  122. #define PSRAM_CS_HOLD_TIME 0
  123. #elif CONFIG_SPIRAM_SPEED_80M && CONFIG_ESPTOOLPY_FLASHFREQ_80M
  124. #define PSRAM_SPEED PSRAM_CACHE_F80M_S80M
  125. #define PSRAM_CS_HOLD_TIME 1
  126. #else
  127. #error "FLASH speed can only be equal to or higher than SRAM speed while SRAM is enabled!"
  128. #endif
  129. typedef struct {
  130. uint8_t flash_clk_io;
  131. uint8_t flash_cs_io;
  132. uint8_t psram_clk_io;
  133. uint8_t psram_cs_io;
  134. uint8_t psram_spiq_sd0_io;
  135. uint8_t psram_spid_sd1_io;
  136. uint8_t psram_spiwp_sd3_io;
  137. uint8_t psram_spihd_sd2_io;
  138. } psram_io_t;
  139. #define PSRAM_INTERNAL_IO_28 28
  140. #define PSRAM_INTERNAL_IO_29 29
  141. #define PSRAM_IO_MATRIX_DUMMY_40M ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_40M
  142. #define PSRAM_IO_MATRIX_DUMMY_80M ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_80M
  143. #define _SPI_CACHE_PORT 0
  144. #define _SPI_FLASH_PORT 1
  145. #define _SPI_80M_CLK_DIV 1
  146. #define _SPI_40M_CLK_DIV 2
  147. //For 4MB PSRAM, we need one more SPI host, select which one to use by kconfig
  148. #ifdef CONFIG_SPIRAM_OCCUPY_HSPI_HOST
  149. #define PSRAM_SPI_MODULE PERIPH_HSPI_MODULE
  150. #define PSRAM_SPI_HOST HSPI_HOST
  151. #define PSRAM_CLK_SIGNAL HSPICLK_OUT_IDX
  152. #define PSRAM_SPI_NUM PSRAM_SPI_2
  153. #define PSRAM_SPICLKEN DPORT_SPI2_CLK_EN
  154. #elif defined CONFIG_SPIRAM_OCCUPY_VSPI_HOST
  155. #define PSRAM_SPI_MODULE PERIPH_VSPI_MODULE
  156. #define PSRAM_SPI_HOST VSPI_HOST
  157. #define PSRAM_CLK_SIGNAL VSPICLK_OUT_IDX
  158. #define PSRAM_SPI_NUM PSRAM_SPI_3
  159. #define PSRAM_SPICLKEN DPORT_SPI3_CLK_EN
  160. #else //set to SPI avoid HSPI and VSPI being used
  161. #define PSRAM_SPI_MODULE PERIPH_SPI_MODULE
  162. #define PSRAM_SPI_HOST SPI_HOST
  163. #define PSRAM_CLK_SIGNAL SPICLK_OUT_IDX
  164. #define PSRAM_SPI_NUM PSRAM_SPI_1
  165. #define PSRAM_SPICLKEN DPORT_SPI01_CLK_EN
  166. #endif
  167. /*
  168. See the TRM, chapter PID/MPU/MMU, header 'External RAM' for the definitions of these modes.
  169. Important is that NORMAL works with the app CPU cache disabled, but gives huge cache coherency
  170. issues when both app and pro CPU are enabled. LOWHIGH and EVENODD do not have these coherency
  171. issues but cannot be used when the app CPU cache is disabled.
  172. */
  173. typedef enum {
  174. PSRAM_VADDR_MODE_NORMAL = 0, ///< App and pro CPU use their own flash cache for external RAM access
  175. PSRAM_VADDR_MODE_LOWHIGH, ///< App and pro CPU share external RAM caches: pro CPU has low 2M, app CPU has high 2M
  176. PSRAM_VADDR_MODE_EVENODD, ///< App and pro CPU share external RAM caches: pro CPU does even 32yte ranges, app does odd ones.
  177. } psram_vaddr_mode_t;
  178. #if CONFIG_FREERTOS_UNICORE
  179. #define PSRAM_MODE PSRAM_VADDR_MODE_NORMAL
  180. #else
  181. #define PSRAM_MODE PSRAM_VADDR_MODE_LOWHIGH
  182. #endif
  183. static const char *TAG = "quad_psram";
  184. typedef enum {
  185. PSRAM_SPI_1 = 0x1,
  186. PSRAM_SPI_2,
  187. PSRAM_SPI_3,
  188. PSRAM_SPI_MAX,
  189. } psram_spi_num_t;
  190. static psram_cache_speed_t s_psram_mode = PSRAM_CACHE_MAX;
  191. static psram_clk_mode_t s_clk_mode = PSRAM_CLK_MODE_DCLK;
  192. static uint64_t s_psram_id = 0;
  193. static bool s_2t_mode_enabled = false;
  194. /* dummy_len_plus values defined in ROM for SPI flash configuration */
  195. extern uint8_t g_rom_spiflash_dummy_len_plus[];
  196. static int extra_dummy = 0;
  197. typedef enum {
  198. PSRAM_CMD_QPI,
  199. PSRAM_CMD_SPI,
  200. } psram_cmd_mode_t;
  201. typedef struct {
  202. uint16_t cmd; /*!< Command value */
  203. uint16_t cmdBitLen; /*!< Command byte length*/
  204. uint32_t *addr; /*!< Point to address value*/
  205. uint16_t addrBitLen; /*!< Address byte length*/
  206. uint32_t *txData; /*!< Point to send data buffer*/
  207. uint16_t txDataBitLen; /*!< Send data byte length.*/
  208. uint32_t *rxData; /*!< Point to recevie data buffer*/
  209. uint16_t rxDataBitLen; /*!< Recevie Data byte length.*/
  210. uint32_t dummyBitLen;
  211. } psram_cmd_t;
  212. static void psram_cache_init(psram_cache_speed_t psram_cache_mode, psram_vaddr_mode_t vaddrmode);
  213. static uint8_t s_psram_cs_io = (uint8_t) -1;
  214. uint8_t esp_psram_impl_get_cs_io(void)
  215. {
  216. return s_psram_cs_io;
  217. }
  218. static void psram_clear_spi_fifo(psram_spi_num_t spi_num)
  219. {
  220. int i;
  221. for (i = 0; i < 16; i++) {
  222. WRITE_PERI_REG(SPI_W0_REG(spi_num) + i * 4, 0);
  223. }
  224. }
  225. //set basic SPI write mode
  226. static void psram_set_basic_write_mode(psram_spi_num_t spi_num)
  227. {
  228. CLEAR_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_FWRITE_QIO);
  229. CLEAR_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_FWRITE_DIO);
  230. CLEAR_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_FWRITE_QUAD);
  231. CLEAR_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_FWRITE_DUAL);
  232. }
  233. //set QPI write mode
  234. static void psram_set_qio_write_mode(psram_spi_num_t spi_num)
  235. {
  236. SET_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_FWRITE_QIO);
  237. CLEAR_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_FWRITE_DIO);
  238. CLEAR_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_FWRITE_QUAD);
  239. CLEAR_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_FWRITE_DUAL);
  240. }
  241. //set QPI read mode
  242. static void psram_set_qio_read_mode(psram_spi_num_t spi_num)
  243. {
  244. SET_PERI_REG_MASK(SPI_CTRL_REG(spi_num), SPI_FREAD_QIO);
  245. CLEAR_PERI_REG_MASK(SPI_CTRL_REG(spi_num), SPI_FREAD_QUAD);
  246. CLEAR_PERI_REG_MASK(SPI_CTRL_REG(spi_num), SPI_FREAD_DUAL);
  247. CLEAR_PERI_REG_MASK(SPI_CTRL_REG(spi_num), SPI_FREAD_DIO);
  248. }
  249. //set SPI read mode
  250. static void psram_set_basic_read_mode(psram_spi_num_t spi_num)
  251. {
  252. CLEAR_PERI_REG_MASK(SPI_CTRL_REG(spi_num), SPI_FREAD_QIO);
  253. CLEAR_PERI_REG_MASK(SPI_CTRL_REG(spi_num), SPI_FREAD_QUAD);
  254. CLEAR_PERI_REG_MASK(SPI_CTRL_REG(spi_num), SPI_FREAD_DUAL);
  255. CLEAR_PERI_REG_MASK(SPI_CTRL_REG(spi_num), SPI_FREAD_DIO);
  256. }
  257. //start sending cmd/addr and optionally, receiving data
  258. static void IRAM_ATTR psram_cmd_recv_start(psram_spi_num_t spi_num, uint32_t *pRxData, uint16_t rxByteLen,
  259. psram_cmd_mode_t cmd_mode)
  260. {
  261. //get cs1
  262. CLEAR_PERI_REG_MASK(SPI_PIN_REG(PSRAM_SPI_1), SPI_CS1_DIS_M);
  263. SET_PERI_REG_MASK(SPI_PIN_REG(PSRAM_SPI_1), SPI_CS0_DIS_M);
  264. uint32_t mode_backup = (READ_PERI_REG(SPI_USER_REG(spi_num)) >> SPI_FWRITE_DUAL_S) & 0xf;
  265. uint32_t rd_mode_backup = READ_PERI_REG(SPI_CTRL_REG(spi_num)) & (SPI_FREAD_DIO_M | SPI_FREAD_DUAL_M | SPI_FREAD_QUAD_M | SPI_FREAD_QIO_M);
  266. if (cmd_mode == PSRAM_CMD_SPI) {
  267. psram_set_basic_write_mode(spi_num);
  268. psram_set_basic_read_mode(spi_num);
  269. } else if (cmd_mode == PSRAM_CMD_QPI) {
  270. psram_set_qio_write_mode(spi_num);
  271. psram_set_qio_read_mode(spi_num);
  272. }
  273. //Wait for SPI0 to idle
  274. while (READ_PERI_REG(SPI_EXT2_REG(0)) != 0);
  275. DPORT_SET_PERI_REG_MASK(DPORT_HOST_INF_SEL_REG, 1 << 14);
  276. // Start send data
  277. SET_PERI_REG_MASK(SPI_CMD_REG(spi_num), SPI_USR);
  278. while ((READ_PERI_REG(SPI_CMD_REG(spi_num)) & SPI_USR));
  279. DPORT_CLEAR_PERI_REG_MASK(DPORT_HOST_INF_SEL_REG, 1 << 14);
  280. //recover spi mode
  281. SET_PERI_REG_BITS(SPI_USER_REG(spi_num), (pRxData ? SPI_FWRITE_DUAL_M : 0xf), mode_backup, SPI_FWRITE_DUAL_S);
  282. CLEAR_PERI_REG_MASK(SPI_CTRL_REG(spi_num), (SPI_FREAD_DIO_M | SPI_FREAD_DUAL_M | SPI_FREAD_QUAD_M | SPI_FREAD_QIO_M));
  283. SET_PERI_REG_MASK(SPI_CTRL_REG(spi_num), rd_mode_backup);
  284. //return cs to cs0
  285. SET_PERI_REG_MASK(SPI_PIN_REG(PSRAM_SPI_1), SPI_CS1_DIS_M);
  286. CLEAR_PERI_REG_MASK(SPI_PIN_REG(PSRAM_SPI_1), SPI_CS0_DIS_M);
  287. if (pRxData) {
  288. int idx = 0;
  289. // Read data out
  290. do {
  291. *pRxData++ = READ_PERI_REG(SPI_W0_REG(spi_num) + (idx << 2));
  292. } while (++idx < ((rxByteLen / 4) + ((rxByteLen % 4) ? 1 : 0)));
  293. }
  294. }
  295. static uint32_t backup_usr[3];
  296. static uint32_t backup_usr1[3];
  297. static uint32_t backup_usr2[3];
  298. //setup spi command/addr/data/dummy in user mode
  299. static int psram_cmd_config(psram_spi_num_t spi_num, psram_cmd_t *pInData)
  300. {
  301. while (READ_PERI_REG(SPI_CMD_REG(spi_num)) & SPI_USR);
  302. backup_usr[spi_num] = READ_PERI_REG(SPI_USER_REG(spi_num));
  303. backup_usr1[spi_num] = READ_PERI_REG(SPI_USER1_REG(spi_num));
  304. backup_usr2[spi_num] = READ_PERI_REG(SPI_USER2_REG(spi_num));
  305. // Set command by user.
  306. if (pInData->cmdBitLen != 0) {
  307. // Max command length 16 bits.
  308. SET_PERI_REG_BITS(SPI_USER2_REG(spi_num), SPI_USR_COMMAND_BITLEN, pInData->cmdBitLen - 1,
  309. SPI_USR_COMMAND_BITLEN_S);
  310. // Enable command
  311. SET_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_USR_COMMAND);
  312. // Load command,bit15-0 is cmd value.
  313. SET_PERI_REG_BITS(SPI_USER2_REG(spi_num), SPI_USR_COMMAND_VALUE, pInData->cmd, SPI_USR_COMMAND_VALUE_S);
  314. } else {
  315. CLEAR_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_USR_COMMAND);
  316. SET_PERI_REG_BITS(SPI_USER2_REG(spi_num), SPI_USR_COMMAND_BITLEN, 0, SPI_USR_COMMAND_BITLEN_S);
  317. }
  318. // Set Address by user.
  319. if (pInData->addrBitLen != 0) {
  320. SET_PERI_REG_BITS(SPI_USER1_REG(spi_num), SPI_USR_ADDR_BITLEN, (pInData->addrBitLen - 1), SPI_USR_ADDR_BITLEN_S);
  321. // Enable address
  322. SET_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_USR_ADDR);
  323. // Set address
  324. WRITE_PERI_REG(SPI_ADDR_REG(spi_num), *pInData->addr);
  325. } else {
  326. CLEAR_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_USR_ADDR);
  327. SET_PERI_REG_BITS(SPI_USER1_REG(spi_num), SPI_USR_ADDR_BITLEN, 0, SPI_USR_ADDR_BITLEN_S);
  328. }
  329. // Set data by user.
  330. uint32_t *p_tx_val = pInData->txData;
  331. if (pInData->txDataBitLen != 0) {
  332. // Enable MOSI
  333. SET_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_USR_MOSI);
  334. // Load send buffer
  335. int len = (pInData->txDataBitLen + 31) / 32;
  336. if (p_tx_val != NULL) {
  337. memcpy((void *)SPI_W0_REG(spi_num), p_tx_val, len * 4);
  338. }
  339. // Set data send buffer length.Max data length 64 bytes.
  340. SET_PERI_REG_BITS(SPI_MOSI_DLEN_REG(spi_num), SPI_USR_MOSI_DBITLEN, (pInData->txDataBitLen - 1),
  341. SPI_USR_MOSI_DBITLEN_S);
  342. } else {
  343. CLEAR_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_USR_MOSI);
  344. SET_PERI_REG_BITS(SPI_MOSI_DLEN_REG(spi_num), SPI_USR_MOSI_DBITLEN, 0, SPI_USR_MOSI_DBITLEN_S);
  345. }
  346. // Set rx data by user.
  347. if (pInData->rxDataBitLen != 0) {
  348. // Enable MOSI
  349. SET_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_USR_MISO);
  350. // Set data send buffer length.Max data length 64 bytes.
  351. SET_PERI_REG_BITS(SPI_MISO_DLEN_REG(spi_num), SPI_USR_MISO_DBITLEN, (pInData->rxDataBitLen - 1),
  352. SPI_USR_MISO_DBITLEN_S);
  353. } else {
  354. CLEAR_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_USR_MISO);
  355. SET_PERI_REG_BITS(SPI_MISO_DLEN_REG(spi_num), SPI_USR_MISO_DBITLEN, 0, SPI_USR_MISO_DBITLEN_S);
  356. }
  357. if (pInData->dummyBitLen != 0) {
  358. SET_PERI_REG_MASK(SPI_USER_REG(PSRAM_SPI_1), SPI_USR_DUMMY); // dummy en
  359. SET_PERI_REG_BITS(SPI_USER1_REG(PSRAM_SPI_1), SPI_USR_DUMMY_CYCLELEN_V, pInData->dummyBitLen - 1,
  360. SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
  361. } else {
  362. CLEAR_PERI_REG_MASK(SPI_USER_REG(PSRAM_SPI_1), SPI_USR_DUMMY); // dummy en
  363. SET_PERI_REG_BITS(SPI_USER1_REG(PSRAM_SPI_1), SPI_USR_DUMMY_CYCLELEN_V, 0, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
  364. }
  365. return 0;
  366. }
  367. static void psram_cmd_end(int spi_num)
  368. {
  369. while (READ_PERI_REG(SPI_CMD_REG(spi_num)) & SPI_USR);
  370. WRITE_PERI_REG(SPI_USER_REG(spi_num), backup_usr[spi_num]);
  371. WRITE_PERI_REG(SPI_USER1_REG(spi_num), backup_usr1[spi_num]);
  372. WRITE_PERI_REG(SPI_USER2_REG(spi_num), backup_usr2[spi_num]);
  373. }
  374. //exit QPI mode(set back to SPI mode)
  375. static void psram_disable_qio_mode(psram_spi_num_t spi_num)
  376. {
  377. psram_cmd_t ps_cmd;
  378. uint32_t cmd_exit_qpi;
  379. cmd_exit_qpi = PSRAM_EXIT_QMODE;
  380. ps_cmd.txDataBitLen = 8;
  381. if (s_clk_mode == PSRAM_CLK_MODE_DCLK) {
  382. switch (s_psram_mode) {
  383. case PSRAM_CACHE_F80M_S80M:
  384. break;
  385. case PSRAM_CACHE_F80M_S40M:
  386. case PSRAM_CACHE_F40M_S40M:
  387. default:
  388. cmd_exit_qpi = PSRAM_EXIT_QMODE << 8;
  389. ps_cmd.txDataBitLen = 16;
  390. break;
  391. }
  392. }
  393. ps_cmd.txData = &cmd_exit_qpi;
  394. ps_cmd.cmd = 0;
  395. ps_cmd.cmdBitLen = 0;
  396. ps_cmd.addr = 0;
  397. ps_cmd.addrBitLen = 0;
  398. ps_cmd.rxData = NULL;
  399. ps_cmd.rxDataBitLen = 0;
  400. ps_cmd.dummyBitLen = 0;
  401. psram_cmd_config(spi_num, &ps_cmd);
  402. psram_cmd_recv_start(spi_num, NULL, 0, PSRAM_CMD_QPI);
  403. psram_cmd_end(spi_num);
  404. }
  405. //read psram id, should issue `psram_disable_qio_mode` before calling this
  406. static void psram_read_id(psram_spi_num_t spi_num, uint64_t *dev_id)
  407. {
  408. uint32_t dummy_bits = 0 + extra_dummy;
  409. uint32_t psram_id[2] = {0};
  410. psram_cmd_t ps_cmd;
  411. uint32_t addr = 0;
  412. ps_cmd.addrBitLen = 3 * 8;
  413. ps_cmd.cmd = PSRAM_DEVICE_ID;
  414. ps_cmd.cmdBitLen = 8;
  415. if (s_clk_mode == PSRAM_CLK_MODE_DCLK) {
  416. switch (s_psram_mode) {
  417. case PSRAM_CACHE_F80M_S80M:
  418. break;
  419. case PSRAM_CACHE_F80M_S40M:
  420. case PSRAM_CACHE_F40M_S40M:
  421. default:
  422. ps_cmd.cmdBitLen = 2; //this two bits is used to delay 2 clock cycle
  423. ps_cmd.cmd = 0;
  424. addr = (PSRAM_DEVICE_ID << 24) | 0;
  425. ps_cmd.addrBitLen = 4 * 8;
  426. break;
  427. }
  428. }
  429. ps_cmd.addr = &addr;
  430. ps_cmd.txDataBitLen = 0;
  431. ps_cmd.txData = NULL;
  432. ps_cmd.rxDataBitLen = 8 * 8;
  433. ps_cmd.rxData = psram_id;
  434. ps_cmd.dummyBitLen = dummy_bits;
  435. psram_cmd_config(spi_num, &ps_cmd);
  436. psram_clear_spi_fifo(spi_num);
  437. psram_cmd_recv_start(spi_num, ps_cmd.rxData, ps_cmd.rxDataBitLen / 8, PSRAM_CMD_SPI);
  438. psram_cmd_end(spi_num);
  439. *dev_id = (uint64_t)(((uint64_t)psram_id[1] << 32) | psram_id[0]);
  440. }
  441. //enter QPI mode
  442. static esp_err_t IRAM_ATTR psram_enable_qio_mode(psram_spi_num_t spi_num)
  443. {
  444. psram_cmd_t ps_cmd;
  445. uint32_t addr = (PSRAM_ENTER_QMODE << 24) | 0;
  446. ps_cmd.cmdBitLen = 0;
  447. if (s_clk_mode == PSRAM_CLK_MODE_DCLK) {
  448. switch (s_psram_mode) {
  449. case PSRAM_CACHE_F80M_S80M:
  450. break;
  451. case PSRAM_CACHE_F80M_S40M:
  452. case PSRAM_CACHE_F40M_S40M:
  453. default:
  454. ps_cmd.cmdBitLen = 2;
  455. break;
  456. }
  457. }
  458. ps_cmd.cmd = 0;
  459. ps_cmd.addr = &addr;
  460. ps_cmd.addrBitLen = 8;
  461. ps_cmd.txData = NULL;
  462. ps_cmd.txDataBitLen = 0;
  463. ps_cmd.rxData = NULL;
  464. ps_cmd.rxDataBitLen = 0;
  465. ps_cmd.dummyBitLen = 0;
  466. psram_cmd_config(spi_num, &ps_cmd);
  467. psram_cmd_recv_start(spi_num, NULL, 0, PSRAM_CMD_SPI);
  468. psram_cmd_end(spi_num);
  469. return ESP_OK;
  470. }
  471. #if CONFIG_SPIRAM_2T_MODE
  472. // use SPI user mode to write psram
  473. static void spi_user_psram_write(psram_spi_num_t spi_num, uint32_t address, uint32_t *data_buffer, uint32_t data_len)
  474. {
  475. uint32_t addr = (PSRAM_QUAD_WRITE << 24) | (address & 0x7fffff);
  476. psram_cmd_t ps_cmd;
  477. ps_cmd.cmdBitLen = 0;
  478. ps_cmd.cmd = 0;
  479. ps_cmd.addr = &addr;
  480. ps_cmd.addrBitLen = 4 * 8;
  481. ps_cmd.txDataBitLen = 32 * 8;
  482. ps_cmd.txData = NULL;
  483. ps_cmd.rxDataBitLen = 0;
  484. ps_cmd.rxData = NULL;
  485. ps_cmd.dummyBitLen = 0;
  486. for (uint32_t i = 0; i < data_len; i += 32) {
  487. psram_clear_spi_fifo(spi_num);
  488. addr = (PSRAM_QUAD_WRITE << 24) | ((address & 0x7fffff) + i);
  489. ps_cmd.txData = data_buffer + (i / 4);
  490. psram_cmd_config(spi_num, &ps_cmd);
  491. psram_cmd_recv_start(spi_num, ps_cmd.rxData, ps_cmd.rxDataBitLen / 8, PSRAM_CMD_QPI);
  492. }
  493. psram_cmd_end(spi_num);
  494. }
  495. // use SPI user mode to read psram
  496. static void spi_user_psram_read(psram_spi_num_t spi_num, uint32_t address, uint32_t *data_buffer, uint32_t data_len)
  497. {
  498. uint32_t addr = (PSRAM_FAST_READ_QUAD << 24) | (address & 0x7fffff);
  499. uint32_t dummy_bits = PSRAM_FAST_READ_QUAD_DUMMY + 1;
  500. psram_cmd_t ps_cmd;
  501. ps_cmd.cmdBitLen = 0;
  502. ps_cmd.cmd = 0;
  503. ps_cmd.addr = &addr;
  504. ps_cmd.addrBitLen = 4 * 8;
  505. ps_cmd.txDataBitLen = 0;
  506. ps_cmd.txData = NULL;
  507. ps_cmd.rxDataBitLen = 32 * 8;
  508. ps_cmd.dummyBitLen = dummy_bits + extra_dummy;
  509. for (uint32_t i = 0; i < data_len; i += 32) {
  510. psram_clear_spi_fifo(spi_num);
  511. addr = (PSRAM_FAST_READ_QUAD << 24) | ((address & 0x7fffff) + i);
  512. ps_cmd.rxData = data_buffer + (i / 4);
  513. psram_cmd_config(spi_num, &ps_cmd);
  514. psram_cmd_recv_start(spi_num, ps_cmd.rxData, ps_cmd.rxDataBitLen / 8, PSRAM_CMD_QPI);
  515. }
  516. psram_cmd_end(spi_num);
  517. }
  518. //enable psram 2T mode
  519. static esp_err_t IRAM_ATTR psram_2t_mode_enable(psram_spi_num_t spi_num)
  520. {
  521. psram_disable_qio_mode(spi_num);
  522. // configure psram clock as 5 MHz
  523. uint32_t div = rtc_clk_apb_freq_get() / 5000000;
  524. esp_rom_spiflash_config_clk(div, spi_num);
  525. psram_cmd_t ps_cmd;
  526. // setp1: send cmd 0x5e
  527. // send one more bit clock after send cmd
  528. ps_cmd.cmd = 0x5e;
  529. ps_cmd.cmdBitLen = 8;
  530. ps_cmd.addrBitLen = 0;
  531. ps_cmd.addr = 0;
  532. ps_cmd.txDataBitLen = 0;
  533. ps_cmd.txData = NULL;
  534. ps_cmd.rxDataBitLen = 0;
  535. ps_cmd.rxData = NULL;
  536. ps_cmd.dummyBitLen = 1;
  537. psram_cmd_config(spi_num, &ps_cmd);
  538. psram_clear_spi_fifo(spi_num);
  539. psram_cmd_recv_start(spi_num, NULL, 0, PSRAM_CMD_SPI);
  540. psram_cmd_end(spi_num);
  541. // setp2: send cmd 0x5f
  542. // send one more bit clock after send cmd
  543. ps_cmd.cmd = 0x5f;
  544. psram_cmd_config(spi_num, &ps_cmd);
  545. psram_clear_spi_fifo(spi_num);
  546. psram_cmd_recv_start(spi_num, NULL, 0, PSRAM_CMD_SPI);
  547. psram_cmd_end(spi_num);
  548. // setp3: keep cs as high level
  549. // send 128 cycles clock
  550. // send 1 bit high levle in ninth clock from the back to PSRAM SIO1
  551. static gpio_hal_context_t _gpio_hal = {
  552. .dev = GPIO_HAL_GET_HW(GPIO_PORT_0)
  553. };
  554. gpio_hal_set_level(&_gpio_hal, D0WD_PSRAM_CS_IO, 1);
  555. esp_rom_gpio_connect_out_signal(D0WD_PSRAM_CS_IO, SIG_GPIO_OUT_IDX, 0, 0);
  556. esp_rom_gpio_connect_out_signal(PSRAM_SPID_SD1_IO, SPIQ_OUT_IDX, 0, 0);
  557. esp_rom_gpio_connect_in_signal(PSRAM_SPID_SD1_IO, SPIQ_IN_IDX, 0);
  558. esp_rom_gpio_connect_out_signal(PSRAM_SPIQ_SD0_IO, SPID_OUT_IDX, 0, 0);
  559. esp_rom_gpio_connect_in_signal(PSRAM_SPIQ_SD0_IO, SPID_IN_IDX, 0);
  560. uint32_t w_data_2t[4] = {0x0, 0x0, 0x0, 0x00010000};
  561. ps_cmd.cmd = 0;
  562. ps_cmd.cmdBitLen = 0;
  563. ps_cmd.txDataBitLen = 128;
  564. ps_cmd.txData = w_data_2t;
  565. ps_cmd.dummyBitLen = 0;
  566. psram_clear_spi_fifo(spi_num);
  567. psram_cmd_config(spi_num, &ps_cmd);
  568. psram_cmd_recv_start(spi_num, NULL, 0, PSRAM_CMD_SPI);
  569. psram_cmd_end(spi_num);
  570. esp_rom_gpio_connect_out_signal(PSRAM_SPIQ_SD0_IO, SPIQ_OUT_IDX, 0, 0);
  571. esp_rom_gpio_connect_in_signal(PSRAM_SPIQ_SD0_IO, SPIQ_IN_IDX, 0);
  572. esp_rom_gpio_connect_out_signal(PSRAM_SPID_SD1_IO, SPID_OUT_IDX, 0, 0);
  573. esp_rom_gpio_connect_in_signal(PSRAM_SPID_SD1_IO, SPID_IN_IDX, 0);
  574. esp_rom_gpio_connect_out_signal(D0WD_PSRAM_CS_IO, SPICS1_OUT_IDX, 0, 0);
  575. // setp4: send cmd 0x5f
  576. // send one more bit clock after send cmd
  577. ps_cmd.cmd = 0x5f;
  578. ps_cmd.cmdBitLen = 8;
  579. ps_cmd.txDataBitLen = 0;
  580. ps_cmd.txData = NULL;
  581. ps_cmd.dummyBitLen = 1;
  582. psram_cmd_config(spi_num, &ps_cmd);
  583. psram_clear_spi_fifo(spi_num);
  584. psram_cmd_recv_start(spi_num, NULL, 0, PSRAM_CMD_SPI);
  585. psram_cmd_end(spi_num);
  586. // configure psram clock back to the default value
  587. switch (s_psram_mode) {
  588. case PSRAM_CACHE_F80M_S40M:
  589. case PSRAM_CACHE_F40M_S40M:
  590. esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, spi_num);
  591. break;
  592. case PSRAM_CACHE_F80M_S80M:
  593. esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, spi_num);
  594. break;
  595. default:
  596. break;
  597. }
  598. psram_enable_qio_mode(spi_num);
  599. return ESP_OK;
  600. }
  601. #define CHECK_DATA_LEN (1024)
  602. #define CHECK_ADDR_STEP (0x100000)
  603. #define SIZE_32MBIT (0x400000)
  604. #define SIZE_64MBIT (0x800000)
  605. static esp_err_t psram_2t_mode_check(psram_spi_num_t spi_num)
  606. {
  607. uint8_t w_check_data[CHECK_DATA_LEN] = {0};
  608. uint8_t r_check_data[CHECK_DATA_LEN] = {0};
  609. for (uint32_t addr = 0; addr < SIZE_32MBIT; addr += CHECK_ADDR_STEP) {
  610. spi_user_psram_write(spi_num, addr, (uint32_t *)w_check_data, CHECK_DATA_LEN);
  611. }
  612. memset(w_check_data, 0xff, sizeof(w_check_data));
  613. for (uint32_t addr = SIZE_32MBIT; addr < SIZE_64MBIT; addr += CHECK_ADDR_STEP) {
  614. spi_user_psram_write(spi_num, addr, (uint32_t *)w_check_data, CHECK_DATA_LEN);
  615. }
  616. for (uint32_t addr = 0; addr < SIZE_32MBIT; addr += CHECK_ADDR_STEP) {
  617. spi_user_psram_read(spi_num, addr, (uint32_t *)r_check_data, CHECK_DATA_LEN);
  618. for (uint32_t j = 0; j < CHECK_DATA_LEN; j++) {
  619. if (r_check_data[j] != 0xff) {
  620. return ESP_FAIL;
  621. }
  622. }
  623. }
  624. return ESP_OK;
  625. }
  626. #endif
  627. void psram_set_cs_timing(psram_spi_num_t spi_num, psram_clk_mode_t clk_mode)
  628. {
  629. if (clk_mode == PSRAM_CLK_MODE_NORM) {
  630. SET_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_CS_HOLD_M | SPI_CS_SETUP_M);
  631. // Set cs time.
  632. SET_PERI_REG_BITS(SPI_CTRL2_REG(spi_num), SPI_HOLD_TIME_V, PSRAM_CS_HOLD_TIME, SPI_HOLD_TIME_S);
  633. SET_PERI_REG_BITS(SPI_CTRL2_REG(spi_num), SPI_SETUP_TIME_V, 0, SPI_SETUP_TIME_S);
  634. } else {
  635. CLEAR_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_CS_HOLD_M | SPI_CS_SETUP_M);
  636. }
  637. }
  638. //spi param init for psram
  639. void IRAM_ATTR psram_spi_init(psram_spi_num_t spi_num, psram_cache_speed_t mode)
  640. {
  641. CLEAR_PERI_REG_MASK(SPI_SLAVE_REG(spi_num), SPI_TRANS_DONE << 5);
  642. // SPI_CPOL & SPI_CPHA
  643. CLEAR_PERI_REG_MASK(SPI_PIN_REG(spi_num), SPI_CK_IDLE_EDGE);
  644. CLEAR_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_CK_OUT_EDGE);
  645. // SPI bit order
  646. CLEAR_PERI_REG_MASK(SPI_CTRL_REG(spi_num), SPI_WR_BIT_ORDER);
  647. CLEAR_PERI_REG_MASK(SPI_CTRL_REG(spi_num), SPI_RD_BIT_ORDER);
  648. // SPI bit order
  649. CLEAR_PERI_REG_MASK(SPI_USER_REG(spi_num), SPI_DOUTDIN);
  650. // May be not must to do.
  651. WRITE_PERI_REG(SPI_USER1_REG(spi_num), 0);
  652. // SPI mode type
  653. CLEAR_PERI_REG_MASK(SPI_SLAVE_REG(spi_num), SPI_SLAVE_MODE);
  654. memset((void *)SPI_W0_REG(spi_num), 0, 16 * 4);
  655. psram_set_cs_timing(spi_num, s_clk_mode);
  656. }
  657. //psram gpio init , different working frequency we have different solutions
  658. static void IRAM_ATTR psram_gpio_config(psram_io_t *psram_io, psram_cache_speed_t mode)
  659. {
  660. int spi_cache_dummy = 0;
  661. uint32_t rd_mode_reg = READ_PERI_REG(SPI_CTRL_REG(0));
  662. if (rd_mode_reg & SPI_FREAD_QIO_M) {
  663. spi_cache_dummy = SPI0_R_QIO_DUMMY_CYCLELEN;
  664. } else if (rd_mode_reg & SPI_FREAD_DIO_M) {
  665. spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN;
  666. SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_ADDR_BITLEN_V, SPI0_R_DIO_ADDR_BITSLEN, SPI_USR_ADDR_BITLEN_S);
  667. } else if (rd_mode_reg & (SPI_FREAD_QUAD_M | SPI_FREAD_DUAL_M)) {
  668. spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN;
  669. } else {
  670. spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN;
  671. }
  672. switch (mode) {
  673. case PSRAM_CACHE_F80M_S40M:
  674. extra_dummy = PSRAM_IO_MATRIX_DUMMY_40M;
  675. g_rom_spiflash_dummy_len_plus[_SPI_CACHE_PORT] = PSRAM_IO_MATRIX_DUMMY_80M;
  676. g_rom_spiflash_dummy_len_plus[_SPI_FLASH_PORT] = PSRAM_IO_MATRIX_DUMMY_40M;
  677. SET_PERI_REG_BITS(SPI_USER1_REG(_SPI_CACHE_PORT), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + PSRAM_IO_MATRIX_DUMMY_80M, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
  678. esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_CACHE_PORT);
  679. esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_FLASH_PORT);
  680. //set drive ability for clock
  681. SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->flash_clk_io], FUN_DRV, 3, FUN_DRV_S);
  682. SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_clk_io], FUN_DRV, 2, FUN_DRV_S);
  683. break;
  684. case PSRAM_CACHE_F80M_S80M:
  685. extra_dummy = PSRAM_IO_MATRIX_DUMMY_80M;
  686. g_rom_spiflash_dummy_len_plus[_SPI_CACHE_PORT] = PSRAM_IO_MATRIX_DUMMY_80M;
  687. g_rom_spiflash_dummy_len_plus[_SPI_FLASH_PORT] = PSRAM_IO_MATRIX_DUMMY_80M;
  688. SET_PERI_REG_BITS(SPI_USER1_REG(_SPI_CACHE_PORT), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + PSRAM_IO_MATRIX_DUMMY_80M, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
  689. esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_CACHE_PORT);
  690. esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_FLASH_PORT);
  691. //set drive ability for clock
  692. SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->flash_clk_io], FUN_DRV, 3, FUN_DRV_S);
  693. SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_clk_io], FUN_DRV, 3, FUN_DRV_S);
  694. break;
  695. case PSRAM_CACHE_F40M_S40M:
  696. extra_dummy = PSRAM_IO_MATRIX_DUMMY_40M;
  697. g_rom_spiflash_dummy_len_plus[_SPI_CACHE_PORT] = PSRAM_IO_MATRIX_DUMMY_40M;
  698. g_rom_spiflash_dummy_len_plus[_SPI_FLASH_PORT] = PSRAM_IO_MATRIX_DUMMY_40M;
  699. SET_PERI_REG_BITS(SPI_USER1_REG(_SPI_CACHE_PORT), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + PSRAM_IO_MATRIX_DUMMY_40M, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
  700. esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_CACHE_PORT);
  701. esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_FLASH_PORT);
  702. //set drive ability for clock
  703. SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->flash_clk_io], FUN_DRV, 2, FUN_DRV_S);
  704. SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_clk_io], FUN_DRV, 2, FUN_DRV_S);
  705. break;
  706. default:
  707. break;
  708. }
  709. SET_PERI_REG_MASK(SPI_USER_REG(0), SPI_USR_DUMMY); // dummy enable
  710. // In bootloader, all the signals are already configured,
  711. // We keep the following code in case the bootloader is some older version.
  712. esp_rom_gpio_connect_out_signal(psram_io->flash_cs_io, SPICS0_OUT_IDX, 0, 0);
  713. esp_rom_gpio_connect_out_signal(psram_io->psram_cs_io, SPICS1_OUT_IDX, 0, 0);
  714. esp_rom_gpio_connect_out_signal(psram_io->psram_spiq_sd0_io, SPIQ_OUT_IDX, 0, 0);
  715. esp_rom_gpio_connect_in_signal(psram_io->psram_spiq_sd0_io, SPIQ_IN_IDX, 0);
  716. esp_rom_gpio_connect_out_signal(psram_io->psram_spid_sd1_io, SPID_OUT_IDX, 0, 0);
  717. esp_rom_gpio_connect_in_signal(psram_io->psram_spid_sd1_io, SPID_IN_IDX, 0);
  718. esp_rom_gpio_connect_out_signal(psram_io->psram_spiwp_sd3_io, SPIWP_OUT_IDX, 0, 0);
  719. esp_rom_gpio_connect_in_signal(psram_io->psram_spiwp_sd3_io, SPIWP_IN_IDX, 0);
  720. esp_rom_gpio_connect_out_signal(psram_io->psram_spihd_sd2_io, SPIHD_OUT_IDX, 0, 0);
  721. esp_rom_gpio_connect_in_signal(psram_io->psram_spihd_sd2_io, SPIHD_IN_IDX, 0);
  722. //select pin function gpio
  723. if ((psram_io->flash_clk_io == SPI_IOMUX_PIN_NUM_CLK) && (psram_io->flash_clk_io != psram_io->psram_clk_io)) {
  724. //flash clock signal should come from IO MUX.
  725. gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[psram_io->flash_clk_io], FUNC_SD_CLK_SPICLK);
  726. } else {
  727. //flash clock signal should come from GPIO matrix.
  728. gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[psram_io->flash_clk_io], PIN_FUNC_GPIO);
  729. }
  730. gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[psram_io->flash_cs_io], PIN_FUNC_GPIO);
  731. gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[psram_io->psram_cs_io], PIN_FUNC_GPIO);
  732. gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[psram_io->psram_clk_io], PIN_FUNC_GPIO);
  733. gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[psram_io->psram_spiq_sd0_io], PIN_FUNC_GPIO);
  734. gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[psram_io->psram_spid_sd1_io], PIN_FUNC_GPIO);
  735. gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[psram_io->psram_spihd_sd2_io], PIN_FUNC_GPIO);
  736. gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[psram_io->psram_spiwp_sd3_io], PIN_FUNC_GPIO);
  737. uint32_t flash_id = g_rom_flashchip.device_id;
  738. if (flash_id == FLASH_ID_GD25LQ32C) {
  739. // Set drive ability for 1.8v flash in 80Mhz.
  740. SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->flash_cs_io], FUN_DRV_V, 3, FUN_DRV_S);
  741. SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->flash_clk_io], FUN_DRV_V, 3, FUN_DRV_S);
  742. SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_cs_io], FUN_DRV_V, 3, FUN_DRV_S);
  743. SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_clk_io], FUN_DRV_V, 3, FUN_DRV_S);
  744. SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_spiq_sd0_io], FUN_DRV_V, 3, FUN_DRV_S);
  745. SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_spid_sd1_io], FUN_DRV_V, 3, FUN_DRV_S);
  746. SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_spihd_sd2_io], FUN_DRV_V, 3, FUN_DRV_S);
  747. SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io->psram_spiwp_sd3_io], FUN_DRV_V, 3, FUN_DRV_S);
  748. }
  749. // Reserve psram pins
  750. esp_gpio_reserve_pins(BIT64(psram_io->flash_clk_io) |
  751. BIT64(psram_io->flash_cs_io) |
  752. BIT64(psram_io->psram_clk_io) |
  753. BIT64(psram_io->psram_cs_io) |
  754. BIT64(psram_io->psram_spiq_sd0_io) |
  755. BIT64(psram_io->psram_spid_sd1_io) |
  756. BIT64(psram_io->psram_spihd_sd2_io) |
  757. BIT64(psram_io->psram_spiwp_sd3_io));
  758. }
  759. //used in UT only
  760. bool psram_is_32mbit_ver0(void)
  761. {
  762. return PSRAM_IS_32MBIT_VER0(s_psram_id);
  763. }
  764. /*
  765. * Psram mode init will overwrite original flash speed mode, so that it is possible to change psram and flash speed after OTA.
  766. * Flash read mode(QIO/QOUT/DIO/DOUT) will not be changed in app bin. It is decided by bootloader, OTA can not change this mode.
  767. */
  768. esp_err_t IRAM_ATTR esp_psram_impl_enable(void) //psram init
  769. {
  770. psram_vaddr_mode_t vaddrmode = PSRAM_MODE;
  771. psram_cache_speed_t mode = PSRAM_SPEED;
  772. psram_io_t psram_io = {0};
  773. uint32_t pkg_ver = efuse_ll_get_chip_ver_pkg();
  774. if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) {
  775. ESP_EARLY_LOGI(TAG, "This chip is ESP32-D2WD");
  776. rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
  777. if (cfg.tieh != RTC_VDDSDIO_TIEH_1_8V) {
  778. ESP_EARLY_LOGE(TAG, "VDDSDIO is not 1.8V");
  779. return ESP_FAIL;
  780. }
  781. psram_io.psram_clk_io = D2WD_PSRAM_CLK_IO;
  782. psram_io.psram_cs_io = D2WD_PSRAM_CS_IO;
  783. } else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4 && ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 300)) {
  784. ESP_EARLY_LOGE(TAG, "This chip is ESP32-PICO-V3. It does not support PSRAM (disable it in Kconfig)");
  785. abort();
  786. } else if ((pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) || (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32U4WDH)) {
  787. ESP_EARLY_LOGI(TAG, "This chip is %s",
  788. (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) ? "ESP32-PICO" : "ESP32-U4WDH");
  789. // We have better alternatives, though it's possible to use U4WDH together with PSRAM.
  790. // U4WDH shares the same pin config with PICO for historical reasons.
  791. rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
  792. if (cfg.tieh != RTC_VDDSDIO_TIEH_3_3V) {
  793. ESP_EARLY_LOGE(TAG, "VDDSDIO is not 3.3V");
  794. return ESP_FAIL;
  795. }
  796. psram_io.psram_clk_io = PICO_PSRAM_CLK_IO;
  797. psram_io.psram_cs_io = PICO_PSRAM_CS_IO;
  798. } else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOV302) {
  799. ESP_EARLY_LOGI(TAG, "This chip is ESP32-PICO-V3-02");
  800. rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
  801. if (cfg.tieh != RTC_VDDSDIO_TIEH_3_3V) {
  802. ESP_EARLY_LOGE(TAG, "VDDSDIO is not 3.3V");
  803. return ESP_FAIL;
  804. }
  805. psram_io.psram_clk_io = PICO_V3_02_PSRAM_CLK_IO;
  806. psram_io.psram_cs_io = PICO_V3_02_PSRAM_CS_IO;
  807. } else if ((pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D0WDQ6) || (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D0WDQ5)) {
  808. ESP_EARLY_LOGI(TAG, "This chip is ESP32-D0WD");
  809. psram_io.psram_clk_io = D0WD_PSRAM_CLK_IO;
  810. psram_io.psram_cs_io = D0WD_PSRAM_CS_IO;
  811. } else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D0WDR2V3) {
  812. ESP_EARLY_LOGI(TAG, "This chip is ESP32-D0WDR2-V3");
  813. rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
  814. if (cfg.tieh != RTC_VDDSDIO_TIEH_3_3V) {
  815. ESP_EARLY_LOGE(TAG, "VDDSDIO is not 3.3V");
  816. return ESP_FAIL;
  817. }
  818. psram_io.psram_clk_io = D0WDR2_V3_PSRAM_CLK_IO;
  819. psram_io.psram_cs_io = D0WDR2_V3_PSRAM_CS_IO;
  820. } else {
  821. ESP_EARLY_LOGE(TAG, "Not a valid or known package id: %d", pkg_ver);
  822. abort();
  823. }
  824. s_psram_cs_io = psram_io.psram_cs_io;
  825. const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
  826. if (spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_SPI) {
  827. psram_io.flash_clk_io = SPI_IOMUX_PIN_NUM_CLK;
  828. psram_io.flash_cs_io = SPI_IOMUX_PIN_NUM_CS;
  829. psram_io.psram_spiq_sd0_io = PSRAM_SPIQ_SD0_IO;
  830. psram_io.psram_spid_sd1_io = PSRAM_SPID_SD1_IO;
  831. psram_io.psram_spiwp_sd3_io = PSRAM_SPIWP_SD3_IO;
  832. psram_io.psram_spihd_sd2_io = PSRAM_SPIHD_SD2_IO;
  833. } else if (spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) {
  834. psram_io.flash_clk_io = FLASH_HSPI_CLK_IO;
  835. psram_io.flash_cs_io = FLASH_HSPI_CS_IO;
  836. psram_io.psram_spiq_sd0_io = PSRAM_HSPI_SPIQ_SD0_IO;
  837. psram_io.psram_spid_sd1_io = PSRAM_HSPI_SPID_SD1_IO;
  838. psram_io.psram_spiwp_sd3_io = PSRAM_HSPI_SPIWP_SD3_IO;
  839. psram_io.psram_spihd_sd2_io = PSRAM_HSPI_SPIHD_SD2_IO;
  840. } else {
  841. psram_io.flash_clk_io = EFUSE_SPICONFIG_RET_SPICLK(spiconfig);
  842. psram_io.flash_cs_io = EFUSE_SPICONFIG_RET_SPICS0(spiconfig);
  843. psram_io.psram_spiq_sd0_io = EFUSE_SPICONFIG_RET_SPIQ(spiconfig);
  844. psram_io.psram_spid_sd1_io = EFUSE_SPICONFIG_RET_SPID(spiconfig);
  845. psram_io.psram_spihd_sd2_io = EFUSE_SPICONFIG_RET_SPIHD(spiconfig);
  846. psram_io.psram_spiwp_sd3_io = bootloader_flash_get_wp_pin();
  847. }
  848. if (psram_io.flash_clk_io == psram_io.psram_clk_io) {
  849. s_clk_mode = PSRAM_CLK_MODE_NORM;
  850. } else {
  851. s_clk_mode = PSRAM_CLK_MODE_DCLK;
  852. }
  853. assert(mode < PSRAM_CACHE_MAX && "we don't support any other mode for now.");
  854. s_psram_mode = mode;
  855. WRITE_PERI_REG(SPI_EXT3_REG(0), 0x1);
  856. CLEAR_PERI_REG_MASK(SPI_USER_REG(PSRAM_SPI_1), SPI_USR_PREP_HOLD_M);
  857. psram_spi_init(PSRAM_SPI_1, mode);
  858. switch (mode) {
  859. case PSRAM_CACHE_F80M_S80M:
  860. esp_rom_gpio_connect_out_signal(psram_io.psram_clk_io, SPICLK_OUT_IDX, 0, 0);
  861. break;
  862. case PSRAM_CACHE_F80M_S40M:
  863. case PSRAM_CACHE_F40M_S40M:
  864. default:
  865. if (s_clk_mode == PSRAM_CLK_MODE_DCLK) {
  866. /* We need to delay CLK to the PSRAM with respect to the clock signal as output by the SPI peripheral.
  867. We do this by routing it signal to signal 224/225, which are used as a loopback; the extra run through
  868. the GPIO matrix causes the delay. We use GPIO20 (which is not in any package but has pad logic in
  869. silicon) as a temporary pad for this. So the signal path is:
  870. SPI CLK --> GPIO28 --> signal224(in then out) --> internal GPIO29 --> signal225(in then out) --> GPIO17(PSRAM CLK)
  871. */
  872. esp_rom_gpio_connect_out_signal(PSRAM_INTERNAL_IO_28, SPICLK_OUT_IDX, 0, 0);
  873. esp_rom_gpio_connect_in_signal(PSRAM_INTERNAL_IO_28, SIG_IN_FUNC224_IDX, 0);
  874. esp_rom_gpio_connect_out_signal(PSRAM_INTERNAL_IO_29, SIG_IN_FUNC224_IDX, 0, 0);
  875. esp_rom_gpio_connect_in_signal(PSRAM_INTERNAL_IO_29, SIG_IN_FUNC225_IDX, 0);
  876. esp_rom_gpio_connect_out_signal(psram_io.psram_clk_io, SIG_IN_FUNC225_IDX, 0, 0);
  877. } else {
  878. esp_rom_gpio_connect_out_signal(psram_io.psram_clk_io, SPICLK_OUT_IDX, 0, 0);
  879. }
  880. break;
  881. }
  882. // Rise VDDSIO for 1.8V psram.
  883. bootloader_common_vddsdio_configure();
  884. // GPIO related settings
  885. psram_gpio_config(&psram_io, mode);
  886. psram_spi_num_t spi_num = PSRAM_SPI_1;
  887. psram_disable_qio_mode(spi_num);
  888. psram_read_id(spi_num, &s_psram_id);
  889. if (!PSRAM_IS_VALID(s_psram_id)) {
  890. /* 16Mbit psram ID read error workaround:
  891. * treat the first read id as a dummy one as the pre-condition,
  892. * Send Read ID command again
  893. */
  894. psram_read_id(spi_num, &s_psram_id);
  895. if (!PSRAM_IS_VALID(s_psram_id)) {
  896. ESP_EARLY_LOGE(TAG, "PSRAM ID read error: 0x%08x, PSRAM chip not found or not supported", (uint32_t)s_psram_id);
  897. return ESP_ERR_NOT_SUPPORTED;
  898. }
  899. }
  900. if (psram_is_32mbit_ver0()) {
  901. if (s_clk_mode != PSRAM_CLK_MODE_DCLK) {
  902. ESP_EARLY_LOGE(TAG, "PSRAM rev0 can't share CLK with Flash");
  903. abort();
  904. }
  905. if (mode == PSRAM_CACHE_F80M_S80M) {
  906. #ifdef CONFIG_SPIRAM_OCCUPY_NO_HOST
  907. ESP_EARLY_LOGE(TAG, "This version of PSRAM needs to claim an extra SPI peripheral at 80MHz. Please either: choose lower frequency by SPIRAM_SPEED_, or select one SPI peripheral it by SPIRAM_OCCUPY_*SPI_HOST in the menuconfig.");
  908. abort();
  909. #else
  910. /* note: If the third mode(80Mhz+80Mhz) is enabled for 32MBit 1V8 psram, one of HSPI/VSPI port will be
  911. occupied by the system (according to kconfig).
  912. Application code should never touch HSPI/VSPI hardware in this case. We try to stop applications
  913. from doing this using the drivers by claiming the port for ourselves */
  914. periph_module_enable(PSRAM_SPI_MODULE);
  915. bool r = spicommon_periph_claim(PSRAM_SPI_HOST, "psram");
  916. if (!r) {
  917. return ESP_ERR_INVALID_STATE;
  918. }
  919. esp_rom_gpio_connect_out_signal(psram_io.psram_clk_io, PSRAM_CLK_SIGNAL, 0, 0);
  920. //use spi3 clock,but use spi1 data/cs wires
  921. //We get a solid 80MHz clock from SPI3 by setting it up, starting a transaction, waiting until it
  922. //is in progress, then cutting the clock (but not the reset!) to that peripheral.
  923. WRITE_PERI_REG(SPI_ADDR_REG(PSRAM_SPI_NUM), 32 << 24);
  924. SET_PERI_REG_MASK(SPI_CMD_REG(PSRAM_SPI_NUM), SPI_FLASH_READ_M);
  925. uint32_t spi_status;
  926. while (1) {
  927. spi_status = READ_PERI_REG(SPI_EXT2_REG(PSRAM_SPI_NUM));
  928. if (spi_status != 0 && spi_status != 1) {
  929. DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, PSRAM_SPICLKEN);
  930. break;
  931. }
  932. }
  933. #endif
  934. }
  935. } else {
  936. // For other psram, we don't need any extra clock cycles after cs get back to high level
  937. s_clk_mode = PSRAM_CLK_MODE_NORM;
  938. esp_rom_gpio_connect_out_signal(PSRAM_INTERNAL_IO_28, SIG_GPIO_OUT_IDX, 0, 0);
  939. esp_rom_gpio_connect_out_signal(PSRAM_INTERNAL_IO_29, SIG_GPIO_OUT_IDX, 0, 0);
  940. esp_rom_gpio_connect_out_signal(psram_io.psram_clk_io, SPICLK_OUT_IDX, 0, 0);
  941. }
  942. // Update cs timing according to psram driving method.
  943. psram_set_cs_timing(PSRAM_SPI_1, s_clk_mode);
  944. psram_set_cs_timing(_SPI_CACHE_PORT, s_clk_mode);
  945. psram_enable_qio_mode(PSRAM_SPI_1);
  946. if (((PSRAM_SIZE_ID(s_psram_id) == PSRAM_EID_SIZE_64MBITS) || PSRAM_IS_64MBIT_TRIAL(s_psram_id))) {
  947. #if CONFIG_SPIRAM_2T_MODE
  948. #if CONFIG_SPIRAM_BANKSWITCH_ENABLE
  949. ESP_EARLY_LOGE(TAG, "PSRAM 2T mode and SPIRAM bank switching can not enabled meanwhile. Please read the help text for SPIRAM_2T_MODE in the project configuration menu.");
  950. abort();
  951. #endif
  952. /* Note: 2T mode command should not be sent twice,
  953. otherwise psram would get back to normal mode. */
  954. if (psram_2t_mode_check(PSRAM_SPI_1) != ESP_OK) {
  955. psram_2t_mode_enable(PSRAM_SPI_1);
  956. if (psram_2t_mode_check(PSRAM_SPI_1) != ESP_OK) {
  957. ESP_EARLY_LOGE(TAG, "PSRAM 2T mode enable fail!");
  958. return ESP_FAIL;
  959. }
  960. }
  961. s_2t_mode_enabled = true;
  962. ESP_EARLY_LOGI(TAG, "PSRAM is in 2T mode");
  963. #endif
  964. }
  965. psram_cache_init(mode, vaddrmode);
  966. return ESP_OK;
  967. }
  968. //register initialization for sram cache params and r/w commands
  969. static void IRAM_ATTR psram_cache_init(psram_cache_speed_t psram_cache_mode, psram_vaddr_mode_t vaddrmode)
  970. {
  971. switch (psram_cache_mode) {
  972. case PSRAM_CACHE_F80M_S80M:
  973. CLEAR_PERI_REG_MASK(SPI_DATE_REG(0), BIT(31)); //flash 1 div clk,80+40;
  974. CLEAR_PERI_REG_MASK(SPI_DATE_REG(0), BIT(30)); //pre clk div , ONLY IF SPI/SRAM@ DIFFERENT SPEED,JUST FOR SPI0. FLASH DIV 2+SRAM DIV4
  975. break;
  976. case PSRAM_CACHE_F80M_S40M:
  977. CLEAR_PERI_REG_MASK(SPI_CLOCK_REG(0), SPI_CLK_EQU_SYSCLK_M);
  978. SET_PERI_REG_BITS(SPI_CLOCK_REG(0), SPI_CLKDIV_PRE_V, 0, SPI_CLKDIV_PRE_S);
  979. SET_PERI_REG_BITS(SPI_CLOCK_REG(0), SPI_CLKCNT_N, 1, SPI_CLKCNT_N_S);
  980. SET_PERI_REG_BITS(SPI_CLOCK_REG(0), SPI_CLKCNT_H, 0, SPI_CLKCNT_H_S);
  981. SET_PERI_REG_BITS(SPI_CLOCK_REG(0), SPI_CLKCNT_L, 1, SPI_CLKCNT_L_S);
  982. SET_PERI_REG_MASK(SPI_DATE_REG(0), BIT(31)); //flash 1 div clk
  983. CLEAR_PERI_REG_MASK(SPI_DATE_REG(0), BIT(30)); //pre clk div , ONLY IF SPI/SRAM@ DIFFERENT SPEED,JUST FOR SPI0.
  984. break;
  985. case PSRAM_CACHE_F40M_S40M:
  986. default:
  987. CLEAR_PERI_REG_MASK(SPI_DATE_REG(0), BIT(31)); //flash 1 div clk
  988. CLEAR_PERI_REG_MASK(SPI_DATE_REG(0), BIT(30)); //pre clk div
  989. break;
  990. }
  991. CLEAR_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_SRAM_DIO_M); //disable dio mode for cache command
  992. SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_SRAM_QIO_M); //enable qio mode for cache command
  993. SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_CACHE_SRAM_USR_RCMD_M); //enable cache read command
  994. SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_CACHE_SRAM_USR_WCMD_M); //enable cache write command
  995. SET_PERI_REG_BITS(SPI_CACHE_SCTRL_REG(0), SPI_SRAM_ADDR_BITLEN_V, 23, SPI_SRAM_ADDR_BITLEN_S); //write address for cache command.
  996. SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_RD_SRAM_DUMMY_M); //enable cache read dummy
  997. //config sram cache r/w command
  998. SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_V, 7,
  999. SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_S);
  1000. SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_VALUE_V, PSRAM_FAST_READ_QUAD,
  1001. SPI_CACHE_SRAM_USR_RD_CMD_VALUE_S); //0xEB
  1002. SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_BITLEN, 7,
  1003. SPI_CACHE_SRAM_USR_WR_CMD_BITLEN_S);
  1004. SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_VALUE, PSRAM_QUAD_WRITE,
  1005. SPI_CACHE_SRAM_USR_WR_CMD_VALUE_S); //0x38
  1006. SET_PERI_REG_BITS(SPI_CACHE_SCTRL_REG(0), SPI_SRAM_DUMMY_CYCLELEN_V, PSRAM_FAST_READ_QUAD_DUMMY + extra_dummy,
  1007. SPI_SRAM_DUMMY_CYCLELEN_S); //dummy, psram cache : 40m--+1dummy; 80m--+2dummy
  1008. switch (psram_cache_mode) {
  1009. case PSRAM_CACHE_F80M_S80M: //in this mode , no delay is needed
  1010. break;
  1011. case PSRAM_CACHE_F80M_S40M: //if sram is @40M, need 2 cycles of delay
  1012. case PSRAM_CACHE_F40M_S40M:
  1013. default:
  1014. if (s_clk_mode == PSRAM_CLK_MODE_DCLK) {
  1015. SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_V, 15,
  1016. SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_S); //read command length, 2 bytes(1byte for delay),sending in qio mode in cache
  1017. SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_VALUE_V, ((PSRAM_FAST_READ_QUAD) << 8),
  1018. SPI_CACHE_SRAM_USR_RD_CMD_VALUE_S); //0xEB, read command value,(0x00 for delay,0xeb for cmd)
  1019. SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_BITLEN, 15,
  1020. SPI_CACHE_SRAM_USR_WR_CMD_BITLEN_S); //write command length,2 bytes(1byte for delay,send in qio mode in cache)
  1021. SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_VALUE, ((PSRAM_QUAD_WRITE) << 8),
  1022. SPI_CACHE_SRAM_USR_WR_CMD_VALUE_S); //0x38, write command value,(0x00 for delay)
  1023. SET_PERI_REG_BITS(SPI_CACHE_SCTRL_REG(0), SPI_SRAM_DUMMY_CYCLELEN_V, PSRAM_FAST_READ_QUAD_DUMMY + extra_dummy,
  1024. SPI_SRAM_DUMMY_CYCLELEN_S); //dummy, psram cache : 40m--+1dummy; 80m--+2dummy
  1025. }
  1026. break;
  1027. }
  1028. DPORT_CLEAR_PERI_REG_MASK(DPORT_PRO_CACHE_CTRL_REG, DPORT_PRO_DRAM_HL | DPORT_PRO_DRAM_SPLIT);
  1029. DPORT_CLEAR_PERI_REG_MASK(DPORT_APP_CACHE_CTRL_REG, DPORT_APP_DRAM_HL | DPORT_APP_DRAM_SPLIT);
  1030. if (vaddrmode == PSRAM_VADDR_MODE_LOWHIGH) {
  1031. DPORT_SET_PERI_REG_MASK(DPORT_PRO_CACHE_CTRL_REG, DPORT_PRO_DRAM_HL);
  1032. DPORT_SET_PERI_REG_MASK(DPORT_APP_CACHE_CTRL_REG, DPORT_APP_DRAM_HL);
  1033. } else if (vaddrmode == PSRAM_VADDR_MODE_EVENODD) {
  1034. DPORT_SET_PERI_REG_MASK(DPORT_PRO_CACHE_CTRL_REG, DPORT_PRO_DRAM_SPLIT);
  1035. DPORT_SET_PERI_REG_MASK(DPORT_APP_CACHE_CTRL_REG, DPORT_APP_DRAM_SPLIT);
  1036. }
  1037. DPORT_CLEAR_PERI_REG_MASK(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MASK_DRAM1 | DPORT_PRO_CACHE_MASK_OPSDRAM); //use Dram1 to visit ext sram.
  1038. //cache page mode : 1 -->16k 4 -->2k 0-->32k,(accord with the settings in cache_sram_mmu_set)
  1039. DPORT_SET_PERI_REG_BITS(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CMMU_SRAM_PAGE_MODE, 0, DPORT_PRO_CMMU_SRAM_PAGE_MODE_S);
  1040. DPORT_CLEAR_PERI_REG_MASK(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MASK_DRAM1 | DPORT_APP_CACHE_MASK_OPSDRAM); //use Dram1 to visit ext sram.
  1041. //cache page mode : 1 -->16k 4 -->2k 0-->32k,(accord with the settings in cache_sram_mmu_set)
  1042. DPORT_SET_PERI_REG_BITS(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CMMU_SRAM_PAGE_MODE, 0, DPORT_APP_CMMU_SRAM_PAGE_MODE_S);
  1043. CLEAR_PERI_REG_MASK(SPI_PIN_REG(0), SPI_CS1_DIS_M); //ENABLE SPI0 CS1 TO PSRAM(CS0--FLASH; CS1--SRAM)
  1044. }
  1045. esp_err_t esp_psram_impl_get_physical_size(uint32_t *out_size_bytes)
  1046. {
  1047. if (!out_size_bytes) {
  1048. return ESP_ERR_INVALID_ARG;
  1049. }
  1050. if ((PSRAM_SIZE_ID(s_psram_id) == PSRAM_EID_SIZE_64MBITS) || PSRAM_IS_64MBIT_TRIAL(s_psram_id)) {
  1051. *out_size_bytes = s_2t_mode_enabled ? PSRAM_SIZE_4MB : PSRAM_SIZE_8MB;
  1052. } else if (PSRAM_SIZE_ID(s_psram_id) == PSRAM_EID_SIZE_32MBITS) {
  1053. *out_size_bytes = PSRAM_SIZE_4MB;
  1054. } else if (PSRAM_SIZE_ID(s_psram_id) == PSRAM_EID_SIZE_16MBITS) {
  1055. *out_size_bytes = PSRAM_SIZE_2MB;
  1056. } else {
  1057. return ESP_ERR_NOT_SUPPORTED;
  1058. }
  1059. return ESP_OK;
  1060. }
  1061. /**
  1062. * This function is to get the available physical psram size in bytes.
  1063. * On ESP32, all of the PSRAM physical region are available
  1064. */
  1065. esp_err_t esp_psram_impl_get_available_size(uint32_t *out_size_bytes)
  1066. {
  1067. return esp_psram_impl_get_physical_size(out_size_bytes);
  1068. }
  1069. #endif // CONFIG_SPIRAM