Exemple #1
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;
}
Exemple #2
0
AJ_Status AJ_WSL_GetReadBufferSpaceAvailable(uint16_t* spaceAvailable)
{
    AJ_Status status = AJ_ERR_SPI_READ;
    uint16_t space = 0;
    status = AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_RDBUF_BYTE_AVA, &space);
    *spaceAvailable = space & ((1 << 12) - 1);

    return status;
}
Exemple #3
0
AJ_Status AJ_WSL_GetWriteBufferSpaceAvailable(uint16_t* spaceAvailable)
{
    AJ_Status status = AJ_ERR_SPI_READ;
    uint16_t space = 0;
    status = AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_WRBUF_SPC_AVA, &space);
    *spaceAvailable = space & ((1 << 12) - 1);
    AJ_InfoPrintf(("write buffer space available: %x %d\n", space, *spaceAvailable));
    return status;
}
Exemple #4
0
AJ_Status AJ_WSL_GetDMABufferSize(uint16_t* dmaSize)
{
    AJ_Status status = AJ_ERR_SPI_READ;
    uint16_t size = 0;
    status = AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_DMA_SIZE, &size);
    *dmaSize = size & ((1 << 12) - 1);

    return status;
}
Exemple #5
0
static void set_SPI_registers(void)
{
    volatile uint16_t spi_API = 0;

    AJ_AlwaysPrintf(("\n\n**************\nTEST:  %s\n\n", __FUNCTION__));

    // reset the target
    //    spi_API = (1 << 15);
    //    AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_SPI_CONFIG, spi_API);
    //    AJ_Sleep(1 << 22);

    // one extra write to force the device out of the reset state.
    spi_API = 0x80;
    AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_SPI_CONFIG, spi_API);
    AJ_Sleep(100);

    // write
    spi_API = 0x80; // same as capture
    AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_SPI_CONFIG, spi_API);
    //    AJ_InfoPrintf(("AJ_WSL_SPI_REG_SPI_CONFIG    was %04x\n", spi_API));

    AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_WRBUF_SPC_AVA, (uint8_t*)&spi_API);
    spi_API = LE16_TO_CPU(spi_API);
    AJ_InfoPrintf(("AJ_WSL_SPI_REG_WRBUF_SPC_AVA          was %04x\n", spi_API));


    spi_API = 0x40; // same as capture
    AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_WRBUF_WATERMARK, spi_API);
    //    AJ_InfoPrintf(("AJ_WSL_SPI_REG_SPI_CONFIG    was %04x\n", spi_API));

    spi_API = 0x400; // same as capture
    AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_CAUSE, spi_API);
    AJ_InfoPrintf(("AJ_WSL_SPI_REG_INTR_CAUSE             was %04x\n", spi_API));

    spi_API = 0x3ff;
    AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_ENABLE, spi_API);
    AJ_InfoPrintf(("AJ_WSL_SPI_REG_INTR_ENABLE    was %04x\n", spi_API));

    spi_API = 0x0e;
    AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_ENABLE, spi_API);
    AJ_InfoPrintf(("AJ_WSL_SPI_REG_INTR_ENABLE    was %04x\n", spi_API));

    spi_API = 0x1e;
    AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_ENABLE, spi_API);
    AJ_InfoPrintf(("AJ_WSL_SPI_REG_INTR_ENABLE    was %04x\n", spi_API));

    spi_API = 0x0;
    AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_ENABLE, spi_API);
    AJ_InfoPrintf(("AJ_WSL_SPI_REG_INTR_ENABLE    was %04x\n", spi_API));

    spi_API = 0x1e;
    AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_ENABLE, spi_API);
    AJ_InfoPrintf(("AJ_WSL_SPI_REG_INTR_ENABLE    was %04x\n", spi_API));

    AJ_Sleep(100);

}
Exemple #6
0
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));
    }
}
Exemple #7
0
AJ_Status AJ_WSL_SPI_HostControlRegisterRead(uint32_t targetRegister, uint8_t increment, uint16_t cbLen, uint8_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;

    // write the size
    AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_HOST_CTRL_BYTE_SIZE, cbLen | (increment ? 0 : 0x40));

    // now send the host_control_config register update
    {
        uint16_t externalRegister = 0;
        externalRegister = (1 << 15) | (0 << 14) | (targetRegister);  // external access, write, counter dec
        externalRegister = CPU_TO_LE16(externalRegister);

        AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_HOST_CTRL_CONFIG, externalRegister);

    }



    // get the spi status
    {
        uint16_t spi_16 = 0;
        AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_SPI_STATUS, (uint8_t*)&spi_16);
        spi_16 = LE16_TO_CPU(spi_16);
    }


    // 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 = AJ_WSL_SPI_REG_HOST_CTRL_RD_PORT;

    // 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, 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);


    // now, read the data back
    if (rc == SPI_OK) {
        while ((rc == SPI_OK) && (cbLen > 1)) {
            /* Test read: should return OK with what is sent. */
            rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, 0, AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE);
            AJ_ASSERT(rc == SPI_OK);
            rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, spi_data, &pcs);
            AJ_ASSERT(rc == SPI_OK);
            spi_data++;
            cbLen = cbLen - 1;
        }
        if (rc == SPI_OK) {
            rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, 0, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END);
            AJ_ASSERT(rc == SPI_OK);
            rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, spi_data, &pcs);
            AJ_ASSERT(rc == SPI_OK);
        }
        if (rc == SPI_OK) {
            status = AJ_OK;
        }
    }

    // clear the rd/wr buffer interrupt
    {
        uint16_t spi_16 = 0x300;
        spi_16 = CPU_TO_LE16(spi_16);
        AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_CAUSE, spi_16);
    }



    return status;
}
Exemple #8
0
static void write_BOOT_PARAM(void)
{
    uint32_t spi_API = 0;
    uint16_t spi_API16 = 0;
    AJ_AlwaysPrintf(("\n\n**************\nTEST:  %s\n\n", __FUNCTION__));


    // read the clock speed value
    spi_API = 0x88888888;
    AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ + 1, FALSE, 4, (uint8_t*)&spi_API);
    spi_API = 0x42424242;
    AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ + 2, FALSE, 4, (uint8_t*)&spi_API);
    spi_API = 0x00000000;
    AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ + 3, FALSE, 4, (uint8_t*)&spi_API);
    spi_API = AJ_WSL_SPI_TARGET_CLOCK_SPEED_ADDR; //0x00428878;
    spi_API = CPU_TO_LE32(spi_API);
    AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ, TRUE, 4, (uint8_t*)&spi_API);
    // now read back the value from the data port.
    AJ_WSL_SPI_HostControlRegisterRead(AJ_WSL_SPI_TARGET_VALUE, TRUE, 4, (uint8_t*)&spi_API);
    spi_API = LE32_TO_CPU(spi_API);
    //AJ_InfoPrintf(("cycles read back          was %ld \n", spi_API));


    // read the flash is present value
    {
        // let's try this dance of writing multiple times...
        spi_API = 0x88888888;
        AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ + 1, FALSE, 4, (uint8_t*)&spi_API);
        spi_API = 0x42424242;
        AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ + 2, FALSE, 4, (uint8_t*)&spi_API);
        spi_API = 0x00000000;
        AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ + 3, FALSE, 4, (uint8_t*)&spi_API);
        spi_API = AJ_WSL_SPI_TARGET_FLASH_PRESENT_ADDR; //0x0042880C;
        spi_API = CPU_TO_LE32(spi_API);
        AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ, TRUE, 4, (uint8_t*)&spi_API);

        // now read back the value from the data port.
        AJ_WSL_SPI_HostControlRegisterRead(AJ_WSL_SPI_TARGET_VALUE, TRUE, 4, (uint8_t*)&spi_API);
        spi_API = LE32_TO_CPU(spi_API);

        //AJ_InfoPrintf(("host if flash is present read back          was %ld \n", spi_API));

    }

    // now write out the flash_is_present value
    spi_API = 0x00000002;
    spi_API = CPU_TO_LE32(spi_API);
    AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_VALUE, TRUE, 4, (uint8_t*)&spi_API);

    spi_API = 0x88888888;
    AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_WRITE + 1, FALSE, 4, (uint8_t*)&spi_API);
    spi_API = 0x42424242;
    AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_WRITE + 2, FALSE, 4, (uint8_t*)&spi_API);
    spi_API = 0x00000000;
    AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_WRITE + 3, FALSE, 4, (uint8_t*)&spi_API);
    spi_API = AJ_WSL_SPI_TARGET_FLASH_PRESENT_ADDR; //0x0042880C;
    spi_API = CPU_TO_LE32(spi_API);
    AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_WRITE, TRUE, 4, (uint8_t*)&spi_API);



    // read the mbox block size
    spi_API = 0x88888888;
    AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ + 1, FALSE, 4, (uint8_t*)&spi_API);
    spi_API = 0x42424242;
    AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ + 2, FALSE, 4, (uint8_t*)&spi_API);
    spi_API = 0x00000000;
    AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ + 3, FALSE, 4, (uint8_t*)&spi_API);
    spi_API = AJ_WSL_SPI_TARGET_MBOX_BLOCKSZ_ADDR; //0x0042886C;
    spi_API = CPU_TO_LE32(spi_API);
    AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ, TRUE, 4, (uint8_t*)&spi_API);
    // now read back the value from the data port.
    AJ_WSL_SPI_HostControlRegisterRead(AJ_WSL_SPI_TARGET_VALUE, TRUE, 4, (uint8_t*)&spi_API);
    spi_API = LE32_TO_CPU(spi_API);
    AJ_WSL_MBOX_BLOCK_SIZE = spi_API;
    //AJ_InfoPrintf(("block size           was %ld \n", spi_API));




    spi_API16 = 0x001f;
    spi_API16 = CPU_TO_LE16(spi_API16);
    AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_ENABLE, spi_API16);


    // wait until the write has been processed.
    spi_API16 = 0;
    while (!(spi_API16 & 1)) {
        AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_SPI_STATUS, (uint8_t*)&spi_API16);
        spi_API16 = LE16_TO_CPU(spi_API16);
        uint16_t space = 0;
        AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_WRBUF_SPC_AVA, (uint8_t*)&space);
    }
    // clear the read and write interrupt cause register
    spi_API = (1 << 9) | (1 << 8);
    spi_API = CPU_TO_LE16(spi_API);
    AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_CAUSE, spi_API);

    {
        spi_API16 = 0x1;
        spi_API16 = CPU_TO_LE16(spi_API16);
        AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_HOST_CTRL_BYTE_SIZE, spi_API16);

        // waiting seems to allow the following write to succeed and thus enable interrupts.
        // we need something more deterministic.
        AJ_Sleep(1000);
        spi_API16 = 0x00FF;
        spi_API = CPU_TO_LE16(spi_API);
        AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_CPU_INT_STATUS, FALSE, 1, (uint8_t*)&spi_API16);
    }



}