16FXlib
can5.c
1 //*****************************************************************************
2 // Author : Nicolas Weber
3 // Created : 14.05.2010
4 // Target MCU : Fujitsu MB96300 series
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 //
19 //*****************************************************************************
20 
21 #include "can3.h"
22 #include "can4.h"
23 #include "can5.h"
24 #include "../util.h"
25 #include "mb96348hs.h"
26 
27 #define CAN5_PING_MSG uint8_t data[4]; data[0] = 'P'; data[1] = 'I'; data[2] = 'N'; data[3] = 'G';
28 #define CAN5_PING_ANS uint8_t data[4]; data[0] = 'P'; data[1] = 'A'; data[2] = 'N'; data[3] = 'S';
29 
30 uint32_t pings[2]; //64 max addresses
31 
32 static uint8_t can5_internal_ping(uint8_t address);
33 static void can5_irqHandler(void);
34 
36  if(can4_init(CAN3_MAX_ADDRESS) && can4_open(CAN5_PORT) && can3_registerIRQHandler(&can5_irqHandler) && can5_getNewAddress()) {
37  return 1;
38  }
39 
40  return 0;
41 }
42 
43 static uint8_t can5_internal_ping(uint8_t address) {
44  uint8_t i;
45  CAN5_PING_MSG
46 
47  //Clear all ping results
48  for(i = 0; i < 2; i++)
49  pings[i] = 0;
50 
51  return can4_send(address,CAN5_PORT,data,4,0);
52 }
53 
55  uint16_t timeout = 0;
56 
57  if(address > 63) return 0;
58 
59  //ping
60  if(!can5_internal_ping(address)) return 0;
61 
62  //wait for answer
63  while(((address < 32 ? pings[0] & _BV(address) : pings[1] & _BV(address-32)) == 0) || (timeout++ < CAN5_ALIVE_TIMEOUT))
64  delay_us(1);
65 
66  //timeout
67  if(timeout >= CAN5_ALIVE_TIMEOUT) return 0;
68 
69  return 1;
70 }
71 
73  uint16_t timeout = 0;
74  uint8_t i;
75  uint8_t check;
76 
77  //ping
78  if(!can5_internal_ping(CAN3_MULTICAST)) return 0;
79 
80  //wait for answers
81  delay_us(CAN5_PING_TIMEOUT);
82 
83  //get free address
84  for(i = 0; i < 64; i++) {
85  if(i < 32) check = pings[0] & _BV(i);
86  else check = pings[1] & _BV(i-32);
87 
88  if(check == 0) {
89  can3_setAddress(i);
90  return 1;
91  }
92  }
93 
94  //all addresses used
95  return 0;
96 }
97 
98 static void can5_irqHandler(void) {
99  uint8_t recdata[4];
100  uint8_t src;
101  uint8_t len;
102 
103  len = can4_getData(CAN5_PORT,recdata,&src);
104 
105  if(len > 0) {
106  if(recdata[0] == 'P' && recdata[1] == 'I' && recdata[2] == 'N' && recdata[3] == 'G') {
107  CAN5_PING_ANS
108  can4_send(src,CAN5_PORT,data,4,0);
109  } else if(recdata[0] == 'P' && recdata[1] == 'A' && recdata[2] == 'N' && recdata[3] == 'S') {
110  if(src < 32) pings[0] |= _BV(src);
111  else pings[1] |= _BV(src-32);
112  }
113  }
114 }
115 
116 void can5_close(void) {
117  can3_removeIRQHandler(&can5_irqHandler);
118  can4_close(CAN5_PORT);
119 }
uint8_t can3_removeIRQHandler(IRQHandler func)
Definition: can3.c:286
unsigned long uint32_t
Definition: inttypes.h:60
#define CAN3_MAX_ADDRESS
Definition: can3.h:123
uint8_t can4_getData(uint8_t port, uint8_t *data, uint8_t *src)
Definition: can4.c:121
uint8_t can4_open(uint8_t port)
Definition: can4.c:78
void can5_close(void)
Definition: can5.c:116
unsigned int uint16_t
Definition: inttypes.h:50
#define _BV(bit)
Definition: util.h:39
void delay_us(uint16_t us)
Definition: util.c:34
unsigned char uint8_t
Definition: inttypes.h:35
uint8_t can4_send(uint8_t dest, uint8_t port, uint8_t *data, uint8_t len, uint8_t interrupt)
Definition: can4.c:96
uint8_t can3_registerIRQHandler(IRQHandler func)
Definition: can3.c:273
uint8_t can5_isAlive(uint8_t address)
Definition: can5.c:54
#define CAN3_MULTICAST
Definition: can3.h:133
uint8_t can5_getNewAddress(void)
Definition: can5.c:72
uint8_t can5_init(void)
Definition: can5.c:35
void can4_close(uint8_t port)
Definition: can4.c:270
uint8_t can4_init(uint8_t address)
Definition: can4.c:62
void can3_setAddress(uint8_t addr)
Definition: can3.c:252