123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- /*
- * FMC driver
- */
- /* include path: install_root/linux/include */
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/cdev.h>
- #include <linux/fs.h>
- #include <linux/errno.h>
- #include <linux/device.h>
- #include <linux/err.h>
- #include <asm/uaccess.h>
- #include "stm32f4xx.h"
- #include "stm32f4xx_hal_rcc.h"
- #include "stm32f4xx_ll_fmc.h"
- #include "stm32f4xx_hal_gpio.h"
- #include "stm32f4xx_hal_sram.h"
- #include "driver.h"
- static int major = MAJOR_FMC;
- static int minor = 0;
- static dev_t devno;
- static struct cdev *fmc_cdev = NULL;
- static int count = 1;
- struct class *my_class = NULL;
- struct device *dev = NULL;
- SRAM_HandleTypeDef hsram;
- #define DEVNAME "fmc_cpld"
- static int fmc_open(struct inode *inode, struct file *filep);
- static int fmc_close(struct inode *inode, struct file *filep);
- static ssize_t fmc_read(struct file *filep, char __user *buf, size_t size, loff_t *offset);
- static ssize_t fmc_write(struct file *filep, const char __user *buf, size_t size, loff_t *offset);
- static int fmc_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg);
- static int fmc_hw_init(uint8_t bus_is16bit);
- static struct file_operations fmc_ops =
- {
- .owner = THIS_MODULE,
- .open = fmc_open,
- .release = fmc_close,
- .read = fmc_read,
- .write = fmc_write,
- .ioctl = fmc_ioctl,
- };
- static int fmc_open(struct inode *inode, struct file *filep)
- {
- //printk("fmc_open!\n");
- __FMC_NORSRAM_ENABLE(FMC_NORSRAM_DEVICE,FMC_NORSRAM_BANK1);
- return 0;
- }
- static int fmc_close(struct inode *inode, struct file *filep)
- {
- //printk("fmc_close!\n");
- __FMC_NORSRAM_DISABLE(FMC_NORSRAM_DEVICE, FMC_NORSRAM_BANK1);
- return 0;
- }
- static ssize_t fmc_read(struct file *filep, char __user *buf, size_t size, loff_t *offset)
- {
- //printk("fmc_read!\n");
- return 0;
- }
- static ssize_t fmc_write(struct file *filep, const char __user *buf, size_t size, loff_t *offset)
- {
- /* uint32_t i;
- uint8_t tmp_buf[100];
- printk("fmc_write");
- for(i=0;i<size;i++)
- tmp_buf[i] = *(uint8_t*)(offset+i);
- copy_to_user();*/
- return 0;
- }
- static int fmc_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg)
- {
- fmc_cpld_t fmc_arg;
-
- if ( copy_from_user(&fmc_arg, (void*)arg, sizeof(fmc_cpld_t)) )
- return -EFAULT;
- //void *map_base = mmap(BULL, 256, PROT_READ | PROT_WRITE, MAP_SHARED, );
- switch(cmd)
- {
- case WRITE_BYTE: //write one byte to cpld
- HAL_SRAM_Write_8b(&hsram, (uint32_t*)fmc_arg.address, &fmc_arg.data, fmc_arg.length);
- break;
- case READ_BYTE: //read one byte from cpld
- HAL_SRAM_Read_8b(&hsram, (uint32_t*)fmc_arg.address, &fmc_arg.data, fmc_arg.length);
- if(copy_to_user((void*)arg, &fmc_arg, sizeof(fmc_cpld_t)) != 0)
- return -EFAULT;
- break;
- case WRITE_SHORT:
- HAL_SRAM_Write_16b(&hsram, (uint32_t*)fmc_arg.address, (uint16_t*)&fmc_arg.data, fmc_arg.length);
- break;
- case READ_SHORT:
- HAL_SRAM_Read_16b(&hsram, (uint32_t*)fmc_arg.address, (uint16_t*)&fmc_arg.data, fmc_arg.length);
- if(copy_to_user((void*)arg, &fmc_arg, sizeof(fmc_cpld_t)) != 0)
- return -EFAULT;
- break;
- case WRITE_WORD:
- HAL_SRAM_Write_32b(&hsram, (uint32_t*)fmc_arg.address, (uint32_t*)&fmc_arg.data, fmc_arg.length);
- break;
- case READ_WORD:
- HAL_SRAM_Read_32b(&hsram, (uint32_t*)fmc_arg.address, (uint32_t*)&fmc_arg.data, fmc_arg.length);
- if(copy_to_user((void*)arg, &fmc_arg, sizeof(fmc_cpld_t)) != 0)
- return -EFAULT;
- break;
- case BUS_8BIT:
- fmc_hw_init(0);
- break;
- case BUS_16BIT:
- fmc_hw_init(1);
- break;
- default:
- printk("Invalid command!\n");
- break;
- }
-
- return 0;
- }
- static int fmc_hw_init(uint8_t bus_is16bit)
- {
- FMC_NORSRAM_TimingTypeDef SRAM_Timing;
- GPIO_InitTypeDef GPIO_Init_Structure;
- /*##-1- Enable peripherals and GPIO Clocks #################################*/
- /* Enable GPIO clocks */
- __HAL_RCC_GPIOB_CLK_ENABLE();
- __HAL_RCC_GPIOC_CLK_ENABLE();
- __HAL_RCC_GPIOD_CLK_ENABLE();
- __HAL_RCC_GPIOE_CLK_ENABLE();
- __HAL_RCC_GPIOF_CLK_ENABLE();
- __HAL_RCC_GPIOG_CLK_ENABLE();
- __HAL_RCC_GPIOI_CLK_ENABLE();
- /* Enable FMC clock */
- __HAL_RCC_FMC_CLK_ENABLE();
-
- /*##-2- Configure peripheral GPIO ##########################################*/
- /*-- GPIOs Configuration -----------------------------------------------------*/
- /*
- * +-------------------+--------------------+--------------------+--------------------+
- * + SRAM(CPLD) pins assignment +
- * +-------------------+--------------------+--------------------+--------------------+
- * | PD0 <-> FMC_D2 | PE0 <-> xxxxxxxx | PF0 <-> FMC_A0 | PG0 <-> FMC_A10 |
- * | PD1 <-> FMC_D3 | PE1 <-> xxxxxxxx | PF1 <-> FMC_A1 | PG1 <-> FMC_A11 |
- * | PD8 <-> FMC_D13 | PE7 <-> FMC_D4 | PF2 <-> FMC_A2 | PG4 <-> xxxxxxx |
- * | PD9 <-> FMC_D14 | PE8 <-> FMC_D5 | PF3 <-> FMC_A3 | PG5 <-> xxxxxxx |
- * | PD10 <-> FMC_D15 | PE9 <-> FMC_D6 | PF4 <-> FMC_A4 | PG9 <-> xxxxxxx |
- * | PD14 <-> FMC_D0 | PE10 <-> FMC_D7 | PF5 <-> FMC_A5 | PG10 <-> xxxxxxx |
- * | PD15 <-> FMC_D1 | PE11 <-> FMC_D8 | xxxx <-> xxxxxxxx | PG12 <-> xxxxxxx
- * | PD4 <-> FMC_NOE | PE12 <-> FMC_D9 | PF12 <-> FMC_A6 |
- * | PD5 <-> FMC_NWE | PE13 <-> FMC_D10 | PF13 <-> FMC_A7 |
- * | PD7 <-> FMC_NE1 | PE14 <-> FMC_D11 | PF14 <-> FMC_A8 |
- * | PE15 <-> FMC_D12 | PF15 <-> FMC_A9 |
- *+-------------------+--------------------+--------------------+--------------------+
- | PI4 <-> xxxxxxx
- | PI5 <-> xxxxxxx
- */
-
- /* Common GPIO configuration */
- GPIO_Init_Structure.Mode = GPIO_MODE_AF_PP;
- GPIO_Init_Structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
- GPIO_Init_Structure.Pull = GPIO_NOPULL;
- GPIO_Init_Structure.Alternate = GPIO_AF12_FMC;
-
- /* GPIOD configuration */
- GPIO_Init_Structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 |
- GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 |
- GPIO_PIN_15| GPIO_PIN_4 | GPIO_PIN_5 |
- GPIO_PIN_7; //NE1
- HAL_GPIO_Init(GPIOD, &GPIO_Init_Structure);
- /* GPIOE configuration */
- GPIO_Init_Structure.Pin = GPIO_PIN_7 |
- GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 |
- GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 |
- GPIO_PIN_14 | GPIO_PIN_15;
- HAL_GPIO_Init(GPIOE, &GPIO_Init_Structure);
- /* GPIOF configuration */
- GPIO_Init_Structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 |
- GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 |
- GPIO_PIN_12 | GPIO_PIN_13 |
- GPIO_PIN_14 | GPIO_PIN_15;
- HAL_GPIO_Init(GPIOF, &GPIO_Init_Structure);
- /* GPIOG configuration */
- GPIO_Init_Structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 |
- GPIO_PIN_3 | GPIO_PIN_9; //NE2
- HAL_GPIO_Init(GPIOG, &GPIO_Init_Structure);
-
- // /* GPIOI configuration */
- // GPIO_Init_Structure.Pin = GPIO_PIN_4 | GPIO_PIN_5;
- // HAL_GPIO_Init(GPIOI, &GPIO_Init_Structure);
- hsram.Instance = FMC_NORSRAM_DEVICE;
-
- SRAM_Timing.AddressSetupTime = 15;//3;
- SRAM_Timing.AddressHoldTime = 15;//2;
- SRAM_Timing.DataSetupTime = 200;//6;
- SRAM_Timing.BusTurnAroundDuration = 15; //3;
- SRAM_Timing.CLKDivision = 16;//2;
- SRAM_Timing.DataLatency = 16;//0;
- SRAM_Timing.AccessMode = FMC_ACCESS_MODE_A;
-
- //fmc config
- hsram.Init.NSBank = FMC_NORSRAM_BANK1 | FMC_NORSRAM_BANK2;
- hsram.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
- hsram.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;
-
- if(bus_is16bit)
- {
- hsram.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
- printk("BUS_WIDTH: 16\n");
- }
- else
- {
- hsram.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_8;
- printk("BUS_WIDTH: 8\n");
- }
- hsram.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
- hsram.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
- hsram.Init.WrapMode = FMC_WRAP_MODE_DISABLE;
- hsram.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
- hsram.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
- hsram.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
- hsram.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
- hsram.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
- hsram.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
- hsram.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ASYNC;
- //hsram.Init.WriteFifo = FMC_WRITE_FIFO_DISABLE;
- hsram.Init.PageSize = FMC_PAGE_SIZE_NONE;
- /* Initialize the SDRAM controller */
- if(HAL_SRAM_Init(&hsram, &SRAM_Timing, NULL) != HAL_OK)
- {
- printk(" FMC Initialization Error\n");
- return -1;
- }
- return 0;
- }
- static int __init fmc_init(void)
- {
- int ret;
- printk("fmc_cpld driver init!\n");
- fmc_cdev = cdev_alloc();
- if(fmc_cdev == NULL)
- {
- return -ENOMEM;
- }
- cdev_init(fmc_cdev, &fmc_ops);
- devno = MKDEV(major, minor);
- ret = register_chrdev_region(devno, count, DEVNAME);
- if(ret)
- {
- goto ERR_STEP;
- }
- ret = cdev_add(fmc_cdev, devno, count);
- if(ret)
- {
- goto ERR_STEP1;
- }
- if(fmc_hw_init(1) != 0) //16bit bus
- goto ERR_STEP1;
- return 0;
- ERR_STEP1:
- unregister_chrdev_region(devno, count);
- ERR_STEP:
- cdev_del(fmc_cdev);
- return 0;
- }
- static void __exit fmc_exit(void)
- {
- unregister_chrdev_region(MKDEV(major, minor), count);
- cdev_del(fmc_cdev);
- }
- module_init(fmc_init);
- module_exit(fmc_exit);
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("jimbo_zhang");
- MODULE_DESCRIPTION("fmc_cpld driver");
|