> Oder häng einfach mal ein Oszi/Logic-Analyzer dran
Gemacht. Statt 100ns-Takt war es ein 800ns low/164ns high-Takt (Version
W1). Oops. Ziemlich verschätzt. Mit aufgerollter Schleife (Version W2)
sind es jetzt 162ns low / 108ns high.
Die Lese-Schleife war nicht ganz so schlimm. 380ns low, 162ns high (R1).
Unrolling brachte 108ns low, 109ns high (Version R2), aber das war wohl
zu knapp - das hat nicht funktioniert. Version R3 geht (160ns low, 164ns
high).
--- Anhänge
Version W1: 164ns hi, 760ns bis 814ns low
1 | for (uint8_t bitmask = 128; bitmask; bitmask >>= 1)
|
2 | {
|
3 | if (out & bitmask)
|
4 | SPI_MOSI_HIGH();
|
5 | else
|
6 | SPI_MOSI_LOW ();
|
7 |
|
8 | DELAY_50NS();
|
9 |
|
10 | SPI_SCK_HIGH();
|
11 |
|
12 | DELAY_50NS();
|
13 |
|
14 | SPI_SCK_LOW();
|
15 |
|
16 | DELAY_50NS();
|
17 | }
|
Version W2: 110ns high, 542ns low
1 | for (uint8_t bitmask = 128; bitmask;)
|
2 | {
|
3 | if (out & bitmask)
|
4 | SPI_MOSI_HIGH();
|
5 | else
|
6 | SPI_MOSI_LOW();
|
7 |
|
8 | SPI_SCK_TOGGLE(); // clock now high
|
9 |
|
10 | bitmask >>= 1; // place here to generate pause
|
11 |
|
12 | SPI_SCK_TOGGLE(); // clock now low
|
13 | }
|
Version W3: 108ns high, 162ns low
1 | // bit 7
|
2 |
|
3 | if (out & 128)
|
4 | SPI_MOSI_HIGH();
|
5 | else
|
6 | SPI_MOSI_LOW();
|
7 |
|
8 | SPI_SCK_TOGGLE(); // clock now high
|
9 |
|
10 | DELAY_50NS();
|
11 |
|
12 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
13 |
|
14 | // bit 6
|
15 |
|
16 | if (out & 64)
|
17 | SPI_MOSI_HIGH();
|
18 | else
|
19 | SPI_MOSI_LOW();
|
20 |
|
21 | SPI_SCK_TOGGLE(); // clock now high
|
22 |
|
23 | DELAY_50NS();
|
24 |
|
25 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
26 |
|
27 | // bit 7
|
28 |
|
29 | if (out & 32)
|
30 | SPI_MOSI_HIGH();
|
31 | else
|
32 | SPI_MOSI_LOW();
|
33 |
|
34 | SPI_SCK_TOGGLE(); // clock now high
|
35 |
|
36 | DELAY_50NS();
|
37 |
|
38 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
39 |
|
40 | if (out & 16)
|
41 | SPI_MOSI_HIGH();
|
42 | else
|
43 | SPI_MOSI_LOW();
|
44 |
|
45 | SPI_SCK_TOGGLE(); // clock now high
|
46 |
|
47 | DELAY_50NS();
|
48 |
|
49 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
50 |
|
51 | if (out & 8)
|
52 | SPI_MOSI_HIGH();
|
53 | else
|
54 | SPI_MOSI_LOW();
|
55 |
|
56 | SPI_SCK_TOGGLE(); // clock now high
|
57 |
|
58 | DELAY_50NS();
|
59 |
|
60 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
61 |
|
62 | if (out & 4)
|
63 | SPI_MOSI_HIGH();
|
64 | else
|
65 | SPI_MOSI_LOW();
|
66 |
|
67 | SPI_SCK_TOGGLE(); // clock now high
|
68 |
|
69 | DELAY_50NS();
|
70 |
|
71 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
72 |
|
73 | if (out & 2)
|
74 | SPI_MOSI_HIGH();
|
75 | else
|
76 | SPI_MOSI_LOW();
|
77 |
|
78 | SPI_SCK_TOGGLE(); // clock now high
|
79 |
|
80 | DELAY_50NS();
|
81 |
|
82 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
83 |
|
84 | if (out & 1)
|
85 | SPI_MOSI_HIGH();
|
86 | else
|
87 | SPI_MOSI_LOW();
|
88 |
|
89 | SPI_SCK_TOGGLE(); // clock now high
|
90 |
|
91 | DELAY_50NS();
|
92 |
|
93 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
Version R1: 162ns high, 380ns low
1 | uint8_t bitmask, in;
|
2 |
|
3 | for (in = 0, bitmask = 128; bitmask; bitmask >>= 1)
|
4 | {
|
5 | // read 100NS after clock went low
|
6 |
|
7 | if (SPI_MISO_READ())
|
8 |
|
9 | in |= bitmask;
|
10 |
|
11 | SPI_SCK_HIGH();
|
12 |
|
13 | DELAY_50NS();
|
14 |
|
15 | SPI_SCK_LOW();
|
16 | }
|
Version R2: 109ns high, 108ns low
1 | uint8_t in = 0;
|
2 |
|
3 | // bit 7
|
4 |
|
5 | if (SPI_MISO_READ())
|
6 |
|
7 | in |= 128;
|
8 |
|
9 | SPI_SCK_TOGGLE(); // clock now high
|
10 |
|
11 | DELAY_50NS();
|
12 |
|
13 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
14 |
|
15 | // bit 6
|
16 |
|
17 | if (SPI_MISO_READ())
|
18 |
|
19 | in |= 64;
|
20 |
|
21 | SPI_SCK_TOGGLE(); // clock now high
|
22 |
|
23 | DELAY_50NS();
|
24 |
|
25 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
26 |
|
27 | // bit 5
|
28 |
|
29 | if (SPI_MISO_READ())
|
30 |
|
31 | in |= 32;
|
32 |
|
33 | SPI_SCK_TOGGLE(); // clock now high
|
34 |
|
35 | DELAY_50NS();
|
36 |
|
37 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
38 |
|
39 | // bit 4
|
40 |
|
41 | if (SPI_MISO_READ())
|
42 |
|
43 | in |= 16;
|
44 |
|
45 | SPI_SCK_TOGGLE(); // clock now high
|
46 |
|
47 | DELAY_50NS();
|
48 |
|
49 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
50 |
|
51 | // bit 3
|
52 |
|
53 | if (SPI_MISO_READ())
|
54 |
|
55 | in |= 8;
|
56 |
|
57 | SPI_SCK_TOGGLE(); // clock now high
|
58 |
|
59 | DELAY_50NS();
|
60 |
|
61 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
62 |
|
63 | // bit 2
|
64 |
|
65 | if (SPI_MISO_READ())
|
66 |
|
67 | in |= 4;
|
68 |
|
69 | SPI_SCK_TOGGLE(); // clock now high
|
70 |
|
71 | DELAY_50NS();
|
72 |
|
73 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
74 |
|
75 | // bit 1
|
76 |
|
77 | if (SPI_MISO_READ())
|
78 |
|
79 | in |= 2;
|
80 |
|
81 | SPI_SCK_TOGGLE(); // clock now high
|
82 |
|
83 | DELAY_50NS();
|
84 |
|
85 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
86 |
|
87 | // bit 0
|
88 |
|
89 | if (SPI_MISO_READ())
|
90 |
|
91 | in |= 1;
|
92 |
|
93 | SPI_SCK_TOGGLE(); // clock now high
|
94 |
|
95 | DELAY_50NS();
|
96 |
|
97 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
Version R3:
1 | uint8_t in = 0;
|
2 |
|
3 | // bit 7
|
4 |
|
5 | if (SPI_MISO_READ())
|
6 |
|
7 | in |= 128;
|
8 |
|
9 | SPI_SCK_TOGGLE(); // clock now high
|
10 |
|
11 | DELAY_100NS();
|
12 |
|
13 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
14 |
|
15 | DELAY_50NS();
|
16 |
|
17 | // bit 6
|
18 |
|
19 | if (SPI_MISO_READ())
|
20 |
|
21 | in |= 64;
|
22 |
|
23 | SPI_SCK_TOGGLE(); // clock now high
|
24 |
|
25 | DELAY_100NS();
|
26 |
|
27 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
28 |
|
29 | DELAY_50NS();
|
30 |
|
31 | // bit 5
|
32 |
|
33 | if (SPI_MISO_READ())
|
34 |
|
35 | in |= 32;
|
36 |
|
37 | SPI_SCK_TOGGLE(); // clock now high
|
38 |
|
39 | DELAY_100NS();
|
40 |
|
41 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
42 |
|
43 | DELAY_50NS();
|
44 |
|
45 | // bit 3
|
46 |
|
47 | if (SPI_MISO_READ())
|
48 |
|
49 | in |= 16;
|
50 |
|
51 | SPI_SCK_TOGGLE(); // clock now high
|
52 |
|
53 | DELAY_100NS();
|
54 |
|
55 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
56 |
|
57 | DELAY_50NS();
|
58 |
|
59 | // bit 3
|
60 |
|
61 | if (SPI_MISO_READ())
|
62 |
|
63 | in |= 8;
|
64 |
|
65 | SPI_SCK_TOGGLE(); // clock now high
|
66 |
|
67 | DELAY_100NS();
|
68 |
|
69 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
70 |
|
71 | DELAY_50NS();
|
72 |
|
73 | // bit 2
|
74 |
|
75 | if (SPI_MISO_READ())
|
76 |
|
77 | in |= 4;
|
78 |
|
79 | SPI_SCK_TOGGLE(); // clock now high
|
80 |
|
81 | DELAY_100NS();
|
82 |
|
83 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
84 |
|
85 | DELAY_50NS();
|
86 |
|
87 | // bit 1
|
88 |
|
89 | if (SPI_MISO_READ())
|
90 |
|
91 | in |= 2;
|
92 |
|
93 | SPI_SCK_TOGGLE(); // clock now high
|
94 |
|
95 | DELAY_100NS();
|
96 |
|
97 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
98 |
|
99 | DELAY_50NS();
|
100 |
|
101 | // bit 0
|
102 |
|
103 | if (SPI_MISO_READ())
|
104 |
|
105 | in |= 1;
|
106 |
|
107 | SPI_SCK_TOGGLE(); // clock now high
|
108 |
|
109 | DELAY_100NS();
|
110 |
|
111 | SPI_SCK_TOGGLE(); // clock now low (idle)
|
112 |
|
113 | DELAY_50NS();
|
114 |
|
115 | return(in);
|