blob: 6967cd59b77f0f26b0cc1207def90b3ed5502cf7 [file] [log] [blame]
LameMonster82314cbd52020-06-04 13:31:12 +02001#include <stdio.h>
2#include <fcntl.h>
3#include <unistd.h>
4#include <cinttypes>
5#include <cmath>
6#include <iostream>
7#include <sys/ioctl.h>
8
9#include "tspdrv.h"
10
11int tspdrv_initialized = 0;
12int tspdrv_file_desc;
13int tspdrv_numActuators = 0;
14
15int initialize_tspdrv()
16{
17 // Open device file as read/write for ioctl and write
18 tspdrv_file_desc = open(TSPDRV, O_RDWR);
19 if(tspdrv_file_desc < 0)
20 {
21 printf("Failed to open device file: %s", TSPDRV);
22 return -1;
23 }
24
25 // create default device parameters
26 device_parameter dev_param1 { 0, VIBE_KP_CFG_FREQUENCY_PARAM1, 0};
27 device_parameter dev_param2 { 0, VIBE_KP_CFG_FREQUENCY_PARAM2, 0};
28 device_parameter dev_param3 { 0, VIBE_KP_CFG_FREQUENCY_PARAM3, 0};
29 device_parameter dev_param4 { 0, VIBE_KP_CFG_FREQUENCY_PARAM4, 400};
30 device_parameter dev_param5 { 0, VIBE_KP_CFG_FREQUENCY_PARAM5, 13435};
31 device_parameter dev_param6 { 0, VIBE_KP_CFG_FREQUENCY_PARAM6, 0};
32 device_parameter dev_param_update_rate {0, VIBE_KP_CFG_UPDATE_RATE_MS, 5};
33
34 // Set magic number for vibration driver, wont allow us to write data without!
35 int ret = ioctl(tspdrv_file_desc, TSPDRV_SET_MAGIC_NUMBER, TSPDRV_MAGIC_NUMBER);
36 if(ret != 0)
37 {
38 printf("Failed to set magic number");
39 return -ret;
40 }
41
42 // Set default device parameter 1
43 ret = ioctl(tspdrv_file_desc, TSPDRV_SET_DEVICE_PARAMETER, &dev_param1);
44 if(ret != 0)
45 {
46 printf("Failed to set device parameter 1");
47 return -ret;
48 }
49
50 // Set default device parameter 2
51 ret = ioctl(tspdrv_file_desc, TSPDRV_SET_DEVICE_PARAMETER, &dev_param2);
52 if(ret != 0)
53 {
54 printf("Failed to set device parameter 2");
55 return -ret;
56 }
57
58 // Set default device parameter 3
59 ret = ioctl(tspdrv_file_desc, TSPDRV_SET_DEVICE_PARAMETER, &dev_param3);
60 if(ret != 0)
61 {
62 printf("Failed to set device parameter 3");
63 return -ret;
64 }
65
66 // Set default device parameter 4
67 ret = ioctl(tspdrv_file_desc, TSPDRV_SET_DEVICE_PARAMETER, &dev_param4);
68 if(ret != 0)
69 {
70 printf("Failed to set device parameter 4");
71 return -ret;
72 }
73
74 // Set default device parameter 5
75 ret = ioctl(tspdrv_file_desc, TSPDRV_SET_DEVICE_PARAMETER, &dev_param5);
76 if(ret != 0)
77 {
78 printf("Failed to set device parameter 5");
79 return -ret;
80 }
81
82 // Set default device parameter 6
83 ret = ioctl(tspdrv_file_desc, TSPDRV_SET_DEVICE_PARAMETER, &dev_param6);
84 if(ret != 0)
85 {
86 printf("Failed to set device parameter 6");
87 return -ret;
88 }
89
90 // Set default device parameter update rate
91 ret = ioctl(tspdrv_file_desc, TSPDRV_SET_DEVICE_PARAMETER, &dev_param_update_rate);
92 if(ret != 0)
93 {
94 printf("Failed to set device parameter update rate");
95 return -ret;
96 }
97
98 // Get number of actuators the device has
99 ret = ioctl(tspdrv_file_desc, TSPDRV_GET_NUM_ACTUATORS, 0);
100 if(ret == 0)
101 {
102 printf("No actuators found!");
103 return -2;
104 }
105
106 tspdrv_numActuators = ret;
107 tspdrv_initialized = 1;
108 return 0;
109}
110
111int tspdrv_off() {
112
113 for(int32_t i = 0; i < tspdrv_numActuators; i++)
114 {
115 int32_t ret = ioctl(tspdrv_file_desc, TSPDRV_DISABLE_AMP, i);
116 if(ret != 0)
117 {
118 printf("Failed to deactivate Actuator with index %d", i);
119 return -1;
120 }
121 }
122
123 return 0;
124}
125
126int vibrate(int timeout_ms)
127{
128 double BUFFER_ENTRIES_PER_MS = 8.21;
129 uint8_t DEFAULT_AMPLITUDE = 127;
130 int32_t OUTPUT_BUFFER_SIZE = 40;
131
132 if(!tspdrv_initialized)
133 {
134 printf("Initializing TSPDRV\n");
135 if(initialize_tspdrv() == 0)
136 {
137 printf("TSPDRV initialized\n");
138 }
139 }
140
141 // Calculate needed buffer entries
142 int32_t bufferSize = (int32_t) round(BUFFER_ENTRIES_PER_MS * timeout_ms);
143 VibeUInt8 fullBuffer[bufferSize];
144
145 // turn previous vibrations off
146 tspdrv_off();
147
148 for(int32_t i = 0; i < bufferSize; i++)
149 {
150 // The vibration is a sine curve, the negative parts are 255 + negative value
151 fullBuffer[i] = (VibeUInt8) (DEFAULT_AMPLITUDE * sin(i/BUFFER_ENTRIES_PER_MS));
152 }
153
154 // Amount of buffer arrays with size of OUTPUT_BUFFER_SIZE
155 int32_t numBuffers = (int32_t) ceil((double)bufferSize / (double)OUTPUT_BUFFER_SIZE);
156 VibeUInt8 outputBuffers[numBuffers][OUTPUT_BUFFER_SIZE];
157 memset(outputBuffers, 0, sizeof(outputBuffers)); // zero the array before we fill it with values
158
159 for(int32_t i = 0; i < bufferSize; i++)
160 {
161 // split fullBuffer into multiple smaller buffers with size OUTPUT_BUFFER_SIZE
162 outputBuffers[i/OUTPUT_BUFFER_SIZE][i%OUTPUT_BUFFER_SIZE] = fullBuffer[i];
163 }
164
165 for(int32_t i = 0; i < tspdrv_numActuators; i++)
166 {
167 for(int32_t j = 0; j < numBuffers; j++)
168 {
169 char output[OUTPUT_BUFFER_SIZE + SPI_HEADER_SIZE];
170 memset(output, 0, sizeof(output));
171 output[0] = i; // first byte is actuator index
172 output[1] = 8; // per definition has to be 8
173 output[2] = OUTPUT_BUFFER_SIZE; // size of the following output buffer
174 for(int32_t k = 3; k < OUTPUT_BUFFER_SIZE+3; k++)
175 {
176 output[k] = outputBuffers[j][k-3];
177 }
178 // write the buffer to the device
179 write(tspdrv_file_desc, output, sizeof(output));
180 if((j+1) % 4 == 0)
181 {
182 // every 4 buffers, but not the first if theres only 1, we send an ENABLE_AMP signal
183 int32_t ret = ioctl(tspdrv_file_desc, TSPDRV_ENABLE_AMP, i);
184 if(ret != 0)
185 {
186 printf("Failed to activate Actuator with index %d", i);
187 return -1;
188 }
189 }
190 }
191 }
192 return 0;
193}