esp-idf/components/hal/spi_hal.c

72 lines
2.1 KiB
C

/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// The HAL layer for SPI (common part)
#include "hal/spi_hal.h"
#include "soc/soc_caps.h"
#include "soc/clk_tree_defs.h"
void spi_hal_init(spi_hal_context_t *hal, uint32_t host_id)
{
memset(hal, 0, sizeof(spi_hal_context_t));
spi_dev_t *hw = SPI_LL_GET_HW(host_id);
hal->hw = hw;
spi_ll_master_init(hw);
//Force a transaction done interrupt. This interrupt won't fire yet because
//we initialized the SPI interrupt as disabled. This way, we can just
//enable the SPI interrupt and the interrupt handler will kick in, handling
//any transactions that are queued.
spi_ll_enable_int(hw);
spi_ll_set_int_stat(hw);
spi_ll_set_mosi_delay(hw, 0, 0);
spi_ll_apply_config(hw);
}
void spi_hal_config_io_default_level(spi_hal_context_t *hal, bool level)
{
#if SPI_LL_MOSI_FREE_LEVEL
// Config default output data line level when don't have transaction
spi_ll_set_mosi_free_level(hal->hw, level);
spi_ll_apply_config(hal->hw);
#endif
}
void spi_hal_deinit(spi_hal_context_t *hal)
{
spi_dev_t *hw = hal->hw;
if (hw) {
spi_ll_disable_int(hw);
spi_ll_clear_int_stat(hw);
}
}
#if SOC_SPI_SCT_SUPPORTED
void spi_hal_sct_init(spi_hal_context_t *hal)
{
spi_ll_conf_state_enable(hal->hw, true);
spi_ll_set_magic_number(hal->hw, SPI_LL_SCT_MAGIC_NUMBER);
spi_ll_disable_int(hal->hw); //trans_done intr enabled in `add device` phase, sct mode should use sct_trans_done only
spi_ll_enable_intr(hal->hw, SPI_LL_INTR_SEG_DONE);
spi_ll_set_intr(hal->hw, SPI_LL_INTR_SEG_DONE);
}
void spi_hal_sct_deinit(spi_hal_context_t *hal)
{
spi_ll_conf_state_enable(hal->hw, false);
spi_ll_disable_intr(hal->hw, SPI_LL_INTR_SEG_DONE);
spi_ll_clear_intr(hal->hw, SPI_LL_INTR_SEG_DONE);
spi_ll_clear_int_stat(hal->hw);
spi_ll_enable_int(hal->hw); //recover trans_done intr
}
#endif //#if SOC_SPI_SCT_SUPPORTED
int spi_hal_master_cal_clock(int fapb, int hz, int duty_cycle)
{
return spi_ll_master_cal_clock(fapb, hz, duty_cycle, NULL);
}