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); }
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); }