software/src/ASF/sam0/drivers/sercom/i2c/i2c_sam0/i2c_master.c
/**
 * \brief Initializes the requested I<SUP>2</SUP>C hardware module
 *
 * Initializes the SERCOM I<SUP>2</SUP>C master device requested and sets the provided
 * software module struct. Run this function before any further use of
 * the driver.
 *
 * \param[out] module  Pointer to software module struct
 * \param[in]  hw      Pointer to the hardware instance
 * \param[in]  config  Pointer to the configuration struct
 *
 * \return Status of initialization.
 * \retval STATUS_OK                        Module initiated correctly
 * \retval STATUS_ERR_DENIED                If module is enabled
 * \retval STATUS_BUSY                      If module is busy resetting
 * \retval STATUS_ERR_ALREADY_INITIALIZED   If setting other GCLK generator than
 *                                          previously set
 * \retval STATUS_ERR_BAUDRATE_UNAVAILABLE  If given baudrate is not compatible
 *                                          with set GCLK frequency
 *
 */
\brief Initializes the requested I2C hardware module
Initializes the SERCOM I2C master device requested and sets the provided
software module struct. Run this function before any further use of
the driver.

\param[out] module  Pointer to software module struct
\param[in]  hw      Pointer to the hardware instance
\param[in]  config  Pointer to the configuration struct

\return Status of initialization.
\ brief Initializes the requested I2C hardware module Initializes the SERCOM I2C master device requested and sets the provided software module struct . Run this function before any further use of the driver . \ param [ out ] module Pointer to software module struct \ param [ in ] hw Pointer to the hardware instance \ param [ in ] config Pointer to the configuration struct \ return Status of initialization .
enum status_code i2c_master_init(
		struct i2c_master_module *const module,
		Sercom *const hw,
		const struct i2c_master_config *const config)
{
	Assert(module);
	Assert(hw);
	Assert(config);
	module->hw = hw;
	SercomI2cm *const i2c_module = &(module->hw->I2CM);
	uint32_t sercom_index = _sercom_get_sercom_inst_index(module->hw);
	uint32_t pm_index, gclk_index;
#if (SAML22) || (SAMC20)
	pm_index     = sercom_index + MCLK_APBCMASK_SERCOM0_Pos;
	gclk_index   = sercom_index + SERCOM0_GCLK_ID_CORE;
#elif (SAML21) || (SAMR30) || (SAMR34) || (SAMR35)
	if (sercom_index == 5) {
		pm_index     = MCLK_APBDMASK_SERCOM5_Pos;
		gclk_index   = SERCOM5_GCLK_ID_CORE;
	} else {
		pm_index     = sercom_index + MCLK_APBCMASK_SERCOM0_Pos;
		gclk_index   = sercom_index + SERCOM0_GCLK_ID_CORE;
	}
#elif (SAMC21)
	pm_index     = sercom_index + MCLK_APBCMASK_SERCOM0_Pos;
	if (sercom_index == 5) {
		gclk_index   = SERCOM5_GCLK_ID_CORE;
	} else {
		gclk_index   = sercom_index + SERCOM0_GCLK_ID_CORE;
	}
#else
	pm_index     = sercom_index + PM_APBCMASK_SERCOM0_Pos;
	gclk_index   = sercom_index + SERCOM0_GCLK_ID_CORE;
#endif
#if (SAML21) || (SAMR30) || (SAMR34) || (SAMR35)
	if (sercom_index == 5) {
		system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBD, 1 << pm_index);
	} else {
		system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, 1 << pm_index);
	}
#else
	system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, 1 << pm_index);
#endif
	struct system_gclk_chan_config gclk_chan_conf;
	system_gclk_chan_get_config_defaults(&gclk_chan_conf);
	gclk_chan_conf.source_generator = config->generator_source;
	system_gclk_chan_set_config(gclk_index, &gclk_chan_conf);
	system_gclk_chan_enable(gclk_index);
	sercom_set_gclk_generator(config->generator_source, false);
	if (i2c_module->CTRLA.reg & SERCOM_I2CM_CTRLA_ENABLE) {
		return STATUS_ERR_DENIED;
	}
	if (i2c_module->CTRLA.reg & SERCOM_I2CM_CTRLA_SWRST) {
		return STATUS_BUSY;
	}
