po_hi_driver_rasta_serial.c 10.8 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.
 *
6
7
8
9
10
11
12
13
14
15
16
 * Copyright (C) 2010-2011, European Space Agency
 */

/*! \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).
17
18
 */

19
20
#include <deployment.h>
/* Generated code header */
21

22
#ifdef __PO_HI_NEED_DRIVER_SERIAL_RASTA
23

24
#include <activity.h>
25
26
#include <marshallers.h>

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

37
38
#include <drivers/po_hi_driver_serial_common.h>

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

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

51
#include <drivers/configuration/serial.h>
52

53
54
55
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];

56
57
__po_hi_request_t    __po_hi_c_driver_serial_rasta_request;
__po_hi_msg_t        __po_hi_c_driver_serial_rasta_poller_msg;
58

59
60
61
62
63
64
65
66
67
68
/*!
 * \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).
 */
69

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

julien.delange's avatar
julien.delange committed
76
   ts = __PO_HI_MESSAGES_MAX_SIZE;
77
78
   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
79
   while (ts > 0)
80
   {
81
      __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Poller waits for incoming message (%d bytes are required)!\n", ts);
82
      n = read (po_hi_c_driver_rasta_serial_fd_read[dev_id], ptr, ts); 
julien.delange's avatar
julien.delange committed
83

84
      __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
85
86
      if (n == -1)
      {
87
         __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Cannot read on socket !\n");
julien.delange's avatar
julien.delange committed
88
89
         return;
      }
90
91
92
93
94
      else
      {
         ptr += n;
         ts -= n;
      }
95
96
   }

97
   __po_hi_c_driver_serial_rasta_poller_msg.length = __PO_HI_MESSAGES_MAX_SIZE;
98

99
100
   __po_hi_unmarshall_request (&__po_hi_c_driver_serial_rasta_request,
                               &__po_hi_c_driver_serial_rasta_poller_msg);
101

102
   if (__po_hi_c_driver_serial_rasta_request.port > __PO_HI_NB_PORTS)
jdelange's avatar
jdelange committed
103
   {
104
      __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
105
   }
106
   __po_hi_main_deliver (&__po_hi_c_driver_serial_rasta_request);
107
108
}

109
110
111
extern amba_confarea_type* __po_hi_driver_rasta_common_get_bus ();
void __po_hi_rasta_interrrupt_register(void *handler, int irqno, void *arg);

112
113
114
115
116
117
118
119
120
121
/*!
 * \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).
 */

122
void __po_hi_c_driver_serial_rasta_init (__po_hi_device_id id)
123
{
124
125
   uint32_t max_size;

126
127
   __po_hi_c_serial_conf_t* serialconf;

128
   __po_hi_c_driver_rasta_common_init ();
129

130
   serialconf = (__po_hi_c_serial_conf_t*)__po_hi_get_device_configuration (id);
131

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

138
139
140
141
    /* provide the spacewire driver with AMBA Plug&Play
     * info so that it can find the GRSPW cores.
     */

142
   __PO_HI_DEBUG_INFO ("[RASTA SERIAL] Initialization starts !\n");
143

144
145
   po_hi_c_driver_rasta_serial_fd_write[id] = 
   po_hi_c_driver_rasta_serial_fd_read[id] = open (serialconf->devname, O_RDWR);
146
147
148
   /*
   po_hi_c_driver_rasta_serial_fd_write = open (serialconf->devname, O_WRONLY);
   */
149

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

159
160
   __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]);
161

162
163
164
   switch (__po_hi_c_driver_serial_common_get_speed (id))
   {
      case __PO_HI_DRIVER_SERIAL_COMMON_SPEED_19200:
165
166
         __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);
167
168
169
         break;

      case __PO_HI_DRIVER_SERIAL_COMMON_SPEED_38400:
170
171
         __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);
172
173
174
         break;

      case __PO_HI_DRIVER_SERIAL_COMMON_SPEED_57600:
175
176
         __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);
177
178
179
         break;

      case __PO_HI_DRIVER_SERIAL_COMMON_SPEED_115200:
180
181
         __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);
182
183
184
185
186
187
188
         break;

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

189
   /*
190
  __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);
191
192
  __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd, APBUART_SET_BLOCKING, APBUART_BLK_FLUSH | APBUART_BLK_RX);
  */
193
194
195
196
197

   max_size = 1024;
#ifdef __PO_HI_MESSAGES_MAX_SIZE
   max_size = 4 * __PO_HI_MESSAGES_MAX_SIZE;
#endif
198
  __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_SET_BLOCKING, APBUART_BLK_FLUSH | APBUART_BLK_TX );
199
200
  __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);
201
202
203
  __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
204

205

206
  if (tcflush (po_hi_c_driver_rasta_serial_fd_read[id], TCIOFLUSH) != 0)
207
208
209
210
  {
     __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Error when trying to flush read part\n");
  }

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

  __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Initialization complete !\n");
217
218
}

219
220
221

__po_hi_msg_t           __po_hi_c_driver_serial_rasta_sender_msg;

222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*!
 * \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.
 */
236
237
int __po_hi_c_driver_serial_rasta_sender (const __po_hi_task_id task_id, const __po_hi_port_t port)
{
238
239
240
241
242
243
244
245
246
247
248
249
250
251
   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;
   }
252
253
254
255
256

   local_port = __po_hi_get_local_port_from_global_port (port);

   request = __po_hi_gqueue_get_most_recent_value (task_id, local_port);

257
258
259
260
261
262
   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;
   }

263
264
   destination_port     = __po_hi_gqueue_get_destination (task_id, local_port, 0);

265
   __po_hi_msg_reallocate (&__po_hi_c_driver_serial_rasta_sender_msg);
266
267

   request->port = destination_port;
jdelange's avatar
jdelange committed
268
   __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]);
269

270
   __po_hi_marshall_request (request, &__po_hi_c_driver_serial_rasta_sender_msg);
271

272
   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);
273

274
   __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] write() returns %d\n", n);
275
276
277

   request->port = __PO_HI_GQUEUE_INVALID_PORT;

278
279
280
   return 1;
}

281
282
#endif