can2515.c


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
}