Exemplo n.º 1
0
/*==============================================================================
 *
 */
void handle_tx_okay_irq(void)
{
    switch(g_comblk_state)
    {
        /*----------------------------------------------------------------------
         * The TX_OKAY interrupt should only be enabled for states COMBLK_TX_CMD
         * and COMBLK_TX_DATA. 
         */
        case COMBLK_TX_CMD:
            if(g_comblk_cmd_size > 0)
            {
                uint32_t size_sent;
                size_sent = fill_tx_fifo(g_comblk_p_cmd, g_comblk_cmd_size);
                if(size_sent < g_comblk_cmd_size)
                {
                    g_comblk_cmd_size = g_comblk_cmd_size - size_sent;
                    g_comblk_p_cmd = &g_comblk_p_cmd[size_sent];
                }
                else
                {
                    g_comblk_cmd_size = 0;
                    if(g_comblk_data_size > 0)
                    {
                        g_comblk_state = COMBLK_TX_DATA;
                    }
                    else
                    {
                        g_comblk_state = COMBLK_WAIT_RESPONSE;
                    }
                }
            }
            else
            {
                /*
                 * This is an invalid situation indicating a bug in the driver
                 * or corrupted memory.
                 */
                ASSERT(0);
                abort_current_cmd();
            }
            break;
            
        case COMBLK_TX_DATA:
            if(g_comblk_data_size > 0)
            {
                uint32_t size_sent;
                size_sent = fill_tx_fifo(g_comblk_p_data, g_comblk_data_size);
                if(size_sent < g_comblk_data_size)
                {
                    g_comblk_data_size = g_comblk_data_size - size_sent;
                    g_comblk_p_data = &g_comblk_p_data[size_sent];
                }
                else
                {
                    COMBLK->INT_ENABLE &= ~TXTOKAY_MASK;
                    g_comblk_state = COMBLK_WAIT_RESPONSE;
                }
            }
            else
            {
                /*
                 * This is an invalid situation indicating a bug in the driver
                 * or corrupted memory.
                 */
                ASSERT(0);
                abort_current_cmd();
            }
            break;
            
        /*----------------------------------------------------------------------
         * The TX_OKAY interrupt should NOT be enabled for states COMBLK_IDLE,
         * COMBLK_WAIT_RESPONSE and COMBLK_RX_RESPONSE.
         */
        case COMBLK_IDLE:
            /* Fall through */
        case COMBLK_WAIT_RESPONSE:
            /* Fall through */
        case COMBLK_RX_RESPONSE:
            /* Fall through */
        default:
            COMBLK->INT_ENABLE &= ~TXTOKAY_MASK;
            g_comblk_state = COMBLK_IDLE;
            break;
    }
}
Exemplo n.º 2
0
/*==============================================================================
 *
 */
void MSS_COMBLK_send_cmd
(
    const uint8_t * p_cmd,
    uint16_t cmd_size,
    const uint8_t * p_data,
    uint32_t data_size,
    uint8_t * p_response,
    uint16_t response_size,
    comblk_completion_handler_t completion_handler
)
{
    uint16_t size_sent;
    
    ASSERT(cmd_size > 0);
    
    /*
     * Disable and clear previous interrupts.
     */
    NVIC_DisableIRQ(ComBlk_IRQn);
    COMBLK->INT_ENABLE = 0;
    NVIC_ClearPendingIRQ(ComBlk_IRQn);
    
    /*
     * Abort current command if any.
     */
    abort_current_cmd();
    
    /*
     * Initialialize COMBLK driver state variables:
     */
    g_request_in_progress = 1;
    g_comblk_cmd_opcode = p_cmd[0];
    g_comblk_p_cmd = p_cmd;
    g_comblk_cmd_size = cmd_size;
    g_comblk_p_data = p_data;
    g_comblk_data_size = data_size;
    g_comblk_p_response = p_response;
    g_comblk_response_size = response_size;
    g_comblk_response_idx = 0;
    g_comblk_completion_handler = completion_handler;
    
    /*
     * Fill FIFO with command.
     */
    send_cmd_opcode(g_comblk_cmd_opcode);
    size_sent = fill_tx_fifo(p_cmd, cmd_size - 1);
    ++size_sent;
    if(size_sent < cmd_size)
    {
        g_comblk_cmd_size = g_comblk_cmd_size - size_sent;
        g_comblk_p_cmd = &g_comblk_p_cmd[size_sent];
        
        g_comblk_state = COMBLK_TX_CMD;
    }
    else
    {
        g_comblk_cmd_size = 0;
        if(g_comblk_data_size > 0)
        {
            g_comblk_state = COMBLK_TX_DATA;
        }
        else
        {
            g_comblk_state = COMBLK_WAIT_RESPONSE;
        }
    }
    
    /*
     * Enable interrupt.
     */
    COMBLK->INT_ENABLE |= (TXTOKAY_MASK | RCVOKAY_MASK);
    NVIC_EnableIRQ(ComBlk_IRQn);
}
Exemplo n.º 3
0
/*==============================================================================
 *
 */
