Statistics
| Branch: | Tag: | Revision:

amiro-os / core / src / aos_rtcan.c @ 6d56ad8d

History | View | Annotate | Download (3.973 KB)

1
/*
2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
4

5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9

10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14

15
You should have received a copy of the GNU General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18

    
19
#include <hal.h>
20
#include <hal_can.h>
21
#include <hal_can_lld.h>
22
#include <aos_rtcan.h>
23
#include <aos_thread.h>
24
#include <chthreads.h>
25
#include <chtime.h>
26
#include <ch.h>
27
#include <stdbool.h>
28
#define True 1
29
#define False 0
30
#define HRTMSG 00
31
#define SRTMSG 01
32
#define NRTMSG 11
33

    
34
static THD_WORKING_AREA(myThreadWorkingArea, 128);
35

    
36
msgqueue_t hrtQueue;
37
msgqueue_t srtQueue;
38
msgqueue_t nrtQueue;
39

    
40
/*
41
 * @brief transmit Message over CAN
42
 */
43
msg_t rtcan_transmit(CANDriver *canp, canmbx_t mailbox, const CANTxFrame *ctfp){
44
    // call cantransmit, needed params driver, mailbox and tx frame
45

    
46
    msg_t transmit = canTransmitTimeout(canp,mailbox,ctfp,TIME_IMMEDIATE);
47
    return transmit;
48
}
49

    
50
/*
51
 * @brief receive Message over CAN
52
 */
53
msg_t rtcan_receive(CANDriver *canp, canmbx_t mailbox,CANRxFrame *crfp){
54
    // call lld cantransmit, needed params driver, mailbox and rx frame
55
    return canReceiveTimeout(canp,mailbox,crfp,TIME_IMMEDIATE);
56
}
57

    
58
bool pushRTCanMsgSorted(rtcan_msg_t *msg,msgqueue_t* msgqueue){
59

    
60
    rtcan_msg_t * prevElem = msgqueue->head;
61
    rtcan_msg_t * compareElem = prevElem->next;
62

    
63
    while(ST2MS(msg->deadline) >= ST2MS(compareElem->deadline)){
64
        if(compareElem->next != NULL){
65
            prevElem = compareElem;
66
            compareElem = compareElem->next;
67
        }else{
68
            prevElem->next = msg;
69
            msgqueue->tail = msg;
70
            return true;
71
        }
72
    }
73
    if(compareElem!= NULL){
74
      msg->next = compareElem;
75
    }
76
    return false;
77
}
78

    
79
/*
80
 * @brief push Message to its Queue, based on type of Message
81
 */
82
bool pushRTCanMsg(rtcan_msg_t *msg,msgqueue_t* msgqueue){
83
  if(msg != NULL){
84
    if(msgqueueEmpty(msgqueue)){
85
        queueInit(msg,msgqueue);
86
        return true;
87
    }
88
      msgqueue->tail->next = msg;
89
      msg->next = NULL;
90
      msgqueue->tail = msg;
91
      msgqueue->size++;
92
      return true;
93
    }
94
  return false;
95
}
96

    
97
/*
98
 * @brief dequeue Message from Queue
99
 */
100
rtcan_msg_t* popRTCanMsg(msgqueue_t* msgqueue){
101
    //todo special case head = tail
102
  if(!msgqueueEmpty(msgqueue)){
103
      rtcan_msg_t *elem = msgqueue->head;
104
      msgqueue->head = elem->next;
105
      return elem;
106
  }
107
  return NULL;
108
}
109

    
110
/*
111
 * @brief init Message Queue
112
 */
113
void queueInit(rtcan_msg_t *head,msgqueue_t* msgqueue){
114
  msgqueue->size = 0;
115
  msgqueue->head = head;
116
  msgqueue->tail = head;
117
  head->next = NULL;
118
  msgqueue->size++;
119
}
120

    
121
// Handling Message Queues
122

    
123
bool enqueueMsg(uint8_t *payload, uint8_t msgType, systime_t deadline){
124
  static rtcan_msg_t msg;
125
  msg.payload = payload;
126
  msg.msgType = msgType;
127
  msg.deadline = deadline;
128
  if(msgType == HRTMSG){
129
    return pushRTCanMsg(&msg,&hrtQueue);
130
  }else if(msgType == SRTMSG){
131
    return pushRTCanMsgSorted(&msg,&srtQueue);
132
  }else if(msgType == NRTMSG){
133
    return pushRTCanMsg(&msg,&nrtQueue);
134
  }
135
  return false;
136
}
137

    
138

    
139
/**
140
 * @brief schedule rtcan messages into mailboxes
141
 */
142

    
143
static msg_t Thread(void *arg){
144
  (void)arg;
145
  chRegSetThreadName("RTCAN Timer");
146

    
147
  while (true){
148
    chThdSleepMilliseconds( 20 );
149
    // Take next element from queue
150
    // place it in buffer to be sent in next time slot
151
    chThdSleepMilliseconds( 20 );
152
  }
153

    
154
  return 0;
155
}
156
/** empty or clear?*/
157
int msgqueueEmpty(msgqueue_t* mqueue){
158
    if(mqueue == NULL){
159
        return true;
160
    }
161
    return false;
162
}
163
//TODO: ISR
164
//TODO: Params