drv_nor_flash.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. * Copyright (c) 2006-2018, Synwit Technology Co.,Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018-05-31 ZYH first version
  9. * 2018-12-10 Zohar_Lee format file
  10. */
  11. #include <rtdevice.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #include <SWM320.h>
  16. #define BLOCK_SIZE (64 * 1024)
  17. #define FLASH_SIZE (BSP_NOR_FLASH_SIZE)
  18. #define BLOCK_COUNTER (FLASH_SIZE / BLOCK_SIZE)
  19. static struct rt_mutex flash_lock;
  20. /* RT-Thread MTD device interface */
  21. static long swm320_read_id(struct rt_mtd_nor_device *device)
  22. {
  23. return 0xdeadbeef;
  24. }
  25. static rt_size_t swm320_read(struct rt_mtd_nor_device *device,
  26. rt_off_t position,
  27. rt_uint8_t *data,
  28. rt_size_t size)
  29. {
  30. int ret = rt_mutex_take(&flash_lock, RT_WAITING_FOREVER);
  31. if (ret == -RT_ETIMEOUT)
  32. {
  33. rt_kprintf("Take mutex time out.\n");
  34. return ret;
  35. }
  36. else if (ret == -RT_ERROR)
  37. {
  38. rt_kprintf("Take mutex error.\n");
  39. return ret;
  40. }
  41. memcpy(data, ((const void *)(NORFLM_BASE + position)), size);
  42. rt_mutex_release(&flash_lock);
  43. return size;
  44. }
  45. static rt_size_t swm320_write(struct rt_mtd_nor_device *device,
  46. rt_off_t position,
  47. const rt_uint8_t *data,
  48. rt_size_t size)
  49. {
  50. rt_size_t i;
  51. const rt_uint16_t *hwdata = (const rt_uint16_t *)data;
  52. int ret = rt_mutex_take(&flash_lock, RT_WAITING_FOREVER);
  53. if (ret == -RT_ETIMEOUT)
  54. {
  55. rt_kprintf("Take mutex time out.\n");
  56. return ret;
  57. }
  58. else if (ret == -RT_ERROR)
  59. {
  60. rt_kprintf("Take mutex error.\n");
  61. return ret;
  62. }
  63. for (i = 0; i < size / 2; i++)
  64. {
  65. NORFL_Write(position, hwdata[i]);
  66. position += 2;
  67. }
  68. rt_mutex_release(&flash_lock);
  69. return size;
  70. }
  71. static rt_err_t swm320_erase_block(struct rt_mtd_nor_device *device,
  72. rt_off_t offset,
  73. rt_uint32_t length)
  74. {
  75. rt_err_t ret = rt_mutex_take(&flash_lock, RT_WAITING_FOREVER);
  76. if (ret == -RT_ETIMEOUT)
  77. {
  78. rt_kprintf("Take mutex time out.\n");
  79. return ret;
  80. }
  81. else if (ret == -RT_ERROR)
  82. {
  83. rt_kprintf("Take mutex error.\n");
  84. return ret;
  85. }
  86. NORFL_SectorErase(offset);
  87. rt_mutex_release(&flash_lock);
  88. return RT_EOK;
  89. }
  90. const static struct rt_mtd_nor_driver_ops mtd_ops =
  91. {
  92. swm320_read_id,
  93. swm320_read,
  94. swm320_write,
  95. swm320_erase_block
  96. };
  97. static rt_err_t hw_init()
  98. {
  99. NORFL_InitStructure NORFL_InitStruct;
  100. PORT->PORTP_SEL0 = 0xAAAAAAAA; //PP0-23 => ADDR0-23
  101. PORT->PORTP_SEL1 = 0xAAAA;
  102. PORT->PORTM_SEL0 = 0xAAAAAAAA; //PM0-15 => DATA15-0
  103. PORT->PORTM_INEN = 0xFFFF;
  104. PORT->PORTM_SEL1 = 0x2AA; //PM16 => OEN, PM17 => WEN, PM18 => NORFL_CSN,PM19 => SDRAM_CSN, PM20 => SRAM_CSN, PM21 => SDRAM_CKE
  105. NORFL_InitStruct.DataWidth = 16;
  106. NORFL_InitStruct.WELowPulseTime = 5;
  107. NORFL_InitStruct.OEPreValidTime = 12;
  108. NORFL_InitStruct.OperFinishIEn = 0;
  109. NORFL_InitStruct.OperTimeoutIEn = 0;
  110. NORFL_Init(&NORFL_InitStruct);
  111. return RT_EOK;
  112. }
  113. static struct rt_mtd_nor_device mtd;
  114. int rt_hw_norflash_init(void)
  115. {
  116. hw_init();
  117. /* set page size and block size */
  118. mtd.block_size = BLOCK_SIZE; /* 64kByte */
  119. mtd.ops = &mtd_ops;
  120. /* initialize mutex */
  121. if (rt_mutex_init(&flash_lock, "nor", RT_IPC_FLAG_FIFO) != RT_EOK)
  122. {
  123. rt_kprintf("init sd lock mutex failed\n");
  124. return -RT_ERROR;
  125. }
  126. mtd.block_start = 0;
  127. mtd.block_end = BLOCK_COUNTER;
  128. /* register MTD device */
  129. rt_mtd_nor_register_device("nor", &mtd);
  130. return RT_EOK;
  131. }
  132. INIT_DEVICE_EXPORT(rt_hw_norflash_init);
  133. #ifdef RT_USING_FINSH
  134. #include <finsh.h>
  135. void nor_erase(void)
  136. {
  137. NORFL_ChipErase();
  138. }
  139. MSH_CMD_EXPORT(nor_erase, erase all block in SPI flash);
  140. #endif