summaryrefslogtreecommitdiff
path: root/digital/avr
diff options
context:
space:
mode:
authorNicolas Schodet2011-04-19 21:18:55 +0200
committerNicolas Schodet2011-04-19 21:18:55 +0200
commite2594ccdadae65d7e7473e51fb8bfbbd49c04a24 (patch)
tree1a0b4fc774a4c880798cbfb14fa29d98004a73c4 /digital/avr
parentf045fd73ec8441a889fe7fb6c6ee64d72e5045c4 (diff)
parent4a7f10430b7eaa3ac4a133c701d2b50a3db4e401 (diff)
Merge branch 'master' into efrei-robotique
Diffstat (limited to 'digital/avr')
-rw-r--r--digital/avr/modules/host/host.h5
-rw-r--r--digital/avr/modules/host/host.host.c50
-rw-r--r--digital/avr/modules/host/mex.h14
-rw-r--r--digital/avr/modules/host/mex.host.c44
-rw-r--r--digital/avr/modules/host/test/test_host.c6
-rw-r--r--digital/avr/modules/host/test/test_mex.c33
-rw-r--r--digital/avr/modules/twi/twi.host.c30
7 files changed, 160 insertions, 22 deletions
diff --git a/digital/avr/modules/host/host.h b/digital/avr/modules/host/host.h
index 73cd4a58..03a8f7b8 100644
--- a/digital/avr/modules/host/host.h
+++ b/digital/avr/modules/host/host.h
@@ -39,6 +39,11 @@ host_init (int argc, char **argv);
void
host_get_program_arguments (int *argc, char ***argv);
+/** Retrieve instance given on command line, or use default. Strip tail
+ * components if requested. Buffer is valid until next call. */
+const char *
+host_get_instance (const char *def, int strip);
+
/** Host variables are usefull on reset. They are passed in the environment.
* This is not optimised for performance. */
diff --git a/digital/avr/modules/host/host.host.c b/digital/avr/modules/host/host.host.c
index 7967e9cd..9d039f75 100644
--- a/digital/avr/modules/host/host.host.c
+++ b/digital/avr/modules/host/host.host.c
@@ -30,18 +30,38 @@
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
/* Saved arguments. Uninitialised global variables are set to 0 by the
* compiler. */
static int host_saved_argc;
static char **host_saved_argv;
+/* User arguments not used by this module. */
+static int host_user_argc;
+static char **host_user_argv;
+
+/* Instance string, from program arguments. */
+static char *host_instance;
+
/** Initialise host module. */
void
host_init (int argc, char **argv)
{
host_saved_argc = argc;
host_saved_argv = argv;
+ /* Get instance argument. */
+ argv++;
+ argc--;
+ if (argc && strncmp (argv[0], "-i", 2) == 0)
+ {
+ host_instance = argv[0] + 2;
+ argv++;
+ argc--;
+ }
+ /* Save other arguments. */
+ host_user_argc = argc;
+ host_user_argv = argv;
}
/** Retrieve saved program arguments. Program name and used parameters are
@@ -50,8 +70,34 @@ void
host_get_program_arguments (int *argc, char ***argv)
{
assert (host_saved_argc);
- *argc = host_saved_argc - 1;
- *argv = host_saved_argv + 1;
+ *argc = host_user_argc;
+ *argv = host_user_argv;
+}
+
+/** Retrieve instance given on command line, or use default. Strip tail
+ * components if requested. Buffer is valid until next call. */
+const char *
+host_get_instance (const char *def, int strip)
+{
+ if (!host_instance)
+ return def;
+ else if (strip == 0)
+ return host_instance;
+ else
+ {
+ static char stripped[256];
+ assert (strlen (host_instance) < sizeof (stripped));
+ strcpy (stripped, host_instance);
+ while (strip--)
+ {
+ char *p = strrchr (stripped, ':');
+ if (!p)
+ return "";
+ else
+ *p = '\0';
+ }
+ return stripped;
+ }
}
/** Register a host integer. */
diff --git a/digital/avr/modules/host/mex.h b/digital/avr/modules/host/mex.h
index feb91188..78e1368d 100644
--- a/digital/avr/modules/host/mex.h
+++ b/digital/avr/modules/host/mex.h
@@ -35,6 +35,7 @@ enum mex_mtype_t
MEX_MTYPE_DATE = 1,
MEX_MTYPE_REQ = 2,
MEX_MTYPE_RSP = 3,
+ MEX_MTYPE_RES = 4,
};
/** Message structure opaque definition. */
@@ -89,6 +90,10 @@ mex_msg_mtype (mex_msg_t *msg);
void
mex_node_connect (void);
+/** Query connection status, returns 0 if not connected. */
+int
+mex_node_connected (void);
+
/** Close connection. */
void
mex_node_close (void);
@@ -121,4 +126,13 @@ mex_node_response (mex_msg_t *msg);
void
mex_node_register (u8 mtype, mex_handler_t *handler, void *user);
+/** Request a message type reservation. */
+u8
+mex_node_reserve (const char *mtype_str);
+
+/** Request a message type reservation, using formated string. */
+u8
+mex_node_reservef (const char *mtype_fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+
#endif /* mex_h */
diff --git a/digital/avr/modules/host/mex.host.c b/digital/avr/modules/host/mex.host.c
index d82a4947..349ee3b6 100644
--- a/digital/avr/modules/host/mex.host.c
+++ b/digital/avr/modules/host/mex.host.c
@@ -30,6 +30,7 @@
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
+#include <stdio.h>
#include <unistd.h>
#include <errno.h>
@@ -394,6 +395,13 @@ mex_node_connect (void)
}
}
+/** Query connection status, returns 0 if not connected. */
+int
+mex_node_connected (void)
+{
+ return mex_node_global.socket != -1;
+}
+
/** Close connection. */
void
mex_node_close (void)
@@ -501,6 +509,42 @@ mex_node_register (u8 mtype, mex_handler_t *handler, void *user)
mex_node_global.handlers_user[mtype] = user;
}
+/** Request a message type reservation. */
+u8
+mex_node_reserve (const char *mtype_str)
+{
+ /* Send request. */
+ mex_msg_t *m = mex_msg_new (MEX_MTYPE_RES);
+ mex_msg_push_buffer (m, mtype_str, strlen (mtype_str));
+ mex_node_send (m);
+ /* Wait for response. */
+ mex_msg_t *rsp;
+ rsp = mex_node_recv ();
+ while (rsp->mtype != MEX_MTYPE_RES)
+ {
+ mex_node_dispatch (rsp);
+ mex_msg_delete (rsp);
+ rsp = mex_node_recv ();
+ }
+ /* Return allocated message type. */
+ u8 mtype;
+ mex_msg_pop (rsp, "B", &mtype);
+ return mtype;
+}
+
+/** Request a message type reservation, using formated string. */
+u8
+mex_node_reservef (const char *mtype_fmt, ...)
+{
+ va_list ap;
+ char mtype_str[MEX_MSG_NEW_PAYLOAD_SIZE + 1];
+ va_start (ap, mtype_fmt);
+ int r = vsnprintf (mtype_str, sizeof (mtype_str), mtype_fmt, ap);
+ assert (r < (int) sizeof (mtype_str));
+ va_end (ap);
+ return mex_node_reserve (mtype_str);
+}
+
/** Receive one message. */
static mex_msg_t *
mex_node_recv (void)
diff --git a/digital/avr/modules/host/test/test_host.c b/digital/avr/modules/host/test/test_host.c
index 8c98a94a..5df65459 100644
--- a/digital/avr/modules/host/test/test_host.c
+++ b/digital/avr/modules/host/test/test_host.c
@@ -51,8 +51,12 @@ main (int argc, char **argv)
else
{
printf ("set\n");
- assert_print (argc == 2 && strcmp (argv[1], "ni") == 0,
+ host_get_program_arguments (&ac, &av);
+ assert_print (ac == 1 && strcmp (av[0], "ni") == 0,
"please provide \"ni\" as the first argument");
+ printf ("instance %s\n", host_get_instance ("none", 0));
+ printf ("instance -1 %s\n", host_get_instance ("none", 1));
+ printf ("instance -2 %s\n", host_get_instance ("none", 2));
host_register_integer ("avr_integer", 42);
host_register_string ("avr_string", "Ni!");
host_reset ();
diff --git a/digital/avr/modules/host/test/test_mex.c b/digital/avr/modules/host/test/test_mex.c
index 1e5d303e..7d4badad 100644
--- a/digital/avr/modules/host/test/test_mex.c
+++ b/digital/avr/modules/host/test/test_mex.c
@@ -28,8 +28,10 @@
#include <stdio.h>
+u8 mtype_coucou1, mtype_coucou2, mtype_oucouc;
+
void
-a82 (void *user, mex_msg_t *msg)
+handle_oucouc (void *user, mex_msg_t *msg)
{
printf ("oucouc\n");
u8 nb;
@@ -41,14 +43,14 @@ a82 (void *user, mex_msg_t *msg)
}
void
-a801 (void *user, mex_msg_t *msg)
+handle_coucou (void *user, mex_msg_t *msg)
{
printf ("coucou\n");
u8 b;
u16 h;
u32 l;
mex_msg_pop (msg, "BHL", &b, &h, &l);
- if (mex_msg_mtype (msg) == 0x80)
+ if (mex_msg_mtype (msg) == mtype_coucou1)
assert (b == 1 && h == 2 && l == 3);
else
assert (b == 4 && h == 5 && l == 6);
@@ -66,22 +68,29 @@ main (int argc, char **argv)
fprintf (stderr, "%s 1|2\n", argv[0]);
return 1;
}
+ assert (!mex_node_connected ());
+ mex_node_connect ();
+ assert (mex_node_connected ());
+ mtype_coucou1 = mex_node_reservef ("%s%d", "coucou", 1);
+ mtype_coucou2 = mex_node_reservef ("%s%d", "coucou", 2);
+ mtype_oucouc = mex_node_reserve ("oucouc");
if (argv[1][0] == '1')
{
- mex_node_register (0x82, a82, NULL);
- mex_node_connect ();
+ mex_node_register (mtype_oucouc, handle_oucouc, NULL);
i = host_fetch_integer ("reseted");
if (i == -1)
{
- mex_msg_t *m = mex_msg_new (0x80);
+ mex_node_wait_date (1);
+ mex_msg_t *m = mex_msg_new (mtype_coucou1);
mex_msg_push (m, "BHL", 1, 2, 3);
mex_node_send (m);
host_register_integer ("reseted", 1);
+ mex_node_wait_date (2);
host_reset ();
}
else
{
- mex_msg_t *m = mex_msg_new (0x81);
+ mex_msg_t *m = mex_msg_new (mtype_coucou2);
mex_msg_push (m, "BHL", 4, 5, 6);
mex_node_send (m);
mex_node_wait ();
@@ -89,13 +98,13 @@ main (int argc, char **argv)
}
else
{
- mex_node_register (0x80, a801, NULL);
- mex_node_register (0x81, a801, NULL);
- mex_node_connect ();
- mex_msg_t *m = mex_msg_new (0x82);
+ mex_node_register (mtype_coucou1, handle_coucou, NULL);
+ mex_node_register (mtype_coucou2, handle_coucou, NULL);
+ mex_node_wait_date (1);
+ mex_msg_t *m = mex_msg_new (mtype_oucouc);
mex_msg_push (m, "B", 42);
mex_msg_t *r = mex_node_request (m);
- assert (mex_msg_mtype (r) == 0x82);
+ assert (mex_msg_mtype (r) == mtype_oucouc);
u8 rb;
mex_msg_pop (r, "B", &rb);
assert (rb == 43);
diff --git a/digital/avr/modules/twi/twi.host.c b/digital/avr/modules/twi/twi.host.c
index eabf842a..394b0793 100644
--- a/digital/avr/modules/twi/twi.host.c
+++ b/digital/avr/modules/twi/twi.host.c
@@ -26,16 +26,16 @@
#include "twi.h"
#include "modules/utils/utils.h"
+#include "modules/host/host.h"
#include "modules/host/mex.h"
#include <string.h>
/** Read messages are sent as request.
* In request, first byte is address, second byte is length.
* In response, whole payload is data. */
-#define TWI_READ 0x90
+
/** Write messages are sent directly.
* First byte is address, rest of payload is data. */
-#define TWI_WRITE 0x91
/** Module context. */
struct twi_host_t
@@ -52,6 +52,10 @@ struct twi_host_t
/** Current master status. */
uint8_t master_current_status;
#endif /* AC_TWI_MASTER_ENABLE */
+ /** Mex read message types. */
+ uint8_t mex_read;
+ /** Mex write message types. */
+ uint8_t mex_write;
};
/** Global context. */
@@ -73,13 +77,23 @@ twi_handle_WRITE (void *user, mex_msg_t *msg);
void
twi_init (uint8_t addr)
{
+ const char *mex_instance;
assert ((addr & 1) == 0);
ctx.address = addr;
+ if (mex_node_connected ())
+ {
+ mex_instance = host_get_instance ("global", 1);
+ ctx.mex_read = mex_node_reservef ("%s:read", mex_instance);
+ ctx.mex_write = mex_node_reservef ("%s:write", mex_instance);
+ }
#if AC_TWI_SLAVE_ENABLE
ctx.slave_send_buffer_size = 1;
ctx.slave_send_buffer[0] = 0;
- mex_node_register (TWI_READ, twi_handle_READ, NULL);
- mex_node_register (TWI_WRITE, twi_handle_WRITE, NULL);
+ if (mex_node_connected ())
+ {
+ mex_node_register (ctx.mex_read, twi_handle_READ, NULL);
+ mex_node_register (ctx.mex_write, twi_handle_WRITE, NULL);
+ }
#endif /* AC_TWI_SLAVE_ENABLE */
#if AC_TWI_MASTER_ENABLE
ctx.master_current_status = TWI_MASTER_ERROR;
@@ -112,7 +126,7 @@ twi_handle_READ (void *user, mex_msg_t *msg)
if (addr == ctx.address)
{
assert (size <= AC_TWI_SLAVE_SEND_BUFFER_SIZE);
- mex_msg_t *m = mex_msg_new (TWI_READ);
+ mex_msg_t *m = mex_msg_new (ctx.mex_read);
mex_msg_push_buffer (m, ctx.slave_send_buffer,
UTILS_MIN (size, ctx.slave_send_buffer_size));
mex_node_response (m);
@@ -141,7 +155,8 @@ void
twi_master_send (uint8_t addr, const uint8_t *buffer, uint8_t size)
{
/* Send message. */
- mex_msg_t *m = mex_msg_new (TWI_WRITE);
+ assert (ctx.mex_write);
+ mex_msg_t *m = mex_msg_new (ctx.mex_write);
mex_msg_push (m, "B", addr);
mex_msg_push_buffer (m, buffer, size);
mex_node_send (m);
@@ -157,7 +172,8 @@ void
twi_master_recv (uint8_t addr, uint8_t *buffer, uint8_t size)
{
/* Send request and wait for response. */
- mex_msg_t *m = mex_msg_new (TWI_READ);
+ assert (ctx.mex_read);
+ mex_msg_t *m = mex_msg_new (ctx.mex_read);
mex_msg_push (m, "BB", addr, size);
m = mex_node_request (m);
int recv = mex_msg_len (m);