Skip to content

Commit 4ddb203

Browse files
committed
Works!
1 parent 2753660 commit 4ddb203

File tree

5 files changed

+250
-55
lines changed

5 files changed

+250
-55
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ else
3535
# called from kernel build system: just declare what our modules are
3636
# obj-m := ads7870.o #ads7870-core.o ads7870-spi.o
3737
obj-m += psoc5mod.o
38-
psoc5mod-objs := psoc5-cdrv.o psoc5-spi.o
38+
psoc5mod-objs := psoc5-spi.o psoc5-cdrv.o
3939

4040
endif
4141

psoc5-cdrv.c

+10-19
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,11 @@
22
#include <linux/sched.h>
33
#include <linux/gpio.h>
44

5-
#include "psoc5-cdrv.h"
65
#include "psoc5-spi.h"
7-
8-
#define INTGPIO 7
9-
10-
static struct cdev psoc5Dev;
11-
struct file_operations psoc5_Fops;
12-
static int devno;
13-
14-
DECLARE_WAIT_QUEUE_HEAD(wait_queue);
15-
int newData = 0;
16-
6+
#include "psoc5-cdrv.h"
177

188
irqreturn_t psoc5_isr(int irq, void *dev_id) {
19-
//printk("PSoC5 interrupt!\n");
9+
//printk(KERN_ALERT "PSoC5 interrupt!\n");
2010
newData = 1;
2111
wake_up_interruptible(&wait_queue);
2212
return IRQ_HANDLED;
@@ -52,10 +42,8 @@ static int __init psoc5_cdrv_init(void) {
5242
}
5343

5444
static void __exit psoc5_cdrv_exit(void) {
55-
int err;
56-
5745
printk("PSoC5 cdrv exit\n");
58-
err = psoc5_spi_exit();
46+
psoc5_spi_exit();
5947
unregister_chrdev_region(devno, 1);
6048
cdev_del(&psoc5Dev);
6149
gpio_free(INTGPIO);
@@ -94,13 +82,13 @@ ssize_t psoc5_cdrv_write(struct file *filep, const char __user *ubuf,
9482
char kbuf[MAXLEN];
9583

9684
len = count < MAXLEN ? count : MAXLEN;
97-
85+
len--;
9886
if(copy_from_user(kbuf, ubuf, len))
9987
return -EFAULT;
10088

101-
printk("Received '%X, %X' from user. Len = %i\n", kbuf[0], kbuf[1],len);
89+
//kbuf[len] = '\0';
10290

103-
psoc5_spi_write(kbuf, len);
91+
psoc5_spi_write(kbuf, len);
10492

10593
return count;
10694
}
@@ -110,9 +98,11 @@ ssize_t psoc5_cdrv_read(struct file *filep, char __user *ubuf,
11098
char result;
11199
char resultBuf[5];
112100

101+
//wait_event_interruptible(wait_queue, newData == 1);
113102
if(wait_event_interruptible_timeout(wait_queue, newData == 1, 1000) == 0) {
114103
result = 0;
115104
copy_to_user(ubuf, &result, 1);
105+
printk(KERN_ALERT "cdrv timeout read: '%X' \n", result);
116106
return 1;
117107
}
118108

@@ -122,7 +112,8 @@ ssize_t psoc5_cdrv_read(struct file *filep, char __user *ubuf,
122112

123113
count = snprintf(resultBuf, sizeof(resultBuf), "%c", result);
124114

125-
printk("cdrv read: '%X' \n", result);
115+
/*if(result != 0x00 && result != 0x0F)
116+
printk(KERN_ALERT "cdrv read: '%X' \n", result);*/
126117

127118
if(copy_to_user(ubuf, resultBuf, sizeof(resultBuf)) != 0) {
128119
printk("Error copying to user \n");

psoc5-cdrv.h

+137-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,28 @@
1+
/**
2+
* @file
3+
* @author Bjarke Vad Andersen
4+
*
5+
* @section LICENSE
6+
*
7+
* This program is free software; you can redistribute it and/or
8+
* modify it under the terms of the GNU General Public License as
9+
* published by the Free Software Foundation; either version 2 of
10+
* the License, or (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful, but
13+
* WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* General Public License for more details at
16+
* http://www.gnu.org/copyleft/gpl.html
17+
*
18+
* @section DESCRIPTION
19+
*
20+
* This kernel module is written to used on a DevKit8000,
21+
* and is supposed used with a PSoC5 device connected trough SPI.
22+
* This file contains the character driver properties of the SPI kernel module.
23+
* This includes init, exit, read, write, open and release methods.
24+
*
25+
*/
126
#include <linux/err.h>
227
#include <linux/ctype.h>
328
#include <linux/cdev.h>
@@ -6,17 +31,127 @@
631
#include <linux/input.h>
732
#include <linux/module.h>
833

34+
/**
35+
* @brief The Major number of the node.
36+
*/
937
#define PSOC5_MAJOR 62
38+
/**
39+
* @brief The Minor number of the node.
40+
*/
1041
#define PSOC5_MINOR 0
42+
/**
43+
* @brief The maximum length for data to write to the device node in one function call.
44+
* */
1145
#define MAXLEN 512
46+
/**
47+
* @brief The GPIO pin which is used for receiving "word complete" interrupts from the PSoC5.
48+
*/
49+
#define INTGPIO 130 //7/137
1250

51+
52+
/**
53+
* @brief The init method.
54+
*
55+
* This method is called whenever the module is inserted into the kernel.
56+
* Here the basic setup and registering of the character driver takes place, including requesting
57+
* GPIO resources for the interrupt pin, and setting said GPIO to input.
58+
* psoc5_spi_init() is called to initialize the SPI part of the module.
59+
*
60+
* @return 0 on success.
61+
*/
1362
static int __init psoc5_cdrv_init(void);
63+
/*
64+
* @brief The exit method.
65+
*
66+
* This method is called whenever the module is removed from the kernel.
67+
* The character device is unregistered and deleted, and the requested GPIO resources are freed.
68+
*/
1469
static void __exit psoc5_cdrv_exit(void);
15-
70+
/**
71+
* @brief The open method.
72+
*
73+
* This method is called whenever a user is trying to read from or write to the device.
74+
* Here interrupt resources are requested. This is done here and not in the init method
75+
* to prevent allocating resources that are not used.
76+
*
77+
* @return 0 on success.
78+
*/
1679
int psoc5_cdrv_open(struct inode *inodep, struct file *filep);
80+
/**
81+
* @brief The release method.
82+
*
83+
* This method is called when a user is closing an open PSoC5 device,
84+
* e.g. after reading from the device.
85+
* Here interrupt line resources are freed.
86+
*
87+
* @return 0 on success.
88+
*/
1789
int psoc5_cdrv_release(struct inode *inodep, struct file *filep);
18-
90+
/**
91+
* @brief The write method.
92+
*
93+
* This method is called when a user is writing to the device.
94+
* Prevents the user from sending strings longer than MAXLEN,
95+
* and sends the data received from userspace through SPI by calling "psoc5_spi_write()".
96+
*
97+
* @param ubuf The received data from userspace, represented as a character array.
98+
* @param count The length of the received character array.
99+
*
100+
* @return The length of the string written to the device.
101+
*/
19102
ssize_t psoc5_cdrv_write(struct file *filep, const char __user *ubuf,
20103
size_t count, loff_t *f_pos);
104+
/**
105+
* @brief The read method.
106+
*
107+
* This method is called when a user is trying to read from the device.
108+
* Waits for an interrupt, and then continues to read out the data from the SPI,
109+
* and copies them to userspace.
110+
* If no interrupt is received within 1000 jiffies 0 is sent to userspace.
111+
*
112+
* @param ubuf The address on which the user expects data to be copied to.
113+
* @return The length of the received character array.
114+
*/
21115
ssize_t psoc5_cdrv_read(struct file *filep, char __user *ubuf,
22116
size_t count, loff_t *f_pos);
117+
118+
/**
119+
* @brief The interrupt service routine.
120+
*
121+
* This ISR is called whenever a interrupt is received on the assigned GPIO pin,
122+
* meaning that a new word is received, it sets newData to 1.
123+
*
124+
* @return IRQ_HANDLED.
125+
*/
126+
irqreturn_t psoc5_isr(int irq, void *dev_id);
127+
128+
/**
129+
* @brief The character device struct.
130+
*
131+
* Used to register the device in the kernel.
132+
* Contains all information of the character driver characteristics of the module,
133+
* including the file_operations struct.
134+
*/
135+
static struct cdev psoc5Dev;
136+
/**
137+
* @brief The file operations struct
138+
*
139+
* Used to define which operations are called when the device
140+
* is used as a file/node.
141+
*/
142+
struct file_operations psoc5_Fops;
143+
/**
144+
* @brief A static in that contains the major/minor number characteristics returned from MKDEV.
145+
*/
146+
static int devno;
147+
/**
148+
* @brief The wait queue which psoc5_cdrv_read() waits for.
149+
*
150+
* This wait queue is used to signal the character driver read method
151+
* from the ISR, that new data is ready from the PSoC5 device.
152+
*/
153+
DECLARE_WAIT_QUEUE_HEAD(wait_queue);
154+
/**
155+
* @brief The variable that is checked to see if new data is ready.
156+
*/
157+
int newData = 0;

psoc5-spi.c

+21-28
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,15 @@
11
#include "psoc5-spi.h"
2-
3-
#define MAXLEN 512
4-
5-
static struct spi_device *psoc5_spi_device;
6-
7-
static struct omap2_mcspi_device_config psoc5_mcspi_device_config = {
8-
.turbo_mode = 0,
9-
.single_channel = 1, //Master
10-
};
11-
122
struct spi_board_info omap3devkit8000_spi_board_info[] = {
133
{
144
.modalias = "psoc5",
155
.bus_num = 1,
166
.chip_select = 0,
17-
.max_speed_hz = 15000000, //Should be ok, can be set lower if transfer errors occur
7+
.max_speed_hz = 2000000, //1500000, //Should be ok, can be set lower if transfer errors occur
188
.controller_data = &psoc5_mcspi_device_config,
199
.mode = SPI_MODE_3,
2010
},
2111
};
2212

23-
2413
static int __devinit psoc5_probe(struct spi_device* spi) {
2514

2615
psoc5_spi_device->bits_per_word = 8;
@@ -43,6 +32,7 @@ static struct spi_driver psoc5_spi_driver = {
4332
},
4433
.probe = psoc5_probe,
4534
.remove = __devexit_p(psoc5_remove),
35+
4636
};
4737

4838
int psoc5_spi_init(void) {
@@ -70,45 +60,48 @@ int psoc5_spi_exit(void) {
7060
char psoc5_spi_read(void) {
7161
struct spi_transfer t[1];
7262
struct spi_message m;
73-
char data;
63+
unsigned char data;
64+
65+
char data2;
66+
data2 = 65;
7467

7568
memset(t, 0, sizeof(t));
7669
spi_message_init(&m);
7770
m.spi = psoc5_spi_device;
7871

79-
t[0].tx_buf = NULL;
72+
t[0].tx_buf = NULL; //&data2;
8073
t[0].rx_buf = &data;
8174
t[0].len = 1;
8275
spi_message_add_tail(&t[0], &m);
8376

8477
spi_sync(m.spi, &m);
8578

86-
printk("PSoC5-spi: read: '%X'\n", data);
79+
//printk("PSoC5-spi: read: '%X'\n", data);
8780

8881
return data;
8982
}
9083

9184
void psoc5_spi_write(char *dataToWrite, unsigned int len) {
92-
int i;
93-
char *data;
94-
struct spi_transfer t[len];
85+
struct spi_transfer t[1];
9586
struct spi_message m;
9687

97-
data = dataToWrite;
98-
99-
memset(&t, 0, sizeof(t));
88+
memset(t, 0, sizeof(t));
10089
spi_message_init(&m);
10190
m.spi = psoc5_spi_device;
10291

92+
t[0].tx_buf = dataToWrite;
93+
t[0].rx_buf = NULL;
94+
t[0].len = 1;
95+
spi_message_add_tail(&t[0], &m);
96+
97+
/* enable this to print out what is sent in HEX
98+
* int i;
10399
for( i = 0 ; i < len ; i++ )
104100
{
105-
t[i].tx_buf = &data[i];
106-
t[i].rx_buf = NULL;
107-
t[i].len = 1;
108-
spi_message_add_tail(&t[i], &m);
109-
printk("PSoC5-spi: write: '%X' \n", data[i]);
110-
}
101+
printk("PSoC5-spi: write: '%c' \nLen: %i \n", dataToWrite[i], len);
102+
}*/
111103

112-
spi_sync(m.spi, &m);
104+
if(spi_sync(m.spi, &m)!= 0)
105+
printk(KERN_ALERT "SPI syncronization error!");
113106
}
114107

0 commit comments

Comments
 (0)