Skip to content
This repository was archived by the owner on Oct 20, 2023. It is now read-only.

Commit 71790d6

Browse files
committed
Revert 9888726..0920f69
This rolls back to commit 9888726.
1 parent 0920f69 commit 71790d6

File tree

125 files changed

+3826
-2885
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+3826
-2885
lines changed

.DS_Store

-10 KB
Binary file not shown.

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
language: objective-c
22
before_install:
3-
- cd Example
4-
script: xcodebuild -workspace EFArduinoFSK.xcworkspace -scheme EFArduinoFSK -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO
3+
- cd FSK-Demo
4+
script: xcodebuild -workspace FSK-Demo.xcworkspace -scheme FSK-Demo -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO

Arduino-SoftModem/Receiver.ino

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <SoftModem.h>
2+
SoftModem modem;
3+
int dat;
4+
5+
void setup()
6+
{
7+
modem.begin();
8+
Serial.begin(115200);
9+
pinMode(13,OUTPUT);
10+
}
11+
void loop()
12+
{
13+
if(modem.available())
14+
{
15+
dat = modem.read();
16+
if(dat == 'C')
17+
{
18+
Serial.write('Y');
19+
digitalWrite(13,HIGH);
20+
}
21+
else
22+
{
23+
Serial.write('N');
24+
digitalWrite(13,LOW);
25+
}
26+
}
27+
}

Arduino-SoftModem/SoftModem.cpp

