123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378 |
- #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 <asm/current.h>
- #include <linux/sched.h>
- #include <linux/device.h>
- #include <linux/err.h>
- #include "asm/uaccess.h"
- #include <linux/delay.h>
- #include "com_gpio.h"
- #include "stm32f4xx.h"
- #include "stm32_hal_legacy.h"
- #include "stm32f4xx_hal_spi.h"
- #include "stm32f4xx_hal_gpio.h"
- #include "driver.h"
- static int major = MAJOR_SPI;
- static int ret=0;
- #define DEVNAME "spi"
- #define NUM_OF_DEVICES 6
- struct spi_device {
- dev_t devno;
- struct cdev cdev;
- char name[16];
- //IRQn_Type Event_IRQn;
- //IRQn_Type Err_IRQn;
- } spi_dev[NUM_OF_DEVICES];
- SPI_HandleTypeDef hspi1, hspi2, hspi3, hspi4, hspi5, hspi6;
- static int spi_open(struct inode *inode, struct file *filep);
- static int spi_close(struct inode *inode, struct file *filep);
- static ssize_t spi_read(struct file *filep, char __user *buf, size_t size, loff_t *offset);
- static ssize_t spi_write(struct file *filep, const char __user *buf, size_t size, loff_t *offset);
- static int spi_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg);
- static struct file_operations spi_ops =
- {
- .owner = THIS_MODULE,
- .open = spi_open,
- .release = spi_close,
- .ioctl = spi_ioctl,
- .read = spi_read,
- .write = spi_write,
-
- };
- static int spi_open(struct inode *inode, struct file *filep)
- {
- SPI_HandleTypeDef *pHspi;
- int imajor,iminor;
- imajor = MAJOR(inode->i_rdev);
- iminor = MINOR(inode->i_rdev);
- if(imajor != major)
- {
- printk("Error: %s %d spi major fail! %d\n",__FILE__,__LINE__,imajor);
- return -1;
- }
- //printk("---> open major=%d, minor=%d\n",imajor,iminor);
- switch(iminor)
- {
- case 0:
- pHspi = &hspi1;
- break;
- case 1:
- pHspi = &hspi2;
- break;
- case 2:
- pHspi = &hspi3;
- break;
- case 3:
- pHspi = &hspi4;
- break;
- case 4:
- pHspi = &hspi5;
- break;
- case 5:
- pHspi = &hspi6;
- break;
- default:
- printk("Error:%s %d Invalid minor %d",__FILE__,__LINE__,iminor);
- return -1;
- }
- __HAL_SPI_ENABLE(pHspi);
- return 0;
- }
- static int spi_close(struct inode *inode, struct file *filep)
- {
- SPI_HandleTypeDef *pHspi;
- int imajor,iminor;
- imajor = MAJOR(inode->i_rdev);
- iminor = MINOR(inode->i_rdev);
- if(imajor != major)
- {
- printk("Error: %s %d spi major fail! %d\n",__FILE__,__LINE__,imajor);
- return -1;
- }
- //printk("---> close major=%d, minor=%d\n",imajor,iminor);
- switch(iminor)
- {
- case 0:
- pHspi = &hspi1;
- break;
- case 1:
- pHspi = &hspi2;
- break;
- case 2:
- pHspi = &hspi3;
- break;
- case 3:
- pHspi = &hspi4;
- break;
- case 4:
- pHspi = &hspi5;
- break;
- case 5:
- pHspi = &hspi6;
- break;
- default:
- printk("Error:%s %d Invalid minor %d",__FILE__,__LINE__,iminor);
- return -1;
- }
- __HAL_SPI_DISABLE(pHspi);
- return 0;
- }
- static int spi_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg)
- {
- HAL_StatusTypeDef ret = HAL_OK;
- spi_arg_t spi_args;
- int imajor,iminor;
- SPI_HandleTypeDef *pHspi;
- int i;
- imajor = MAJOR(inode->i_rdev);
- iminor = MINOR(inode->i_rdev);
- if(imajor != MAJOR_SPI)
- {
- printk("Error: %s %d spi major fail! %d\n",__FILE__,__LINE__,imajor);
- return -EFAULT;
- }
- switch(iminor)
- {
- case 0:
- pHspi = &hspi1;
- break;
- case 1:
- pHspi = &hspi2;
- break;
- case 2:
- pHspi = &hspi3;
- break;
- case 3:
- pHspi = &hspi4;
- break;
- case 4:
- pHspi = &hspi5;
- break;
- case 5:
- pHspi = &hspi6;
- break;
- default:
- printk("Error:%s %d Invalid minor %d",__FILE__,__LINE__,iminor);
- return -1;
- }
- if ( copy_from_user(&spi_args, (void*)arg, sizeof(spi_arg_t)) != 0)
- {
- printk("---> copy form user space fail!\n");
- return -1;
- }
- switch(cmd)
- {
- case SPI_MASTER_TRANSFER:
- // printk("SPI%d_transfer %d: ", iminor+1, spi_args.Size);
- // for(i=0;i<spi_args.Size;i++)
- // {
- // printk("%#x ", spi_args.buf[i]);
- // }
- // printk("\n");
- ret = HAL_SPI_Transmit( pHspi, spi_args.buf, spi_args.Size, HAL_MAX_DELAY);
- if(ret != HAL_OK)
- {
- printk("SPI master transfer error, %d\n", ret);
- }
- break;
- case SPI_MASTER_RECEIVE:
- ret = HAL_SPI_Receive(pHspi, spi_args.buf, spi_args.Size, HAL_MAX_DELAY);
- if(ret != HAL_OK)
- {
- printk("SPI master transfer error, %d\n", ret);
- }
-
- // printk("SPI%d_receive %d: ", iminor+1, spi_args.Size);
- // for(i=0;i<spi_args.Size;i++)
- // {
- // printk("%#x ", spi_args.buf[i]);
- // }
- // printk("\n");
-
- if ( copy_to_user((void*)arg, &spi_args, sizeof(spi_arg_t)) != 0)
- {
- printk("---> copy to user space fail!\n");
- return -1;
- }
- break;
- default:
- printk("---> Invalid action\n");
- ret = -1;
- break;
- }
- return ret;
- }
- static ssize_t spi_read(struct file *filep, char __user *buf, size_t size, loff_t *offset)
- {
- return 0;
- }
- static ssize_t spi_write(struct file *filep, const char __user *buf, size_t size, loff_t *offset)
- {
- return 0;
- }
- void spi_hw_init(void)
- {
- GPIO_InitTypeDef spi_gpio;
- //SPI1
- //SPI2
- __HAL_RCC_GPIOI_CLK_ENABLE();
- spi_gpio.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3;
- spi_gpio.Mode = GPIO_MODE_AF_PP;
- spi_gpio.Pull = GPIO_PULLUP;
- spi_gpio.Speed = GPIO_SPEED_FREQ_HIGH;
- spi_gpio.Alternate = GPIO_AF5_SPI2;
- HAL_GPIO_Init(GPIOI, &spi_gpio);
- //NSS
- HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_SET);
- spi_gpio.Pin = GPIO_PIN_0;
- spi_gpio.Mode = GPIO_MODE_OUTPUT_PP;
- spi_gpio.Pull = GPIO_PULLUP;
- spi_gpio.Speed = GPIO_SPEED_FREQ_HIGH;
- HAL_GPIO_Init(GPIOI, &spi_gpio);
- __HAL_RCC_SPI2_CLK_ENABLE();
- hspi2.Instance = SPI2;
- hspi2.Init.Direction = SPI_DIRECTION_2LINES;
- hspi2.Init.Mode = SPI_MODE_MASTER;
- hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
- hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
- hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;
- hspi2.Init.NSS = SPI_NSS_SOFT;
- hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
- hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
- hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
- hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
- hspi2.Init.CRCPolynomial = 0;
- HAL_SPI_Init(&hspi2);
- //SPI3
- //SPI4
- //SPI5
- __HAL_RCC_GPIOF_CLK_ENABLE();
- spi_gpio.Pin = GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9;
- spi_gpio.Mode = GPIO_MODE_AF_PP;
- spi_gpio.Pull = GPIO_PULLUP;
- spi_gpio.Speed = GPIO_SPEED_FREQ_HIGH;
- spi_gpio.Alternate = GPIO_AF5_SPI5;
- HAL_GPIO_Init(GPIOF, &spi_gpio);
- //NSS
- HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6, GPIO_PIN_SET);
- spi_gpio.Pin = GPIO_PIN_6;
- spi_gpio.Mode = GPIO_MODE_OUTPUT_PP;
- spi_gpio.Pull = GPIO_PULLUP;
- spi_gpio.Speed = GPIO_SPEED_FREQ_HIGH;
- HAL_GPIO_Init(GPIOF, &spi_gpio);
- __HAL_RCC_SPI5_CLK_ENABLE();
- hspi5.Instance = SPI5;
- hspi5.Init.Direction = SPI_DIRECTION_2LINES;
- hspi5.Init.Mode = SPI_MODE_MASTER;
- hspi5.Init.DataSize = SPI_DATASIZE_8BIT;
- hspi5.Init.CLKPolarity = SPI_POLARITY_HIGH;
- hspi5.Init.CLKPhase = SPI_PHASE_2EDGE;
- hspi5.Init.NSS = SPI_NSS_SOFT;
- hspi5.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
- hspi5.Init.FirstBit = SPI_FIRSTBIT_MSB;
- hspi5.Init.TIMode = SPI_TIMODE_DISABLE;
- hspi5.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
- hspi5.Init.CRCPolynomial = 0;
- HAL_SPI_Init(&hspi5);
-
- //SPI6
- }
- static int __init spi_init(void)
- {
- int ret;
-
- //SPI1
- //SPI2
- printk("spi2 module start ...\n");
- spi_dev[1].devno = MKDEV(MAJOR_SPI, 1);
- sprintf(spi_dev[1].name, "%s%d", DEVNAME, 2);
- register_chrdev_region(spi_dev[1].devno, 1, spi_dev[1].name);
- cdev_add(&spi_dev[1].cdev, spi_dev[1].devno, 1);
- cdev_init(&spi_dev[1].cdev, &spi_ops);
- //SPI3
-
- //SPI4
- //SPI5
- printk("spi5 module start ...\n");
- spi_dev[4].devno = MKDEV(MAJOR_SPI, 4);
- sprintf(spi_dev[4].name, "%s%d", DEVNAME, 5);
- register_chrdev_region(spi_dev[4].devno, 1, spi_dev[4].name);
- cdev_add(&spi_dev[4].cdev, spi_dev[4].devno, 1);
- cdev_init(&spi_dev[4].cdev, &spi_ops);
- //SPI6
- spi_hw_init();
- return 0;
- ERR_STEP1:
- unregister_chrdev_region(spi_dev[1].devno, 1);
- unregister_chrdev_region(spi_dev[4].devno, 1);
- ERR_STEP:
- cdev_del(&spi_dev[1].cdev);
- cdev_del(&spi_dev[4].cdev);
- return ret;
- }
- static void __exit spi_exit(void)
- {
- unregister_chrdev_region(spi_dev[1].devno,1);
- cdev_del(&spi_dev[1].cdev);
- unregister_chrdev_region(spi_dev[4].devno,1);
- cdev_del(&spi_dev[4].cdev);
- }
- module_init(spi_init);
- module_exit(spi_exit);
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("jimbo");
- MODULE_DESCRIPTION("this is spi module");
|