This repository was archived by the owner on Nov 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathNanodeMAC.cpp
More file actions
152 lines (123 loc) · 3.26 KB
/
NanodeMAC.cpp
File metadata and controls
152 lines (123 loc) · 3.26 KB
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
152
/***********************************************************************
* NanodeMAC
* Rufus Cable, June 2011 (threebytesfull)
*
* Library version created by Andrew Lindsay for use with Nanode and
* EtherShield Library at https://github.com/thiseldo/EtherShield
*
* Based on sample code to read the MAC address from the 11AA02E48 on the
* back of the Nanode V5 board.
*
* This code is hacky and basic - it doesn't check for bus errors
* and will probably fail horribly if it's interrupted. It's best
* run in setup() - fetch the MAC address once and keep it. After
* the address is fetched, it puts the chip back in standby mode
* in which it apparently only consumes 1uA.
*
* Feel free to reuse this code - suggestions for improvement are
* welcome! :)
*
* BITS 7 6 5 4 3 2 1 0
* PORTD = D7 D6 D5 D4 D3 D2 D1 D0
* PORTB = - - D13 D12 D11 D10 D9 D8
*
* Nanode has UNI/O SCIO on DIG7
*
***********************************************************************/
#include "NanodeMAC.h"
#include <inttypes.h>
#define D7_ON (1<<7)
#define D7_OFF (~D7_ON)
#define SCIO_HIGH PORTD |= D7_ON
#define SCIO_LOW PORTD &= D7_OFF
#define SCIO_OUTPUT DDRD |= D7_ON
#define SCIO_INPUT DDRD &= D7_OFF
#define SCIO_READ ((PIND & D7_ON) != 0)
#define WAIT_QUARTER_BIT delayMicroseconds(9);
#define WAIT_HALF_BIT delayMicroseconds(20);
#define NOP PORTD &= 0xff
// Fixed Timings
// standby pulse time (600us+)
#define UNIO_TSTBY_US 600
// start header setup time (10us+)
#define UNIO_TSS_US 10
// start header low pulse (5us+)
#define UNIO_THDR_US 6
// SCIO Manipulation macros
#define BIT0 SCIO_HIGH;WAIT_HALF_BIT;SCIO_LOW;WAIT_HALF_BIT;
#define BIT1 SCIO_LOW;WAIT_HALF_BIT;SCIO_HIGH;WAIT_HALF_BIT;
void NanodeMAC::unio_standby() {
SCIO_OUTPUT;
SCIO_HIGH;
delayMicroseconds(UNIO_TSTBY_US);
}
void NanodeMAC::unio_start_header() {
SCIO_LOW;
delayMicroseconds(UNIO_THDR_US);
unio_sendByte(B01010101);
}
void NanodeMAC::unio_sendByte(byte data) {
SCIO_OUTPUT;
for (int i=0; i<8; i++) {
if (data & 0x80) {
BIT1;
} else {
BIT0;
}
data <<= 1;
}
// MAK
BIT1;
// SAK?
//bool sak = unio_readBit();
unio_readBit();
}
void NanodeMAC::unio_readBytes(byte *addr, int length) {
for (int i=0; i<length; i++) {
byte data = 0;
for (int b=0; b<8; b++) {
data = (data << 1) | (unio_readBit() ? 1 : 0);
}
SCIO_OUTPUT;
if (i==length-1) {
BIT0; // NoMAK
} else {
BIT1; // MAK
}
//bool sak = unio_readBit();
unio_readBit();
addr[i] = data;
}
}
inline bool NanodeMAC::unio_readBit()
{
SCIO_INPUT;
WAIT_QUARTER_BIT;
bool value1 = SCIO_READ;
WAIT_HALF_BIT;
bool value2 = SCIO_READ;
WAIT_QUARTER_BIT;
return (value2 && !value1);
}
NanodeMAC::NanodeMAC( byte *mac_address ) {
// Turn off Interrupts while we read the mac address
noInterrupts();
// standby
unio_standby();
// start header
unio_start_header();
// address A0
unio_sendByte(0xA0);
// 0x3 READ
unio_sendByte(0x03);
// word address MSB 0x00
unio_sendByte(0x00);
// word address LSB 0xFA
unio_sendByte(0xFA);
// read 6 bytes into array
unio_readBytes(mac_address, 6);
// back to standby
unio_standby();
// Re-enable interrupts
interrupts();
}