Lines changed: 309 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,309 @@
1+
#include "SoftModem.h"
2+
3+
#define TX_PIN (3)
4+
#define RX_PIN1 (6) // AIN0
5+
#define RX_PIN2 (7) // AIN1
6+
7+
SoftModem *SoftModem::activeObject = 0;
8+
9+
SoftModem::SoftModem() {
10+
}
11+
12+
SoftModem::~SoftModem() {
13+
end();
14+
}
15+
16+
#if F_CPU == 16000000
17+
#if SOFT_MODEM_BAUD_RATE <= 126
18+
#define TIMER_CLOCK_SELECT (7)
19+
#define MICROS_PER_TIMER_COUNT (clockCyclesToMicroseconds(1024))
20+
#elif SOFT_MODEM_BAUD_RATE <= 315
21+
#define TIMER_CLOCK_SELECT (6)
22+
#define MICROS_PER_TIMER_COUNT (clockCyclesToMicroseconds(256))
23+
#elif SOFT_MODEM_BAUD_RATE <= 630
24+
#define TIMER_CLOCK_SELECT (5)
25+
#define MICROS_PER_TIMER_COUNT (clockCyclesToMicroseconds(128))
26+
#elif SOFT_MODEM_BAUD_RATE <= 1225
27+
#define TIMER_CLOCK_SELECT (4)
28+
#define MICROS_PER_TIMER_COUNT (clockCyclesToMicroseconds(64))
29+
#else
30+
#define TIMER_CLOCK_SELECT (3)
31+
#define MICROS_PER_TIMER_COUNT (clockCyclesToMicroseconds(32))
32+
#endif
33+
#else
34+
#if SOFT_MODEM_BAUD_RATE <= 126
35+
#define TIMER_CLOCK_SELECT (6)
36+
#define MICROS_PER_TIMER_COUNT (clockCyclesToMicroseconds(256))
37+
#elif SOFT_MODEM_BAUD_RATE <= 315
38+
#define TIMER_CLOCK_SELECT (5)
39+
#define MICROS_PER_TIMER_COUNT (clockCyclesToMicroseconds(128))
40+
#elif SOFT_MODEM_BAUD_RATE <= 630
41+
#define TIMER_CLOCK_SELECT (4)
42+
#define MICROS_PER_TIMER_COUNT (clockCyclesToMicroseconds(64))
43+
#else
44+
#define TIMER_CLOCK_SELECT (3)
45+
#define MICROS_PER_TIMER_COUNT (clockCyclesToMicroseconds(32))
46+
#endif
47+
#endif
48+
49+
#define BIT_PERIOD (1000000/SOFT_MODEM_BAUD_RATE)
50+
#define HIGH_FREQ_MICROS (1000000/SOFT_MODEM_HIGH_FREQ)
51+
#define LOW_FREQ_MICROS (1000000/SOFT_MODEM_LOW_FREQ)
52+
53+
#define HIGH_FREQ_CNT (BIT_PERIOD/HIGH_FREQ_MICROS)
54+
#define LOW_FREQ_CNT (BIT_PERIOD/LOW_FREQ_MICROS)
55+
56+
#define MAX_CARRIR_BITS (40000/BIT_PERIOD) // 40ms
57+
58+
#define TCNT_BIT_PERIOD (BIT_PERIOD/MICROS_PER_TIMER_COUNT)
59+
#define TCNT_HIGH_FREQ (HIGH_FREQ_MICROS/MICROS_PER_TIMER_COUNT)
60+
#define TCNT_LOW_FREQ (LOW_FREQ_MICROS/MICROS_PER_TIMER_COUNT)
61+
62+
#define TCNT_HIGH_TH_L (TCNT_HIGH_FREQ * 0.80)
63+
#define TCNT_HIGH_TH_H (TCNT_HIGH_FREQ * 1.15)
64+
#define TCNT_LOW_TH_L (TCNT_LOW_FREQ * 0.85)
65+
#define TCNT_LOW_TH_H (TCNT_LOW_FREQ * 1.20)
66+
67+
#if SOFT_MODEM_DEBUG_ENABLE
68+
static volatile uint8_t *_portLEDReg;
69+
static uint8_t _portLEDMask;
70+
#endif
71+
72+
enum { START_BIT = 0, DATA_BIT = 8, STOP_BIT = 9, INACTIVE = 0xff };
73+
74+
void SoftModem::begin(void)
75+
{
76+
pinMode(RX_PIN1, INPUT);
77+
digitalWrite(RX_PIN1, LOW);
78+
79+
pinMode(RX_PIN2, INPUT);
80+
digitalWrite(RX_PIN2, LOW);
81+
82+
pinMode(TX_PIN, OUTPUT);
83+
digitalWrite(TX_PIN, LOW);
84+
85+
_txPortReg = portOutputRegister(digitalPinToPort(TX_PIN));
86+
_txPortMask = digitalPinToBitMask(TX_PIN);
87+
88+
#if SOFT_MODEM_DEBUG_ENABLE
89+
_portLEDReg = portOutputRegister(digitalPinToPort(13));
90+
_portLEDMask = digitalPinToBitMask(13);
91+
pinMode(13, OUTPUT);
92+
#endif
93+
94+
_recvStat = INACTIVE;
95+
_recvBufferHead = _recvBufferTail = 0;
96+
97+
SoftModem::activeObject = this;
98+
99+
_lastTCNT = TCNT2;
100+
_lastDiff = _lowCount = _highCount = 0;
101+
102+
TCCR2A = 0;
103+
TCCR2B = TIMER_CLOCK_SELECT;
104+
ACSR = _BV(ACIE) | _BV(ACIS1);
105+
DIDR1 = _BV(AIN1D) | _BV(AIN0D); // digital port off
106+
}
107+
108+
void SoftModem::end(void)
109+
{
110+
ACSR &= ~(_BV(ACIE));
111+
TIMSK2 &= ~(_BV(OCIE2A));
112+
DIDR1 &= ~(_BV(AIN1D) | _BV(AIN0D));
113+
SoftModem::activeObject = 0;
114+
}
115+
116+
void SoftModem::demodulate(void)
117+
{
118+
uint8_t t = TCNT2;
119+
uint8_t diff;
120+
121+
if(TIFR2 & _BV(TOV2)){
122+
TIFR2 |= _BV(TOV2);
123+
diff = (255 - _lastTCNT) + t + 1;
124+
}
125+
else{
126+
diff = t - _lastTCNT;
127+
}
128+
129+
if(diff < (uint8_t)(TCNT_HIGH_TH_L)) // Noise?
130+
return;
131+
132+
_lastTCNT = t;
133+
134+
if(diff > (uint8_t)(TCNT_LOW_TH_H))
135+
return;
136+
137+
// _lastDiff = (diff >> 1) + (diff >> 2) + (_lastDiff >> 2);
138+
_lastDiff = diff;
139+
140+
if(_lastDiff >= (uint8_t)(TCNT_LOW_TH_L)){
141+
_lowCount += _lastDiff;
142+
if((_recvStat == INACTIVE) && (_lowCount >= (uint8_t)(TCNT_BIT_PERIOD * 0.5))){ // maybe Start-Bit
143+
_recvStat = START_BIT;
144+
_highCount = 0;
145+
_recvBits = 0;
146+
OCR2A = t + (uint8_t)(TCNT_BIT_PERIOD) - _lowCount; // 1 bit period after detected
147+
TIFR2 |= _BV(OCF2A);
148+
TIMSK2 |= _BV(OCIE2A);
149+
}
150+
}
151+
else if(_lastDiff <= (uint8_t)(TCNT_HIGH_TH_H)){
152+
_highCount += _lastDiff;
153+
if((_recvStat == INACTIVE) && (_highCount >= (uint8_t)(TCNT_BIT_PERIOD))){
154+
_lowCount = _highCount = 0;
155+
}
156+
}
157+
}
158+
159+
ISR(ANALOG_COMP_vect)
160+
{
161+
SoftModem::activeObject->demodulate();
162+
}
163+
164+
void SoftModem::recv(void)
165+
{
166+
uint8_t high;
167+
if(_highCount > _lowCount){
168+
if(_highCount >= (uint8_t)TCNT_BIT_PERIOD)
169+
_highCount -= (uint8_t)TCNT_BIT_PERIOD;
170+
else
171+
_highCount = 0;
172+
high = 0x80;
173+
}
174+
else{
175+
if(_lowCount >= (uint8_t)TCNT_BIT_PERIOD)
176+
_lowCount -= (uint8_t)TCNT_BIT_PERIOD;
177+
else
178+
_lowCount = 0;
179+
high = 0x00;
180+
}
181+
182+
if(_recvStat == START_BIT){ // Start bit
183+
if(!high){
184+
_recvStat++;
185+
}else{
186+
goto end_recv;
187+
}
188+
}
189+
else if(_recvStat <= DATA_BIT) { // Data bits
190+
_recvBits >>= 1;
191+
_recvBits |= high;
192+
_recvStat++;
193+
}
194+
else if(_recvStat == STOP_BIT){ // Stop bit
195+
uint8_t new_tail = (_recvBufferTail + 1) & (SOFT_MODEM_RX_BUF_SIZE - 1);
196+
if(new_tail != _recvBufferHead){
197+
_recvBuffer[_recvBufferTail] = _recvBits;
198+
_recvBufferTail = new_tail;
199+
}
200+
goto end_recv;
201+
}
202+
else{
203+
end_recv:
204+
_recvStat = INACTIVE;
205+
TIMSK2 &= ~_BV(OCIE2A);
206+
}
207+
}
208+
209+
ISR(TIMER2_COMPA_vect)
210+
{
211+
OCR2A += (uint8_t)TCNT_BIT_PERIOD;
212+
SoftModem::activeObject->recv();
213+
#if SOFT_MODEM_DEBUG_ENABLE
214+
*_portLEDReg ^= _portLEDMask;
215+
#endif
216+
}
217+
218+
int SoftModem::available()
219+
{
220+
return (_recvBufferTail + SOFT_MODEM_RX_BUF_SIZE - _recvBufferHead) & (SOFT_MODEM_RX_BUF_SIZE - 1);
221+
}
222+
223+
int SoftModem::read()
224+
{
225+
if(_recvBufferHead == _recvBufferTail)
226+
return -1;
227+
int d = _recvBuffer[_recvBufferHead];
228+
_recvBufferHead = (_recvBufferHead + 1) & (SOFT_MODEM_RX_BUF_SIZE - 1);
229+
return d;
230+
}
231+
232+
int SoftModem::peek()
233+
{
234+
if(_recvBufferHead == _recvBufferTail)
235+
return -1;
236+
return _recvBuffer[_recvBufferHead];
237+
}
238+
239+
void SoftModem::flush()
240+
{
241+
_recvBufferHead = _recvBufferTail = 0;
242+
}
243+
244+
void SoftModem::modulate(uint8_t b)
245+
{
246+
uint8_t cnt,tcnt,tcnt2;
247+
if(b){
248+
cnt = (uint8_t)(HIGH_FREQ_CNT);
249+
tcnt2 = (uint8_t)(TCNT_HIGH_FREQ / 2);
250+
tcnt = (uint8_t)(TCNT_HIGH_FREQ) - tcnt2;
251+
}else{
252+
cnt = (uint8_t)(LOW_FREQ_CNT);
253+
tcnt2 = (uint8_t)(TCNT_LOW_FREQ / 2);
254+
tcnt = (uint8_t)(TCNT_LOW_FREQ) - tcnt2;
255+
}
256+
do {
257+
cnt--;
258+
{
259+
OCR2B += tcnt;
260+
TIFR2 |= _BV(OCF2B);
261+
while(!(TIFR2 & _BV(OCF2B)));
262+
}
263+
*_txPortReg ^= _txPortMask;
264+
{
265+
OCR2B += tcnt2;
266+
TIFR2 |= _BV(OCF2B);
267+
while(!(TIFR2 & _BV(OCF2B)));
268+
}
269+
*_txPortReg ^= _txPortMask;
270+
} while (cnt);
271+
}
272+
273+
// Brief carrier tone before each transmission
274+
// 1 start bit (LOW)
275+
// 8 data bits, LSB first
276+
// 1 stop bit (HIGH)
277+
// ...
278+
// 1 push bit (HIGH)
279+
280+
size_t SoftModem::write(const uint8_t *buffer, size_t size)
281+
{
282+
uint8_t cnt = ((micros() - _lastWriteTime) / BIT_PERIOD) + 1;
283+
if(cnt > MAX_CARRIR_BITS)
284+
cnt = MAX_CARRIR_BITS;
285+
for(uint8_t i = 0; i<cnt; i++)
286+
modulate(HIGH);
287+
size_t n = size;
288+
while (size--) {
289+
uint8_t data = *buffer++;
290+
modulate(LOW); // Start Bit
291+
for(uint8_t mask = 1; mask; mask <<= 1){ // Data Bits
292+
if(data & mask){
293+
modulate(HIGH);
294+
}
295+
else{
296+
modulate(LOW);
297+
}
298+
}
299+
modulate(HIGH); // Stop Bit
300+
}
301+
modulate(HIGH); // Push Bit
302+
_lastWriteTime = micros();
303+
return n;
304+
}
305+
306+
size_t SoftModem::write(uint8_t data)
307+
{
308+
return write(&data, 1);
309+
}

0 commit comments

Comments
 (0)