pocketcmd.c
Go to the documentation of this file.00001
00056 #include "pocketcmd.h"
00057 #include "pocketbus.h"
00058
00059 #include "cfg/cfg_pocketbus.h"
00060
00061
00062 #define LOG_LEVEL POCKETBUS_LOG_LEVEL
00063 #define LOG_VERBOSITY POCKETBUS_LOG_FORMAT
00064 #include <cfg/log.h>
00065 #include <cfg/debug.h>
00066 #include <cfg/macros.h>
00067 #include <cfg/module.h>
00068
00069 #include <drv/timer.h>
00070
00071 #include <cpu/byteorder.h>
00072 #include <cpu/detect.h>
00073
00074 #include <string.h>
00075
00080 void pocketcmd_poll(struct PocketCmdCtx *ctx)
00081 {
00082 PocketCmdMsg msg;
00083 while (pocketcmd_recv(ctx, &msg))
00084 {
00085
00086 pocketcmd_hook_t callback = ctx->search(msg.cmd);
00087
00088
00089 if (callback)
00090 callback(&msg);
00091 }
00092 }
00093
00094
00095
00100 bool pocketcmd_recv(struct PocketCmdCtx *ctx, PocketCmdMsg *recv_msg)
00101 {
00102 PocketMsg msg;
00103
00104
00105 while (pocketbus_recv(ctx->bus_ctx, &msg))
00106 {
00107
00108 if (msg.addr == ctx->addr ||
00109 msg.addr == POCKETBUS_BROADCAST_ADDR)
00110 {
00111
00112 #if CPU_AVR
00113 const PocketCmdHdr *hdr = (const PocketCmdHdr *)msg.payload;
00114 #else
00115 #if !CPU_ARM
00116 #warning Fix alignment problem..
00117
00118
00119
00120
00121
00122
00123 #endif
00124 PocketCmdHdr hd;
00125 memcpy(&hd, msg.payload, sizeof(PocketCmdHdr));
00126 const PocketCmdHdr *hdr = &hd;
00127 #endif
00128
00129 pocketcmd_t cmd = be16_to_cpu(hdr->cmd);
00130
00131
00132 if (cmd == ctx->waiting)
00133 ctx->waiting = PKTCMD_NULL;
00134
00135 recv_msg->cmd_ctx = ctx;
00136 recv_msg->cmd = cmd;
00137 recv_msg->len = msg.len - sizeof(PocketCmdHdr);
00138 recv_msg->buf = msg.payload + sizeof(PocketCmdHdr);
00139
00140 return true;
00141 }
00142 }
00143
00144 return false;
00145 }
00146
00147
00154 bool pocketcmd_send(struct PocketCmdCtx *ctx, pocketcmd_t cmd, const void *buf, size_t len, bool wait_reply)
00155 {
00156
00157 if (ctx->waiting != PKTCMD_NULL)
00158 {
00159
00160 if (timer_clock() - ctx->reply_timer < ms_to_ticks(CONFIG_POCKETBUS_CMD_REPLY_TIMEOUT))
00161 {
00162 LOG_ERR("Pkt discard! waiting cmd[%04X]\n", ctx->waiting);
00163 return false;
00164 }
00165 else
00166 {
00167 LOG_INFO("Timeout waiting cmd[%04X]\n", ctx->waiting);
00168 ctx->waiting = PKTCMD_NULL;
00169 }
00170 }
00171
00172
00173 cmd = cpu_to_be16(cmd);
00174
00175
00176 pocketbus_begin(ctx->bus_ctx, ctx->addr);
00177 pocketbus_write(ctx->bus_ctx, &cmd, sizeof(cmd));
00178 pocketbus_write(ctx->bus_ctx, buf, len);
00179 pocketbus_end(ctx->bus_ctx);
00180
00181 if (wait_reply)
00182 {
00183 ctx->waiting = be16_to_cpu(cmd);
00184 ctx->reply_timer = timer_clock();
00185 }
00186
00187 return true;
00188 }
00189
00197 void pocketcmd_init(struct PocketCmdCtx *ctx, struct PocketBusCtx *bus_ctx, pocketbus_addr_t addr, pocketcmd_lookup_t search)
00198 {
00199 ASSERT(ctx);
00200 ASSERT(bus_ctx);
00201 ASSERT(search);
00202 MOD_CHECK(timer);
00203
00204 memset(ctx, 0, sizeof(*ctx));
00205 ctx->bus_ctx = bus_ctx;
00206 ctx->search = search;
00207 pocketcmd_setAddr(ctx, addr);
00208 }
00209
00213 void pocketcmd_replyAck(struct PocketCmdMsg *msg)
00214 {
00215 uint8_t ack[] = { POCKETBUS_ACK };
00216
00217 pocketcmd_slaveReply(msg->cmd_ctx, msg->cmd, ack, sizeof(ack));
00218 }
00219
00223 void pocketcmd_replyNak(struct PocketCmdMsg *msg)
00224 {
00225 uint8_t nak[] = { POCKETBUS_NAK };
00226
00227 pocketcmd_slaveReply(msg->cmd_ctx, msg->cmd, nak, sizeof(nak));
00228 }
00229