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_hw_gpio_init(hal_spi_t id, hal_spi_ownership_t ownership)
{

#if     defined(HAL_USE_CPU_FAM_STM32F1)

    static const GPIO_InitTypeDef  s_hal_spi_sckmosi_master_altcfg  =
    {
        .GPIO_Pin       = 0,
        .GPIO_Speed     = GPIO_Speed_50MHz,
        .GPIO_Mode      = GPIO_Mode_AF_PP, // il PP serve per spi del display3 .... GPIO_Mode_AF_OD,
    };

    static const GPIO_InitTypeDef  s_hal_spi_miso_master_altcfg  =
    {
        .GPIO_Pin       = 0,
        .GPIO_Speed     = GPIO_Speed_50MHz,
        .GPIO_Mode      = GPIO_Mode_IN_FLOATING, //GPIO_Mode_IPD, // oppure ... GPIO_Mode_IN_FLOATING?
    };

    static const GPIO_InitTypeDef  s_hal_spi_sckmosi_slave_altcfg  =
    {
        .GPIO_Pin       = 0,
        .GPIO_Speed     = GPIO_Speed_50MHz,
        .GPIO_Mode      = GPIO_Mode_IN_FLOATING, //GPIO_Mode_IPD, // oppure ... GPIO_Mode_IN_FLOATING,
    };

    static const GPIO_InitTypeDef  s_hal_spi_miso_slave_altcfg  =
    {
        .GPIO_Pin       = 0,
        .GPIO_Speed     = GPIO_Speed_50MHz,
        .GPIO_Mode      = GPIO_Mode_AF_PP,
    };


    // 1. prepare af.
    // for spi1 (sck, miso, mosi): no-remap if it is (PA5, PA6, PA7). GPIO_Remap_SPI1 if it is (PB3, PB4, PB5).
    // for spi2 (sck, miso, mosi): no remap if it is (PB13, PB14, PB15).
    // for spi3 (sck, miso, mosi): no-remap if it is (PB3, PB4, PB5). GPIO_Remap_SPI3 if it is (PC10, PC11, PC12).
    uint32_t afname = HAL_GPIO_AFNAME_NONE;
    uint32_t afmode = HAL_GPIO_AFMODE_NONE;
    hal_bool_t found = hal_false;

    hal_gpio_port_t portsck  = hal_brdcfg_spi__theconfig.gpio_sck[HAL_spi_id2index(id)].gpio.port;
    hal_gpio_pin_t  pinsck   = hal_brdcfg_spi__theconfig.gpio_sck[HAL_spi_id2index(id)].gpio.pin;
    hal_gpio_port_t portmiso = hal_brdcfg_spi__theconfig.gpio_miso[HAL_spi_id2index(id)].gpio.port;
    hal_gpio_pin_t  pinmiso  = hal_brdcfg_spi__theconfig.gpio_miso[HAL_spi_id2index(id)].gpio.pin;
    hal_gpio_port_t portmosi = hal_brdcfg_spi__theconfig.gpio_mosi[HAL_spi_id2index(id)].gpio.port;
    hal_gpio_pin_t  pinmosi  = hal_brdcfg_spi__theconfig.gpio_mosi[HAL_spi_id2index(id)].gpio.pin;


    if(hal_spi1 == id)
    {
        if((hal_gpio_portA == portsck) && (hal_gpio_pin5 == pinsck) && (hal_gpio_portA == portmiso) && (hal_gpio_pin6 == pinmiso) && (hal_gpio_portA == portmosi) && (hal_gpio_pin7 == pinmosi))
        {   // PA5, PA6, PA7
            afname = HAL_GPIO_AFNAME_NONE;
            afmode = HAL_GPIO_AFMODE_NONE;
            found = hal_true;
        }
        else if((hal_gpio_portB == portsck) && (hal_gpio_pin3 == pinsck) && (hal_gpio_portB == portmiso) && (hal_gpio_pin4 == pinmiso) && (hal_gpio_portB == portmosi) && (hal_gpio_pin5 == pinmosi))
        {   // PB3, PB4, PB5
            afname = GPIO_Remap_SPI1;
            afmode = ENABLE;
            found = hal_true;
        }
    }
    else if(hal_spi2 == id)
    {
        if((hal_gpio_portB == portmiso) && (hal_gpio_portB == portmosi) && (hal_gpio_portB == portsck) && (hal_gpio_pin14 == pinmiso) && (hal_gpio_pin15 == pinmosi) && (hal_gpio_pin13 == pinsck))
        {   // PB13, PB14, PB15
            afname = HAL_GPIO_AFNAME_NONE;
            afmode = HAL_GPIO_AFMODE_NONE;
            found = hal_true;
        }
    }
    else if(hal_spi3 == id)
    {
        if((hal_gpio_portB == portsck) && (hal_gpio_pin3 == pinsck) && (hal_gpio_portB == portmiso) && (hal_gpio_pin4 == pinmiso) && (hal_gpio_portB == portmosi) && (hal_gpio_pin5 == pinmosi))
        {   // PB3, PB4, PB5
            afname = HAL_GPIO_AFNAME_NONE;
            afmode = HAL_GPIO_AFMODE_NONE;
            found = hal_true;
        }
        else if((hal_gpio_portC == portsck) && (hal_gpio_pin10 == pinsck) && (hal_gpio_portC == portmiso) && (hal_gpio_pin11 == pinmiso) && (hal_gpio_portC == portmosi) && (hal_gpio_pin12 == pinmosi))
        {   // PC10, PC11, PC12
            afname = GPIO_Remap_SPI3;
            afmode = ENABLE;
            found = hal_true;
        }
    }

    if(hal_false == found)
    {
        hal_base_on_fatalerror(hal_fatalerror_incorrectparameter, "hal_spi_init(): incorrect pin mapping");
    }

    hal_gpio_altcfg_t hal_spi_sck_altcfg;
    hal_gpio_altcfg_t hal_spi_miso_altcfg;
    hal_gpio_altcfg_t hal_spi_mosi_altcfg;
    hal_gpio_cfg_t config;

    // prepare the altcfg for sck, miso, mosi pins
    if(hal_spi_ownership_master == ownership)
    {
        memcpy(&hal_spi_sck_altcfg, &s_hal_spi_sckmosi_master_altcfg, sizeof(hal_gpio_altcfg_t));
        memcpy(&hal_spi_miso_altcfg, &s_hal_spi_miso_master_altcfg, sizeof(hal_gpio_altcfg_t));
        memcpy(&hal_spi_mosi_altcfg, &s_hal_spi_sckmosi_master_altcfg, sizeof(hal_gpio_altcfg_t));
    }
    else
    {
        memcpy(&hal_spi_sck_altcfg, &s_hal_spi_sckmosi_slave_altcfg, sizeof(hal_gpio_altcfg_t));
        memcpy(&hal_spi_miso_altcfg, &s_hal_spi_miso_slave_altcfg, sizeof(hal_gpio_altcfg_t));
        memcpy(&hal_spi_mosi_altcfg, &s_hal_spi_sckmosi_slave_altcfg, sizeof(hal_gpio_altcfg_t));
    }

    hal_spi_sck_altcfg.afname = hal_spi_miso_altcfg.afname = hal_spi_mosi_altcfg.afname = afname;
    hal_spi_sck_altcfg.afname = hal_spi_miso_altcfg.afmode = hal_spi_mosi_altcfg.afmode = afmode;

    // configure miso, mosi, sck pins
    memcpy(&config, &hal_brdcfg_spi__theconfig.gpio_sck[HAL_spi_id2index(id)].config, sizeof(hal_gpio_cfg_t));
    config.altcfg = &hal_spi_sck_altcfg;
    hal_gpio_init(hal_brdcfg_spi__theconfig.gpio_sck[HAL_spi_id2index(id)].gpio, &config);

    memcpy(&config, &hal_brdcfg_spi__theconfig.gpio_miso[HAL_spi_id2index(id)].config, sizeof(hal_gpio_cfg_t));
    config.altcfg = &hal_spi_miso_altcfg;
    hal_gpio_init(hal_brdcfg_spi__theconfig.gpio_miso[HAL_spi_id2index(id)].gpio, &config);

    memcpy(&config, &hal_brdcfg_spi__theconfig.gpio_mosi[HAL_spi_id2index(id)].config, sizeof(hal_gpio_cfg_t));
    config.altcfg = &hal_spi_mosi_altcfg;
    hal_gpio_init(hal_brdcfg_spi__theconfig.gpio_mosi[HAL_spi_id2index(id)].gpio, &config);

//     hal_gpio_configure(hal_brdcfg_spi__theconfig.gpio_sck[HAL_spi_id2index(id)], &hal_spi_sck_altcfg);
//     hal_gpio_configure(hal_brdcfg_spi__theconfig.gpio_miso[HAL_spi_id2index(id)], &hal_spi_miso_altcfg);
//     hal_gpio_configure(hal_brdcfg_spi__theconfig.gpio_mosi[HAL_spi_id2index(id)], &hal_spi_mosi_altcfg);


#elif   defined(HAL_USE_CPU_FAM_STM32F4)

    static const GPIO_InitTypeDef  s_hal_spi_misomosisck_altcfg  =
    {
        .GPIO_Pin       = 0,
        .GPIO_Mode      = GPIO_Mode_AF,
        .GPIO_Speed     = GPIO_Speed_50MHz,
        .GPIO_OType     = GPIO_OType_PP,
        .GPIO_PuPd      = GPIO_PuPd_DOWN
    };


    // 1. prepare af.
    // for spi1 (sck, miso, mosi): sck -> PA5, PB3.         miso -> PA6, PB4.           mosi -> PA7, PB5.
    // for spi2 (sck, miso, mosi): sck -> PB10, PB13, PI1.  miso -> PAB14, PC2, PI2.    mosi -> PB15, PC3, PI3.
    // for spi3 (sck, miso, mosi): sck -> PB3, PC10.        miso -> PB4, PC11.          mosi -> PB5, PC12.

    uint32_t afname = HAL_GPIO_AFNAME_NONE;
    uint32_t afmode = HAL_GPIO_AFMODE_NONE;
    hal_bool_t foundsck  = hal_false;
    hal_bool_t foundmiso = hal_false;
    hal_bool_t foundmosi = hal_false;


    hal_gpio_port_t portsck  = hal_brdcfg_spi__theconfig.gpiomap[HAL_spi_id2index(id)].sck.gpio.port;
    hal_gpio_pin_t  pinsck   = hal_brdcfg_spi__theconfig.gpiomap[HAL_spi_id2index(id)].sck.gpio.pin;
    hal_gpio_port_t portmiso = hal_brdcfg_spi__theconfig.gpiomap[HAL_spi_id2index(id)].miso.gpio.port;
    hal_gpio_pin_t  pinmiso  = hal_brdcfg_spi__theconfig.gpiomap[HAL_spi_id2index(id)].miso.gpio.pin;
    hal_gpio_port_t portmosi = hal_brdcfg_spi__theconfig.gpiomap[HAL_spi_id2index(id)].mosi.gpio.port;
    hal_gpio_pin_t  pinmosi  = hal_brdcfg_spi__theconfig.gpiomap[HAL_spi_id2index(id)].mosi.gpio.pin;


    if(hal_spi1 == id)
    {
        afname = GPIO_AF_SPI1;
        afmode = ENABLE;

        if( ((hal_gpio_portA == portsck) && (hal_gpio_pin5 == pinsck))  ||
                ((hal_gpio_portB == portsck) && (hal_gpio_pin3 == pinsck))  )
        {   // PA5, PB3
            foundsck = hal_true;
        }

        if( ((hal_gpio_portA == portmiso) && (hal_gpio_pin6 == pinmiso))  ||
                ((hal_gpio_portB == portmiso) && (hal_gpio_pin4 == pinmiso))  )
        {   // PA6, PB4
            foundmiso = hal_true;
        }

        if( ((hal_gpio_portA == portmosi) && (hal_gpio_pin7 == pinmosi))  ||
                ((hal_gpio_portB == portmosi) && (hal_gpio_pin5 == pinmosi))  )
        {   // PA7, PB5
            foundmosi = hal_true;
        }

    }
    else if(hal_spi2 == id)
    {
        afname = GPIO_AF_SPI2;
        afmode = ENABLE;

        if( ((hal_gpio_portB == portsck) && (hal_gpio_pin10 == pinsck))  ||
                ((hal_gpio_portB == portsck) && (hal_gpio_pin13 == pinsck))  ||
                ((hal_gpio_portI == portsck) && (hal_gpio_pin1 == pinsck)) )
        {   // PB10, PB13, PI1
            foundsck = hal_true;
        }

        if( ((hal_gpio_portB == portmiso) && (hal_gpio_pin14 == pinmiso))  ||
                ((hal_gpio_portC == portmiso) && (hal_gpio_pin2 == pinmiso))  ||
                ((hal_gpio_portI == portmiso) && (hal_gpio_pin2 == pinmiso)) )
        {   // PAB14, PC2, PI2
            foundmiso = hal_true;
        }

        if( ((hal_gpio_portB == portmosi) && (hal_gpio_pin15 == pinmosi))  ||
                ((hal_gpio_portC == portmosi) && (hal_gpio_pin3 == pinmosi))  ||
                ((hal_gpio_portI == portmosi) && (hal_gpio_pin3 == pinmosi)) )
        {   // PB15, PC3, PI3
            foundmosi = hal_true;
        }

    }
    else if(hal_spi3 == id)
    {
        afname = GPIO_AF_SPI3;
        afmode = ENABLE;

        if( ((hal_gpio_portB == portsck) && (hal_gpio_pin3 == pinsck))  ||
                ((hal_gpio_portC == portsck) && (hal_gpio_pin10 == pinsck))  )
        {   // PB3, PC10
            foundsck = hal_true;
        }

        if( ((hal_gpio_portB == portmiso) && (hal_gpio_pin4 == pinmiso))  ||
                ((hal_gpio_portC == portmiso) && (hal_gpio_pin11 == pinmiso))  )
        {   // PB4, PC11
            foundmiso = hal_true;
        }

        if( ((hal_gpio_portB == portmosi) && (hal_gpio_pin5 == pinmosi))  ||
                ((hal_gpio_portC == portmosi) && (hal_gpio_pin12 == pinmosi))  )
        {   // PB5, PC12
            foundmosi = hal_true;
        }

    }

    if((hal_false == foundsck) || (hal_false == foundmiso) || (hal_false == foundmosi))
    {
        hal_base_on_fatalerror(hal_fatalerror_incorrectparameter, "hal_spi_init(): incorrect pin mapping");
    }


    hal_gpio_cfg_t hal_spi_sck_cfg;
    hal_gpio_cfg_t hal_spi_miso_cfg;
    hal_gpio_cfg_t hal_spi_mosi_cfg;
    hal_gpio_altcfg_t hal_spi_sck_altcfg;
    hal_gpio_altcfg_t hal_spi_miso_altcfg;
    hal_gpio_altcfg_t hal_spi_mosi_altcfg;


    // prepare the altcfg for sck miso mosi pins
    memcpy(&hal_spi_sck_altcfg.gpioext, &s_hal_spi_misomosisck_altcfg, sizeof(GPIO_InitTypeDef));
    memcpy(&hal_spi_miso_altcfg.gpioext, &s_hal_spi_misomosisck_altcfg, sizeof(GPIO_InitTypeDef));
    memcpy(&hal_spi_mosi_altcfg.gpioext, &s_hal_spi_misomosisck_altcfg, sizeof(GPIO_InitTypeDef));
    hal_spi_sck_altcfg.afname = hal_spi_miso_altcfg.afname = hal_spi_mosi_altcfg.afname = afname;
    hal_spi_sck_altcfg.afmode = hal_spi_miso_altcfg.afmode = hal_spi_mosi_altcfg.afmode = afmode;

    // the gpiocfgs.
    hal_spi_sck_cfg.dir     = hal_gpio_dirALT;
    hal_spi_sck_cfg.speed   = hal_gpio_speed_default;
    hal_spi_sck_cfg.altcfg  = &hal_spi_sck_altcfg;
    hal_spi_miso_cfg.dir    = hal_gpio_dirALT;
    hal_spi_miso_cfg.speed  = hal_gpio_speed_default;
    hal_spi_miso_cfg.altcfg = &hal_spi_miso_altcfg;
    hal_spi_mosi_cfg.dir    = hal_gpio_dirALT;
    hal_spi_mosi_cfg.speed  = hal_gpio_speed_default;
    hal_spi_mosi_cfg.altcfg = &hal_spi_mosi_altcfg;

    // configure sck miso mosi pins
    hal_gpio_init(hal_brdcfg_spi__theconfig.gpiomap[HAL_spi_id2index(id)].sck.gpio, &hal_spi_sck_cfg);
    hal_gpio_init(hal_brdcfg_spi__theconfig.gpiomap[HAL_spi_id2index(id)].miso.gpio, &hal_spi_miso_cfg);
    hal_gpio_init(hal_brdcfg_spi__theconfig.gpiomap[HAL_spi_id2index(id)].mosi.gpio, &hal_spi_mosi_cfg);


#else //defined(HAL_USE_CPU_FAM_*)
#error ERR --> choose a HAL_USE_CPU_FAM_*
#endif
}

