1 | #include <avr/io.h>
|
2 |
|
3 | #define F_CPU 8388608
|
4 |
|
5 | #include <util/delay.h>
|
6 |
|
7 | #define BAUD 9600
|
8 | #define MYUBRR (F_CPU/16/BAUD-1)
|
9 |
|
10 | #define DD_CS PB0 //Selektiert den Master
|
11 | #define DD_SCK PB1 //Takt
|
12 | #define DD_MOSI PB2 //Master Out, Slave In
|
13 | #define DD_MISO PB3 //Master In, Slave Out
|
14 |
|
15 | #define CC_FIFO PE5
|
16 | #define CC_FIFOP PE6
|
17 | #define CC_CCA PD5 //Clear Channel Assessment
|
18 | #define CC_SFD PD4 //Start of Frame Delimiter
|
19 | #define CC_RESET PB6 //Reset
|
20 | #define CC_VREG_EN PB7 //VREG Enable
|
21 |
|
22 | void SPI_Init(void)
|
23 | {
|
24 | // MOSI, SCK, CS, RESET ausgang, MISO eingang
|
25 | DDRB = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_CS)|(1<<CC_RESET)|(1<<CC_VREG_EN);
|
26 |
|
27 | // Master, aktiviere SPI, fck/4, MSB first, SPI mode
|
28 | SPCR = (1<<MSTR)|(1<<SPE)|(1<<CPHA);
|
29 | }
|
30 |
|
31 | uint8_t SPI_TxRx(uint8_t cData)
|
32 | {
|
33 | SPDR = cData;
|
34 | while(!(SPSR & (1<<SPIF)));
|
35 | return SPDR;
|
36 | }
|
37 |
|
38 | uint16_t SPI_RxReg(uint8_t Address)
|
39 | {
|
40 | uint8_t state;
|
41 | uint16_t data;
|
42 | Address = Address | 0x40;
|
43 |
|
44 | PORTB &= ~(1<<DD_CS); // CS\ low
|
45 |
|
46 | _delay_us(25);
|
47 |
|
48 | state = SPI_TxRx(Address); // eventuell den Status auswerten
|
49 | data = SPI_TxRx(0xff)<<8; // MSB
|
50 | data = data + SPI_TxRx(0xff); // LSB
|
51 |
|
52 | PORTB |= (1<<DD_CS); // CS\ high
|
53 | return data;
|
54 | }
|
55 |
|
56 | uint8_t SPI_TxReg(uint8_t Address, uint16_t data)
|
57 | {
|
58 | uint8_t state;
|
59 |
|
60 | PORTB &= ~(1<<DD_CS); // CS\ low
|
61 |
|
62 | _delay_us(25);
|
63 |
|
64 | state = SPI_TxRx(Address); // eventuell den Status auswerten
|
65 | SPI_TxRx(data>>8); // MSB
|
66 | SPI_TxRx(data); // LSB
|
67 |
|
68 | PORTB |= (1<<DD_CS); // CS\ high
|
69 |
|
70 | return state;
|
71 | }
|
72 |
|
73 | void SPI_TxRam(uint16_t Address, uint16_t data)
|
74 | {
|
75 | uint8_t status;
|
76 | Address = (Address<<6) | 0x8000;
|
77 |
|
78 | PORTB &= ~(1<<DD_CS); // CS\ low
|
79 |
|
80 | _delay_us(25);
|
81 | status = SPI_TxRx((uint8_t)(Address>>8));
|
82 |
|
83 | _delay_us(25);
|
84 | SPI_TxRx((uint8_t)(Address & 0x00ff));
|
85 | SPI_TxRx((uint8_t)(data>>8));
|
86 | SPI_TxRx((uint8_t)(data & 0x00ff));
|
87 |
|
88 | PORTB |= (1<<DD_CS); // CS\ high
|
89 | }
|
90 |
|
91 | void setKanal()
|
92 | {
|
93 | uint16_t FSCTRL_reg;
|
94 | uint16_t FSCTRL_kanal;
|
95 |
|
96 | FSCTRL_kanal = 357 + 5 * (26-11);
|
97 | FSCTRL_reg = (SPI_RxReg(0x18) & 0xfc00) | FSCTRL_kanal;
|
98 |
|
99 | SPI_TxReg(0x18, FSCTRL_reg);
|
100 | }
|
101 |
|
102 | void setShortAddress(uint16_t addr)
|
103 | {
|
104 | SPI_TxRam(0x016a, addr);
|
105 | }
|
106 |
|
107 | void CC2420_Init(void)
|
108 | {
|
109 | uint8_t oscStatus;
|
110 | uint16_t MANAND_reg;
|
111 |
|
112 | // Ein- und Ausgänge definieren
|
113 | DDRD &= ~(1<<CC_SFD) & ~(1<<CC_CCA);
|
114 | DDRE &= ~(1<<CC_FIFO) & ~(1<<CC_FIFOP);
|
115 |
|
116 | // CC2420 einschalten
|
117 | PORTB |= (1<<CC_VREG_EN);
|
118 | _delay_us(600); // VREG_EN start up time
|
119 |
|
120 | // CC2420 Reset
|
121 | PORTB |= (1<<CC_RESET);
|
122 |
|
123 | PORTB &= ~(1<<DD_CS); // CS\ low
|
124 | SPI_TxRx(0x01); // SXOSCON
|
125 | PORTB |= (1<<DD_CS); // CS\ high
|
126 | _delay_ms(1); // SXOSCON start up time
|
127 |
|
128 | // XOSC16M_PD + BIAS_PD = 0 für Crystal Oscillator (Command Strobe 0x01)
|
129 | MANAND_reg = SPI_RxReg(0x21);
|
130 | MANAND_reg &= ~(0x4080);
|
131 | oscStatus = SPI_TxReg(0x21, MANAND_reg);
|
132 |
|
133 | while(!(oscStatus && 0x40)); // Warte bis Crystal Oscillator stable
|
134 |
|
135 | setKanal();
|
136 | setShortAddress(0x0001);
|
137 |
|
138 | // Command Strobe
|
139 | PORTB &= ~(1<<DD_CS); // CS\ low
|
140 | SPI_TxRx(0x04); // STXON
|
141 | SPI_TxRx(0x03); // SRXON
|
142 | PORTB |= (1<<DD_CS); // CS\ high
|
143 | }
|
144 |
|
145 | int main(void)
|
146 | {
|
147 | USART_Init(MYUBRR);
|
148 | SPI_Init();
|
149 | CC2420_Init();
|
150 |
|
151 | _delay_ms(1000);
|
152 |
|
153 | while(1) {
|
154 | while((PINE & (1<<CC_FIFOP)) || (PIND & (1<<CC_SFD)));
|
155 |
|
156 | PORTB &= ~(1<<PB4) & ~(1<<PB5); //LED's aus
|
157 |
|
158 | // Command Strobe
|
159 | PORTB &= ~(1<<DD_CS); // CS\ low
|
160 | SPI_TxRx(0x09); // SFLUSHTX
|
161 | PORTB |= (1<<DD_CS); // CS\ high
|
162 |
|
163 | SPI_TxReg(0x3e, 0x0b20);
|
164 | SPI_TxReg(0x3e, 0x2200);
|
165 | SPI_TxReg(0x3e, 0x0002);
|
166 | SPI_TxReg(0x3e, 0x0001);
|
167 | SPI_TxReg(0x3e, 0x1234);
|
168 |
|
169 | while ((PIND & (1<<CC_SFD)));
|
170 |
|
171 | _delay_ms(250);
|
172 |
|
173 | PORTB |= (1<<PB4)|(1<<PB5); //LED's an
|
174 | _delay_ms(250);
|
175 | }
|
176 | return 0;
|
177 | }
|