po_hi_driver_rasta_serial.c 10.9 KB
Newer Older
1
2
3
4
5
/*
 * This is a part of PolyORB-HI-C distribution, a minimal
 * middleware written for generated code from AADL models.
 * You should use it with the Ocarina toolsuite.
 *
yoogx's avatar
yoogx committed
6
 * For more informations, please visit http://taste.tuxfamily.org/wiki
jhugues's avatar
jhugues committed
7
 *
yoogx's avatar
yoogx committed
8
 * Copyright (C) 2010-2014 ESA & ISAE.
9
10
11
12
13
14
15
16
17
18
 */

/*! \file po_hi_driver_rasta_serial.c
 *  \brief Driver that interface PolyORB-HI-C and the serial interface of RASTA boards using the RTEMS 4.8 driver.
 *
 *  This driver works ONLY with the RTEMS 4.8 version that was available on GAISLER website
 *  on April 2010. This version is available at:
 *    - http://download.tuxfamily.org/taste/tools/rtems-4.8-gaisler.tgz
 *  However, please note that it is no longer supported by GAISLER and contains
 *  other bugs (such as the serial driver for the LEON that does not work).
19
20
 */

21
22
#include <deployment.h>
/* Generated code header */
23

24
#ifdef __PO_HI_NEED_DRIVER_SERIAL_RASTA
25

26
#include <activity.h>
27
28
#include <marshallers.h>

29
#include <po_hi_debug.h>
30
31
32
#include <po_hi_transport.h>
#include <po_hi_gqueue.h>
#include <po_hi_messages.h>
33
#include <po_hi_returns.h>
34
#include <po_hi_utils.h>
35
#include <drivers/po_hi_rtems_utils.h>
36
#include <drivers/po_hi_driver_rasta_serial.h>
37
#include <drivers/po_hi_driver_rasta_common.h>
38

39
40
#include <drivers/po_hi_driver_serial_common.h>

41
42
43
44
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
julien.delange's avatar
julien.delange committed
45
#include <termios.h>
46
47
/* POSIX-style files */

48
49
50
51
52
#include <pci.h>
#include <rasta.h>
#include <apbuart_rasta.h>
/* Rasta includes from GAISLER drivers */

53
#include <drivers/configuration/serial.h>
54

55
56
57
int po_hi_c_driver_rasta_serial_fd_read[__PO_HI_NB_DEVICES];
int po_hi_c_driver_rasta_serial_fd_write[__PO_HI_NB_DEVICES];

58
59
__po_hi_request_t    __po_hi_c_driver_serial_rasta_request;
__po_hi_msg_t        __po_hi_c_driver_serial_rasta_poller_msg;
60

61
62
63
64
65
66
67
68
69
70
/*!
 * \fn void __po_hi_c_driver_serial_rasta_poller (const __po_hi_device_id dev_id)
 * \brief Polling function for the RASTA.
 *
 * This function is the poller for the serial interface of the RASTA board.
 * It is supposed to be called by the underlying AADL code at a given period/rate.
 * The argument dev_id is the device_id handled by the device driver. By using
 * such an argument, we can use this function on a single node that uses several
 * driver instances (several serial interfaces connected to different serial buses).
 */
71

72
void __po_hi_c_driver_serial_rasta_poller (const __po_hi_device_id dev_id)
73
{
74
75
76
   int                  n;
   int                  ts;
   uint8_t*             ptr;
77

julien.delange's avatar
julien.delange committed
78
   ts = __PO_HI_MESSAGES_MAX_SIZE;
79
80
   ptr = &(__po_hi_c_driver_serial_rasta_poller_msg.content[0]);
   __po_hi_msg_reallocate (&__po_hi_c_driver_serial_rasta_poller_msg);
julien.delange's avatar
julien.delange committed
81
   while (ts > 0)
82
   {
83
      __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Poller waits for incoming message (%d bytes are required)!\n", ts);
84
      n = read (po_hi_c_driver_rasta_serial_fd_read[dev_id], ptr, ts); 
julien.delange's avatar
julien.delange committed
85

86
      __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] read() %d returns %d!\n", po_hi_c_driver_rasta_serial_fd_read[dev_id], n);
julien.delange's avatar
julien.delange committed
87
88
      if (n == -1)
      {
89
         __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Cannot read on socket !\n");
julien.delange's avatar
julien.delange committed
90
91
         return;
      }
92
93
94
95
96
      else
      {
         ptr += n;
         ts -= n;
      }
97
98
   }

99
   __po_hi_c_driver_serial_rasta_poller_msg.length = __PO_HI_MESSAGES_MAX_SIZE;