static void s_hal_spi_hw_enable(hal_spi_t id, const hal_spi_cfg_t* cfg)
{
#if     defined(HAL_USE_CPU_FAM_STM32F1) || defined(HAL_USE_CPU_FAM_STM32F4)

    SPI_TypeDef* SPIx = HAL_spi_id2stmSPI(id);
    uint16_t prescaler_stm32fx = 0;
    SPI_InitTypeDef spi_cfg;


    SPI_I2S_DeInit(SPIx);

    memcpy(&spi_cfg, &s_hal_spi_stm32_cfg, sizeof(SPI_InitTypeDef));
    // apply the mode
    spi_cfg.SPI_Mode                = (hal_spi_ownership_master == cfg->ownership) ? (SPI_Mode_Master) : (SPI_Mode_Slave);


    // configure speed of spi ...

    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:
        {
            prescaler_stm32fx = (hal_spi1 == id) ? SPI_BaudRatePrescaler_4 : SPI_BaudRatePrescaler_2;
        }
        break;
        case hal_spi_prescaler_008:
        {
            prescaler_stm32fx = (hal_spi1 == id) ? SPI_BaudRatePrescaler_8 : SPI_BaudRatePrescaler_4;
        }
        break;
        case hal_spi_prescaler_016:
        {
            prescaler_stm32fx = (hal_spi1 == id) ? SPI_BaudRatePrescaler_16 : SPI_BaudRatePrescaler_8;
        }
        break;
        case hal_spi_prescaler_032:
        {
            prescaler_stm32fx = (hal_spi1 == id) ? SPI_BaudRatePrescaler_32 : SPI_BaudRatePrescaler_16;
        }
        break;
        case hal_spi_prescaler_064:
        {
            prescaler_stm32fx = (hal_spi1 == id) ? SPI_BaudRatePrescaler_64 : SPI_BaudRatePrescaler_32;
        }
        break;
        case hal_spi_prescaler_128:
        {
            prescaler_stm32fx = (hal_spi1 == id) ? SPI_BaudRatePrescaler_128 : SPI_BaudRatePrescaler_64;
        }
        break;
        case hal_spi_prescaler_256:
        {
            prescaler_stm32fx = (hal_spi1 == id) ? SPI_BaudRatePrescaler_256 : SPI_BaudRatePrescaler_128;
        }
        break;
        default:
        {
            prescaler_stm32fx = SPI_BaudRatePrescaler_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:
            prescaler_stm32fx = SPI_BaudRatePrescaler_2;
            break;
        case 4:
            prescaler_stm32fx = SPI_BaudRatePrescaler_4;
            break;
        case 8:
            prescaler_stm32fx = SPI_BaudRatePrescaler_8;
            break;
        case 16:
            prescaler_stm32fx = SPI_BaudRatePrescaler_16;
            break;
        case 32:
            prescaler_stm32fx = SPI_BaudRatePrescaler_32;
            break;
        case 64:
            prescaler_stm32fx = SPI_BaudRatePrescaler_64;
            break;
        case 128:
            prescaler_stm32fx = SPI_BaudRatePrescaler_128;
            break;
        case 256:
            prescaler_stm32fx = SPI_BaudRatePrescaler_256;
            break;
        default:
            prescaler_stm32fx = SPI_BaudRatePrescaler_256;
            break;
        }

    }

    // ok ... we have prescaler_stm32fx at last.
    spi_cfg.SPI_BaudRatePrescaler = prescaler_stm32fx;

    // can init spi
    SPI_Init(SPIx, &spi_cfg);

    if(hal_spi_act_framebased == cfg->activity)
    {
        // enable dma rx request
        SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, ENABLE);
        // enable dma tx request
        SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Tx, ENABLE);
    }

