KM3NeT CLB  2.0
KM3NeT CLB v2 Embedded Software
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
msg_dbg.c
1 /*
2  * KM3NeT CLB v2 Firmware
3  *
4  * Copyright 2013 KM3NeT Collaboration
5  *
6  * All Rights Reserved.
7  *
8  * msg_dbg.c
9  *
10  * Created on: 10 jul. 2013
11  * Author: Vincent van Beveren
12  */
13 
14 
15 #define MAX_SIZE 512
16 #define MAX_READS 96
17 
18 #include "errorcode.h"
19 
20 #include <stdio.h>
21 
22 #include "lm32soc/dev_soc.h"
23 #include "drv/wb/i2c.h"
24 #include "drv/wb/suart.h"
25 #include "drv/spi/sflash.h"
26 #include "net/msg.h"
27 #include "net/network.h"
28 
29 
30 uint8_t replyBuf[512];
31 
32 /**
33  * Reads an address.
34  */
35 bool _msgBusRead(MsgId * msgId, DataBuffer * cmd)
36 {
37  uint32_t * addr;
38  uint16_t count;
39  int i;
40  // parse command arguments
41  dbReadU32(cmd, (uint32_t *)&addr); // read first argument, the offset address
42  dbReadU16(cmd, &count); // read second argument the count
43 
44  if (!msgRxBufCheck(cmd)) return false; // check if buffer still valid
45 
46  if (count > MAX_READS) { // can't read that many addresses
47  msgTxError(msgId, ERROR(E_INVARGUMENT)); // return an error
48  return true; // true only means 'I've handled the message'
49  }
50 
51  // printf("Requesting %d words to read from address %08x\n", count, addr);
52 
53  // create reply arguments
54  DataBuffer reply = DB_BUF_INIT(replyBuf, MAX_SIZE); // initialize reply buffer
55  dbWriteU16(&reply, count); // return no of elements in return array
56  for (i = 0; i < count; ++i, ++addr) // for each address
57  dbWriteU32(&reply, *addr); // load the data into the reply buffer
58 
59  msgTxReply(msgId, &reply); // send the reply to the message processing
60  return true;
61 }
62 
63 /**
64  * Writes one or more addresses.
65  */
66 bool _msgBusWrite(MsgId * msgId, DataBuffer * cmd)
67 {
68  // parse command arguments
69  uint16_t count;
70  uint32_t * addr;
71  int i;
72 
73  dbReadU32(cmd, (uint32_t *)&addr); // read first argument, the offset address
74  dbReadU16(cmd, &count);
75 
76 
77  if (count > MAX_READS) { // can't read that many addresses
78  msgTxError(msgId, ERROR(E_INVARGUMENT)); // return an error
79  return true; // true only means 'I've handled the message'
80  }
81 
82  for (i = 0; i < count; ++i, ++addr) // for each address
83  dbReadU32(cmd, addr); // write the data into the memory.
84 
85  if (!msgRxBufCheck(cmd)) return false; // check if buffer still valid
86 
87  msgTxReply(msgId, NULL);
88 
89  return true;
90 }
91 
92 /**
93  * Read, Modifies and Writes one or more addresses.
94  */
95 bool _msgBusRmw(MsgId * msgId, DataBuffer * cmd)
96 {
97  // parse command arguments
98  uint16_t count;
99  uint32_t * addr;
100  uint32_t value;
101  uint32_t mask;
102  int i;
103 
104  dbReadU32(cmd, (uint32_t *)&addr); // read first argument, the offset address
105  dbReadU16(cmd, &count);
106 
107 
108  if (count > MAX_READS) { // can't read that many addresses
109  msgTxError(msgId, ERROR(E_INVARGUMENT)); // return an error
110  return true; // true only means 'I've handled the message'
111  }
112 
113  DataBuffer reply = DB_BUF_INIT(replyBuf, MAX_SIZE); // initialize reply buffer
114 
115  dbWriteU16(&reply, count);
116  for (i = 0; i < count; ++i, ++addr) // for each address
117  {
118  dbReadU32(cmd, &value); // write the data into the memory.
119  dbReadU32(cmd, &mask);
120  *addr = ( *addr & ~mask ) | ( value & mask);
121  dbWriteU32(&reply, *addr);
122  }
123 
124  if (!msgRxBufCheck(cmd)) return false; // check if buffer still valid
125 
126  msgTxReply(msgId, &reply);
127 
128  return true;
129 }
130 
131 #define MAX_I2C_DATE_LEN 32
132 
133 static I2C_Device * _i2cDevs[] = { I2C1, I2C2, I2C3 };
134 
135 bool _msgI2CRead(MsgId * msgId, DataBuffer * buf)
136 {
137  int i;
138  uint8_t iface;
139  uint8_t addr;
140  int16_t reg;
141  uint16_t len;
142  uint8_t i2cBuf[MAX_I2C_DATE_LEN];
143 
144  dbReadU8(buf, &iface);
145 
146  if (iface > 2) return false;
147 
148  dbReadU8(buf, &addr);
149  dbReadI16(buf, &reg); // not yet implemented
150  dbReadU16(buf, &len);
151 
152  if (!msgRxBufCheck(buf)) return false; // check if buffer still valid
153 
154  if (len > MAX_I2C_DATE_LEN) return false;
155 
156  if (!i2cRead(_i2cDevs[iface], addr, i2cBuf, len))
157  {
158  msgTxError(msgId, errGet(), errGetDescr(), errGetName());
159  errClear();
160  return true;
161  }
162 
163 
164  DataBuffer reply = DB_BUF_INIT(replyBuf, MAX_SIZE); // initialize reply buffer
165 
166  dbWriteU16(&reply, len);
167  for (i = 0; i < len; ++i)
168  dbWriteU8(&reply, i2cBuf[i]);
169 
170  msgTxReply(msgId, &reply);
171 
172  return true;
173 }
174 
175 
176 bool _msgI2CWrite(MsgId * msgId, DataBuffer * buf)
177 {
178  if (dbLength(buf) < 6 ) return false;
179 
180  int i;
181  uint8_t iface;
182  uint8_t addr;
183  int16_t reg;
184  uint16_t len;
185  uint8_t i2cBuf[MAX_I2C_DATE_LEN];
186 
187  dbReadU8(buf, &iface);
188 
189  if (iface > 2) return false;
190 
191  dbReadU8(buf, &addr);
192  dbReadI16(buf, &reg); // not yet implemented.
193  dbReadU16(buf, &len);
194 
195  if (len > MAX_I2C_DATE_LEN) return false;
196 
197  for (i = 0; i < len; ++i)
198  dbReadU8(buf, &(i2cBuf[i]));
199 
200  if (!msgRxBufCheck(buf)) return false; // check if buffer still valid
201 
202  if (!i2cWrite(_i2cDevs[iface], addr, i2cBuf, len))
203  {
204  msgTxError(msgId, errGet(), errGetDescr(), errGetName());
205  errClear();
206  return true;
207  }
208 
209 
210  msgTxReply(msgId, NULL);
211 
212  return true;
213 }
214 
215 
216 static SUART_Descriptor * getUart(int no)
217 {
218  switch (no)
219  {
220  case 1:
221  return UART_DESCR_PTR(UART_ID1);
222 #ifdef BASE
223  case 2:
224  return UART_DESCR_PTR(UART_ID2);
225  case 3:
226  return UART_DESCR_PTR(UART_ID3);
227  case 4:
228  return UART_DESCR_PTR(UART_ID4);
229 #endif
230  default:
231  return NULL;
232  }
233 
234 }
235 
236 #define UART_BUFFER_SIZE 80
237 
238 
239 #define FLASH_READ_SIZE 256
240 #define FLASH_READ_MASK (FLASH_READ_SIZE - 1)
241 
242 bool _msgFlashRead(MsgId * msgId, DataBuffer * cmd)
243 {
244  uint8_t chipNo;
245  uint32_t addr;
246  dbReadU8(cmd, &chipNo);
247  dbReadU32(cmd, &addr);
248  if (!msgRxBufCheck(cmd)) return false;
249  if ((addr & FLASH_READ_MASK) != 0)
250  return msgTxError(msgId, E_INVARGUMENT, E_INVARGUMENT_DESCR, "msgDbg");
251 
252  DataBuffer reply = DB_BUF_INIT(replyBuf, sizeof(replyBuf));
253  sfRead(addr, reply.cur, FLASH_READ_SIZE);
254  reply.cur+=FLASH_READ_SIZE;
255  return msgTxReply(msgId, &reply);
256 }
257 
258 
259 bool _msgUartTx(MsgId * msgId, DataBuffer * buf)
260 {
261  uint8_t uartNo;
262  char tmp[UART_BUFFER_SIZE];
263  char * ptr = tmp;
264  dbReadU8(buf, &uartNo);
265 
266  SUART_Descriptor * u = getUart(uartNo); // XXX todo, get device
267 
268  if (u == NULL) return false;
269 
270  dbReadString(buf, tmp, sizeof(tmp));
271  if (!msgRxBufCheck(buf)) return false;
272  // XXX add timeout
273  while (*ptr != '\0') {
274  while (!suartTxReady(u)) {};
275  suartTx(u, *ptr);
276  ptr++;
277  }
278  return msgTxReplyAck(msgId);
279 }
280 
281 bool _msgUartRx(MsgId * msgId, DataBuffer * buf)
282 {
283  uint8_t uartNo;
284  dbReadU8(buf, &uartNo);
285  if (!msgRxBufCheck(buf)) return false;
286 
287  uint8_t uartBuf[UART_BUFFER_SIZE + 2];
288  char tmp[UART_BUFFER_SIZE];
289  int len = 0;
290  SUART_Descriptor * u = getUart(uartNo);
291 
292  if (u == NULL) return false;
293 
294  DataBuffer reply = DB_BUF_INIT(uartBuf, UART_BUFFER_SIZE + 2);
295 
296  while (suartRxReady(u) && len < (UART_BUFFER_SIZE - 1))
297  {
298  suartRx(u, &tmp[len]);
299  len++;
300  }
301 
302  dbWriteString(&reply, tmp, UART_BUFFER_SIZE);
303 
304  return msgTxReply(msgId, &reply);
305 }
306 
307 bool _msgRxPktLogRead(MsgId * msgId, DataBuffer * buf)
308 {
309  uint16_t pos;
310  dbReadU16(buf, &pos);
311  if (!msgRxBufCheck(buf)) return false;
312 
313  PacketLog_t * pktLog = getPacketLog(pos);
314 
315  uint8_t rbuf[12];
316  DataBuffer reply = DB_BUF_INIT(rbuf, 12);
317 
318  if (pktLog != NULL)
319  {
320  dbWriteU32(&reply, pktLog->ticks);
321  dbWriteU16(&reply, pktLog->length);
322  dbWriteU16(&reply, pktLog->eth_type);
323  dbWriteU16(&reply, pktLog->proc_time);
324  dbWriteU8(&reply, pktLog->d_mac5);
325  dbWriteU8(&reply, pktLog->d_mac6);
326  }
327 
328  return msgTxReply(msgId, &reply);
329 }
330 
331 bool _msgPktLogReset(MsgId * msgId, DataBuffer * buf)
332 {
333  resetPacketLog();
334  return msgTxReplyAck(msgId);
335 }
bool i2cWrite(I2C_Device *dev, i2cAddr addr, uint8_t *bytes, int len)
Writes to the I2C device.
Definition: i2c.c:219
bool _msgBusRead(MsgId *id, DataBuffer *buf)
Reads an address.
Definition: msg_dbg.c:35
bool dbReadU8(DataBuffer *buf, uint8_t *byte)
Reads an unsigned byte.
Definition: databuffer.c:153
bool dbReadString(DataBuffer *buf, char *s, int size)
Reads a string from the stream.
Definition: databuffer.c:103
bool dbReadU16(DataBuffer *buf, uint16_t *u)
Reads a unsigned short (16 bits unsigned) integer.
Definition: databuffer.c:186
Structure defines OpenCores I2C Device.
Definition: dev_i2c.h:55
static bool suartTxReady(SUART_Descriptor *desc)
Returns whether or not the TX buffer is empty.
Definition: suart.h:80
White Rabbit Simple UART Driver.
PacketLog_t * getPacketLog(uint32_t pos)
Get packet log at position pos.
Definition: network.c:71
const char * errGetDescr()
Returns the last error description, if any, else null.
Definition: err.c:57
bool _msgBusWrite(MsgId *id, DataBuffer *buf)
Writes one or more addresses.
Definition: msg_dbg.c:66
#define I2C3
Virtual OpenCores I2C.
Definition: dev_soc.h:66
#define I2C2
Virtual OpenCores I2C.
Definition: dev_soc.h:65
Defines a DataBuffer structure.
Definition: databuffer.h:45
#define E_INVARGUMENT
Generic error: invalid argument.
Definition: errorcode.h:112
static uint32_t dbLength(DataBuffer *buf)
Returns the lenght of the current buffer.
Definition: databuffer.h:83
Handles MCF packed messages from the higher protocol layer.
bool msgTxReply(MsgId *id, DataBuffer *buf)
Invoke to send a reply.
Definition: msg.c:286
bool msgTxError(MsgId *id, int errCode, const char *errMsg, const char *name)
Invoke to send an error response.
Definition: msg.c:293
void resetPacketLog()
Reset the packet log.
Definition: network.c:77
void errClear()
Clears the current error.
Definition: err.c:46
bool msgRxBufCheck(DataBuffer *buf)
Checks the received buffer, and logs an error if there is something wrong.
Definition: msg.c:141
uint32_t errGet()
Returns the last error code, or null.
Definition: err.c:74
This module is responsible for distributing error codes.
bool suartRx(SUART_Descriptor *desc, char *c)
Receives a character.
Definition: suart.c:73
bool dbWriteU8(DataBuffer *buf, uint8_t byte)
Writes a unsigned byte.
Definition: databuffer.c:146
Packet log.
Definition: network.h:35
bool i2cRead(I2C_Device *dev, i2cAddr addr, uint8_t *bytes, int len)
Reads from the I2C device.
Definition: i2c.c:161
#define I2C1
Virtual OpenCores I2C.
Definition: dev_soc.h:64
bool dbReadU32(DataBuffer *buf, uint32_t *u)
Reads an 32 bits unsigned integer.
Definition: databuffer.c:219
bool sfRead(uint32_t address, uint8_t *data, uint32_t count)
Read from a specific address in flash.
Definition: sflash.c:491
If defined, events will not require an acknowledge.
Definition: msg.h:274
bool dbWriteString(DataBuffer *buf, const char *s, int max)
Writes a String as &#39;sort of&#39; UTF-8 encoding, as defined in the Java DataOuput and DataInput writeUTF ...
Definition: databuffer.c:74
static bool suartRxReady(SUART_Descriptor *desc)
Returns whether or not the RX buffer has data.
Definition: suart.h:104
This file assigns all device structures to memory mapped structures.
const char * errGetName()
Returns the last error cause name, or null.
Definition: err.c:65
#define ERROR(CODE,...)
Expands an error code to an error code with a description (if ERROR_W_DESCR is declared).
This driver implements access to the Serial Flash.
bool dbReadI16(DataBuffer *buf, int16_t *i)
Reads a short (16 bits signed) integer.
Definition: databuffer.c:194
bool suartTx(SUART_Descriptor *desc, char c)
Transmits a character.
Definition: suart.c:58
#define DB_BUF_INIT(PTR, LEN)
Simple buffer initialization.
Definition: databuffer.h:63
uint8_t * cur
Current Pointer.
Definition: databuffer.h:49
static bool msgTxReplyAck(MsgId *id)
Replies a simple ACK with no content.
Definition: msg.h:323
bool dbWriteU32(DataBuffer *buf, uint32_t u)
Writes an 32 bits unsigned integer.
Definition: databuffer.c:200
bool dbWriteU16(DataBuffer *buf, uint16_t u)
Writes a unsigned short (16 bits unsigned) integer.
Definition: databuffer.c:162
OpenCores I2C device driver.