extern hal_result_t hal_spi_get(hal_spi_t id, uint8_t* rxframe, uint8_t* remainingrxframes)
{
    if(hal_false == hal_spi_hid_initted_is(id))
    {
        return(hal_res_NOK_generic);
    }

#if 0
    s_hal_spi_scheduling_suspend();
    if(hal_false == s_hal_spi_is_status_locked(id))
    {
        s_hal_spi_scheduling_restart();
        return(hal_res_NOK_generic);
    }
    s_hal_spi_status_setlock();
    and unlock etc ....
#endif

    if(NULL == rxframe)
    {
        return(hal_res_NOK_nullpointer);
    }

    return(s_hal_spi_get(id, rxframe, remainingrxframes));
}
Exemplo n.º 2
0
extern hal_result_t hal_spi_on_framereceiv_set(hal_spi_t id, hal_callback_t onframereceiv, void* arg)
{
    hal_spi_internal_item_t* intitem = s_hal_spi_theinternals.items[HAL_spi_id2index(id)]; 
    
    if(hal_false == hal_spi_hid_initted_is(id))
    {
        return(hal_res_NOK_generic);
    }
    
    intitem->config.onframereceiv       = onframereceiv;
    intitem->config.argonframereceiv    = arg;
    
    return(hal_res_OK);    
}
Exemplo n.º 3
0
extern hal_result_t hal_spi_stop(hal_spi_t id)
{
    if(hal_false == hal_spi_hid_initted_is(id))
    {
        return(hal_res_NOK_generic);
    }


    // empty ...
    #warning --> it must be called only if the spi has already stopped inside the isr
    
    //s_hal_spi_periph_dma_disable(id);
           
    return(hal_res_OK);    
}
Exemplo n.º 4
0
extern hal_result_t hal_spi_get(hal_spi_t id, uint8_t* rxframe, uint8_t* remainingrxframes)
{
    if(hal_false == hal_spi_hid_initted_is(id))
    {
        return(hal_res_NOK_generic);
    }

       
    if(NULL == rxframe)
    {
        return(hal_res_NOK_nullpointer);
    }
    
    return(s_hal_spi_get(id, rxframe, remainingrxframes));       
}
Exemplo n.º 5
0
extern hal_result_t hal_spi_put(hal_spi_t id, uint8_t* txframe)
{ 
    if(hal_false == hal_spi_hid_initted_is(id))
    {
        return(hal_res_NOK_generic);
    }
       
    if(NULL == txframe)
    {
        return(hal_res_NOK_nullpointer);
    }
    
    return(hal_res_NOK_generic);
    //return(s_hal_spi_put(id, txframe));
}
extern hal_result_t hal_spi_raw_master_writeread(hal_spi_t id, uint8_t byte, uint8_t* readbyte)
{
    hal_spi_internal_item_t* intitem = s_hal_spi_theinternals.items[HAL_spi_id2index(id)];
    hal_spi_cfg_t* cfg = NULL;
    volatile uint32_t timeout = 0;
    SPI_TypeDef* SPIx = HAL_spi_id2stmSPI(id);


    if(hal_false == hal_spi_hid_initted_is(id))
    {
        return(hal_res_NOK_generic);
    }

    cfg = &intitem->config;

    if(hal_spi_act_raw != cfg->activity)
    {
        return(hal_res_NOK_generic);
    }

    // before we write we need to wait for the spi has txe set
    timeout = s_hal_spi_timeout_flag;
    while(RESET == SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE))
    {
        if(0 == (timeout--)) s_hal_spi_timeoutexpired();
    }

    // ok. we send the byte
    SPI_I2S_SendData(SPIx, byte);

    // we need to wait for a reply from the slave
    timeout = s_hal_spi_timeout_flag;
    while(RESET == SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE))
    {
        if(0 == (timeout--)) s_hal_spi_timeoutexpired();
    }

    // ok. here it is
    uint8_t rb = SPI_I2S_ReceiveData(SPIx);

    // if we want to retrieve it we copy into return value
    if(NULL != readbyte)
    {
        *readbyte = rb;
    }

    return(hal_res_OK);
}
Exemplo n.º 7
0
extern hal_result_t hal_spi_start(hal_spi_t id, uint8_t lengthofburst)
{
    hal_spi_internal_item_t* intitem = s_hal_spi_theinternals.items[HAL_spi_id2index(id)];
    SPI_TypeDef* SPIx = HAL_spi_id2stmSPI(id);
    uint8_t num2use = 1;
    
    if(hal_false == hal_spi_hid_initted_is(id))
    {
        return(hal_res_NOK_generic);
    }  

#if 0    
    if(hal_spi_act_framebased != intitem->config.activity)
    {
        return(hal_res_NOK_generic);
    }    
#endif
      

    // protect ... may be not needed
    s_hal_spi_rx_isr_disable(id);       //hal_SPI4ENCODER_IT_RX_DISA(SPIx);
    
    // tells how many frames to use
    intitem->frameburstcountdown = num2use;
    
    // reset isrrxframe and its counter  
    memset(intitem->isrrxframe, 0, intitem->config.sizeofframe);
    intitem->isrrxcounter = 0;
    
    s_hal_spi_rx_isr_enable(id);    // hal_SPI4ENCODER_IT_RX_ENA(SPIx);    // enable interrupt rx

    s_hal_spi_periph_enable(id);      // hal_SPI4ENCODER_ENA(SPIx);	        // enable spi peripheral
    
	// in order to read data I have to write a dummy byte. the channel is configured in full duplex mode.
	while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
	
	SPI_I2S_SendData(SPIx, intitem->config.dummytxvalue);    
    
    // ok, the isr shall read n frames of m bytes each and then issue a callback to me.
    // n = intitem->frameburstcountdown (=1 for encoder), and m = intitem->config.sizeofframe (=3 for encoder)
    
    return(hal_res_OK);    
}
extern hal_result_t hal_spi_stop(hal_spi_t id)
{
    if(hal_false == hal_spi_hid_initted_is(id))
    {
        return(hal_res_NOK_generic);
    }

#if 0
    s_hal_spi_scheduling_suspend();
    if(hal_false == s_hal_spi_is_status_locked(id))
    {
        s_hal_spi_scheduling_restart();
        return(hal_res_NOK_generic);
    }
    s_hal_spi_status_setlock();
    and unlock etc ....
#endif


    s_hal_spi_periph_dma_disable(id);

    return(hal_res_OK);
}
static hal_result_t s_hal_spi_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_spi_cfg_t *usedcfg = NULL;
    uint8_t* tmpbuffer = NULL;

    if(NULL == cfg)
    {
        cfg = &hal_spi_cfg_default;
    }


    if(hal_true != s_hal_spi_supported_is(id))
    {
        return(hal_res_NOK_unsupported);
    }

    if(hal_true == hal_spi_hid_initted_is(id))
    {
        return(hal_res_OK);
    }

    // mild verification of the config: speed, activity, sizeofframe only

    if(hal_false == s_hal_spi_is_speed_correct((int32_t)cfg->speed))
    {
        return(hal_res_NOK_generic);
    }


    if(hal_spi_act_raw == cfg->activity)
    {
        // verify only ownership: it can be only master
        if(hal_spi_ownership_master != cfg->ownership)
        {
            return(hal_res_NOK_generic);
        }
    }
    else if(hal_spi_act_framebased == cfg->activity)
    {
        // verify only size of frame
        if(0 == cfg->sizeofframe)
        {
            return(hal_res_NOK_generic);
        }
    }


    // acemor: very important info.
    // init the miso and mosi gpio before calling hw_init.
    // because if the spi is already initted and it detects mosi or miso low it sets
    // register SPI_SR2.BUSY to 1, which makes things hang up.

    s_hal_spi_hw_gpio_init(id, cfg->ownership);
    s_hal_spi_hw_init(id);
    s_hal_spi_hw_enable(id, cfg);


    // --------------------------------------------------------------------------------------
    // init the spi internals data structure

    // if it does not have ram yet, then attempt to allocate it.
    if(NULL == intitem)
    {
        intitem = s_hal_spi_theinternals.items[HAL_spi_id2index(id)] = hal_heap_new(sizeof(hal_spi_internal_item_t));
        // minimal initialisation of the internal item
        // nothing to init.
    }

    // - the config
    usedcfg = &intitem->config;
    memcpy(usedcfg, cfg, sizeof(hal_spi_cfg_t));

    if(hal_spi_act_raw == usedcfg->activity)
    {
        // the rest is not used ... however i initialise it anyway ...
        intitem->dummytxframe           = NULL;
        intitem->dmatxframe             = NULL;
        intitem->dmarxframe             = NULL;
        intitem->dmatxframe             = NULL;
        hal_utility_fifo_init(&intitem->fifotx, 0, 0, NULL, NULL);
        hal_utility_fifo_init(&intitem->fiforx, 0, 0, NULL, NULL);
        intitem->id                   = id;
        intitem->frameburstcountdown    = 0;
        intitem->forcestop              = 0;
        intitem->dmaisenabled           = hal_false;
    }
    else if(hal_spi_act_framebased == usedcfg->activity)
    {

        // - the dummy tx frame
        intitem->dummytxframe = (uint8_t*)hal_heap_new(usedcfg->sizeofframe);
#if     defined(HAL_MPU_SPI_DEBUG_MODE )
        uint8_t i;
        for(i=0; i<usedcfg->sizeofframe; i++) {
            intitem->dummytxframe[i] = usedcfg->dummytxvalue + i;
        }
#else
        memset(intitem->dummytxframe, usedcfg->dummytxvalue, usedcfg->sizeofframe);
#endif

        // - the dma tx frame
        intitem->dmatxframe = (uint8_t*)hal_heap_new(usedcfg->sizeofframe);
        memcpy(intitem->dmatxframe, intitem->dummytxframe, usedcfg->sizeofframe);

        // - the dma rx frame
        intitem->dmarxframe = (uint8_t*)hal_heap_new(usedcfg->sizeofframe);


        // - the fifo of tx frames. but only if it needed ... we dont need it if ...
        if((0 == usedcfg->capacityoftxfifoofframes) || (hal_spi_dir_rxonly == usedcfg->direction))
        {
            usedcfg->capacityoftxfifoofframes = 0;
            hal_utility_fifo_init(&intitem->fifotx, 0, 0, NULL, NULL);
        }
        else
        {
            tmpbuffer = (uint8_t*)hal_heap_new(usedcfg->capacityoftxfifoofframes*usedcfg->sizeofframe);
            hal_utility_fifo_init(&intitem->fifotx, usedcfg->capacityoftxfifoofframes, usedcfg->sizeofframe, tmpbuffer, NULL);
        }

        // - the fifo of rx frames. but only if it needed ... we dont need it if ...
        if((0 == usedcfg->capacityofrxfifoofframes) || (hal_spi_dir_txonly == usedcfg->direction))
        {
            usedcfg->capacityofrxfifoofframes = 0;
            hal_utility_fifo_init(&intitem->fiforx, 0, 0, NULL, NULL);
        }
        else
        {
            tmpbuffer = (uint8_t*) hal_heap_new(usedcfg->capacityofrxfifoofframes*usedcfg->sizeofframe);
            hal_utility_fifo_init(&intitem->fiforx, usedcfg->capacityofrxfifoofframes, usedcfg->sizeofframe, tmpbuffer, NULL);
        }

        // - the id
        intitem->id = id;

        // - frameburstcountdown
        intitem->frameburstcountdown = 0;

        // - forcestop
        intitem->forcestop = 0;

        // -- locked
        intitem->dmaisenabled = hal_false;

    }


    // now ... init the dma (only for frame-based activity)

    if(hal_spi_act_framebased == usedcfg->activity)
    {
        s_hal_spi_dma_init(id, usedcfg);
    }


    // ok, it is initted
    s_hal_spi_initted_set(id);

    return(hal_res_OK);
}
extern hal_result_t hal_spi_start(hal_spi_t id, uint8_t lengthofburst)
{
    hal_spi_internal_item_t* intitem = s_hal_spi_theinternals.items[HAL_spi_id2index(id)];

    if(hal_false == hal_spi_hid_initted_is(id))
    {
        return(hal_res_NOK_generic);
    }

#if 0
    s_hal_spi_scheduling_suspend();
    if(hal_false == s_hal_spi_is_status_locked(id))
    {
        s_hal_spi_scheduling_restart();
        return(hal_res_NOK_generic);
    }
    s_hal_spi_status_setlock();
    and unlock etc ....
#endif


    if(hal_spi_act_framebased != intitem->config.activity)
    {
        return(hal_res_NOK_generic);
    }

    uint8_t num2use = 0;

    if(hal_spi_ownership_slave == intitem->config.ownership)
    {   // slave ...
        num2use = 255;
    }
    else if((hal_spi_ownership_master == intitem->config.ownership) && (0 == lengthofburst))
    {   // master ... only the size of the tx buffer
        num2use = hal_utility_fifo_size(&intitem->fifotx);
        if(0 == num2use)
        {
            return(hal_res_NOK_generic);
        }
    }
    else
    {
        num2use = lengthofburst;
    }


    // protect
    s_hal_spi_periph_dma_disable(id);

    // tells how many frames to use
    intitem->frameburstcountdown = num2use;

    // load tx frame into dma
    if(hal_spi_dir_rxonly != intitem->config.direction)
    {
        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);
        }
    }

    s_hal_spi_periph_dma_enable(id);

    return(hal_res_OK);
}
Exemplo n.º 11
0
static hal_result_t s_hal_spi_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_spi_cfg_t *usedcfg = NULL;
    uint8_t* tmpbuffer = NULL;
    
    if(NULL == cfg)
    {
        cfg = &hal_spi_cfg_default;
    }
       
    if(hal_true != s_hal_spi_supported_is(id))
    {
        return(hal_res_NOK_unsupported);
    }

    if(hal_true == hal_spi_hid_initted_is(id))
    {
        return(hal_res_OK);
    }   

    // mild verification of the config: speed, activity, sizeofframe only
    
    if(hal_false == s_hal_spi_is_speed_correct((int32_t)cfg->speed))
    {
        return(hal_res_NOK_generic);
    }
 

    if(hal_spi_ownership_master != cfg->ownership)
    {
        return(hal_res_NOK_generic);
    }
        
    if(hal_spi_act_framebased != cfg->activity)
    {
        return(hal_res_NOK_generic);
    }

    if(0 == cfg->sizeofframe)
    {
        return(hal_res_NOK_generic);
    }    

    if(hal_spi_dir_rxonly != cfg->direction)  
    {
        return(hal_res_NOK_generic);
    }   

    if(0 == cfg->capacityofrxfifoofframes)
    {
        return(hal_res_NOK_generic);
    }    

    // acemor: very important info.
    // init the miso and mosi gpio before calling hw_init. 
    // because if the spi is already initted and it detects mosi or miso low it sets
    // register SPI_SR2.BUSY to 1, which makes things hang up.
    
    //s_hal_spi_hw_gpio_init(id, cfg->ownership);
    //s_hal_spi_hw_init(id);
    //s_hal_spi_hw_enable(id, cfg);
    // on ems001 and ems4rd it works with SPI_CPOL_High
    const hl_spi_advcfg_t hl_spi_advcfg_ems4rd =
    {   
        .SPI_Direction          = SPI_Direction_2Lines_FullDuplex,
        .SPI_Mode               = SPI_Mode_Master,                              // param
        .SPI_DataSize           = SPI_DataSize_8b, 
        .SPI_CPOL               = SPI_CPOL_High, //SPI_CPOL_High, //SPI_CPOL_Low, //SPI_CPOL_Low, // SPI_CPOL_High high is ok with display and also ok with isr mode
        .SPI_CPHA               = SPI_CPHA_1Edge, //SPI_CPHA_2Edge,
        .SPI_NSS                = SPI_NSS_Soft,
        .SPI_BaudRatePrescaler  = SPI_BaudRatePrescaler_64, // param: depends on speed. with 64 it it is 42/64 = 0.65625 mhz (or 1.3125 w/ 32)
        .SPI_FirstBit           = SPI_FirstBit_MSB, // SPI_FirstBit_MSB is ok with display, su stm3210c e' indifferente
        .SPI_CRCPolynomial      = 0x0007 // reset value
    };
    
    hl_spi_cfg_t hlcfg =
    {
        .mode       = hl_spi_mode_master,
        .prescaler  = hl_spi_prescaler_064, 
        .advcfg     = &hl_spi_advcfg_ems4rd                
    };
    hlcfg.mode = (hal_spi_ownership_master == cfg->ownership) ? (hl_spi_mode_master) : (hl_spi_mode_slave); 
    hlcfg.prescaler = s_hal_spi_get_hl_prescaler(id, cfg);;

    // we must initialise hl_spi_map w/ suited values. 
    // we have built hal_brdcfg_spi__theconfig to have the same layout, but we verify it anyway
    hl_VERIFYproposition(xxx, sizeof(hl_spi_mapping_t) == sizeof(hal_spi_hid_brdcfg_t));
    hl_spi_map = (hl_spi_mapping_t*)&hal_brdcfg_spi__theconfig;
    
    
    hl_spi_init((hl_spi_t)id, &hlcfg);      // the gpio, the clock
    hl_spi_enable((hl_spi_t)id);            // the SPI_Init(), but not the DMA ...

    #warning --> see in hal1 if there is anything about isr of spi 
    
    // --------------------------------------------------------------------------------------
    // init the spi internals data structure
    
    // if it does not have ram yet, then attempt to allocate it.
    if(NULL == intitem)
    {
        intitem = s_hal_spi_theinternals.items[HAL_spi_id2index(id)] = hal_heap_new(sizeof(hal_spi_internal_item_t));
        // minimal initialisation of the internal item
        // nothing to init.      
    }      
    
    // - the config   
    memcpy(&intitem->config, cfg, sizeof(hal_spi_cfg_t));
    hal_spi_cfg_t *usedcfg = NULL;
    usedcfg = &intitem->config;    
    

    // only frame-based
    
    // - the isr rx frame  
    intitem->isrrxframe = (uint8_t*)hal_heap_new(usedcfg->sizeofframe);    
    intitem->isrrxcounter = 0;
 
    // - the fifo of rx frames. but only if it is needed ... we dont need it if ...
    tmpbuffer = (uint8_t*) hal_heap_new(usedcfg->capacityofrxfifoofframes*usedcfg->sizeofframe);
    hal_utility_fifo_init(&intitem->fiforx, usedcfg->capacityofrxfifoofframes, usedcfg->sizeofframe, tmpbuffer, NULL);

 
    // - the id
    intitem->id = id;

    // - frameburstcountdown
    intitem->frameburstcountdown = 0;

   
    // -- locked
    intitem->isrisenabled = hal_false;

        
    // now ... init the isr (only for frame-based activity)
    s_hal_spi_isr_init(id, usedcfg);

    
           
    // ok, it is initted
    s_hal_spi_initted_set(id);
         
    return(hal_res_OK);
}

