]> 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 inline void can_data_pins_dir_output(void)
15 {
16         IO1DIR|=P1_SJA1000_DATA_PINS; // Port as output to send data
17 }
18
19 inline void can_data_pins_dir_input(void)
20 {
21         IO1DIR&=~P1_SJA1000_DATA_PINS; // Sets port as input
22 }
23
24 inline void can_data_pins_set_value(uint8_t data)
25 {
26         uint32_t val = __val2mfld(P1_SJA1000_DATA_PINS,data);
27         /*
28          * Clear only that pins, which need that, lower transition
29          * frequency and eliminate spikes
30          */
31         IO1CLR= val ^ P1_SJA1000_DATA_PINS;
32         IO1SET= val;
33 }
34
35 inline uint8_t can_data_pins_get_value(void)
36 {
37         return __mfld2val(P1_SJA1000_DATA_PINS,IO1PIN);
38 }
39
40
41 void can_comm_init()
42 {
43         //CANMSG("Start can_comm_init\n");
44         IO1DIR |= P1_OUT_PORT_CS_PIN|P1_SJA1000_RST_PIN;
45         // Due to change in design there is CS_PIN connected with ALE_PIN and ALE_PIN connection to LPC is interrupted
46         // We don't use ALE_PIN
47         //IO0DIR|=P0_SJA1000_ALE_PIN|P0_SJA1000_CS_PIN|P0_SJA1000_RD_PIN|P0_SJA1000_WR_PIN;
48         IO0DIR|=P0_SJA1000_CS_PIN|P0_SJA1000_RD_PIN|P0_SJA1000_WR_PIN;
49         IO0DIR&=~(P0_SJA1000_INT_PIN);
50
51         SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
52         CLR_OUT_PIN(IO1,P1_SJA1000_RST_PIN);
53         SJA1000_INIT_DELAY();
54         SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
55         // Due to change in design there is CS_PIN connected with ALE_PIN and ALE_PIN connection to LPC is interrupted
56         //      CLR_OUT_PIN(IO0,P0_SJA1000_ALE_PIN);
57         SET_OUT_PIN(IO1,P1_SJA1000_RST_PIN);
58         SJA1000_INIT_DELAY();
59 }
60
61 void can_write(uint8_t data, uint8_t address)
62 {
63         can_data_pins_dir_output();
64         // Set memory address
65         can_data_pins_set_value(address);
66         // Init
67         SET_OUT_PIN(IO0,P0_SJA1000_RD_PIN);     // Stays high on write
68         SET_OUT_PIN(IO0,P0_SJA1000_WR_PIN); // Stays high on address write
69         SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN); // Sets output buffers to third state
70         //SJA1000_DELAY();
71         //SET_OUT_PIN(IO0,P0_SJA1000_ALE_PIN); // Start command
72
73         //SJA1000_DELAY();
74         //CLR_OUT_PIN(IO0,P0_SJA1000_ALE_PIN); // Makes address active
75         CLR_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
76         //SJA1000_DELAY();
77
78         // Setting data
79         can_data_pins_set_value(data);
80
81         CLR_OUT_PIN(IO0,P0_SJA1000_WR_PIN);
82         CLR_OUT_PIN(IO0,P0_SJA1000_WR_PIN);
83         //SJA1000_DELAY();
84         SET_OUT_PIN(IO0,P0_SJA1000_WR_PIN); // Data should be accepted by now
85         SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
86         //SJA1000_DELAY();
87 }
88
89 uint8_t can_read(const uint8_t address)
90 {
91         uint8_t data;
92
93         can_data_pins_dir_output();
94         // Set memory address
95         can_data_pins_set_value(address);
96         // Init
97         SET_OUT_PIN(IO0,P0_SJA1000_WR_PIN); // Stays high on read
98         SET_OUT_PIN(IO0,P0_SJA1000_RD_PIN); // Stays high while entering address
99         SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
100         //SJA1000_DELAY();
101         //SET_OUT_PIN(IO0,P0_SJA1000_ALE_PIN);
102
103         //SJA1000_DELAY();
104         //CLR_OUT_PIN(IO0,P0_SJA1000_ALE_PIN);
105         CLR_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
106
107         // Get data
108
109         can_data_pins_dir_input();
110         CLR_OUT_PIN(IO0,P0_SJA1000_RD_PIN);
111         CLR_OUT_PIN(IO0,P0_SJA1000_RD_PIN);
112         //SJA1000_DELAY();
113         data = can_data_pins_get_value();
114         SET_OUT_PIN(IO0,P0_SJA1000_RD_PIN);
115         SET_OUT_PIN(IO0,P0_SJA1000_CS_PIN);
116         //SJA1000_DELAY();
117
118         return data;
119 }
120
121 int can_init(){
122         uint8_t data=0,count=0;
123         do {
124                 can_comm_init();
125                 data = can_read(SJAMOD);
126                 if (count++ > 50)
127                         return -1;
128         } while (!(data&sjaMOD_RM));
129
130         data=sjaCDR_CLKOUT_DIV1|sjaCDR_CLK_OFF|sjaCDR_CBP|sjaCDR_PELICAN;
131         can_write(data, SJACDR);
132
133         // Single acceptance filter, reset mode
134         data=sjaMOD_AFM|sjaMOD_RM;
135         can_write(data, SJAMOD);
136
137         // Enabling all interrupt sources
138         data=sjaENABLE_INTERRUPTS;
139         can_write(data, SJAIER);
140
141         // Accept all messages
142         data=0xFF;
143         can_write(data, SJAAMR0);
144         can_write(data, SJAAMR0+1);
145         can_write(data, SJAAMR0+2);
146         can_write(data, SJAAMR0+3);
147
148         data=sjaCMR_CDO;
149         can_write(data, SJACMR);
150
151         return 0;
152 }