/* Cesar project {{{ * * Copyright (C) 2008 Spidcom * * <<>> * * }}} */ /** * \file hal/phy/src/tx.c * \brief HAL Phy TX functions. * \ingroup hal_phy */ #include "common/std.h" #include "inc/context.h" #include "inc/regs.h" #include "hal/leon/itc2.h" void phy_tx_fc10 (phy_t *ctx, u32 fc_10) { dbg_assert (ctx); dbg_assert (BF_CHECK (PHY_DSPSS_TX_FC_10__FC, fc_10)); PHY_TRACE (TX_FC10, fc_10); /* Set FC 1.0, will be created later. */ PHY_DSPSS_TX_FC_10 = BF_SHIFT (PHY_DSPSS_TX_FC_10__FC, fc_10) | BF_MASK (PHY_DSPSS_TX_FC_10__CRC); /* TODO: do it later. */ PHY_PRATIC_IMMEDIATE_ACTION = PHY_PRATIC_ACTION__CREATE_FC_10; } void phy_tx_param (phy_t *ctx, phy_fc_mode_t fc_mode, bool short_ppdu, phy_mod_t mod, phy_fecrate_t fecrate, phy_pb_size_t pb_size, phy_gil_t gil, uint tonemap_index) { dbg_assert (ctx); dbg_assert (fc_mode < PHY_FC_MODE_NB && ((short_ppdu == false && mod < PHY_MOD_NONE && fecrate < PHY_FEC_RATE_NONE && pb_size < PHY_PB_SIZE_NONE && gil < PHY_GIL_NB && BF_CHECK (PHY_DSPSS_TX_PARAM__TMBI, tonemap_index)) || short_ppdu == true)); PHY_TRACE (TX_PARAM, fc_mode, short_ppdu, mod, fecrate, pb_size, gil, tonemap_index); if (short_ppdu) { PHY_DSPSS_TX_PARAM = BF_FILL (PHY_DSPSS_TX_PARAM, (FC_MODE, fc_mode), (LONG_PPDU, 0)) | PHY_DSPSS_TX_PARAM__DEFAULT; gil = PHY_GIL_567; } else { PHY_DSPSS_TX_PARAM = BF_FILL (PHY_DSPSS_TX_PARAM, (PB_SIZE, pb_size), (PB_RATE, fecrate), (PB_MOD, mod), (FC_MODE, fc_mode), (LONG_PPDU, 1), (TMBI, tonemap_index)) | PHY_DSPSS_TX_PARAM__DEFAULT; } ctx->tx_short_ppdu = short_ppdu; static const uint gil_durations_table[] = { PHY_DSPSS_TX_GUARD_LENGTH__VALUE_417, PHY_DSPSS_TX_GUARD_LENGTH__VALUE_567, PHY_DSPSS_TX_GUARD_LENGTH__VALUE_3534, }; switch (fc_mode) { case PHY_FC_MODE_HYBRID_1: PHY_DSPSS_TX_GUARD_LENGTH_0 = PHY_DSPSS_TX_GUARD_LENGTH__VALUE_FC_10; PHY_DSPSS_TX_GUARD_LENGTH_1 = PHY_DSPSS_TX_GUARD_LENGTH__VALUE_FC_AV; PHY_DSPSS_TX_GUARD_LENGTH_2 = PHY_DSPSS_TX_GUARD_LENGTH__VALUE_567; PHY_DSPSS_TX_GUARD_LENGTH_3 = PHY_DSPSS_TX_GUARD_LENGTH__VALUE_567; PHY_DSPSS_TX_GUARD_LENGTH_4 = gil_durations_table[gil]; break; case PHY_FC_MODE_HYBRID_2: PHY_DSPSS_TX_GUARD_LENGTH_0 = PHY_DSPSS_TX_GUARD_LENGTH__VALUE_FC_10; PHY_DSPSS_TX_GUARD_LENGTH_1 = PHY_DSPSS_TX_GUARD_LENGTH__VALUE_FC_AV; PHY_DSPSS_TX_GUARD_LENGTH_2 = PHY_DSPSS_TX_GUARD_LENGTH__VALUE_FC_AV; PHY_DSPSS_TX_GUARD_LENGTH_3 = PHY_DSPSS_TX_GUARD_LENGTH__VALUE_567; PHY_DSPSS_TX_GUARD_LENGTH_4 = PHY_DSPSS_TX_GUARD_LENGTH__VALUE_567; break; case PHY_FC_MODE_AV_1: PHY_DSPSS_TX_GUARD_LENGTH_0 = PHY_DSPSS_TX_GUARD_LENGTH__VALUE_FC_AV; PHY_DSPSS_TX_GUARD_LENGTH_1 = PHY_DSPSS_TX_GUARD_LENGTH__VALUE_567; PHY_DSPSS_TX_GUARD_LENGTH_2 = PHY_DSPSS_TX_GUARD_LENGTH__VALUE_567; PHY_DSPSS_TX_GUARD_LENGTH_3 = gil_durations_table[gil]; PHY_DSPSS_TX_GUARD_LENGTH_4 = gil_durations_table[gil]; break; case PHY_FC_MODE_AV_2: PHY_DSPSS_TX_GUARD_LENGTH_0 = PHY_DSPSS_TX_GUARD_LENGTH__VALUE_FC_AV; PHY_DSPSS_TX_GUARD_LENGTH_1 = PHY_DSPSS_TX_GUARD_LENGTH__VALUE_FC_AV; PHY_DSPSS_TX_GUARD_LENGTH_2 = PHY_DSPSS_TX_GUARD_LENGTH__VALUE_567; PHY_DSPSS_TX_GUARD_LENGTH_3 = PHY_DSPSS_TX_GUARD_LENGTH__VALUE_567; PHY_DSPSS_TX_GUARD_LENGTH_4 = gil_durations_table[gil]; break; default: dbg_assert_default (); } PHY_DSPSS_TX_GUARD_LENGTH_5 = gil_durations_table[gil]; } void phy_tx_frame (phy_t *ctx, u32 date, bool want_conf, bool stop_tx_on_prp_lost, const u32 fc_av[4]) { dbg_assert (ctx); dbg_assert (fc_av); PHY_TRACE (TX_FRAME, phy_date (ctx), date, want_conf, stop_tx_on_prp_lost, fc_av[0]); /* Set FC. */ PHY_DSPSS_TX_FC_AV_0 = fc_av[0]; PHY_DSPSS_TX_FC_AV_1 = fc_av[1]; PHY_DSPSS_TX_FC_AV_2 = fc_av[2]; PHY_DSPSS_TX_FC_AV_3 = fc_av[3]; /* TODO: stop_tx_on_prp_lost. */ LEON_ITC2_CLEAR = 1 << LEON_ITC2_IT__PRATIC_ACCESS_CONF; if (want_conf) LEON_ITC2_MASK |= 1 << LEON_ITC2_IT__PRATIC_ACCESS_CONF; else LEON_ITC2_MASK &= ~(1 << LEON_ITC2_IT__PRATIC_ACCESS_CONF); /* Program TX. */ PHY_PRATIC_TIMER_2_DATE = date; if (ctx->tx_short_ppdu) { PHY_PRATIC_TIMER_2_CTRL = BF_FILL (PHY_PRATIC_TIMER_X_CTRL, (ACTION, PHY_PRATIC_ACTION__START_TX), (VALID, 1)); } else { PHY_PRATIC_TIMER_2_CTRL = BF_FILL (PHY_PRATIC_TIMER_X_CTRL, (ACTION_2, PHY_PRATIC_ACTION__PBD_START), (ACTION, PHY_PRATIC_ACTION__START_TX), (VALID, 1)); } }