24 #include "../interrupts.h"
25 #include "mb96348hs.h"
27 #define _AC(x) (((uint32_t)x) << 22)
28 #define _SC(x) (((uint32_t)x) << 16)
29 #define CAN3_RETURN_ERROR(x,y) if(x) return y
30 #define CAN3_RETURN_UBOUNDS(x,max,out) if(x > max) return out
31 #define CAN3_RETURN_SBOUNDS(x,min,max,out) if(x < min || x > max) return out
32 #define CAN3_EXTRACT_DESTINATION(id) (uint8_t)((id & 0x0FC00000) >> 22)
33 #define CAN3_EXTRACT_SOURCE(id) (uint8_t)((id & 0x003F0000) >> 16)
34 #define CAN3_EXTRACT_ID(id) (uint16_t)(id & 0x0000FFFF)
35 #define CAN3_EXTRACT_MULTICAST(id) (uint8_t)((id & 0x10000000) >> 28)
36 #define CAN3_FREE_BUFFER 255
38 __interrupt
void IRQHandler_CAN (
void);
48 struct DataBuffer databuffer[CAN3_DATABUFFER_SIZE];
50 IRQHandler irqHandler[CAN3_MAX_IRQHANDLER];
55 static void can3_internal_block(
uint8_t buffer) {
56 can3_usedbuffer |=
_BV(buffer - 1);
59 static uint8_t can3_internal_getFreeBuffer(
void) {
64 CAN3_RETURN_UBOUNDS(can3_usedbuffer,0xFFFD,0);
70 while(check < 0xFFFF) {
71 if(!(check & can3_usedbuffer)) {
84 static struct DataBuffer* can3_internal_getFreeDataBuffer(
void) {
87 for(i = 0; i < CAN3_DATABUFFER_SIZE; i++) {
88 if(databuffer[i].buffer == CAN3_FREE_BUFFER)
89 return &databuffer[i];
95 static void can3_irqHandler(
void) {
100 if(!(
_BV(buffer - 1) & can3_usedbuffer))
return;
101 if(!(data = can3_internal_getFreeDataBuffer()))
return;
107 #ifndef CAN3_SKIP_ADDRESS_CHECK
108 if(data->len == 0 || (CAN3_EXTRACT_MULTICAST(received_id) == 0 && CAN3_EXTRACT_DESTINATION(received_id) != can3_address)) {
114 data->buffer = buffer;
115 data->source = CAN3_EXTRACT_SOURCE(received_id);
116 data->id = CAN3_EXTRACT_ID(received_id);
124 CAN3_RETURN_ERROR(!
can_init(CAN3_BAUDRATE,1),0);
132 can3_address = address;
135 can3_usedbuffer = 0x0000;
138 for(i = 0; i < CAN3_DATABUFFER_SIZE; i++)
139 databuffer[i].buffer = CAN3_FREE_BUFFER;
142 for(i = 0; i < CAN3_MAX_IRQHANDLER; i++)
161 id = _AC(dest) | _SC(can3_address) | (
uint32_t)uid;
166 buffer = can3_internal_getFreeBuffer();
169 if(buffer == 0)
return 0;
183 while(((STATR0_TXOK == 0)|| (TREQR0 &
_BV(buffer -1) != 0))
184 && (timeout++ < CAN3_SEND_TIMEOUT))
187 if(timeout >= CAN3_SEND_TIMEOUT)
203 CAN3_RETURN_UBOUNDS(can3_usedbuffer,0xFFFD,0);
208 mask = 0x00000000 | idMask;
214 buffer = can3_internal_getFreeBuffer();
217 can3_internal_block(buffer);
228 if(!(
_BV(buffer - 1) & can3_usedbuffer))
return 0;
230 for(i = 0; i < CAN3_DATABUFFER_SIZE; i++) {
231 if(databuffer[i].buffer == buffer) {
232 for(n = 0; n < databuffer[i].len; n++) {
233 data[n] = databuffer[i].data[n];
236 *
id = databuffer[i].id;
237 *source = databuffer[i].source;
239 databuffer[i].buffer = CAN3_FREE_BUFFER;
241 return databuffer[i].len;
261 if(check & can3_usedbuffer) {
262 can3_usedbuffer ^= check;
266 for(i = 0; i < CAN3_DATABUFFER_SIZE; i++) {
267 if(databuffer[i].buffer == buffer)
268 databuffer[i].buffer = CAN3_FREE_BUFFER;
276 for(i = 0; i < CAN3_MAX_IRQHANDLER; i++) {
277 if(irqHandler[i] == 0) {
278 irqHandler[i] = func;
289 for(i = 0; i < CAN3_MAX_IRQHANDLER; i++) {
290 if(irqHandler[i] == func) {
300 void IRQHandler_CAN (
void) {
303 if (source == 0x8000) {
309 if ((source & 0x80) == 0x80) {
313 if ((source & 0x40) == 0x40) {
317 if ((source & 0x20) == 0x20) {
321 if ((source & 0x10) == 0x10) {
326 if ((source & 0x08) == 0x08) {
331 if ((source & 0x07) != 0x00) {
335 }
else if ((source - 1) < 32) {
338 for(i = 0; i < CAN3_MAX_IRQHANDLER; i++) {
339 if(irqHandler[i] != 0) {
uint8_t can3_removeIRQHandler(IRQHandler func)
uint8_t can3_maskedOpen(uint16_t uid, uint16_t idMask)
#define interrupts_enable()
uint8_t can_config_buffer(uint8_t buffer, uint32_t id, uint8_t options, uint8_t maskOptions, uint32_t idMask)
uint8_t can3_getAddress(void)
void interrupts_init(void)
#define CAN_BUF_OPT_TRANSMIT
uint8_t can3_getData(uint8_t buffer, uint8_t *data, uint8_t *source, uint16_t *id)
void delay_us(uint16_t us)
#define CAN_BUF_OPT_TX_INTERRUPT
uint8_t can3_registerIRQHandler(IRQHandler func)
uint8_t can3_init(uint8_t address)
uint8_t can3_open(uint16_t uid)
#define CAN_BUF_OPT_ENABLED
uint8_t can_set_buffer_data(uint8_t buffer, uint8_t *data, uint8_t len)
#define CAN_BUF_OPT_EXTENDED
#define interrupts_setLevel(maxLevel)
uint8_t can3_send(uint8_t dest, uint16_t uid, uint8_t *data, uint8_t len, uint8_t interrupt)
int8_t can_buffer_getData(uint8_t buffer, uint8_t *data, uint32_t *id)
void can3_close(uint8_t buffer)
#define CAN_BUF_MASK_EXTENDED
uint8_t can_init(uint8_t prescaler, uint8_t propSeg, uint8_t phSeg1, uint8_t phSeg2, uint8_t jumpWidth, uint8_t interrupts)
uint8_t can_buffer_newData(uint8_t buffer)
#define RETURN_ERROR(value, max)
#define CAN_BUF_OPT_RX_INTERRUPT
void interrupts_setHandler(uint8_t interruptNr, uint8_t interruptLevel, IRQHandler handler)
void can3_setAddress(uint8_t addr)
uint8_t can_send_buffer(uint8_t buffer)