static void handle_tx_okay_irq(void)
{
    switch(g_comblk_state)
    {
    /*----------------------------------------------------------------------
     * The TX_OKAY interrupt should only be enabled for states COMBLK_TX_CMD
     * and COMBLK_TX_DATA.
     */
    case COMBLK_TX_CMD:
        if(g_comblk_cmd_size > 0u)
        {
            uint32_t size_sent;
            size_sent = fill_tx_fifo(g_comblk_p_cmd, g_comblk_cmd_size);
            if(size_sent < g_comblk_cmd_size)
            {
                g_comblk_cmd_size = g_comblk_cmd_size - (uint16_t)size_sent;
                g_comblk_p_cmd = &g_comblk_p_cmd[size_sent];
            }
            else
            {
                g_comblk_cmd_size = 0u;
                if(g_comblk_data_size > 0u)
                {
                    g_comblk_state = COMBLK_TX_DATA;
                }
                else
                {
                    g_comblk_state = COMBLK_WAIT_RESPONSE;
                }
            }
        }
        else
        {
            /*
             * This is an invalid situation indicating a bug in the driver
             * or corrupted memory.
             */
            ASSERT(0);
            abort_current_cmd();
        }
        break;

    case COMBLK_TX_DATA:
        if(g_comblk_data_size > 0u)
        {
            uint32_t size_sent;
            size_sent = fill_tx_fifo(g_comblk_p_data, g_comblk_data_size);
            if(size_sent < g_comblk_data_size)
            {
                g_comblk_data_size = g_comblk_data_size - size_sent;
                g_comblk_p_data = &g_comblk_p_data[size_sent];
            }
            else
            {
                COMBLK->INT_ENABLE &= ~TXTOKAY_MASK;
                g_comblk_state = COMBLK_WAIT_RESPONSE;
            }
        }
        else
        {
            /*
             * This is an invalid situation indicating a bug in the driver
             * or corrupted memory.
             */
            ASSERT(0);
            abort_current_cmd();
        }
        break;

    case COMBLK_TX_PAGED_DATA:
        /*
         * Read a page of data if required.
         */
        if(0u == g_comblk_data_size)
        {
            if(g_comblk_page_handler != 0)
            {
                g_comblk_data_size = g_comblk_page_handler(&g_comblk_p_data);
                if(0u == g_comblk_data_size)
                {
                    COMBLK->INT_ENABLE &= ~TXTOKAY_MASK;
                    g_comblk_state = COMBLK_WAIT_RESPONSE;
                }
            }
            else
            {
                ASSERT(0);
                abort_current_cmd();
            }
        }

        /*
         * Transmit the page data or move to COMBLK_WAIT_RESPONSE state if
         * no further page data could be obtained by the call to the page
         * handler above.
         */
        if(0u == g_comblk_data_size)
        {
            COMBLK->INT_ENABLE &= ~TXTOKAY_MASK;
            g_comblk_state = COMBLK_WAIT_RESPONSE;
        }
        else
        {
            uint32_t size_sent;
            size_sent = fill_tx_fifo(g_comblk_p_data, g_comblk_data_size);
            g_comblk_data_size = g_comblk_data_size - size_sent;
            g_comblk_p_data = &g_comblk_p_data[size_sent];
        }
        break;

    /*----------------------------------------------------------------------
     * The TX_OKAY interrupt should NOT be enabled for states COMBLK_IDLE,
     * COMBLK_WAIT_RESPONSE and COMBLK_RX_RESPONSE.
     */
    case COMBLK_IDLE:
    /* Fall through */
    case COMBLK_WAIT_RESPONSE:
    /* Fall through */
    case COMBLK_RX_RESPONSE:
    /* Fall through */
    default:
        COMBLK->INT_ENABLE &= ~TXTOKAY_MASK;
        complete_request(0u);
        g_comblk_state = COMBLK_IDLE;
        break;
    }
}
Exemplo n.º 4
0
/*==============================================================================
 *
 */
