fmc_main.c 8.2 KB

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