#if I2C_MASTER_CALLBACK_MODE == true
	uint8_t instance_index = _sercom_get_sercom_inst_index(module->hw);
	_sercom_set_handler(instance_index, _i2c_master_interrupt_handler);
	_sercom_instances[instance_index] = module;
	module->registered_callback = 0;
	module->enabled_callback = 0;
	module->buffer_length = 0;
	module->buffer_remaining = 0;
	module->status = STATUS_OK;
	module->buffer = NULL;
#endif
	i2c_module->CTRLA.reg = SERCOM_I2CM_CTRLA_MODE(0x5);
	return _i2c_master_set_config(module, config);
}
enum status_code i2c_master_init ( struct i2c_master_module * const module , Sercom * const hw , const struct i2c_master_config * const config ) { Assert ( module ) ; Assert ( hw ) ; Assert ( config ) ; module -> hw = hw ; SercomI2cm * const i2c_module = & ( module -> hw -> I2CM ) ; uint32_t sercom_index = _sercom_get_sercom_inst_index ( module -> hw ) ; uint32_t pm_index , gclk_index ; #if ( SAML22 ) || ( SAMC20 ) pm_index = sercom_index + MCLK_APBCMASK_SERCOM0_Pos ; gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE ; #elif ( SAML21 ) || ( SAMR30 ) || ( SAMR34 ) || ( SAMR35 ) if ( sercom_index == 5 ) { pm_index = MCLK_APBDMASK_SERCOM5_Pos ; gclk_index = SERCOM5_GCLK_ID_CORE ; } else { pm_index = sercom_index + MCLK_APBCMASK_SERCOM0_Pos ; gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE ; } #elif ( SAMC21 ) pm_index = sercom_index + MCLK_APBCMASK_SERCOM0_Pos ; if ( sercom_index == 5 ) { gclk_index = SERCOM5_GCLK_ID_CORE ; } else { gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE ; } #else pm_index = sercom_index + PM_APBCMASK_SERCOM0_Pos ; gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE ; #endif #if ( SAML21 ) || ( SAMR30 ) || ( SAMR34 ) || ( SAMR35 ) if ( sercom_index == 5 ) { system_apb_clock_set_mask ( SYSTEM_CLOCK_APB_APBD , 1 << pm_index ) ; } else { system_apb_clock_set_mask ( SYSTEM_CLOCK_APB_APBC , 1 << pm_index ) ; } #else system_apb_clock_set_mask ( SYSTEM_CLOCK_APB_APBC , 1 << pm_index ) ; #endif struct system_gclk_chan_config gclk_chan_conf ; system_gclk_chan_get_config_defaults ( & gclk_chan_conf ) ; gclk_chan_conf . source_generator = config -> generator_source ; system_gclk_chan_set_config ( gclk_index , & gclk_chan_conf ) ; system_gclk_chan_enable ( gclk_index ) ; sercom_set_gclk_generator ( config -> generator_source , false ) ; if ( i2c_module -> CTRLA . reg & SERCOM_I2CM_CTRLA_ENABLE ) { return STATUS_ERR_DENIED ; } if ( i2c_module -> CTRLA . reg & SERCOM_I2CM_CTRLA_SWRST ) { return STATUS_BUSY ; } #if I2C_MASTER_CALLBACK_MODE == true uint8_t instance_index = _sercom_get_sercom_inst_index ( module -> hw ) ; _sercom_set_handler ( instance_index , _i2c_master_interrupt_handler ) ; _sercom_instances [ instance_index ] = module ; module -> registered_callback = 0 ; module -> enabled_callback = 0 ; module -> buffer_length = 0 ; module -> buffer_remaining = 0 ; module -> status = STATUS_OK ; module -> buffer = NULL ; #endif i2c_module -> CTRLA . reg = SERCOM_I2CM_CTRLA_MODE ( 0x5 ) ; return _i2c_master_set_config ( module , config ) ; }
\brief Initializes the requested I<SUP>2</SUP>C hardware module
 Initializes the SERCOM I<SUP>2</SUP>C master device requested and sets the provided
 software module struct.
\ brief Initializes the requested I<SUP > 2< / SUP > C hardware module Initializes the SERCOM I<SUP > 2< / SUP > C master device requested and sets the provided software module struct .
/* Sanity check arguments. */ /* Initialize software module */ /* Turn on module in PM */ /* Set up the GCLK for the module */ /* Check if module is enabled. */ /* Check if reset is in progress. */ /* Get sercom instance index and register callback. */ /* Initialize values in module. */ /* Set sercom module to operate in I2C master mode. */ /* Set config and return status. */