void MSS_COMBLK_send_cmd_with_ptr
(
    uint8_t cmd_opcode,
    uint32_t cmd_params_ptr,
    uint8_t * p_response,
    uint16_t response_size,
    comblk_completion_handler_t completion_handler
)
{
    uint32_t tx_okay;
    
    /*--------------------------------------------------------------------------
     * Disable and clear previous interrupts.
     */
    NVIC_DisableIRQ(ComBlk_IRQn);
    COMBLK->INT_ENABLE = 0;
    NVIC_ClearPendingIRQ(ComBlk_IRQn);
    
    /*--------------------------------------------------------------------------
     * Abort current command if any.
     */
    abort_current_cmd();
    
    /*--------------------------------------------------------------------------
     * Initialialize COMBLK driver state variables:
     */
    g_request_in_progress = 1;
    g_comblk_cmd_opcode = cmd_opcode;
    g_comblk_p_cmd = 0;
    g_comblk_cmd_size = 0;
    g_comblk_p_data = 0;
    g_comblk_data_size = 0;
    g_comblk_p_response = p_response;
    g_comblk_response_size = response_size;
    g_comblk_response_idx = 0;
    g_comblk_completion_handler = completion_handler;
    
    /*--------------------------------------------------------------------------
     * Send command opcode as a single byte write to the Tx FIFO.
     */
    send_cmd_opcode(g_comblk_cmd_opcode);
    
    /*--------------------------------------------------------------------------
     * Send the command parameters pointer to the Tx FIFO as a single 4 bytes
     * write to the Tx FIFO.
     */
    COMBLK->CONTROL |= CR_SIZETX_MASK;
    
    /* Wait for space to become available in Tx FIFO. */
    do {
        tx_okay = COMBLK->STATUS & TXTOKAY_MASK;
    } while(!tx_okay);
    
    /* Send command opcode. */
    COMBLK->DATA32 = cmd_params_ptr;
    
    COMBLK->CONTROL &= ~CR_SIZETX_MASK;
    
    g_comblk_state = COMBLK_WAIT_RESPONSE;
    
    /*--------------------------------------------------------------------------
     * Enable interrupt.
     */
    COMBLK->INT_ENABLE |= RCVOKAY_MASK;
    NVIC_EnableIRQ(ComBlk_IRQn);
}
Exemplo n.º 5
0
/*==============================================================================
 *
 */
void MSS_COMBLK_send_paged_cmd
(
    const uint8_t * p_cmd,
    uint16_t cmd_size,
    uint8_t * p_response,
    uint16_t response_size,
    uint32_t (*page_read_handler)(uint8_t const **),
    void (*completion_handler)(uint8_t *, uint16_t)
)
{
    uint32_t size_sent;
    uint8_t irq_enable = 0u;

    ASSERT(cmd_size > 0u);

    /*
     * Disable and clear previous interrupts.
     */
    NVIC_DisableIRQ(ComBlk_IRQn);
    COMBLK->INT_ENABLE = 0u;
    NVIC_ClearPendingIRQ(ComBlk_IRQn);

    /*
     * Abort current command if any.
     */
    abort_current_cmd();

    /*
     * Initialialize COMBLK driver state variables:
     */
    g_request_in_progress = 1u;
    g_comblk_cmd_opcode = p_cmd[0];
    g_comblk_p_cmd = p_cmd;
    g_comblk_cmd_size = cmd_size;
    g_comblk_p_data = 0;
    g_comblk_data_size = 0u;
    g_comblk_p_response = p_response;
    g_comblk_response_size = response_size;
    g_comblk_response_idx = 0u;
    g_comblk_page_handler = page_read_handler;
    g_comblk_completion_handler = completion_handler;

    /*
     * Fill FIFO with command.
     */
    send_cmd_opcode(g_comblk_cmd_opcode);
    size_sent = fill_tx_fifo(&p_cmd[1], cmd_size - 1u);
    ++size_sent;    /* Adjust for opcode byte sent. */
    if(size_sent < cmd_size)
    {
        g_comblk_cmd_size = g_comblk_cmd_size - (uint16_t)size_sent;
        g_comblk_p_cmd = &g_comblk_p_cmd[size_sent];

        g_comblk_state = COMBLK_TX_CMD;
        irq_enable = TXTOKAY_MASK | RCVOKAY_MASK;
    }
    else
    {
        g_comblk_cmd_size = 0u;
        g_comblk_state = COMBLK_TX_PAGED_DATA;
        irq_enable = TXTOKAY_MASK | RCVOKAY_MASK;
    }

    /*
     * Enable interrupt.
     */
    COMBLK->INT_ENABLE |= irq_enable;
    NVIC_EnableIRQ(ComBlk_IRQn);
}