#else //defined(HAL_USE_CPU_FAM_*)
#error ERR --> choose a HAL_USE_CPU_FAM_*
#endif
}




static hal_result_t s_hal_spi_timeoutexpired(void)
{
    hal_base_on_fatalerror(hal_fatalerror_incorrectparameter, "timeout error in spi raw operations");
    return(hal_res_NOK_generic);
}

#if 0
static void s_hal_spi_scheduling_suspend(void)
{
    hal_base_osal_scheduling_suspend();
}

static void s_hal_spi_scheduling_restart(void)
{
    hal_base_osal_scheduling_restart();
}
#endif

static hal_result_t s_hal_spi_put(hal_spi_t id, uint8_t* txframe)
{
    hal_result_t res = hal_res_NOK_generic;
    hal_spi_internal_item_t* intitem = s_hal_spi_theinternals.items[HAL_spi_id2index(id)];
    hal_spi_cfg_t* cfg = &intitem->config;


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

    if(hal_spi_dir_rxonly != cfg->direction)
    {
        // disable so that we can change a data structure which is used by the isr

        hal_bool_t dmaisenabled = s_hal_spi_is_dma_enabled(id);
        if(hal_true == dmaisenabled)
        {
            s_hal_spi_periph_dma_isr_disable(id);
        }

        res =  hal_utility_fifo_put(&intitem->fifotx, txframe);

        if(hal_true == dmaisenabled)
        {
            s_hal_spi_periph_dma_isr_enable(id);
        }
    }

//    if(hal_true == sendnow)
//    {
//        // enable again
//        s_hal_spi_periph_dma_enable(id);
//    }

    return(res);
}

