This repository has been archived by the owner on Jun 27, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathWriter.m
151 lines (129 loc) · 4.69 KB
/
Writer.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//
// based on SerialExample.m
//
#import "Writer.h"
@implementation Writer
// executes after everything in the xib/nib is initiallized
- (void)initalize {
// we don't have a serial port open yet
serialFileDescriptor = -1;
NSLog(@"\nWHYYY\n");
}
- (void) flush {
struct timespec interval = {0,20000000}, remainder;
if(serialFileDescriptor!=-1) {
ioctl(serialFileDescriptor, TIOCDRAIN);
ioctl(serialFileDescriptor, TIOCFLUSH, FWRITE);
}
}
- (void) dealloc {
struct timespec interval = {0,100000000}, remainder;
if(serialFileDescriptor!=-1) {
ioctl(serialFileDescriptor, TIOCSDTR);
nanosleep(&interval, &remainder); // wait 0.1 seconds
ioctl(serialFileDescriptor, TIOCCDTR);
close(serialFileDescriptor);
}
[super dealloc];
}
// open the serial port
// - nil is returned on success
// - an error message is returned otherwise
- (NSString *) openSerialPort: (NSString *)serialPortFile baud: (speed_t)baudRate {
NSLog(@"\nHALLO\n");
int success;
// close the port if it is already open
if (serialFileDescriptor != -1) {
close(serialFileDescriptor);
serialFileDescriptor = -1;
// re-opening the same port REALLY fast will fail spectacularly... better to sleep a sec
sleep(0.5);
}
// c-string path to serial-port file
const char *bsdPath = [serialPortFile cStringUsingEncoding:NSUTF8StringEncoding];
// Hold the original termios attributes we are setting
struct termios options;
// receive latency ( in microseconds )
unsigned long mics = 3;
// error message string
NSMutableString *errorMessage = nil;
// open the port
// O_NONBLOCK causes the port to open without any delay (we'll block with another call)
serialFileDescriptor = open(bsdPath, O_RDWR | O_NOCTTY | O_NONBLOCK );
if (serialFileDescriptor == -1) {
// check if the port opened correctly
[errorMessage appendString: @"Error: couldn't open serial port"];
} else {
// TIOCEXCL causes blocking of non-root processes on this serial-port
success = ioctl(serialFileDescriptor, TIOCEXCL);
if ( success == -1) {
[errorMessage appendString: @"Error: couldn't obtain lock on serial port"];
} else {
success = fcntl(serialFileDescriptor, F_SETFL, 0);
if ( success == -1) {
// clear the O_NONBLOCK flag; all calls from here on out are blocking for non-root processes
[errorMessage appendString: @"Error: couldn't obtain lock on serial port"];
} else {
// Get the current options and save them so we can restore the default settings later.
success = tcgetattr(serialFileDescriptor, &gOriginalTTYAttrs);
if ( success == -1) {
[errorMessage appendString: @"Error: couldn't get serial attributes"];
} else {
// copy the old termios settings into the current
// you want to do this so that you get all the control characters assigned
options = gOriginalTTYAttrs;
/*
cfmakeraw(&options) is equivilent to:
options->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
options->c_oflag &= ~OPOST;
options->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
options->c_cflag &= ~(CSIZE | PARENB);
options->c_cflag |= CS8;
*/
cfmakeraw(&options);
// set tty attributes (raw-mode in this case)
success = tcsetattr(serialFileDescriptor, TCSANOW, &options);
if ( success == -1) {
[errorMessage appendString: @"Error: coudln't set serial attributes"];
} else {
// Set baud rate (any arbitrary baud rate can be set this way)
success = ioctl(serialFileDescriptor, IOSSIOSPEED, &baudRate);
if ( success == -1) {
[errorMessage appendString: @"Error: Baud Rate out of bounds"];
} else {
// Set the receive latency (a.k.a. don't wait to buffer data)
success = ioctl(serialFileDescriptor, IOSSDATALAT, &mics);
if ( success == -1) {
[errorMessage appendString: @"Error: coudln't set serial latency"];
}
}
}
}
}
}
}
// make sure the port is closed if a problem happens
if ((serialFileDescriptor != -1) && (errorMessage != nil)) {
close(serialFileDescriptor);
serialFileDescriptor = -1;
}
return errorMessage;
}
// send a string to the serial po
- (void) writeColorArray: (uint8_t []) bytes: (uint16) size {
if(serialFileDescriptor!=-1) {
write(serialFileDescriptor, bytes, size);
} else {
// make sure the user knows they should select a serial port
NSLog(@"\n ERROR: Select a Serial Port from the pull-down menu\n");
}
}
- (void) writeByte: (uint8_t*) byte {
if(serialFileDescriptor!=-1) {
write(serialFileDescriptor, byte, 1);
} else {
// make sure the user knows they should select a serial port
NSLog(@"\n ERROR: Select a Serial Port from the pull-down menu\n");
}
}
@end