100

101
102
   __po_hi_unmarshall_request (&__po_hi_c_driver_serial_rasta_request,
                               &__po_hi_c_driver_serial_rasta_poller_msg);
103

104
   if (__po_hi_c_driver_serial_rasta_request.port > __PO_HI_NB_PORTS)
jdelange's avatar
jdelange committed
105
   {
106
      __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Invalid port number (%d), will not deliver", __po_hi_c_driver_serial_rasta_request.port);
jdelange's avatar
jdelange committed
107
   }
108
   __po_hi_main_deliver (&__po_hi_c_driver_serial_rasta_request);
109
110
}

111
112
113
extern amba_confarea_type* __po_hi_driver_rasta_common_get_bus ();
void __po_hi_rasta_interrrupt_register(void *handler, int irqno, void *arg);

114
115
116
117
118
119
120
121
122
123
/*!
 * \fn void __po_hi_c_driver_serial_rasta_init (__po_hi_device_id id)
 * \brief Initialization function for the RASTA serial driver.
 *
 * This function  is used to initialize the device driver connected to the
 * serial interface to a RASTA board. It uses the configuration properties
 * from its associated configuration parameters (using the 
 * __po_hi_get_device_configuration function).
 */

124
void __po_hi_c_driver_serial_rasta_init (__po_hi_device_id id)
125
{
126
127
   uint32_t max_size;

128
129
   __po_hi_c_serial_conf_t* serialconf;

130
   __po_hi_c_driver_rasta_common_init ();
131

132
   serialconf = (__po_hi_c_serial_conf_t*)__po_hi_get_device_configuration (id);
133

134
   if (serialconf == NULL)
135
136
137
138
139
   {
      __PO_HI_DEBUG_INFO ("[RASTA SERIAL] Cannot get the name of the device !\n");
      return;
   }

jdelange's avatar
jdelange committed
140
141
   __po_hi_transport_set_sending_func (id, __po_hi_c_driver_serial_rasta_sender);

142
143
144
145
    /* provide the spacewire driver with AMBA Plug&Play
     * info so that it can find the GRSPW cores.
     */

146
   __PO_HI_DEBUG_INFO ("[RASTA SERIAL] Initialization starts !\n");
147

148
149
   po_hi_c_driver_rasta_serial_fd_write[id] = 
   po_hi_c_driver_rasta_serial_fd_read[id] = open (serialconf->devname, O_RDWR);
150
151
152
   /*
   po_hi_c_driver_rasta_serial_fd_write = open (serialconf->devname, O_WRONLY);
   */
153

154
   if (po_hi_c_driver_rasta_serial_fd_read[id] < 0)
155
   {
156
      __PO_HI_DEBUG_CRITICAL ("[RASTA SERIAL] Error while opening device %s for reading\n", serialconf->devname);
157
   }
158
   if (po_hi_c_driver_rasta_serial_fd_write[id] < 0)
159
160
161
162
   {
      __PO_HI_DEBUG_CRITICAL ("[RASTA SERIAL] Error while opening device %s for writing\n", serialconf->devname);
   }

163
164
   __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Device opened for read (%s), fd=%d\n", serialconf->devname , po_hi_c_driver_rasta_serial_fd_read[id]);
   __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Device opened for write (%s), fd=%d\n", serialconf->devname , po_hi_c_driver_rasta_serial_fd_write[id]);
165

166
167
168
   switch (__po_hi_c_driver_serial_common_get_speed (id))
   {
      case __PO_HI_DRIVER_SERIAL_COMMON_SPEED_19200:
169
170
         __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_SET_BAUDRATE, 19200);
         __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_write[id], APBUART_SET_BAUDRATE, 19200);
171
172
173
         break;

      case __PO_HI_DRIVER_SERIAL_COMMON_SPEED_38400:
174
175
         __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_SET_BAUDRATE, 38400);
         __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_write[id], APBUART_SET_BAUDRATE, 38400);
176
177
178
         break;

      case __PO_HI_DRIVER_SERIAL_COMMON_SPEED_57600:
179
180
         __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_SET_BAUDRATE, 57600);
         __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_write[id], APBUART_SET_BAUDRATE, 57600);
181
182
183
         break;

      case __PO_HI_DRIVER_SERIAL_COMMON_SPEED_115200:
184
185
         __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_SET_BAUDRATE, 115200);
         __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_write[id], APBUART_SET_BAUDRATE, 115200);
