]> rtime.felk.cvut.cz Git - lincan.git/blob - embedded/app/usbcan/can.c
Merge branch 'master' into can-usb1
[lincan.git] / embedded / app / usbcan / can.c
1 /**
2 can.c
3
4 Routines for sending and receiving messages for configuration and/or
5 communication over CAN network using a SJA1000 transceiver.
6 For use in UL_USB1 module, it runs in Intel mode.
7 See documentation for details.
8
9 */
10
11
12 #include "can/can.h"
13
14 /// Baud rates
15 #if SJA1000_CLK==(24000000)
16         /*      Bus speed, Precaler, SJW, TSEG1, TSEG2
17          *      For SJW setting we assume 1% xtal accuracy
18          */
19         const long sja1000_freqs[3][5]=
20         {{1000, 0x00,   0xC0,   0x08,   0x10}
21         ,{250,  0x02,   0xC0,   0x0A,   0x30}
22         ,{100,  0x07,   0xC0,   0x09,   0x30}};
23         const int sja1000_freq_cnt=3;
24 #endif
25
26 struct can_baudparams_t canbaud;
27
28 void can_comm_init()
29 {
30         // Due to change in design there is CS_PIN connected with ALE_PIN and ALE_PIN connection to LPC is interrupted
31         // We don't use ALE_PIN
32         //IO0DIR|=P0_SJA1000_ALE_PIN|P0_SJA1000_CS_PIN|P0_SJA1000_RD_PIN|P0_SJA1000_WR_PIN;
33         IO0DIR|=P0_SJA1000_CS_PIN|P0_SJA1000_RD_PIN|P0_SJA1000_WR_PIN;
34         IO0DIR&=~(P0_SJA1000_INT_PIN);
35
36         SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
37         CLR_OUT_PIN(IO1,P1_SJA1000_RST_PIN);
38         SJA1000_INIT_DELAY();
39         SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
40         // Due to change in design there is CS_PIN connected with ALE_PIN and ALE_PIN connection to LPC is interrupted
41         //      CLR_OUT_PIN(IO0,P0_SJA1000_ALE_PIN);
42         SET_OUT_PIN(IO1,P1_SJA1000_RST_PIN);
43         SJA1000_INIT_DELAY();
44 }
45
46 int can_write(uint8_t address,uint8_t* data)
47 {
48         IO1DIR|=0x00FF0000; // Port as output to send data
49         IO1CLR=0x00FF0000; // Clear all data on port
50         // Init
51         SET_OUT_PIN(IO0,P0_SJA1000_RD_PIN);     // Stays high on write
52         SET_OUT_PIN(IO0,P0_SJA1000_WR_PIN); // Stays high on address write
53         SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN); // Sets output buffers to third state
54         SJA1000_DELAY();
55         //SET_OUT_PIN(IO0,P0_SJA1000_ALE_PIN); // Start command
56
57         // Set memory address
58         IO1SET=__val2mfld(0x00FF0000,address); // Shift data to SJA pins and output them
59         SJA1000_DELAY();
60         //CLR_OUT_PIN(IO0,P0_SJA1000_ALE_PIN); // Makes address active
61         CLR_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
62         SJA1000_DELAY();
63
64         // Setting data
65         CLR_OUT_PIN(IO0,P0_SJA1000_WR_PIN);
66
67         IO1CLR=0x00FF0000;
68         IO1SET=__val2mfld(0x00FF0000,*data);
69         SJA1000_DELAY();
70         SET_OUT_PIN(IO0,P0_SJA1000_WR_PIN); // Data should be accepted by now
71         SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
72         SJA1000_DELAY();
73         return 0;
74 }
75
76 int can_read(const uint8_t address,uint8_t* data)
77 {
78         IO1DIR|=0x00FF0000; // Port as output to set address
79         IO1CLR=0x00FF0000; // Clear all data
80         // Init
81         SET_OUT_PIN(IO0,P0_SJA1000_WR_PIN); // Stays high on read
82         SET_OUT_PIN(IO0,P0_SJA1000_RD_PIN); // Stays high while entering address
83         SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
84         SJA1000_DELAY();
85         //SET_OUT_PIN(IO0,P0_SJA1000_ALE_PIN);
86
87         // Request memory address
88         IO1SET=__val2mfld(0x00FF0000,address);
89         SJA1000_DELAY();
90         //CLR_OUT_PIN(IO0,P0_SJA1000_ALE_PIN);
91         CLR_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
92
93         // Get data
94
95         IO1DIR&=~0x00FF0000; // Sets port as input
96         CLR_OUT_PIN(IO0,P0_SJA1000_RD_PIN);
97         SJA1000_DELAY();
98         *data=__mfld2val(0x00FF0000,IO1PIN);
99         SET_OUT_PIN(IO0,P0_SJA1000_RD_PIN);
100         SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
101         SJA1000_DELAY();
102         return 0;
103 }
104
105 int can_init(){
106         uint8_t data=0,count=0;
107         do {
108                 can_comm_init();
109                 can_read(SJAMOD,&data);
110                 if (count++ > 50)
111                         return -1;
112         } while (!(data&sjaMOD_RM));
113
114         data=sjaCDR_CLKOUT_DIV1|sjaCDR_CLK_OFF|sjaCDR_CBP|sjaCDR_PELICAN;
115         can_write((uint8_t)SJACDR,(uint8_t*)&data);
116
117         // Single acceptance filter, reset mode
118         data=sjaMOD_AFM|sjaMOD_RM;
119         can_write((uint8_t)SJAMOD,(uint8_t*)&data);
120
121         // Enabling all interrupt sources
122         data=sjaENABLE_INTERRUPTS;
123         can_write((uint8_t)SJAIER,(uint8_t*)&data);
124
125         // Accept all messages
126         data=0xFF;
127         can_write((uint8_t)SJAAMR0,(uint8_t*)&data);
128         can_write((uint8_t)SJAAMR0+1,(uint8_t*)&data);
129         can_write((uint8_t)SJAAMR0+2,(uint8_t*)&data);
130         can_write((uint8_t)SJAAMR0+3,(uint8_t*)&data);
131
132         data=sjaCMR_CDO;
133         can_write((uint8_t)SJACMR,(uint8_t*)&data);
134
135         return 0;
136 }