/* * FMC driver */ /* include path: install_root/linux/include */ #include #include #include #include #include #include #include #include #include #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 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");