static hal_result_t s_hal_spi_get(hal_spi_t id, uint8_t* rxframe, uint8_t* remainingrxframes)
{
    hal_result_t res = hal_res_NOK_generic;
    hal_spi_internal_item_t* intitem = s_hal_spi_theinternals.items[HAL_spi_id2index(id)];
    hal_spi_cfg_t* cfg = &intitem->config;


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

    if(hal_spi_dir_txonly != intitem->config.direction)
    {

        hal_bool_t dmaisenabled = s_hal_spi_is_dma_enabled(id);
        if(hal_true == dmaisenabled)
        {
            s_hal_spi_periph_dma_isr_disable(id);
        }

        res =  hal_utility_fifo_get(&intitem->fiforx, rxframe, remainingrxframes);

        if(hal_true == dmaisenabled)
        {
            s_hal_spi_periph_dma_isr_enable(id);
        }
    }


//    if(NULL != size)
//    {
//        *size = (hal_res_OK == res) ? (s_hal_spi_internals[HAL_spi_id2index(id)].config.sizeofframe) : (0);
//    }

    // enable again
//        s_hal_spi_isr_enable(id);

    return(res);
}


static void s_hal_spi_periph_dma_isr_enable(hal_spi_t id)
{
    hal_dma_isr_enable(s_hal_spi_dma_port2use_rx[HAL_spi_id2index(id)]);
    hal_dma_isr_enable(s_hal_spi_dma_port2use_tx[HAL_spi_id2index(id)]);
}
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);
        }
    }

}