26 #include <linux/module.h> |
26 #include <linux/module.h> |
27 #include <linux/delay.h> |
27 #include <linux/delay.h> |
28 #include <linux/timer.h> |
28 #include <linux/timer.h> |
29 #include <linux/interrupt.h> |
29 #include <linux/interrupt.h> |
30 |
30 |
|
31 // RTAI |
31 #include "rtai.h" |
32 #include "rtai.h" |
32 #include "rtai_sched.h" |
33 #include "rtai_sched.h" |
33 #include "rtai_sem.h" |
34 #include "rtai_sem.h" |
34 |
35 |
35 #include "../../include/ecrt.h" // EtherCAT realtime interface |
36 // EtherCAT realtime interface |
36 |
37 #include "../../include/ecrt.h" |
|
38 |
|
39 /*****************************************************************************/ |
|
40 |
|
41 // comment this for synchronous IO |
37 #define ASYNC |
42 #define ASYNC |
38 #define TIMERTICKS 1000000 |
43 |
|
44 // RTAI task frequency in Hz |
|
45 #define FREQUENCY 10000 |
|
46 |
|
47 #define TIMERTICKS (1000000000 / FREQUENCY) |
39 |
48 |
40 /*****************************************************************************/ |
49 /*****************************************************************************/ |
41 |
50 |
42 // RTAI |
51 // RTAI |
43 RT_TASK task; |
52 RT_TASK task; |
44 SEM master_sem; |
53 SEM master_sem; |
|
54 cycles_t t_last_start = 0; |
|
55 cycles_t t_critical; |
45 |
56 |
46 // EtherCAT |
57 // EtherCAT |
47 ec_master_t *master = NULL; |
58 ec_master_t *master = NULL; |
48 ec_domain_t *domain1 = NULL; |
59 ec_domain_t *domain1 = NULL; |
49 |
60 |
50 // data fields |
61 // data fields |
51 //void *r_ssi_input, *r_ssi_status, *r_4102[3]; |
62 void *r_ssi_input; |
52 |
63 |
53 // channels |
64 // channels |
54 uint32_t k_pos; |
65 uint32_t k_pos; |
55 uint8_t k_stat; |
66 uint8_t k_stat; |
56 |
67 |
57 ec_field_init_t domain1_fields[] = { |
68 ec_field_init_t domain1_fields[] = { |
58 {NULL, "3", "Beckhoff", "EL5001", "InputValue", 0}, |
69 {&r_ssi_input, "3", "Beckhoff", "EL5001", "InputValue", 0}, |
59 {NULL, "2", "Beckhoff", "EL4132", "OutputValue", 0}, |
70 {NULL, "2", "Beckhoff", "EL4132", "OutputValue", 0}, |
60 {} |
71 {} |
61 }; |
72 }; |
62 |
73 |
63 /*****************************************************************************/ |
74 /*****************************************************************************/ |
64 |
75 |
65 void run(long data) |
76 void run(long data) |
66 { |
77 { |
67 while (1) { |
78 while (1) |
|
79 { |
|
80 t_last_start = get_cycles(); |
68 rt_sem_wait(&master_sem); |
81 rt_sem_wait(&master_sem); |
69 |
82 |
70 #ifdef ASYNC |
83 #ifdef ASYNC |
71 // receive |
84 // receive |
72 ecrt_master_async_receive(master); |
85 ecrt_master_async_receive(master); |
78 ecrt_master_sync_io(master); |
91 ecrt_master_sync_io(master); |
79 ecrt_domain_process(domain1); |
92 ecrt_domain_process(domain1); |
80 #endif |
93 #endif |
81 |
94 |
82 // process data |
95 // process data |
83 //k_pos = EC_READ_U32(r_ssi); |
96 k_pos = EC_READ_U32(r_ssi_input); |
84 |
97 |
85 #ifdef ASYNC |
98 #ifdef ASYNC |
86 // send |
99 // send |
87 ecrt_domain_queue(domain1); |
100 ecrt_domain_queue(domain1); |
88 ecrt_master_run(master); |
101 ecrt_master_run(master); |
89 ecrt_master_async_send(master); |
102 ecrt_master_async_send(master); |
90 #endif |
103 #endif |
91 |
104 |
92 rt_sem_signal(&master_sem); |
105 rt_sem_signal(&master_sem); |
93 |
|
94 rt_task_wait_period(); |
106 rt_task_wait_period(); |
95 } |
107 } |
96 } |
108 } |
97 |
109 |
98 /*****************************************************************************/ |
110 /*****************************************************************************/ |
99 |
111 |
100 int request_lock(void *data) |
112 int request_lock(void *data) |
101 { |
113 { |
|
114 // too close to the next RT cycle: deny access... |
|
115 if (get_cycles() - t_last_start > t_critical) return -1; |
|
116 |
|
117 // allow access |
102 rt_sem_wait(&master_sem); |
118 rt_sem_wait(&master_sem); |
103 return 0; // access allowed |
119 return 0; |
104 } |
120 } |
105 |
121 |
106 /*****************************************************************************/ |
122 /*****************************************************************************/ |
107 |
123 |
108 void release_lock(void *data) |
124 void release_lock(void *data) |
117 RTIME tick_period, requested_ticks, now; |
133 RTIME tick_period, requested_ticks, now; |
118 |
134 |
119 printk(KERN_INFO "=== Starting EtherCAT RTAI sample module... ===\n"); |
135 printk(KERN_INFO "=== Starting EtherCAT RTAI sample module... ===\n"); |
120 |
136 |
121 rt_sem_init(&master_sem, 1); |
137 rt_sem_init(&master_sem, 1); |
|
138 |
|
139 t_critical = cpu_khz * 800 / FREQUENCY; // ticks for 80% |
122 |
140 |
123 if ((master = ecrt_request_master(0)) == NULL) { |
141 if ((master = ecrt_request_master(0)) == NULL) { |
124 printk(KERN_ERR "Requesting master 0 failed!\n"); |
142 printk(KERN_ERR "Requesting master 0 failed!\n"); |
125 goto out_return; |
143 goto out_return; |
126 } |
144 } |