fmc_main.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /*
  2. * FMC driver
  3. */
  4. /* include path: install_root/linux/include */
  5. #include <linux/module.h>
  6. #include <linux/kernel.h>
  7. #include <linux/init.h>
  8. #include <linux/cdev.h>
  9. #include <linux/fs.h>
  10. #include <linux/errno.h>
  11. #include <linux/device.h>
  12. #include <linux/err.h>
  13. #include <asm/uaccess.h>
  14. #include "stm32f4xx.h"
  15. #include "stm32f4xx_hal_rcc.h"
  16. #include "stm32f4xx_ll_fmc.h"
  17. #include "stm32f4xx_hal_gpio.h"
  18. #include "stm32f4xx_hal_sram.h"
  19. #include "driver.h"
  20. static int major = MAJOR_FMC;
  21. static int minor = 0;
  22. static dev_t devno;
  23. static struct cdev *fmc_cdev = NULL;
  24. static int count = 1;
  25. struct class *my_class = NULL;
  26. struct device *dev = NULL;
  27. SRAM_HandleTypeDef hsram;
  28. #define DEVNAME "fmc_cpld"
  29. static int fmc_open(struct inode *inode, struct file *filep);
  30. static int fmc_close(struct inode *inode, struct file *filep);
  31. static ssize_t fmc_read(struct file *filep, char __user *buf, size_t size, loff_t *offset);
  32. static ssize_t fmc_write(struct file *filep, const char __user *buf, size_t size, loff_t *offset);
  33. static int fmc_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg);
  34. static int fmc_hw_init(uint8_t bus_is16bit);
  35. static struct file_operations fmc_ops =
  36. {
  37. .owner = THIS_MODULE,
  38. .open = fmc_open,
  39. .release = fmc_close,
  40. .read = fmc_read,
  41. .write = fmc_write,
  42. .ioctl = fmc_ioctl,
  43. };
  44. static int fmc_open(struct inode *inode, struct file *filep)
  45. {
  46. //printk("fmc_open!\n");
  47. __FMC_NORSRAM_ENABLE(FMC_NORSRAM_DEVICE,FMC_NORSRAM_BANK1);
  48. return 0;
  49. }
  50. static int fmc_close(struct inode *inode, struct file *filep)
  51. {
  52. //printk("fmc_close!\n");
  53. __FMC_NORSRAM_DISABLE(FMC_NORSRAM_DEVICE, FMC_NORSRAM_BANK1);
  54. return 0;
  55. }
  56. static ssize_t fmc_read(struct file *filep, char __user *buf, size_t size, loff_t *offset)
  57. {
  58. //printk("fmc_read!\n");
  59. return 0;
  60. }
  61. static ssize_t fmc_write(struct file *filep, const char __user *buf, size_t size, loff_t *offset)
  62. {
  63. /* uint32_t i;
  64. uint8_t tmp_buf[100];
  65. printk("fmc_write");
  66. for(i=0;i<size;i++)
  67. tmp_buf[i] = *(uint8_t*)(offset+i);
  68. copy_to_user();*/
  69. return 0;
  70. }
  71. static int fmc_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg)
  72. {
  73. fmc_cpld_t fmc_arg;
  74. if ( copy_from_user(&fmc_arg, (void*)arg, sizeof(fmc_cpld_t)) )
  75. return -EFAULT;
  76. //void *map_base = mmap(BULL, 256, PROT_READ | PROT_WRITE, MAP_SHARED, );
  77. switch(cmd)
  78. {
  79. case WRITE_BYTE: //write one byte to cpld
  80. HAL_SRAM_Write_8b(&hsram, (uint32_t*)fmc_arg.address, &fmc_arg.data, fmc_arg.length);
  81. break;
  82. case READ_BYTE: //read one byte from cpld
  83. HAL_SRAM_Read_8b(&hsram, (uint32_t*)fmc_arg.address, &fmc_arg.data, fmc_arg.length);
  84. if(copy_to_user((void*)arg, &fmc_arg, sizeof(fmc_cpld_t)) != 0)
  85. return -EFAULT;
  86. break;
  87. case WRITE_SHORT:
  88. HAL_SRAM_Write_16b(&hsram, (uint32_t*)fmc_arg.address, (uint16_t*)&fmc_arg.data, fmc_arg.length);
  89. break;
  90. case READ_SHORT:
  91. HAL_SRAM_Read_16b(&hsram, (uint32_t*)fmc_arg.address, (uint16_t*)&fmc_arg.data, fmc_arg.length);
  92. if(copy_to_user((void*)arg, &fmc_arg, sizeof(fmc_cpld_t)) != 0)
  93. return -EFAULT;
  94. break;
  95. case WRITE_WORD:
  96. HAL_SRAM_Write_32b(&hsram, (uint32_t*)fmc_arg.address, (uint32_t*)&fmc_arg.data, fmc_arg.length);
  97. break;
  98. case READ_WORD:
  99. HAL_SRAM_Read_32b(&hsram, (uint32_t*)fmc_arg.address, (uint32_t*)&fmc_arg.data, fmc_arg.length);
  100. if(copy_to_user((void*)arg, &fmc_arg, sizeof(fmc_cpld_t)) != 0)
  101. return -EFAULT;
  102. break;
  103. case BUS_8BIT:
  104. fmc_hw_init(0);
  105. break;
  106. case BUS_16BIT:
  107. fmc_hw_init(1);
  108. break;
  109. default:
  110. printk("Invalid command!\n");
  111. break;
  112. }
  113. return 0;
  114. }
  115. static int fmc_hw_init(uint8_t bus_is16bit)
  116. {
  117. FMC_NORSRAM_TimingTypeDef SRAM_Timing;
  118. GPIO_InitTypeDef GPIO_Init_Structure;
  119. /*##-1- Enable peripherals and GPIO Clocks #################################*/
  120. /* Enable GPIO clocks */
  121. __HAL_RCC_GPIOB_CLK_ENABLE();
  122. __HAL_RCC_GPIOC_CLK_ENABLE();
  123. __HAL_RCC_GPIOD_CLK_ENABLE();
  124. __HAL_RCC_GPIOE_CLK_ENABLE();
  125. __HAL_RCC_GPIOF_CLK_ENABLE();
  126. __HAL_RCC_GPIOG_CLK_ENABLE();
  127. __HAL_RCC_GPIOI_CLK_ENABLE();
  128. /* Enable FMC clock */
  129. __HAL_RCC_FMC_CLK_ENABLE();
  130. /*##-2- Configure peripheral GPIO ##########################################*/
  131. /*-- GPIOs Configuration -----------------------------------------------------*/
  132. /*
  133. * +-------------------+--------------------+--------------------+--------------------+
  134. * + SRAM(CPLD) pins assignment +
  135. * +-------------------+--------------------+--------------------+--------------------+
  136. * | PD0 <-> FMC_D2 | PE0 <-> xxxxxxxx | PF0 <-> FMC_A0 | PG0 <-> FMC_A10 |
  137. * | PD1 <-> FMC_D3 | PE1 <-> xxxxxxxx | PF1 <-> FMC_A1 | PG1 <-> FMC_A11 |
  138. * | PD8 <-> FMC_D13 | PE7 <-> FMC_D4 | PF2 <-> FMC_A2 | PG4 <-> xxxxxxx |
  139. * | PD9 <-> FMC_D14 | PE8 <-> FMC_D5 | PF3 <-> FMC_A3 | PG5 <-> xxxxxxx |
  140. * | PD10 <-> FMC_D15 | PE9 <-> FMC_D6 | PF4 <-> FMC_A4 | PG9 <-> xxxxxxx |
  141. * | PD14 <-> FMC_D0 | PE10 <-> FMC_D7 | PF5 <-> FMC_A5 | PG10 <-> xxxxxxx |
  142. * | PD15 <-> FMC_D1 | PE11 <-> FMC_D8 | xxxx <-> xxxxxxxx | PG12 <-> xxxxxxx
  143. * | PD4 <-> FMC_NOE | PE12 <-> FMC_D9 | PF12 <-> FMC_A6 |
  144. * | PD5 <-> FMC_NWE | PE13 <-> FMC_D10 | PF13 <-> FMC_A7 |
  145. * | PD7 <-> FMC_NE1 | PE14 <-> FMC_D11 | PF14 <-> FMC_A8 |
  146. * | PE15 <-> FMC_D12 | PF15 <-> FMC_A9 |
  147. *+-------------------+--------------------+--------------------+--------------------+
  148. | PI4 <-> xxxxxxx
  149. | PI5 <-> xxxxxxx
  150. */
  151. /* Common GPIO configuration */
  152. GPIO_Init_Structure.Mode = GPIO_MODE_AF_PP;
  153. GPIO_Init_Structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  154. GPIO_Init_Structure.Pull = GPIO_NOPULL;
  155. GPIO_Init_Structure.Alternate = GPIO_AF12_FMC;
  156. /* GPIOD configuration */
  157. GPIO_Init_Structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 |
  158. GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 |
  159. GPIO_PIN_15| GPIO_PIN_4 | GPIO_PIN_5 |
  160. GPIO_PIN_7; //NE1
  161. HAL_GPIO_Init(GPIOD, &GPIO_Init_Structure);
  162. /* GPIOE configuration */
  163. GPIO_Init_Structure.Pin = GPIO_PIN_7 |
  164. GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 |
  165. GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 |
  166. GPIO_PIN_14 | GPIO_PIN_15;
  167. HAL_GPIO_Init(GPIOE, &GPIO_Init_Structure);
  168. /* GPIOF configuration */
  169. GPIO_Init_Structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 |
  170. GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 |
  171. GPIO_PIN_12 | GPIO_PIN_13 |
  172. GPIO_PIN_14 | GPIO_PIN_15;
  173. HAL_GPIO_Init(GPIOF, &GPIO_Init_Structure);
  174. /* GPIOG configuration */
  175. GPIO_Init_Structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 |
  176. GPIO_PIN_3 | GPIO_PIN_9; //NE2
  177. HAL_GPIO_Init(GPIOG, &GPIO_Init_Structure);
  178. // /* GPIOI configuration */
  179. // GPIO_Init_Structure.Pin = GPIO_PIN_4 | GPIO_PIN_5;
  180. // HAL_GPIO_Init(GPIOI, &GPIO_Init_Structure);
  181. hsram.Instance = FMC_NORSRAM_DEVICE;
  182. SRAM_Timing.AddressSetupTime = 15;//3;
  183. SRAM_Timing.AddressHoldTime = 15;//2;
  184. SRAM_Timing.DataSetupTime = 200;//6;
  185. SRAM_Timing.BusTurnAroundDuration = 15; //3;
  186. SRAM_Timing.CLKDivision = 16;//2;
  187. SRAM_Timing.DataLatency = 16;//0;
  188. SRAM_Timing.AccessMode = FMC_ACCESS_MODE_A;
  189. //fmc config
  190. hsram.Init.NSBank = FMC_NORSRAM_BANK1 | FMC_NORSRAM_BANK2;
  191. hsram.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
  192. hsram.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;
  193. if(bus_is16bit)
  194. {
  195. hsram.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
  196. printk("BUS_WIDTH: 16\n");
  197. }
  198. else
  199. {
  200. hsram.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_8;
  201. printk("BUS_WIDTH: 8\n");
  202. }
  203. hsram.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
  204. hsram.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
  205. hsram.Init.WrapMode = FMC_WRAP_MODE_DISABLE;
  206. hsram.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
  207. hsram.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
  208. hsram.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
  209. hsram.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
  210. hsram.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
  211. hsram.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
  212. hsram.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ASYNC;
  213. //hsram.Init.WriteFifo = FMC_WRITE_FIFO_DISABLE;
  214. hsram.Init.PageSize = FMC_PAGE_SIZE_NONE;
  215. /* Initialize the SDRAM controller */
  216. if(HAL_SRAM_Init(&hsram, &SRAM_Timing, NULL) != HAL_OK)
  217. {
  218. printk(" FMC Initialization Error\n");
  219. return -1;
  220. }
  221. return 0;
  222. }
  223. static int __init fmc_init(void)
  224. {
  225. int ret;
  226. printk("fmc_cpld driver init!\n");
  227. fmc_cdev = cdev_alloc();
  228. if(fmc_cdev == NULL)
  229. {
  230. return -ENOMEM;
  231. }
  232. cdev_init(fmc_cdev, &fmc_ops);
  233. devno = MKDEV(major, minor);
  234. ret = register_chrdev_region(devno, count, DEVNAME);
  235. if(ret)
  236. {
  237. goto ERR_STEP;
  238. }
  239. ret = cdev_add(fmc_cdev, devno, count);
  240. if(ret)
  241. {
  242. goto ERR_STEP1;
  243. }
  244. if(fmc_hw_init(1) != 0) //16bit bus
  245. goto ERR_STEP1;
  246. return 0;
  247. ERR_STEP1:
  248. unregister_chrdev_region(devno, count);
  249. ERR_STEP:
  250. cdev_del(fmc_cdev);
  251. return 0;
  252. }
  253. static void __exit fmc_exit(void)
  254. {
  255. unregister_chrdev_region(MKDEV(major, minor), count);
  256. cdev_del(fmc_cdev);
  257. }
  258. module_init(fmc_init);
  259. module_exit(fmc_exit);
  260. MODULE_LICENSE("GPL");
  261. MODULE_AUTHOR("jimbo_zhang");
  262. MODULE_DESCRIPTION("fmc_cpld driver");