Esempio n. 1
0
void AJ_WSL_Free(void* ptr)
{
    AJ_EnterCriticalRegion();
    // if the address is within the WSL heap, free the pool entry, else fallback to free.
    if ((ptr > (void*)&wsl_heap) && (ptr < (void*)&wsl_heap[WSL_HEAP_WORD_COUNT])) {
        AJ_PoolFree(ptr);
    } else {
        AJ_Free(ptr);
    }
    AJ_LeaveCriticalRegion();
}
Esempio n. 2
0
//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;
}
Esempio n. 3
0
void* AJ_WSL_Malloc(size_t size)
{
    void* mem = NULL;
    // allocate from the WSL pool first.
    AJ_EnterCriticalRegion();
    if (size <= 100) {
        mem = AJ_PoolAlloc(size);
    }

    // if the pool was full or the size too big, fall back to malloc
    if (!mem) {
        mem = AJ_Malloc(size);
    }
    if (!mem) {
        AJ_ErrPrintf(("AJ_WSL_Malloc(): Malloc failed\n"));
        AJ_Reboot();
    }
    AJ_LeaveCriticalRegion();
    return mem;
}
Esempio n. 4
0
AJ_EXPORT AJ_Status AJ_WSL_WriteBufListToMBox(uint8_t box, uint8_t endpoint, uint16_t len, AJ_BufList* list)
{
    AJ_Status status = AJ_ERR_SPI_WRITE;
    uint16_t spaceAvailable = 0;
    uint16_t bytesRemaining;
    uint16_t cause = 0;

    AJ_ASSERT(0 == box);
//    AJ_InfoPrintf(("=HTC Credits 0:%x, 1:%x, 2:%x\n", AJ_WSL_HTC_Global.endpoints[0].txCredits, AJ_WSL_HTC_Global.endpoints[1].txCredits, AJ_WSL_HTC_Global.endpoints[2].txCredits));
    AJ_Time credit_timer;
    AJ_InitTimer(&credit_timer);
    while (AJ_WSL_HTC_Global.endpoints[endpoint].txCredits < 1) {
        // do nothing and wait until there are credits
        if (AJ_GetElapsedTime(&credit_timer, TRUE) > 1500) {
            AJ_WSL_HTC_Global.endpoints[endpoint].txCredits++;
            break;
        }
        AJ_YieldCurrentTask();
    }

    // don't let the other tasks interrupt our SPI access
    AJ_EnterCriticalRegion();


    AJ_Time space_timer;
    AJ_InitTimer(&space_timer);
    // read space available in mbox from register
    do {
        if (AJ_GetElapsedTime(&space_timer, TRUE) > 1500) {
            spaceAvailable = 0xc5b;
            AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_SPI_CONFIG, 1 << 15);
            break;
        }
        status = AJ_WSL_GetWriteBufferSpaceAvailable(&spaceAvailable);
    } while (spaceAvailable == 0);

    AJ_ASSERT((status == AJ_OK) && (spaceAvailable >= len));
    if ((status == AJ_OK) && (spaceAvailable >= len)) {
        uint16_t targetAddress;


        // write size to be transferred
        status = AJ_WSL_SetDMABufferSize(len);
        AJ_ASSERT(status == AJ_OK);

        // write the target address (where we want to send data)
        // the write should end up at the end of the MBox alias
        // example 0xFFF - len
        targetAddress = AJ_WSL_SPI_MBOX_0_EOM_ALIAS - len;
        status = AJ_WSL_SPI_DMAWriteStart(targetAddress);
        AJ_ASSERT(status == AJ_OK);

        bytesRemaining = len;

        // Take the AJ_BufList to write out and write it out to the SPI interface via DMA
        AJ_WSL_BufListIterate_DMA(list);

        // clear the packet available interrupt
        cause = 0x1f;
        status = AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_ENABLE, cause);
        AJ_ASSERT(status == AJ_OK);


        AJ_WSL_HTC_Global.endpoints[endpoint].txCredits -= 1;


    } else {
        status = AJ_ERR_SPI_NO_SPACE;
    }
    AJ_LeaveCriticalRegion();
    return status;
}