BeRTOS
|
00001 00056 #include "pocketcmd.h" 00057 #include "pocketbus.h" 00058 00059 #include "cfg/cfg_pocketbus.h" 00060 00061 // Define logging setting (for cfg/log.h module). 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 /* Check for command callback */ 00086 pocketcmd_hook_t callback = ctx->search(msg.cmd); 00087 00088 /* Call it if exists */ 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 /* Try to read a packet from pocketBus */ 00105 while (pocketbus_recv(ctx->bus_ctx, &msg)) 00106 { 00107 /* Check address */ 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 * The code below make one memcopy, this the only way to 00119 * solve alignment problem on ARM. If you are use other 00120 * architecture you should find other way to optimize 00121 * this code. 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 /* We're no longer waiting for a reply (in case we were) */ 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 /* Check if we are waiting a reply from someone */ 00157 if (ctx->waiting != PKTCMD_NULL) 00158 { 00159 /* Check is reply timeout is elapsed */ 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 /* Endianess! */ 00173 cmd = cpu_to_be16(cmd); 00174 00175 /* Send packet */ 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