1 | #include "can2515.h"
|
2 |
|
3 |
|
4 | void controller_reset()
|
5 | {
|
6 | set_cs(LOW);
|
7 | spi_putc(SPI_RESET);
|
8 | _delay_ms(1);
|
9 | set_cs(HIGH);
|
10 | _delay_ms(100);
|
11 | }
|
12 |
|
13 | void controller_normal_mode()
|
14 | {
|
15 | modify_register(CANCTRL, 0xE0, 0);
|
16 | }
|
17 |
|
18 | void init_bittiming()
|
19 | {
|
20 | write_register(CNF1, (1 << BRP0) | (1 << BRP1) | (1 << BRP2));
|
21 | // Prop Seg und Phase Seg1 einstellen
|
22 | write_register(CNF2, (1 << BTLMODE) | (1 << PHSEG11));
|
23 |
|
24 | // Wake-up Filter deaktivieren, Phase Seg2 einstellen
|
25 | write_register(CNF3, (1 << PHSEG21));
|
26 | }
|
27 |
|
28 | void init_transmitter()
|
29 | {
|
30 | // Aktivieren der Rx Buffer Interrupts
|
31 | write_register(CANINTE, (1 << RX1IE) | (1 << RX0IE));
|
32 |
|
33 | // Deaktivieren der Pins RXnBF Pins (High Impedance State)
|
34 | write_register(BFPCTRL, 0);
|
35 |
|
36 | // TXnRTS Bits als Inputs schalten
|
37 | write_register(TXRTSCTRL, 0);
|
38 |
|
39 | }
|
40 |
|
41 | void init_receiver()
|
42 | {
|
43 | // Aktivieren der Rx Buffer Interrupts
|
44 | write_register(CANINTE, (1 << RX1IE) | (1 << RX0IE));
|
45 |
|
46 | /*
|
47 | * Einstellen der Filter
|
48 | */
|
49 |
|
50 | // Buffer 0 : Empfangen aller Nachrichten
|
51 | write_register(RXB0CTRL, (1 << RXM1) | (1 << RXM0));
|
52 |
|
53 | // Buffer 1 : Empfangen aller Nachrichten
|
54 | write_register(RXB1CTRL, (1 << RXM1) | (1 << RXM0));
|
55 |
|
56 | // Alle Bits der Empfangsmaske loeschen,
|
57 | // damit werden alle Nachrichten empfangen
|
58 | write_register(RXM0SIDH, 0);
|
59 | write_register(RXM0SIDL, 0);
|
60 | write_register(RXM0EID8, 0);
|
61 | write_register(RXM0EID0, 0);
|
62 |
|
63 | write_register(RXM1SIDH, 0);
|
64 | write_register(RXM1SIDL, 0);
|
65 | write_register(RXM1EID8, 0);
|
66 | write_register(RXM1EID0, 0);
|
67 |
|
68 | /*
|
69 | * Einstellen der Pin Funktionen
|
70 | */
|
71 |
|
72 | // Deaktivieren der Pins RXnBF Pins (High Impedance State)
|
73 | write_register(BFPCTRL, 0);
|
74 |
|
75 | // TXnRTS Bits als Inputs schalten
|
76 | write_register(TXRTSCTRL, 0);
|
77 |
|
78 | }
|
79 |
|
80 |
|
81 |
|
82 | uint8_t read_rx_status(void)
|
83 | {
|
84 | uint8_t data;
|
85 |
|
86 | // /CS des MCP2515 auf Low ziehen
|
87 | set_cs(LOW);
|
88 |
|
89 | spi_putc(SPI_RX_STATUS);
|
90 | data = spi_putc(0xff);
|
91 |
|
92 | spi_putc(0xff);
|
93 |
|
94 | // /CS Leitung wieder freigeben
|
95 | set_cs(HIGH);
|
96 |
|
97 | return data;
|
98 | }
|
99 |
|
100 | char *byte_as_bits(int length, uint16_t val){
|
101 | char *tmp = malloc(sizeof(char)*length+1);
|
102 | for(int i=0;i<length;i++){
|
103 | if(val & (1<<i)){
|
104 | *(tmp+length-1-i) = '1';
|
105 | }else{
|
106 | *(tmp+length-1-i) = '0';
|
107 | }
|
108 | }
|
109 | *(tmp+length)='\0';
|
110 | return tmp;
|
111 | }
|
112 |
|
113 |
|
114 | uint8_t handle_interrupt(Message *message)
|
115 | {
|
116 | uint8_t status = read_rx_status();
|
117 |
|
118 | set_cs(LOW);
|
119 |
|
120 | if(status & (1<<3)){
|
121 | message->rtr = 1;
|
122 | }
|
123 | if (status & (1 << 6)) {
|
124 | spi_putc(SPI_READ_RX);
|
125 | get_message_from_buffer(0, message);
|
126 | set_cs(HIGH);
|
127 | return MESSAGE_IN_BUFFER_0;
|
128 | } else if (status & (1 << 7)) {
|
129 | spi_putc(SPI_READ_RX | 0x04);
|
130 | get_message_from_buffer(1, message);
|
131 | set_cs(HIGH);
|
132 | return MESSAGE_IN_BUFFER_1;
|
133 | }else{
|
134 | set_cs(HIGH);
|
135 | return NO_MESSAGE;
|
136 | }
|
137 |
|
138 | }
|
139 |
|
140 |
|
141 |
|
142 |
|
143 | void get_message_from_buffer(uint8_t buffer, Message * message)
|
144 | {
|
145 | uint8_t id0 = spi_putc(0xff);
|
146 | uint8_t id1 = spi_putc(0xff);
|
147 | uint16_t id01 = (uint16_t)id0 << 3;
|
148 | id01 |= (uint16_t)id1 >> 5;
|
149 | message->id = id01;
|
150 | spi_putc(0xff);
|
151 | spi_putc(0xff);
|
152 |
|
153 | message->length = spi_putc(0xff) & 0x0f;
|
154 | for (uint8_t i = 0; i < message->length; i++) {
|
155 | message->data[i] = spi_putc(0xff);
|
156 | }
|
157 | //set_cs(HIGH);
|
158 | set_bit(CANINTF, buffer, 0);
|
159 | }
|
160 |
|
161 |
|
162 | void write_message_to_can(uint16_t id, uint8_t length, char *data){
|
163 | // ID einstellen
|
164 | write_register(TXB0SIDH, (uint8_t) (id >> 3));
|
165 | write_register(TXB0SIDL, (uint8_t) (id << 5));
|
166 |
|
167 | write_register(TXB0DLC, length);
|
168 |
|
169 | for(int i=0;i<length;i++){
|
170 | write_register(TXB0D0+i, *(data+i));
|
171 | }
|
172 | //set_cs(LOW);
|
173 | spi_putc(SPI_RTS | 0x01);
|
174 | //set_cs(HIGH);
|
175 | set_bit(TXB0CTRL, TXREQ, 1);
|
176 |
|
177 | }
|