186
187
188
189
190
191
192
         break;

      case __PO_HI_DRIVER_SERIAL_COMMON_SPEED_UNKNWON:
         __PO_HI_DEBUG_INFO ("[RASTA SERIAL] Unknwon speed for the serial line\n");
         break;
   }

193
   /*
194
  __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd, APBUART_SET_BLOCKING, APBUART_BLK_RX | APBUART_BLK_TX | APBUART_BLK_FLUSH);
195
196
  __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd, APBUART_SET_BLOCKING, APBUART_BLK_FLUSH | APBUART_BLK_RX);
  */
197
198
199
200
201

   max_size = 1024;
#ifdef __PO_HI_MESSAGES_MAX_SIZE
   max_size = 4 * __PO_HI_MESSAGES_MAX_SIZE;
#endif
202
  __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_SET_BLOCKING, APBUART_BLK_FLUSH | APBUART_BLK_TX );
203
204
  __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_SET_TXFIFO_LEN, max_size);
  __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_SET_RXFIFO_LEN, max_size);
205
206
207
  __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_SET_ASCII_MODE, 0); /* Make \n go \n\r or \r\n */
  __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_CLR_STATS, 0);
  __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_START, 0);
julien.delange's avatar
julien.delange committed
208

209

210
  if (tcflush (po_hi_c_driver_rasta_serial_fd_read[id], TCIOFLUSH) != 0)
211
212
213
214
  {
     __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Error when trying to flush read part\n");
  }

215
  if (tcflush (po_hi_c_driver_rasta_serial_fd_write[id], TCIOFLUSH) != 0)
julien.delange's avatar
julien.delange committed
216
  {
217
     __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Error when trying to flush write part\n");
julien.delange's avatar
julien.delange committed
218
  }
219
220

  __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Initialization complete !\n");
221
222
}

223
224
225

__po_hi_msg_t           __po_hi_c_driver_serial_rasta_sender_msg;

226
227
228
229
230
231
232
233
234
235
236
237
238
239
/*!
 * \fn int __po_hi_c_driver_serial_rasta_sender (const __po_hi_task_id task_id, const __po_hi_port_t port)
 * \brief Function related to the RASTA serial driver - sender function.
 *
 * This function implements the sender function to send bytes through the serial line using
 * the RASTA device. 
 * There are the description of the arguments used by the function:
 *   - task_id: task that actually sends the data (emitter/producer task)
 *   - port   : (global) port that contains the data
 * It returns the following possible values :
 *   - __PO_HI_UNAVAILABLE : the driver does not handle the device connected to argument port.
 *   - __PO_HI_SUCCESS     : either no value was available to be sent or the function
 *                           send the message successfully over the network.
 */
240
241
int __po_hi_c_driver_serial_rasta_sender (const __po_hi_task_id task_id, const __po_hi_port_t port)
{
242
243
244
245
246
247
248
249
250
251
252
253
254
255
   int                     n;
   int                     ts;
   __po_hi_local_port_t    local_port;
   __po_hi_request_t*      request;
   __po_hi_port_t          destination_port;
   __po_hi_device_id       dev_id;

   dev_id = __po_hi_get_device_from_port (port);

   if (dev_id == invalid_device_id)
   {
      __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Invalid device id for sending\n");
      return __PO_HI_UNAVAILABLE;
   }
256
257
258
259
260

   local_port = __po_hi_get_local_port_from_global_port (port);

   request = __po_hi_gqueue_get_most_recent_value (task_id, local_port);

261
262
263
264
265
266
   if (request->port == -1)
   {
      __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Send output task %d, port %d (local_port=%d): no value to send\n", task_id, port, local_port);
      return __PO_HI_SUCCESS;
   }

267
268
   destination_port     = __po_hi_gqueue_get_destination (task_id, local_port, 0);

269
   __po_hi_msg_reallocate (&__po_hi_c_driver_serial_rasta_sender_msg);
270
271

   request->port = destination_port;
jdelange's avatar
jdelange committed
272
   __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Destination port= %d, send through device %d (fd=%d)\n", destination_port, dev_id, po_hi_c_driver_rasta_serial_fd_write[dev_id]);
273

274
   __po_hi_marshall_request (request, &__po_hi_c_driver_serial_rasta_sender_msg);
275

276
   n = write (po_hi_c_driver_rasta_serial_fd_write[dev_id], &__po_hi_c_driver_serial_rasta_sender_msg, __PO_HI_MESSAGES_MAX_SIZE);
277

278
   __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] write() returns %d\n", n);
279
280
281

   request->port = __PO_HI_GQUEUE_INVALID_PORT;

282
283
284
   return 1;
}

285
#endif