static hal_bool_t s_hal_spi_is_speed_correct(int32_t speed)
{
    if(hal_spi_speed_dontuse == speed)
    {
        return(hal_true);
    }
    else
    {
        return(hal_false);
    }   
}




static hl_spi_prescaler_t s_hal_spi_get_hl_prescaler(hal_spi_t id, const hal_spi_cfg_t* cfg)
{
    hl_spi_prescaler_t hlprescaler = hl_spi_prescaler_064;
    
    return(hlprescaler);
    
//     if((hal_spi_speed_dontuse == cfg->speed) && (hal_spi_prescaler_dontuse == cfg->prescaler))
//     {
//          hal_base_on_fatalerror(hal_fatalerror_incorrectparameter, "hal_spi_init(): use one of speed or prescaler");
//     }
//     if((hal_spi_speed_dontuse != cfg->speed) && (hal_spi_prescaler_dontuse != cfg->prescaler))
//     {
//          hal_base_on_fatalerror(hal_fatalerror_incorrectparameter, "hal_spi_init(): use either speed or prescaler, not both");
//     }
//     
//     if(hal_spi_prescaler_dontuse != cfg->prescaler)
//     {   // ok, we have the prescaler. need only to convert it in stm32fx format
//         
//         switch(cfg->prescaler)
//         {   // remember that hal_spi_prescaler_xxx is referred to high speed bus, 
//             // and prescaler_stm32fx to high speed bus for spi1 but to low speed for spi2 and spi3
//             case hal_spi_prescaler_004: 
//             { 
//                 hlprescaler = hl_spi_prescaler_004;    
//             } break;
//             case hal_spi_prescaler_008: 
//             {
//                 hlprescaler = hl_spi_prescaler_008;
//             } break;
//             case hal_spi_prescaler_016: 
//             {
//                 hlprescaler = hl_spi_prescaler_016;  
//             } break;
//             case hal_spi_prescaler_032: 
//             { 
//                 hlprescaler = hl_spi_prescaler_032;   
//             } break;
//             case hal_spi_prescaler_064: 
//             {
//                 hlprescaler = hl_spi_prescaler_064;   
//             } break;
//             case hal_spi_prescaler_128: 
//             {
//                 hlprescaler = hl_spi_prescaler_128;  
//             } break;
//             case hal_spi_prescaler_256: 
//             {
//                hlprescaler = hl_spi_prescaler_256;  
//             } break;
//             default:                    
//             {
//                 hlprescaler = hl_spi_prescaler_256; 
//             } break;
//         }        
//     }    
//     else if(hal_spi_speed_dontuse != cfg->speed)
//     {   // ok, use the speed to compute the prescaler in stm32fx format
//         
//         // remember that hal_spi_prescaler_xxx is referred to high speed bus, 
//         // and prescaler_stm32fx to high speed bus for spi1 but to low speed for spi2 and spi3
//         uint16_t factor = (hal_spi1 == id) ? (hal_brdcfg_cpu__theconfig.speeds.fastbus / cfg->speed) : (hal_brdcfg_cpu__theconfig.speeds.slowbus / cfg->speed);
//         
//         switch(factor)
//         {
//             case 2:     hlprescaler = hl_spi_prescaler_002;  break;  
//             case 4:     hlprescaler = hl_spi_prescaler_004;  break;
//             case 8:     hlprescaler = hl_spi_prescaler_008;  break;
//             case 16:    hlprescaler = hl_spi_prescaler_016;  break;
//             case 32:    hlprescaler = hl_spi_prescaler_032;  break;
//             case 64:    hlprescaler = hl_spi_prescaler_064;  break;
//             case 128:   hlprescaler = hl_spi_prescaler_128;  break;
//             case 256:   hlprescaler = hl_spi_prescaler_256;  break;
//             default:    hlprescaler = hl_spi_prescaler_256;  break;
//         }        
//     } 


//     return(hlprescaler);    
}