]> rtime.felk.cvut.cz Git - lincan.git/blob - embedded/app/usbcan/can.c
skeleton of ul_usb1-can module (doesn't work yet)
[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         for (slowdown=0;slowdown<20*SJA1000_SCLK;slowdown++);
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         for (slowdown=0;slowdown<20*SJA1000_SCLK;slowdown++);
44
45 }
46
47 int can_write(uint8_t address,uint8_t* data)
48 {
49         IO1DIR|=0x00FF0000; // Port as output to send data
50         IO1CLR=0x00FF0000; // Clear all data on port
51         // Init
52         SET_OUT_PIN(IO0,P0_SJA1000_RD_PIN);     // Stays high on write
53         SET_OUT_PIN(IO0,P0_SJA1000_WR_PIN); // Stays high on address write
54         SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN); // Sets output buffers to third state
55         for (slowdown=0;slowdown<SJA1000_SCLK;slowdown++);
56         //SET_OUT_PIN(IO0,P0_SJA1000_ALE_PIN); // Start command
57
58         // Set memory address
59         IO1SET=__val2mfld(0x00FF0000,address); // Shift data to SJA pins and output them
60         for (slowdown=0;slowdown<SJA1000_SCLK;slowdown++);
61         //CLR_OUT_PIN(IO0,P0_SJA1000_ALE_PIN); // Makes address active
62         CLR_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
63         for (slowdown=0;slowdown<SJA1000_SCLK;slowdown++);
64
65         // Setting data
66         CLR_OUT_PIN(IO0,P0_SJA1000_WR_PIN);
67
68         IO1CLR=0x00FF0000;
69         IO1SET=__val2mfld(0x00FF0000,*data);
70         for (slowdown=0;slowdown<SJA1000_SCLK;slowdown++);
71         SET_OUT_PIN(IO0,P0_SJA1000_WR_PIN); // Data should be accepted by now
72         SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
73         for (slowdown=0;slowdown<SJA1000_SCLK;slowdown++);
74         return 0;
75 }
76
77 int can_read(const uint8_t address,uint8_t* data)
78 {
79         IO1DIR|=0x00FF0000; // Port as output to set address
80         IO1CLR=0x00FF0000; // Clear all data
81         // Init
82         SET_OUT_PIN(IO0,P0_SJA1000_WR_PIN); // Stays high on read
83         SET_OUT_PIN(IO0,P0_SJA1000_RD_PIN); // Stays high while entering address
84         SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
85         for (slowdown=0;slowdown<SJA1000_SCLK;slowdown++);
86         //SET_OUT_PIN(IO0,P0_SJA1000_ALE_PIN);
87
88         // Request memory address
89         IO1SET=__val2mfld(0x00FF0000,address);
90         for (slowdown=0;slowdown<SJA1000_SCLK;slowdown++);
91         //CLR_OUT_PIN(IO0,P0_SJA1000_ALE_PIN);
92         CLR_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
93
94         // Get data
95
96         IO1DIR&=~0x00FF0000; // Sets port as input
97         CLR_OUT_PIN(IO0,P0_SJA1000_RD_PIN);
98         for (slowdown=0;slowdown<SJA1000_SCLK;slowdown++);
99         *data=__mfld2val(0x00FF0000,IO1PIN);
100         SET_OUT_PIN(IO0,P0_SJA1000_RD_PIN);
101         SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
102         for (slowdown=0;slowdown<SJA1000_SCLK;slowdown++);
103         return 0;
104 }
105
106 int can_init(){
107         uint8_t data=0,count=0;
108         do {
109                 can_comm_init();
110                 can_read(SJAMOD,&data);
111                 if (count++ > 50)
112                         return -1;
113         } while (!(data&sjaMOD_RM));
114
115         data=sjaCDR_CLKOUT_DIV1|sjaCDR_CLK_OFF|sjaCDR_CBP|sjaCDR_PELICAN;
116         can_write((uint8_t)SJACDR,(uint8_t*)&data);
117
118         // Single acceptance filter, reset mode
119         data=sjaMOD_AFM|sjaMOD_RM;
120         can_write((uint8_t)SJAMOD,(uint8_t*)&data);
121
122         // Enabling all interrupt sources
123         data=sjaENABLE_INTERRUPTS;
124         can_write((uint8_t)SJAIER,(uint8_t*)&data);
125
126         // Accept all messages
127         data=0xFF;
128         can_write((uint8_t)SJAAMR0,(uint8_t*)&data);
129         can_write((uint8_t)SJAAMR0+1,(uint8_t*)&data);
130         can_write((uint8_t)SJAAMR0+2,(uint8_t*)&data);
131         can_write((uint8_t)SJAAMR0+3,(uint8_t*)&data);
132
133         data=sjaCMR_CDO;
134         can_write((uint8_t)SJACMR,(uint8_t*)&data);
135
136         return 0;
137 }
138
139 int can_autobaud(int tries){
140         uint8_t data=0;
141         int i=0,j,baudset=0;
142         // Single acceptance filter, reset mode, listen mode for baud determination
143         data=sjaMOD_LOM|sjaMOD_AFM|sjaMOD_RM;
144         can_write((uint8_t)SJAMOD,(uint8_t*)&data);
145         do {
146                 canbaud.baudrate=sja1000_freqs[i][0]*1000;
147                 canbaud.sjw=(sja1000_freqs[i][1]&0x3F)|(sja1000_freqs[i][2]&0xC0);
148                 canbaud.sample_pt=(sja1000_freqs[i][3]&0x0F)|(sja1000_freqs[i][4]&0x70);
149                 can_write(SJABTR0,(uint8_t *)(&canbaud.sjw));
150                 can_write(SJABTR1,(uint8_t *)(&canbaud.sample_pt));
151                 uint8_t intstor,temp;
152                 can_read(SJAIER,&intstor);
153                 temp=sjaIER_RIE|sjaIER_BEIE;
154                 can_write(SJAIER,&temp);
155
156                 /// Leave reset mode
157                 can_read(SJAMOD,&temp);
158                 temp&=~sjaMOD_RM;
159                 can_write(SJAMOD,&temp);
160                 j=0;
161                 do{
162                         can_read(SJAMOD,&temp);
163                         if (j++>20)
164                                 return -1;
165                 } while (temp&sjaMOD_RM);
166
167                 /// Wait for successfull packet receive or receive error
168                 j=0;
169                 while (!(IO0PIN & P0_SJA1000_INT_PIN)){
170                 }
171
172                 can_read(SJAIR,&temp);
173                 if (temp & sjaIR_RI)
174                         baudset=1;
175
176                 /// Back to reset
177                 can_read(SJAMOD,&temp);
178                 temp|=sjaMOD_RM;
179                 can_write(SJAMOD,&temp);
180                 j=0;
181                 do{
182                         can_read(SJAMOD,&temp);
183                         if (j++>20)
184                                 return -1;
185                 } while (!(temp&sjaMOD_RM));
186
187                 if (++i==sja1000_freq_cnt)
188                         return -1;
189         } while (baudset==0);
190         return 0;
191 }
192
193 int can_poll(){
194
195         return 0;
196 }
197
198 int can_transmit_direct(uint8_t *data){
199         int len=0,ext=0,i;
200         uint8_t *ptr=data,tmitptr,temp;
201         ext=(*ptr)& sjaFRM_FF;
202         len=(*ptr)& 0xFF;
203
204         // check if transmit buffer is free
205         do {
206                 if (can_poll()==-1)
207                         return -1;
208                 can_read(SJASR,&temp);
209                 temp&=sjaSR_TBS;
210         } while (!temp);
211
212         tmitptr=SJAFRM;
213         can_write(tmitptr++,data++); // Header
214         can_write(tmitptr++,data++); // Ident 1
215         can_write(tmitptr++,data++); // Ident 2
216         if (ext){
217                 can_write(tmitptr++,data++); // Ident 3
218                 can_write(tmitptr++,data++); // Ident 4
219         }
220         for (i=0;i<len;i++)
221                 can_write(tmitptr++,data++); // Data i;
222
223         // Set TR bit
224         temp=sjaCMR_TR;
225         can_write(SJACMR,&temp);
226
227         return 0;
228 }
229
230 int can_transmit(int ext_header,int rtr,uint8_t *mask,int numbytes,uint8_t *data){
231         uint8_t tmitptr,temp;
232         int i=0;
233
234         if (numbytes<0)
235                 numbytes=0;
236
237         if (mask==NULL)
238         ;       // use internal mask
239
240         // check if transmit buffer is free
241         do {
242                 if (can_poll()==-1)
243                         return -1;
244                 can_read(SJASR,&temp);
245                 temp&=sjaSR_TBS;
246         } while (!temp);
247
248         tmitptr=SJAFRM;
249         temp=(ext_header?sjaFRM_FF:0)|(rtr?sjaFRM_RTR:0)|(numbytes>8?0x08:numbytes);
250         can_write(tmitptr++,&temp); // Header
251
252         can_write(tmitptr++,mask++); // Ident 1
253         can_write(tmitptr++,mask++); // Ident 2
254         if (ext_header){
255                 can_write(tmitptr++,mask++); // Ident 3
256                 can_write(tmitptr++,mask++); // Ident 4
257         }
258         for (i=0;i<(numbytes>8?0x08:numbytes);i++)
259                 can_write(tmitptr++,data++); // Data i;
260
261         // Set TR bit
262         temp=sjaCMR_TR;
263         can_write(SJACMR,&temp);
264
265         return 0;
266 }
267
268 int can_receive(uint8_t len,uint8_t *data){
269
270
271         return 0;
272 }