Ejemplo n.º 1
0
static void s_hal_spi_read_isr(hal_spi_t id)
{
    hal_spi_internal_item_t* intitem = s_hal_spi_theinternals.items[HAL_spi_id2index(id)]; 
    SPI_TypeDef* SPIx = HAL_spi_id2stmSPI(id);
     
    uint8_t rxbyte = SPI_I2S_ReceiveData(SPIx);
     
    if(intitem->isrrxcounter < intitem->config.sizeofframe)
    {
        intitem->isrrxframe[intitem->isrrxcounter] = rxbyte;
        intitem->isrrxcounter ++;
    }
     
    if(intitem->isrrxcounter == intitem->config.sizeofframe)
    {   // ok. the frame is finished
    
        // 1. stop spi 
        s_hal_spi_periph_disable(id);         // disable periph                                        	     
		s_hal_spi_rx_isr_disable(id); //hal_SPI4ENCODER_IT_RX_DISA(port);   // disable interrupt rx
        
        // set back to zero the frame burst
        intitem->frameburstcountdown = 0;
        // set rx counter to zero again
        intitem->isrrxcounter = 0;
        
        // copy the rxframe into the rx fifo
        
        if(hal_true == hal_utility_fifo_full(&(intitem->fiforx)))
        {
            hal_utility_fifo_pop(&(intitem->fiforx));
        }
        hal_utility_fifo_put(&(intitem->fiforx), intitem->isrrxframe);         
        
        // now manage the callback
        hal_callback_t onframereceiv = intitem->config.onframereceiv;
        void *arg = intitem->config.argonframereceiv;     
        if(NULL != onframereceiv)
        {
            onframereceiv(arg);
        }        
    }
    else
    {
        // transmit one dummy byte to trigger yet another reception
        SPI_I2S_SendData(SPIx, intitem->config.dummytxvalue);    
    }
 
}
static void s_hal_spi_dma_init(hal_spi_t id, const hal_spi_cfg_t *cfg)
{
    hal_spi_internal_item_t* intitem = s_hal_spi_theinternals.items[HAL_spi_id2index(id)];

    hal_dma_cfg_t s_hal_spi_dma_cfg =
    {
        .transfer               = hal_dma_transfer_mem2per,     // it changes
        .mode                   = hal_dma_mode_oneshot,         // fixed
        .intpriority            = hal_int_priority06,           // fixed
        .datasize               = cfg->sizeofframe,             // fixed
        .source                 = 0,                            // it changes
        .destin                 = 0,                            // it changes
        .cbk_on_transfer_done   = NULL,                         // it changes
        .arg_on_transfer_done   = NULL                          // it changes
    };


    s_hal_spi_dma_cfg.transfer                  = hal_dma_transfer_per2mem;
    s_hal_spi_dma_cfg.source                    = (void*)&s_hal_spi_stmSPImap[HAL_spi_id2index(id)]->DR;
    s_hal_spi_dma_cfg.destin                    = intitem->dmarxframe;
    s_hal_spi_dma_cfg.cbk_on_transfer_done      = s_hal_spi_dma_on_tranfer_done_rx;
    s_hal_spi_dma_cfg.arg_on_transfer_done      = intitem;
    hal_dma_init(s_hal_spi_dma_port2use_rx[HAL_spi_id2index(id)], &s_hal_spi_dma_cfg);

    // init dma for tx
    s_hal_spi_dma_cfg.transfer                  = hal_dma_transfer_mem2per;
//    s_hal_spi_dma_cfg.source                    = intitem->dmatxframe;
//    s_hal_spi_dma_cfg.destin                    = &s_hal_spi_stmSPImap[HAL_spi_id2index(id)]->DR;
    s_hal_spi_dma_cfg.source                    = (void*)&s_hal_spi_stmSPImap[HAL_spi_id2index(id)]->DR;
    s_hal_spi_dma_cfg.destin                    = intitem->dmatxframe;
    s_hal_spi_dma_cfg.cbk_on_transfer_done      = s_hal_spi_dma_on_tranfer_done_tx;
    s_hal_spi_dma_cfg.arg_on_transfer_done      = intitem;
    hal_dma_init(s_hal_spi_dma_port2use_tx[HAL_spi_id2index(id)], &s_hal_spi_dma_cfg);
}



static void s_hal_spi_dma_on_tranfer_done_rx(void* p)
{
    hal_spi_internal_item_t* intitem = (hal_spi_internal_item_t*)p;

    // 1. copy the rx frame into fifo

    if(hal_spi_dir_txonly != intitem->config.direction)
    {
        if(hal_true == hal_utility_fifo_full(&(intitem->fiforx)))
        {
            hal_utility_fifo_pop(&(intitem->fiforx));
        }
        hal_utility_fifo_put(&(intitem->fiforx), intitem->dmarxframe);
    }

    // 2. verify if we need to stop
    hal_bool_t stopit = hal_false;

    if(hal_spi_ownership_slave == intitem->config.ownership)
    {
        stopit = hal_false;
    }
    else if(hal_spi_ownership_master == intitem->config.ownership)
    {
        if(255 == intitem->frameburstcountdown)
        {
            stopit = hal_false;
        }
        else if(0 == intitem->frameburstcountdown)
        {
            stopit = hal_true;
        }
        else
        {
            intitem->frameburstcountdown --;

            if(0 == intitem->frameburstcountdown)
            {
                stopit = hal_true;
            }
            else
            {
                stopit = hal_false;
            }
        }
    }


    if(hal_true == stopit)
    {
        // stop
    }
    else
    {
        if(hal_spi_dir_rxonly != intitem->config.direction)
        {
            // copy into txbuffer a new frame
            if(hal_res_OK != hal_utility_fifo_get(&(intitem->fifotx), intitem->dmatxframe, NULL))
            {   // put the dummy one.
                memcpy(intitem->dmatxframe, intitem->dummytxframe, intitem->config.sizeofframe);
            }
        }

        // retrigger tx
        hal_dma_retrigger(s_hal_spi_dma_port2use_tx[HAL_spi_id2index(intitem->id)]);

        // retrigger rx
        hal_dma_retrigger(s_hal_spi_dma_port2use_rx[HAL_spi_id2index(intitem->id)]);
    }

    if(hal_spi_dir_txonly != intitem->config.direction)
    {
        // alert about a reception
        hal_callback_t onframereceiv = intitem->config.onframereceiv;
        if(NULL != onframereceiv)
        {
            onframereceiv(intitem->config.argonframereceiv);
        }
    }

}