// Set up a transfer: send a write command with an address AJ_Status AJ_WSL_SPI_DMAWriteStart(uint16_t targetAddress) { aj_spi_status rc; wsl_spi_command send; AJ_Status status = AJ_ERR_SPI_WRITE; uint16_t toss; uint8_t pcs = AJ_WSL_SPI_PCS; // initialize an SPI CMD structure with the register of interest send.cmd_rx = AJ_WSL_SPI_WRITE; send.cmd_reg = AJ_WSL_SPI_EXTERNAL; send.cmd_addr = targetAddress; // write the register rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *((uint8_t*)&send + 1), AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, &pcs); // toss. AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *(uint8_t*)&send, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, &pcs); // toss. AJ_ASSERT(rc == SPI_OK); if (rc == SPI_OK) { status = AJ_OK; } return status; }
void AJ_WSL_SPI_ReadIntoBuffer(uint16_t bytesToRead, uint8_t** buf) { aj_spi_status rc; wsl_spi_command send; AJ_Status status = AJ_ERR_SPI_READ; uint8_t pcs = AJ_WSL_SPI_PCS; uint16_t toss; // initialize an SPI CMD structure with the register of interest send.cmd_rx = AJ_WSL_SPI_READ; send.cmd_reg = AJ_WSL_SPI_EXTERNAL; send.cmd_addr = AJ_WSL_SPI_MBOX_0_EOM_ALIAS - bytesToRead; // write the register rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *((uint8_t*)&send + 1), AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, &pcs); // toss. AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *(uint8_t*)&send, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, &pcs); // toss. AJ_ASSERT(rc == SPI_OK); AJ_WSL_SPI_DMATransfer((uint32_t)*buf, bytesToRead, 0); }
AJ_Status AJ_UnmarshalCloseContainer(AJ_Message* msg, AJ_Arg* arg) { AJ_ASSERT(TYPE_FLAG(arg->typeId) & AJ_CONTAINER); AJ_ASSERT(msg->outer == arg); msg->outer = arg->container; if (arg->typeId == AJ_ARG_ARRAY) { AJ_IOBuffer* ioBuf = &msg->bus->sock.rx; /* * Check that all the array elements have been unmarshaled */ size_t len = (uint16_t)(ioBuf->readPtr - (uint8_t*)arg->val.v_data); if (len != arg->len) { return AJ_ERR_UNMARSHAL; } } else { /* * Check that all of the struct elements have been unmarshaled */ if ((arg->typeId == AJ_ARG_STRUCT) && (*arg->sigPtr != AJ_STRUCT_CLOSE)) { return AJ_ERR_SIGNATURE; } if ((arg->typeId == AJ_ARG_DICT_ENTRY) && (*arg->sigPtr != AJ_DICT_ENTRY_CLOSE)) { return AJ_ERR_SIGNATURE; } } return AJ_OK; }
/* * This function is called when a stack overflow is detected */ void vApplicationStackOverflowHook(xTaskHandle pxTask, signed char*pcTaskName) { AJ_ASSERT(FALSE); while (1) { } ; }
static void AJ_WSL_HTCProcessControlMessageResponse_Fake(AJ_BufNode* pNodeHTCBody) { wsl_wmi_cmd_hdr* wmiCmdHdr2; wmiCmdHdr2 = (wsl_wmi_cmd_hdr*)pNodeHTCBody->buffer; AJ_WSL_WMI_CMD_HDR_FROM_WIRE(wmiCmdHdr2); AJ_WSL_WMI_CMD_HDR_Print(wmiCmdHdr2); AJ_BufNodePullBytes(pNodeHTCBody, sizeof(wsl_wmi_cmd_hdr)); if (wmiCmdHdr2->commandID == WMI_SOCKET_CMDID) { wsl_wmi_socket_response_event* pSocketResp = (wsl_wmi_socket_response_event*)pNodeHTCBody->buffer; AJ_WSL_WMI_SOCK_RESPONSE_FROM_WIRE(pSocketResp); switch (pSocketResp->responseType) { case WSL_SOCK_OPEN: { //AJ_AlwaysPrintf(("PING response was received over the wire: addr 0x%x, size 0x%x\n\n", ping->ip_addr, ping->size)); AJ_AlwaysPrintf(("OPEN response was received over the wire, Handle is %x\n\n", pSocketResp->socketHandle)); break; } case WSL_SOCK_PING: { //wsl_wmi_sock_ping* ping = (wsl_wmi_sock_ping*)pNodeHTCBody->buffer; //AJ_WSL_WMI_SOCK_PING_FROM_WIRE(ping); //AJ_AlwaysPrintf(("PING response was received over the wire: addr 0x%x, size 0x%x\n\n", ping->ip_addr, ping->size)); AJ_AlwaysPrintf(("PING response was received over the wire, Handle is %x\n\n", pSocketResp->socketHandle)); break; } default: AJ_ASSERT("unknown socket command\n\n"); } } }
static CCM_Context* InitCCMContext(const uint8_t* nonce, uint32_t nLen, uint32_t hdrLen, uint32_t msgLen, uint8_t M) { int i; int l; uint8_t L = 15 - max(nLen, 11); uint8_t flags = ((hdrLen) ? 0x40 : 0) | (((M - 2) / 2) << 3) | (L - 1); CCM_Context* context; AJ_ASSERT(nLen <= 15); context = (CCM_Context*)AJ_Malloc(sizeof(CCM_Context)); if (context) { memset(context, 0, sizeof(CCM_Context)); /* * Set ivec and other initial args. */ context->ivec.data[0] = L - 1; memcpy(&context->ivec.data[1], nonce, nLen); /* * Compute the B_0 block. This encodes the flags, the nonce, and the message length. */ context->B_0.data[0] = flags; memcpy(&context->B_0.data[1], nonce, nLen); for (i = 15, l = msgLen - hdrLen; l != 0; i--) { context->B_0.data[i] = (uint8_t)l; l >>= 8; } } return context; }
static int NativeServiceObjectFinalizer(duk_context* ctx) { const char* peer; SessionInfo* sessionInfo; AJ_InfoPrintf(("ServiceObjectFinalizer\n")); duk_get_prop_string(ctx, 0, "dest"); if (!duk_is_undefined(ctx, -1)) { peer = duk_get_string(ctx, -1); if (peer) { AJS_GetGlobalStashObject(ctx, "sessions"); duk_get_prop_string(ctx, -1, peer); duk_get_prop_string(ctx, -1, "info"); sessionInfo = duk_get_buffer(ctx, -1, NULL); duk_pop_2(ctx); AJ_ASSERT(sessionInfo->refCount != 0); if ((--sessionInfo->refCount == 0) && sessionInfo->sessionId) { duk_del_prop_string(ctx, -1, peer); (void) AJ_BusLeaveSession(AJS_GetBusAttachment(), sessionInfo->sessionId); sessionInfo->sessionId = 0; } duk_pop(ctx); } /* * There is no guarantee that finalizers are only called once. This ensures that the * finalizer is idempotent. */ duk_del_prop_string(ctx, 0, "dest"); } duk_pop(ctx); return 0; }
/* * Called with a service object on the top of the stack. Returns with a message object on top of * the stack replacing the service object. */ static void MessageSetup(duk_context* ctx, const char* iface, const char* member, const char* path, uint8_t msgType) { AJ_Status status; AJ_MsgHeader hdr; AJ_Message msg; AJS_MsgInfo* msgInfo; const char* dest; uint8_t secure; size_t dlen; duk_idx_t objIdx = duk_push_object(ctx); /* * Get the destination from the service object */ duk_get_prop_string(ctx, -2, "dest"); dest = duk_get_lstring(ctx, -1, &dlen); duk_pop(ctx); /* * If this is not a broadcast message make sure the destination peer is still connected */ if (dlen) { CheckPeerIsAlive(ctx, dest); } /* * Initialize a message struct so we can lookup the message id. We do this now because it is * alot more efficient if the method object we are creating is used multiple times. */ memset(&msg, 0, sizeof(AJ_Message)); memset(&hdr, 0, sizeof(AJ_MsgHeader)); msg.hdr = &hdr; msg.signature = "*"; msg.member = member; msg.iface = iface; msg.objPath = path ? path : AJS_GetStringProp(ctx, -2, "path"); /* * This allows us to use one object table entry for all messages */ AJS_SetObjectPath(msg.objPath); hdr.msgType = msgType; status = AJ_LookupMessageId(&msg, &secure); if (status != AJ_OK) { duk_error(ctx, DUK_ERR_REFERENCE_ERROR, "Unknown %s %s", path ? "SIGNAL" : "METHOD", member); } /* * Buffer to caching message information stored in the "info" property on the method object */ msgInfo = duk_push_fixed_buffer(ctx, sizeof(AJS_MsgInfo) + dlen + 1); msgInfo->secure = secure; msgInfo->session = AJS_GetIntProp(ctx, -2, "session"); msgInfo->msgId = msg.msgId; memcpy(msgInfo->dest, dest, dlen); msgInfo->dest[dlen] = 0; duk_put_prop_string(ctx, objIdx, "info"); AJ_ASSERT(duk_get_top_index(ctx) == objIdx); /* * Remove sessions object and leave the message object on the top of the stack */ duk_remove(ctx, -2); }
static void CreateManifest(uint8_t** manifest, size_t* len) { *len = strlen(intfc); *manifest = (uint8_t*) AJ_Malloc(*len); AJ_ASSERT(*manifest); memcpy(*manifest, (uint8_t*) intfc, *len); }
/* * @remarks SPI mode is not being changed here. */ AJ_Status AJ_WSL_SPI_WriteByte8(uint8_t spi_data, uint8_t end) { aj_spi_status rc; AJ_Status status = AJ_ERR_SPI_WRITE; uint8_t pcs = AJ_WSL_SPI_PCS; uint16_t toss; rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, (uint16_t)spi_data, AJ_WSL_SPI_PCS, end); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, &pcs); AJ_ASSERT(rc == SPI_OK); if (rc == SPI_OK) { status = AJ_OK; } return status; }
/* * This function is called when a malloc failure is detected */ void vApplicationMallocFailedHook(void) { AJ_ASSERT(FALSE); while (1) { } ; }
static uint16_t SlipBytes(AJ_SlippedBuffer volatile* slip, uint8_t* data, uint16_t len) { uint16_t i; uint8_t b; for (i = 0; i < len; ++i) { if (slip->actualLen == slip->allocatedLen) { AJ_ASSERT(FALSE); break; } b = *data++; if ((b == BOUNDARY_BYTE) || (b == ESCAPE_BYTE)) { /* * need room for two bytes */ if ((slip->actualLen + 1) == slip->allocatedLen) { break; } slip->buffer[slip->actualLen++] = ESCAPE_BYTE; b = (b == ESCAPE_BYTE) ? ESCAPE_SUBSTITUTE : BOUNDARY_SUBSTITUTE; } slip->buffer[slip->actualLen++] = b; } return i; }
int AJ_Main() { AJ_Status status = AJ_OK; AJ_Printf("AJ_Main 1\n"); AJ_Initialize(); AJ_NVRAM_Clear(); AJ_Printf("Clearing NVRAM\n"); AJ_Printf("AJ_Main 2\n"); status = TestNVRAM(); AJ_Printf("AJ_Main 3\n"); AJ_ASSERT(status == AJ_OK); status = TestCreds(); AJ_ASSERT(status == AJ_OK); return 0; }
aj_spi_status AJ_SPI_WRITE(Spi* p_spi, uint16_t us_data, uint8_t uc_pcs, uint8_t uc_last) { aj_spi_status status; // AJ_InfoPrintf(("=WRITE= %x\n", us_data)); status = spi_write(p_spi, us_data, uc_pcs, uc_last); AJ_ASSERT(status == SPI_OK); return status; }
AJ_Status AJS_HandleJoinSessionReply(duk_context* ctx, AJ_Message* msg) { const char* peer = NULL; SessionInfo* sessionInfo = NULL; uint32_t replySerial = msg->replySerial; uint8_t joined = FALSE; AJS_GetGlobalStashObject(ctx, "sessions"); duk_enum(ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY); while (duk_next(ctx, -1, 1)) { peer = duk_get_string(ctx, -2); AJ_ASSERT(duk_is_object(ctx, -1)); duk_get_prop_string(ctx, -1, "info"); sessionInfo = duk_get_buffer(ctx, -1, NULL); AJ_ASSERT(sessionInfo); duk_pop_3(ctx); if (sessionInfo->replySerial == replySerial) { uint32_t sessionId; uint32_t replyStatus; /* * Check if the join was successful */ AJ_UnmarshalArgs(msg, "uu", &replyStatus, &sessionId); if (replyStatus == AJ_JOINSESSION_REPLY_SUCCESS) { /* * TODO - if we have a well-known name send a ping to get the unique name */ sessionInfo->sessionId = sessionId; joined = TRUE; } sessionInfo->replySerial = 0; break; } } duk_pop(ctx); /* Pop the enum */ if (joined) { /* * TODO - we may need to initiate authentication with the remote peer */ AnnouncementCallbacks(ctx, peer, sessionInfo); } /* Pop "sessions" */ duk_pop(ctx); return AJ_OK; }
AJ_Status AJ_MarshalReplyMsg(const AJ_Message* methodCall, AJ_Message* reply) { AJ_ASSERT(methodCall->hdr->msgType == AJ_MSG_METHOD_CALL); memset(reply, 0, sizeof(AJ_Message)); reply->bus = methodCall->bus; reply->destination = methodCall->sender; reply->sessionId = methodCall->sessionId; reply->replySerial = methodCall->hdr->serialNum; return MarshalMsg(reply, AJ_MSG_METHOD_RET, methodCall->msgId, methodCall->hdr->flags & AJ_FLAG_ENCRYPTED); }
aj_spi_status AJ_SPI_READ(Spi* p_spi, uint8_t* us_data, uint8_t* p_pcs) { aj_spi_status status; uint16_t data; status = spi_read(p_spi, &data, p_pcs); AJ_ASSERT(status == SPI_OK); *us_data = data & 0xFF; // AJ_InfoPrintf(("=R= %02x\n", (*us_data) & 0xFF)); return status; }
AJ_Status AJ_DeliverMsgPartial(AJ_Message* msg, uint32_t bytesRemaining) { AJ_IOBuffer* ioBuf = &msg->bus->sock.tx; uint8_t typeId = msg->signature[msg->sigOffset]; size_t pad; AJ_ASSERT(!msg->outer); if (!msg->hdr || !bytesRemaining) { return AJ_ERR_UNEXPECTED; } /* * Partial delivery not currently supported for messages that must be encrypted. */ if (msg->hdr->flags & AJ_FLAG_ENCRYPTED) { return AJ_ERR_SECURITY; } /* * There must be arguments to marshal */ if (!typeId) { return AJ_ERR_SIGNATURE; } /* * Pad to the start of the argument. */ pad = PadForType(typeId, ioBuf); if (pad) { AJ_Status status = WritePad(msg, pad); if (status != AJ_OK) { return status; } } /* * Set the body length in the header buffer. */ msg->hdr->bodyLen = (uint32_t)(msg->bodyBytes + pad + bytesRemaining); AJ_DumpMsg("SENDING(partial)", msg, FALSE); /* * The buffer space occupied by the header is going to be overwritten * so the header is going to become invalid. */ msg->hdr = NULL; /* * From now on we are going to count down the remaining body bytes */ msg->bodyBytes = (uint32_t)bytesRemaining; /* * Standard signature matching is now meaningless */ msg->signature = ""; msg->sigOffset = 0;; return AJ_OK; }
AJ_Status AJ_MarshalCloseContainer(AJ_Message* msg, AJ_Arg* arg) { AJ_IOBuffer* ioBuf = &msg->bus->sock.tx; AJ_Status status = AJ_OK; AJ_ASSERT(TYPE_FLAG(arg->typeId) & AJ_CONTAINER); AJ_ASSERT(msg->outer == arg); msg->outer = arg->container; if (arg->typeId == AJ_ARG_ARRAY) { uint32_t lenOffset = (uint32_t)((uint8_t*)arg->val.v_data - ioBuf->bufStart); /* * The length we marshal does not include the length field itself. */ arg->len = (uint16_t)(ioBuf->writePtr - (uint8_t*)arg->val.v_data) - 4; /* * If the array element is 8 byte aligned and the array is not empty check if there was * padding after the length. The length we marshal should not include the padding. */ if ((ALIGNMENT(*arg->sigPtr) == 8) && !(lenOffset & 4) && arg->len) { arg->len -= 4; } /* * Write array length into the buffer */ *(arg->val.v_uint32) = arg->len; } else { arg->len = 0; /* * Check the signature is correctly closed. */ if ((arg->typeId == AJ_ARG_STRUCT) && (*arg->sigPtr != AJ_STRUCT_CLOSE)) { return AJ_ERR_SIGNATURE; } if ((arg->typeId == AJ_ARG_DICT_ENTRY) && (*arg->sigPtr != AJ_DICT_ENTRY_CLOSE)) { return AJ_ERR_SIGNATURE; } } return status; }
/* * Number of packets on the txSent queue. These are packets that have been sent * but not yet acknowledged. */ static uint8_t txSentPending(void) { uint8_t n = 0; static TxPkt volatile* pkt; for (pkt = txSent; pkt != NULL; pkt = pkt->next) { ++n; } AJ_ASSERT(n <= AJ_SerialLinkParams.windowSize); return n; }
void AJ_WSL_SPI_DMATransfer(void* buffer, uint32_t size, uint8_t direction) { dma_transfer_descriptor_t transfer; AJ_ASSERT(AJ_WSL_DMA_send_done == 0); /* Disable both channels before parameters are set */ dmac_channel_disable(DMAC, AJ_DMA_TX_CHANNEL); dmac_channel_disable(DMAC, AJ_DMA_RX_CHANNEL); if (direction == AJ_DMA_TX) { /* Direction is TX so set the destination to the SPI hardware */ transfer = transfer_descriptors[AJ_DMA_TX][AJ_DMA_TX_CHANNEL]; /* Set the source to the buffer your sending */ transfer.ul_source_addr = (uint32_t) buffer; transfer.ul_ctrlA |= size; dmac_channel_single_buf_transfer_init(DMAC, AJ_DMA_TX_CHANNEL, (dma_transfer_descriptor_t*) &transfer); /* Enable the channel to start DMA */ dmac_channel_enable(DMAC, AJ_DMA_TX_CHANNEL); /* Setup RX direction as NULL destination and SPI0 as source */ transfer = transfer_descriptors[AJ_DMA_TX][AJ_DMA_RX_CHANNEL]; transfer.ul_ctrlA |= size; dmac_channel_single_buf_transfer_init(DMAC, AJ_DMA_RX_CHANNEL, &transfer); /* Enable the channel to start DMA */ dmac_channel_enable(DMAC, AJ_DMA_RX_CHANNEL); /* Wait for the transfer to complete */ while (!AJ_WSL_DMA_send_done); } else { /* We are transferring in the RX direction */ /* Set up the destination address */ transfer = transfer_descriptors[AJ_DMA_RX][AJ_DMA_RX_CHANNEL]; transfer.ul_destination_addr = (uint32_t) buffer; transfer.ul_ctrlA |= size; dmac_channel_single_buf_transfer_init(DMAC, AJ_DMA_RX_CHANNEL, &transfer); dmac_channel_enable(DMAC, AJ_DMA_RX_CHANNEL); /* Setup the TX channel to transfer from a NULL pointer * This must be done in order for the transfer to start */ transfer = transfer_descriptors[AJ_DMA_RX][AJ_DMA_TX_CHANNEL]; transfer.ul_ctrlA |= size; dmac_channel_single_buf_transfer_init(DMAC, AJ_DMA_TX_CHANNEL, (dma_transfer_descriptor_t*) &transfer); dmac_channel_enable(DMAC, AJ_DMA_TX_CHANNEL); while (!AJ_WSL_DMA_send_done); } /* reset the DMA completed indicator */ AJ_WSL_DMA_send_done = 0; dmac_channel_disable(DMAC, AJ_DMA_TX_CHANNEL); dmac_channel_disable(DMAC, AJ_DMA_RX_CHANNEL); }
/* * @remarks SPI mode is not being changed here. */ AJ_Status AJ_WSL_SPI_WriteByte16(uint16_t spi_data, uint8_t end) { aj_spi_status rc; AJ_Status status = AJ_ERR_SPI_WRITE; uint8_t pcs = AJ_WSL_SPI_PCS; uint16_t toss; rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, spi_data, AJ_WSL_SPI_PCS, end); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, &pcs); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, spi_data & 0xFF, AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, &pcs); // toss. AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, spi_data >> 8, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, &pcs); // toss. AJ_ASSERT(rc == SPI_OK); if (rc == SPI_OK) { status = AJ_OK; } return status; }
void AJ_WSL_HTC_ProcessInterruptCause(void) { uint16_t cause = 0; AJ_Status status = AJ_ERR_SPI_READ; status = AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_INTR_CAUSE, (uint8_t*)&cause); AJ_ASSERT(status == AJ_OK); cause = LE16_TO_CPU(cause); if (cause & AJ_WSL_SPI_REG_INTR_CAUSE_DATA_AVAILABLE) { AJ_WSL_HTC_ProcessIncoming(); cause = cause ^ AJ_WSL_SPI_REG_INTR_CAUSE_DATA_AVAILABLE; //clear the bit } if (cause & AJ_WSL_SPI_REG_INTR_CAUSE_READ_DONE) { uint16_t clearCause = CPU_TO_LE16(AJ_WSL_SPI_REG_INTR_CAUSE_READ_DONE); status = AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_CAUSE, clearCause); AJ_ASSERT(status == AJ_OK); cause = cause ^ AJ_WSL_SPI_REG_INTR_CAUSE_READ_DONE; } if (cause & AJ_WSL_SPI_REG_INTR_CAUSE_WRITE_DONE) { uint16_t clearCause = CPU_TO_LE16(AJ_WSL_SPI_REG_INTR_CAUSE_WRITE_DONE); status = AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_CAUSE, clearCause); AJ_ASSERT(status == AJ_OK); cause = cause ^ AJ_WSL_SPI_REG_INTR_CAUSE_WRITE_DONE; } if (cause & AJ_WSL_SPI_REG_INTR_CAUSE_CPU_AWAKE) { uint16_t clearCause = CPU_TO_LE16(AJ_WSL_SPI_REG_INTR_CAUSE_CPU_AWAKE); status = AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_CAUSE, clearCause); AJ_ASSERT(status == AJ_OK); cause = cause ^ AJ_WSL_SPI_REG_INTR_CAUSE_CPU_AWAKE; } if (cause & AJ_WSL_SPI_REG_INTR_CAUSE_COUNTER) { uint16_t clearCause = CPU_TO_LE16(AJ_WSL_SPI_REG_INTR_CAUSE_COUNTER); status = AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_CAUSE, clearCause); AJ_ASSERT(status == AJ_OK); cause = cause ^ AJ_WSL_SPI_REG_INTR_CAUSE_COUNTER; } if (cause & ~AJ_WSL_SPI_REG_INTR_CAUSE_DATA_AVAILABLE) { //AJ_InfoPrintf(("Some other interrupt cause as well %x\n", cause)); } }
// Set up a transfer: send a write command with an address AJ_Status AJ_WSL_SPI_DMARead16(uint16_t targetAddress, uint16_t len, uint16_t* spi_data) { aj_spi_status rc; wsl_spi_command send; AJ_Status status = AJ_ERR_SPI_READ; uint8_t pcs = AJ_WSL_SPI_PCS; uint16_t toss; uint8_t* bytePoint = (uint8_t*)spi_data; // initialize an SPI CMD structure with the register of interest send.cmd_rx = AJ_WSL_SPI_READ; send.cmd_reg = AJ_WSL_SPI_EXTERNAL; send.cmd_addr = targetAddress; // write the register rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *((uint8_t*)&send + 1), AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, &pcs); // toss. AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *(uint8_t*)&send, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, &pcs); // toss. AJ_ASSERT(rc == SPI_OK); while ((rc == SPI_OK) && (len > 1)) { /* Test read: should return OK with what is sent. */ rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, 0 /*xFF*/, AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, bytePoint, &pcs); AJ_ASSERT(rc == SPI_OK); bytePoint++; len = len - 1; } if (rc == SPI_OK) { rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, 0 /*xFF*/, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, bytePoint, &pcs); AJ_ASSERT(rc == SPI_OK); } if (rc == SPI_OK) { status = AJ_OK; } return status; }
void AJ_TransmitCallback(uint8_t* buffer, uint16_t bytesWritten) { dataSent = 1; AJ_ASSERT((buffer == pendingSendBuffer->buffer) && (bytesWritten == pendingSendBuffer->actualLen)); // put pendingSendBuffer on the free list pendingSendBuffer->next = bufferTxFreeList; bufferTxFreeList = pendingSendBuffer; pendingSendBuffer = bufferTxPending; if (pendingSendBuffer != NULL) { bufferTxPending = bufferTxPending->next; pendingSendBuffer->next = NULL; AJ_TX(pendingSendBuffer->buffer, pendingSendBuffer->actualLen); AJ_ResumeTX(); } }
AJ_Status AJ_WSL_SPI_RegisterRead(uint16_t reg, uint8_t* spi_data) { aj_spi_status rc; wsl_spi_command send; AJ_Status status = AJ_ERR_SPI_READ; uint8_t pcs = AJ_WSL_SPI_PCS; // initialize an SPI CMD structure with the register of interest send.cmd_rx = AJ_WSL_SPI_READ; send.cmd_reg = AJ_WSL_SPI_INTERNAL; send.cmd_addr = reg; /* Test write: should return OK. */ rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *((uint8_t*)&send + 1), AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, spi_data, &pcs); // toss. AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *(uint8_t*)&send, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, spi_data, &pcs); // toss. AJ_ASSERT(rc == SPI_OK); // read the first byte of response rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, 0 /*xFF*/, AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); // junk to write while reading AJ_ASSERT(rc == SPI_OK); if (rc == SPI_OK) { /* Test read: should return OK with what is sent. */ rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, spi_data, &pcs); AJ_ASSERT(rc == SPI_OK); status = AJ_OK; } // read the second byte spi_data++; rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, 0 /*xFF*/, AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); // junk to write while reading AJ_ASSERT(rc == SPI_OK); if (rc == SPI_OK) { /* Test read: should return OK with what is sent. */ rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, spi_data, &pcs); AJ_ASSERT(rc == SPI_OK); status = AJ_OK; } spi_data--; // move back to the original location *(uint16_t*)spi_data = CPU_TO_BE16(*(uint16_t*)spi_data); return status; }
AJ_Status AJ_WSL_SPI_RegisterWrite(uint16_t reg, uint16_t spi_data) { aj_spi_status rc; wsl_spi_command send; AJ_Status status = AJ_ERR_SPI_WRITE; uint8_t pcs = AJ_WSL_SPI_PCS; uint16_t toss; uint8_t* bytePoint = (uint8_t*)&spi_data; // initialize an SPI CMD structure with the register of interest send.cmd_rx = AJ_WSL_SPI_WRITE; send.cmd_reg = AJ_WSL_SPI_INTERNAL; send.cmd_addr = reg; // write the register, one byte at a time, in the right order rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *((uint8_t*)&send + 1), AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, &pcs); // toss. AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *(uint8_t*)&send, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, &pcs); // toss. AJ_ASSERT(rc == SPI_OK); if (rc == SPI_OK) { rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *(bytePoint + 1), AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, &pcs); AJ_ASSERT(rc == SPI_OK); if (rc == SPI_OK) { status = AJ_OK; } } if (rc == SPI_OK) { rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *(bytePoint) & 0xFF, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, &pcs); AJ_ASSERT(rc == SPI_OK); if (rc == SPI_OK) { status = AJ_OK; } } return status; }
//Mailbox Read Steps: //1. Interrupt going from the QCA4002 to the SPI host. //2. INTERNAL read from INTR_CAUSE register. //3. INTERNAL read from RDBUF_BYTE_AVA register. //4. Internal read from RDBUF_LOOKAHEAD1 register //5. Internal read from RDBUF_LOOKAHEAD2 register. From the 4 bytes we have read from RDBUF_LOOKAHEAD registers, get the packet size. //6. INTERNAL write to DMA_SIZE register with the packet size. //7. Start DMA read command and start reading the data by de-asserting chip select pin. //8. The packet available will be cleared by HW at the end of the DMA read. // AJ_EXPORT AJ_Status AJ_WSL_ReadFromMBox(uint8_t box, uint16_t* len, uint8_t** buf) { AJ_Status status = AJ_ERR_SPI_READ; uint16_t cause = 0; uint16_t bytesInBuffer = 0; uint16_t bytesToRead = 0; uint16_t lookAhead; uint16_t payloadLength; AJ_ASSERT(0 == box); AJ_EnterCriticalRegion(); //2. INTERNAL read from INTR_CAUSE register. do { //3. INTERNAL read from RDBUF_BYTE_AVA register. status = AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_RDBUF_BYTE_AVA, &bytesInBuffer); AJ_ASSERT(status == AJ_OK); //bytesInBuffer = CPU_TO_BE16(bytesInBuffer); // The first few bytes of the packet can now be examined and the right amount of data read from the target //4. Internal read from RDBUF_LOOKAHEAD1 register //5. Internal read from RDBUF_LOOKAHEAD2 register. From the 4 bytes we have read from RDBUF_LOOKAHEAD registers, get the packet size. status = AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_RDBUF_LOOKAHEAD1, &lookAhead); AJ_ASSERT(status == AJ_OK); lookAhead = CPU_TO_BE16(lookAhead); status = AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_RDBUF_LOOKAHEAD2, &payloadLength); AJ_ASSERT(status == AJ_OK); payloadLength = CPU_TO_BE16(payloadLength); // calculate number of bytes to read from the lookahead info, and round up to the next block size bytesToRead = payloadLength + 6; //sizeof(header); bytesToRead = ((bytesToRead / AJ_WSL_MBOX_BLOCK_SIZE) + ((bytesToRead % AJ_WSL_MBOX_BLOCK_SIZE) ? 1 : 0)) * AJ_WSL_MBOX_BLOCK_SIZE; *buf = (uint8_t*)AJ_WSL_Malloc(bytesToRead); *len = bytesToRead; //6. INTERNAL write to DMA_SIZE register with the packet size. // write size to be transferred status = AJ_WSL_SetDMABufferSize(bytesToRead); AJ_ASSERT(status == AJ_OK); AJ_WSL_SPI_ReadIntoBuffer(bytesToRead, buf); // clear the packet available interrupt cause = 0x1; status = AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_CAUSE, cause); AJ_ASSERT(status == AJ_OK); break; } while (0); AJ_LeaveCriticalRegion(); return status; }
/** * This function is called by the receive layer when a data packet or an explicit ACK * has been received. The ACK value is one greater (modulo 8) than the seq number of the * last packet successfully received. */ void AJ_SerialTx_ReceivedAck(uint8_t ack) { TxPkt volatile* ackedPkt = NULL; if (txSent == NULL) { return; } /* * Remove acknowledged packets from sent queue. */ while ((txSent != NULL) && SEQ_GT(ack, txSent->seq)) { ackedPkt = txSent; txSent = txSent->next; //AJ_AlwaysPrintf("Releasing seq=%d (acked by %d)\n", ackedPkt->seq, ack); AJ_ASSERT(ackedPkt->type == AJ_SERIAL_DATA); /* * Return pkt to ACL free list. */ ackedPkt->next = txFreeList; txFreeList = ackedPkt; /* * If all packet have been ack'd, halt the resend timer and return. */ if (txSent == NULL) { AJ_InitTimer(&resendTime); AJ_TimeAddOffset(&resendTime, AJ_TIMER_FOREVER); resendPrimed = FALSE; return; } } /* * Reset the resend timer if one or more packets were ack'd. */ if (ackedPkt != NULL) { AJ_InitTimer(&resendTime); AJ_TimeAddOffset(&resendTime, AJ_SerialLinkParams.txResendTimeout); resendPrimed = TRUE; } }
AJ_Status AllocPWM(GPIO* pin) { size_t i; size_t idx; uint16_t physicalPin = AJS_TargetIO_GetInfo(pin->pinIdx)->physicalPin; for (idx = 0; idx < ArraySize(pinInfo); ++idx) { if (pinInfo[idx].pinNum == physicalPin) { break; } } AJ_ASSERT(!pin->pwm.dutyCycle); for (i = 0; i < MAX_PWM_PINS; ++i) { if (!pwmPins[i]) { pwmPins[i] = pin; pin->pwm.count = 0; ++pwmCount; //pin->pwm.object = new PwmOut((PinName)pinInfo[idx].pinId); return AJ_OK; } } return AJ_ERR_RESOURCES; }