/**************************************************************************//** * @brief Setup the ACMP *****************************************************************************/ void setupACMP(void) { /* ACMP configuration constant table. */ static const ACMP_Init_TypeDef initACMP = { .fullBias = false, /* fullBias */ .halfBias = true, /* halfBias */ .biasProg = 0x0, /* biasProg */ .interruptOnFallingEdge = false, /* interrupt on rising edge */ .interruptOnRisingEdge = false, /* interrupt on falling edge */ //.interruptOnFallingEdge = true, /* interrupt on rising edge */ //.interruptOnRisingEdge = true, /* interrupt on falling edge */ .warmTime = acmpWarmTime4, /* 512 cycle warmup to be safe */ .hysteresisLevel = acmpHysteresisLevel0, /* No Hysteresis */ .inactiveValue = false, /* inactive value */ .lowPowerReferenceEnabled = true, /* low power reference */ .vddLevel = 32, /* VDD level : VDD/2 */ .enable = false /* Don't request enabling. */ }; /* Configure ACMP. */ ACMP_Init(ACMP1, &initACMP); /* Disable ACMP0 out to a pin. */ ACMP_GPIOSetup(ACMP1, 0, false, false); /* Set up ACMP negSel to VDD, posSel is controlled by LESENSE. */ ACMP_ChannelSet(ACMP1, acmpChannelVDD, acmpChannel0); /* LESENSE controls ACMP thus ACMP_Enable(ACMP0) should NOT be called in order * to ensure lower current consumption. */ #ifdef DEBUG_ACMP ACMP_ChannelSet(ACMP1, acmpChannelVDD, acmpChannel2); ACMP1->IEN = 1; ACMP_Enable(ACMP1); NVIC_ClearPendingIRQ(ACMP0_IRQn); NVIC_EnableIRQ(ACMP0_IRQn); #endif } #ifdef DEBUG_ACMP // ACMP IRQ Handler is shared between ACMP0 and ACMP1 void ACMP0_IRQHandler(void) { PRINTF("%s\r\n",__func__); ACMP1->IFC = 1; NVIC_ClearPendingIRQ(ACMP0_IRQn); }
/**************************************************************************//** * @brief ACMP_setup * Configures and starts the ACMP *****************************************************************************/ void ACMP_setup(void) { /* Enable necessary clocks */ CMU_ClockEnable(cmuClock_ACMP0, true); CMU_ClockEnable(cmuClock_GPIO, true); /* Configure PC4 as input with pull down for ACMP channel 4 input */ GPIO_PinModeSet(gpioPortC, 4, gpioModeInputPullFilter, 0); /* Analog comparator parameters */ const ACMP_Init_TypeDef acmpInit = { .fullBias = false, /* no full bias current*/ .halfBias = false, /* no half bias current */ .biasProg = 7, /* Biasprog current 1.4 uA */ .interruptOnFallingEdge = false, /* disable interrupt for falling edge */ .interruptOnRisingEdge = false, /* disable interrupt for rising edge */ .warmTime = acmpWarmTime256, /* Warm-up time in clock cycles, should be >140 cycles for >10us warm-up @ 14MHz */ .hysteresisLevel = acmpHysteresisLevel0, /* Hysteresis level 0 - no hysteresis */ .inactiveValue = 0, /* Inactive comparator output value */ .lowPowerReferenceEnabled = false, /* Low power reference mode disabled */ .vddLevel = 32, /* Vdd reference scaling of 32 */ }; /* Init ACMP and set ACMP channel 4 as positive input and scaled Vdd as negative input */ ACMP_Init(ACMP0, &acmpInit); ACMP_ChannelSet(ACMP0, acmpChannelVDD, acmpChannel4); ACMP_Enable(ACMP0); } /**************************************************************************//** * @brief PRS_ScanChannel * Waits for activity on a selected PRS channel and writes on the LCD when activity occurs * * @param[in] timer * Pointer to TIMER peripheral register block. * * @param[in] prsCh * PRS Channel to be monitored * * @param[in] edgeType * Signal edge to be monitored/captured *****************************************************************************/ void PRS_ScanChannel(TIMER_TypeDef *timer, TIMER_PRSSEL_TypeDef prsCh, TIMER_Edge_TypeDef edgeType) { /* enable the clock for the correct timer */ #define TIMER_Clock(T) (T==TIMER0 ? cmuClock_TIMER0 : \ T==TIMER1 ? cmuClock_TIMER1 : 0) /* Enable necessary clocks */ CMU_ClockEnable((CMU_Clock_TypeDef)TIMER_Clock(timer), true); /* Initialize LCD */ SegmentLCD_Init(false); /* Select CC channel parameters */ const TIMER_InitCC_TypeDef timerCCInit = { .eventCtrl = timerEventFalling, /* input capture event control */ .edge = edgeType, /* input capture on falling edge */ .prsSel = prsCh, /* prs channel select channel 5*/ .cufoa = timerOutputActionNone, /* no action on counter underflow */ .cofoa = timerOutputActionNone, /* no action on counter overflow */ .cmoa = timerOutputActionNone, /* no action on counter match */ .mode = timerCCModeCapture, /* CC channel mode capture */ .filter = false, /* no filter */ .prsInput = true, /* CC channel PRS input */ .coist = false, /* comparator output initial state */ .outInvert = false, /* no output invert */ }; /* Initialize TIMER0 CC0 */ TIMER_InitCC(timer, 0, &timerCCInit); /* Select timer parameters */ const TIMER_Init_TypeDef timerInit = { .enable = true, /* start counting when init complete */ .debugRun = false, /* counter not running on debug halt */ .prescale = timerPrescale1024, /* prescaler of 64 */ .clkSel = timerClkSelHFPerClk, /* TIMER0 clocked by the HFPERCLK */ .fallAction = timerInputActionNone, /* stop counter on falling edge */ .riseAction = timerInputActionNone, /* reload and start on rising edge */ .mode = timerModeUp, /* counting up */ .dmaClrAct = false, /* no DMA */ .quadModeX4 = false, /* no quad decoding */ .oneShot = false, /* counting up constinuously */ .sync = false, /* no start/stop/reload by other timers */ }; /* Initialize TIMER0 */ TIMER_Init(timer, &timerInit); /* Poll the Input Capture Valid flag in the Status register The program will hang at this point waiting for activity on this channel */ while(!((TIMER0->STATUS & _TIMER_STATUS_ICV0_MASK )>>16)); } /**************************************************************************//** * @brief Main function * Main is called from __iar_program_start, see assembly startup file *****************************************************************************/ int main(void) { /* Align different chip revisions*/ CHIP_Init(); /* Initialise the ACMP */ ACMP_setup(); /* PRS setup */ /* Enable clock for PRS and select ACMP as source and ACMP0OUT (ACMP0 OUTPUT) as signal for channel 5 */ CMU_ClockEnable(cmuClock_PRS, true); PRS_SourceSignalSet(5, PRS_CH_CTRL_SOURCESEL_ACMP0, PRS_CH_CTRL_SIGSEL_ACMP0OUT, prsEdgeOff); /* Start PRS scan This function will halt the program while there is no PRS activity This function assumes that the PRS has been setup previously */ PRS_ScanChannel(TIMER0, timerPRSSELCh5, timerEdgeFalling); /* Write PRS and channel number on the LCD to acknowledge PRS activity */ SegmentLCD_Write("PRS"); SegmentLCD_Number((int)timerPRSSELCh5); while(1) { /* Enter EM1 while waiting for capture. */ EMU_EnterEM1(); } }
/**************************************************************************//** * @brief TIMER0_setup * Configures the TIMER *****************************************************************************/ void TIMER_setup(void) { /* Enable necessary clocks */ CMU_ClockEnable(cmuClock_TIMER0, true); CMU_ClockEnable(cmuClock_PRS, true); /* Select CC channel parameters */ TIMER_InitCC_TypeDef timerCCInit = { .eventCtrl = timerEventEveryEdge, /* Input capture event control */ .edge = timerEdgeBoth, /* Input capture on falling edge */ .prsSel = timerPRSSELCh5, /* Prs channel select channel 5*/ .cufoa = timerOutputActionNone, /* No action on counter underflow */ .cofoa = timerOutputActionNone, /* No action on counter overflow */ .cmoa = timerOutputActionNone, /* No action on counter match */ .mode = timerCCModeCapture, /* CC channel mode capture */ .filter = false, /* No filter */ .prsInput = true, /* CC channel PRS input */ .coist = false, /* Comparator output initial state */ .outInvert = false, /* No output invert */ }; /* Initialize TIMER0 CC0 channel */ TIMER_InitCC(HIJACK_RX_TIMER, 0, &timerCCInit); /* Select timer parameters */ const TIMER_Init_TypeDef timerInit = { .enable = false, /* Do not start counting when init complete */ .debugRun = false, /* Counter not running on debug halt */ .prescale = HIJACK_TIMER_RESOLUTION, /* Prescaler of 1 */ .clkSel = timerClkSelHFPerClk, /* TIMER0 clocked by the HFPERCLK */ .fallAction = timerInputActionReloadStart, /* Stop counter on falling edge */ .riseAction = timerInputActionReloadStart, /* Reload and start on rising edge */ .mode = timerModeUp, /* Counting up */ .dmaClrAct = false, /* No DMA */ .quadModeX4 = false, /* No quad decoding */ .oneShot = false, /* Counting up constinuously */ .sync = false, /* No start/stop/reload by other timers */ }; /* Initialize TIMER0 */ TIMER_Init(HIJACK_RX_TIMER, &timerInit); /* PRS setup */ /* Select ACMP as source and ACMP0OUT (ACMP0 OUTPUT) as signal */ PRS_SourceSignalSet(5, PRS_CH_CTRL_SOURCESEL_ACMP0, PRS_CH_CTRL_SIGSEL_ACMP0OUT, prsEdgeOff); /* Enable CC0 interrupt */ TIMER_IntEnable(HIJACK_RX_TIMER, TIMER_IF_CC0); /* Enable TIMER0 interrupt vector in NVIC */ NVIC_EnableIRQ(TIMER0_IRQn); } /**************************************************************************//** * @brief ACMP_setup * Configures and starts the ACMP *****************************************************************************/ static void ACMP_setup(void) { /* Enable necessary clocks */ CMU_ClockEnable(HIJACK_RX_ACMPCLK, true); CMU_ClockEnable(cmuClock_GPIO, true); /* Configure ACMP input pin. */ GPIO_PinModeSet(HIJACK_RX_GPIO_PORT, HIJACK_RX_GPIO_PIN, gpioModeInput, 0); /* Analog comparator parameters */ const ACMP_Init_TypeDef acmpInit = { .fullBias = false, /* No full bias current*/ .halfBias = true, /* No half bias current */ .biasProg = 2, /* Biasprog current 1.4 uA */ .interruptOnFallingEdge = false, /* Disable interrupt for falling edge */ .interruptOnRisingEdge = false, /* Disable interrupt for rising edge */ .warmTime = acmpWarmTime256, /* Warm-up time in clock cycles, should be >140 cycles for >10us warm-up @ 14MHz */ .hysteresisLevel = acmpHysteresisLevel7, /* Hysteresis level 0 - no hysteresis */ .inactiveValue = 1, /* Inactive comparator output value */ .lowPowerReferenceEnabled = false, /* Low power reference mode disabled */ .vddLevel = HIJACK_RX_ACMP_LEVEL, /* Vdd reference scaling of 32 */ }; /* Use ACMP0 output, PD6 . */ //GPIO_PinModeSet(gpioPortD, 6, gpioModePushPull, 0); //ACMP_GPIOSetup(ACMP0, 2, true, false); /* Init ACMP and set ACMP channel 4 as positive input and scaled Vdd as negative input */ ACMP_Init(HIJACK_RX_ACMP, &acmpInit); ACMP_ChannelSet(HIJACK_RX_ACMP, HIJACK_RX_ACMP_NEG, HIJACK_RX_ACMP_CH); ACMP_Enable(HIJACK_RX_ACMP); } /** * @brief calculate whether cnt is in 500us region * ticker = 64Mhz/128 = 2us * 475us < cnt < 510us * */ static chk_result_t IsTime2Detect(uint32_t inv) { chk_result_t ret; if( inv < HIJACK_DEC_NUM_TICKS_MIN){ offset = inv; ret = pass; } else if ( ( inv <= HIJACK_DEC_NUM_TICKS_MAX ) && ( inv >= HIJACK_DEC_NUM_TICKS_MIN ) ) { offset = 0; inv = 0; ret = suit; } else{ offset = 0; inv = 0; ret = error; } return ret; } /* * Find phase remain or phase reversal. */ static void dec_parser(uint8_t bit_msk, state_t state) { if ( ( suit == IsTime2Detect(inv) ) ){ //it's time to determine if( falling == cur_edge ){ dec.data &= ~(1 << bit_msk); #if DEC_DEBUG == 1 uartPutChar( '+' ) ; uartPutChar( '_' ) ; #endif//DEC_DEBUG == 1 } else{ dec.data |= (1 << bit_msk); #if DEC_DEBUG == 1 uartPutChar( '_' ) ; uartPutChar( '+' ) ; #endif//DEC_DEBUG == 1 dec.odd++; } dec.state = state; //state switch } else if ( error == IsTime2Detect(inv) ){ //wait for edge detection time dec.state = Waiting; //state switch } } /**************************************************************************//** * @brief decode state machine * Invoke in TIMER_ISR for decoding. *****************************************************************************/ void decode_machine(void) { inv = offset + cur_stamp; //update offset #if 0 if( dec.state > Waiting ){ USART_printHexBy16u(inv); if(cur_edge == rising){ uartPutChar( '\\' ) ; } else{ uartPutChar( '/' ) ; } } #endif switch (dec.state){ case Waiting: /* go to start bit if rising edge exist. */ if (rising == cur_edge) { dec.state = Sta0; offset = 0; inv = 0; } break; // case Sta0: if( ( suit == IsTime2Detect(inv) ) && ( falling == cur_edge ) ){ dec.data = 0; //clear data field for store new potential data dec.odd = 0; //clear odd field parity counter dec.state = Bit0; #if DEC_DEBUG == 1 uartPutChar( 'S' ) ; uartPutChar( '+' ) ; uartPutChar( '_' ) ; #endif } else{ dec.state = Waiting; } break; // case Bit0: #if DEC_DEBUG == 1 uartPutChar( '0' ) ; #endif dec_parser(BIT0, Bit1); break; // case Bit1: #if DEC_DEBUG == 1 uartPutChar( '1' ) ; #endif dec_parser(BIT1, Bit2); break; // case Bit2: #if DEC_DEBUG == 1 uartPutChar( '2' ) ; #endif dec_parser(BIT2, Bit3); break; // case Bit3: #if DEC_DEBUG == 1 uartPutChar( '3' ) ; #endif dec_parser(BIT3, Bit4); break; // case Bit4: #if DEC_DEBUG == 1 uartPutChar( '4' ) ; #endif dec_parser(BIT4, Bit5); break; // case Bit5: #if DEC_DEBUG == 1 uartPutChar( '5' ) ; #endif dec_parser(BIT5, Bit6); break; // case Bit6: #if DEC_DEBUG == 1 uartPutChar( '6' ) ; #endif dec_parser(BIT6, Bit7); break; // case Bit7: #if DEC_DEBUG == 1 uartPutChar( '7' ) ; #endif dec_parser(BIT7, Parity); break; // case Parity: if ( ( suit == IsTime2Detect(inv) ) ){ //it's time to determine if( rising == cur_edge ){ dec.odd++; #if DEC_DEBUG == 1 uartPutChar( '_' ) ; uartPutChar( '+' ) ; #endif } else{ #if DEC_DEBUG == 1 uartPutChar( '+' ) ; uartPutChar( '_' ) ; #endif } #if DEC_DEBUG == 1 uartPutChar( dec.odd + 0x30) ; #endif if( 1 == (dec.odd%2)){ //parity pass dec.state = Sto0; } else{ //parity failed dec.state = Waiting; } } else if ( error == IsTime2Detect(inv) ){ //wait for edge detection time dec.state = Waiting; } break; // case Sto0: if ( ( suit == IsTime2Detect(inv) ) ){ //it's time to determine if( rising == cur_edge ){ //stop bit is rising edge USART_txByte(dec.data); #if DEC_DEBUG == 1 uartPutChar( '_' ) ; uartPutChar( '+' ) ; #endif HIJACKPutData(&dec.data, &decBuf, sizeof(uint8_t)); } else{ #if DEC_DEBUG == 1 uartPutChar( '+' ) ; uartPutChar( '_' ) ; #endif } dec.state = Waiting; #if DEC_DEBUG == 1 uartPutChar( '\r' ) ; uartPutChar( '\n' ) ; #endif } else if ( error == IsTime2Detect(inv) ){ //wait for edge detection time dec.state = Waiting; } break; // default: break; // } }
/**************************************************************************//** * @brief Sets up the ACMP *****************************************************************************/ void setupACMP(void) { /* Configuration structure for ACMP */ static const ACMP_Init_TypeDef acmpInit = { .fullBias = false, .halfBias = false, .biasProg = 0x6, /* Experiment with higher value if sensor doesn't work */ .interruptOnFallingEdge = false, .interruptOnRisingEdge = false, .warmTime = acmpWarmTime256, /* Warmuptime should be longer than 10 micro s */ .hysteresisLevel = acmpHysteresisLevel0, .inactiveValue = false, .lowPowerReferenceEnabled = false, .vddLevel = 0x00, /* Controlled by LESENSE */ .enable = false }; /* Initialize ACMP */ ACMP_Init(ACMP0, &acmpInit); /* Disable ACMP0 out to a pin. */ ACMP_GPIOSetup(ACMP0, 0, false, false); /* Set up ACMP negSel to VDD, posSel is controlled by LESENSE. */ ACMP_ChannelSet(ACMP0, acmpChannelVDD, acmpChannel0); /* LESENSE controls ACMP thus ACMP_Enable(ACMP0) should NOT be called in order * to ensure lower current consumption. */ } /**************************************************************************//** * @brief Sets up the LESENSE *****************************************************************************/ void setupLESENSE(void) { /* LESENSE configuration structure */ static const LESENSE_Init_TypeDef initLesense = { .coreCtrl = LESENSE_CORECTRL_DESC_DEFAULT, .timeCtrl = LESENSE_TIMECTRL_DESC_DEFAULT, .perCtrl = { .dacCh0Data = lesenseDACIfData, .dacCh0ConvMode = lesenseDACConvModeDisable, .dacCh0OutMode = lesenseDACOutModeDisable, .dacCh1Data = lesenseDACIfData, .dacCh1ConvMode = lesenseDACConvModeDisable, .dacCh1OutMode = lesenseDACOutModeDisable, .dacPresc = 0, .dacRef = lesenseDACRefBandGap, .acmp0Mode = lesenseACMPModeMuxThres, /* LESENSE controls the threshold value (VDDLEVEL) of ACMP0 */ .acmp1Mode = lesenseACMPModeMuxThres, /* LESENSE controls the threshold value (VDDLEVEL) of ACMP1 */ .warmupMode = lesenseWarmupModeNormal /* The analog comparators are shut down when LESENSE is idle */ }, .decCtrl = LESENSE_DECCTRL_DESC_DEFAULT }; /* Channel configuration */ static const LESENSE_ChDesc_TypeDef initLesenseCh = { .enaScanCh = true, /* Enable scan on this channel */ .enaPin = false, .enaInt = false, .chPinExMode = lesenseChPinExHigh, /* Pin is high when excitating */ .chPinIdleMode = lesenseChPinIdleDis, /* Pin idle when channel idle */ .useAltEx = true, /* Use alternative excitation pin */ .shiftRes = true, /* Result is shifted into the decoder register */ .invRes = false, .storeCntRes = true, .exClk = lesenseClkHF, /* Use HF clock for excitation timing */ .sampleClk = lesenseClkHF, /* Use HF clock for sample timing */ .exTime = 0x1F, /* Clk cycles to excite emitter and decoder */ .sampleDelay = 0x1F, /* Clc cycles to wait before sampling comparator */ .measDelay = 0x00, .acmpThres = 0x0F, /* Initial comperator threshold */ .sampleMode = lesenseSampleModeACMP, .intMode = lesenseSetIntNone, .cntThres = 0x0000, .compMode = lesenseCompModeLess }; /* Alternate excitation channels configuration */ static const LESENSE_ConfAltEx_TypeDef initAltEx = { .altExMap = lesenseAltExMapALTEX, .AltEx[0] = { .enablePin = true, .idleConf = lesenseAltExPinIdleDis, .alwaysEx = true /* Connected to IR sensor */ }, .AltEx[1] = { .enablePin = true, .idleConf = lesenseAltExPinIdleDis, .alwaysEx = false /* Connected to IR LED */ } }; /* Initialize LESENSE interface _with_ RESET. */ LESENSE_Init(&initLesense, true); /* Configure channels */ LESENSE_ChannelConfig(&initLesenseCh, 0); LESENSE_ChannelConfig(&initLesenseCh, 1); /* Configure alternate excitation channels */ LESENSE_AltExConfig(&initAltEx); /* State machine proximity sensor setup */ LESENSE_DecStDesc_TypeDef decConf = { .chainDesc = false, .confA = { .compVal = 0x1, /* Trigger transition when scan result = compVal */ .compMask = 0xC, /* Mask out the upper two bits */ .nextState = STATE_1, .prsAct = lesenseTransActNone, .setInt = true }, .confB = { .compVal = 0x1, .compMask = 0xC, .nextState = STATE_1, .prsAct = lesenseTransActNone, .setInt = true } };
int rt28xx_init( IN PRTMP_ADAPTER pAd, IN PSTRING pDefaultMac, IN PSTRING pHostName) { UINT index; UCHAR TmpPhy; NDIS_STATUS Status; UINT32 MacCsr0 = 0; #ifdef CONFIG_STA_SUPPORT #ifdef PCIE_PS_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { // If dirver doesn't wake up firmware here, // NICLoadFirmware will hang forever when interface is up again. if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) { AUTO_WAKEUP_STRUC AutoWakeupCfg; AsicForceWakeup(pAd, TRUE); AutoWakeupCfg.word = 0; RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); } } #endif // PCIE_PS_SUPPORT // #endif // CONFIG_STA_SUPPORT // // reset Adapter flags RTMP_CLEAR_FLAGS(pAd); // Init BssTab & ChannelInfo tabbles for auto channel select. #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { AutoChBssTableInit(pAd); ChannelInfoInit(pAd); } #endif // CONFIG_AP_SUPPORT // #ifdef DOT11_N_SUPPORT // Allocate BA Reordering memory if (ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM) != TRUE) goto err1; #endif // DOT11_N_SUPPORT // // Make sure MAC gets ready. index = 0; do { RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0); pAd->MACVersion = MacCsr0; if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF)) break; if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) goto err1; RTMPusecDelay(10); } while (index++ < 100); DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion)); #ifdef RTMP_MAC_PCI // To fix driver disable/enable hang issue when radio off RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x2); #endif // RTMP_MAC_PCI // // Disable DMA RT28XXDMADisable(pAd); // Load 8051 firmware Status = NICLoadFirmware(pAd); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status)); goto err1; } NICLoadRateSwitchingParams(pAd); // Disable interrupts here which is as soon as possible // This statement should never be true. We might consider to remove it later #ifdef RTMP_MAC_PCI if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) { RTMP_ASIC_INTERRUPT_DISABLE(pAd); } #endif // RTMP_MAC_PCI // #ifdef RESOURCE_PRE_ALLOC Status = RTMPInitTxRxRingMemory(pAd); #else Status = RTMPAllocTxRxRingMemory(pAd); #endif // RESOURCE_PRE_ALLOC // if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("RTMPAllocTxRxMemory failed, Status[=0x%08x]\n", Status)); goto err2; } RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); // initialize MLME // Status = RtmpMgmtTaskInit(pAd); if (Status != NDIS_STATUS_SUCCESS) goto err3; Status = MlmeInit(pAd); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status)); goto err4; } #ifdef RMTP_RBUS_SUPPORT #ifdef VIDEO_TURBINE_SUPPORT VideoConfigInit(pAd); #endif // VIDEO_TURBINE_SUPPORT // #endif // RMTP_RBUS_SUPPORT // // Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default // UserCfgInit(pAd); Status = RtmpNetTaskInit(pAd); if (Status != NDIS_STATUS_SUCCESS) goto err5; // COPY_MAC_ADDR(pAd->ApCfg.MBSSID[apidx].Bssid, netif->hwaddr); // pAd->bForcePrintTX = TRUE; CfgInitHook(pAd); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) APInitialize(pAd); #endif // CONFIG_AP_SUPPORT // #ifdef BLOCK_NET_IF initblockQueueTab(pAd); #endif // BLOCK_NET_IF // Status = MeasureReqTabInit(pAd); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("MeasureReqTabInit failed, Status[=0x%08x]\n",Status)); goto err6; } Status = TpcReqTabInit(pAd); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("TpcReqTabInit failed, Status[=0x%08x]\n",Status)); goto err6; } // // Init the hardware, we need to init asic before read registry, otherwise mac register will be reset // Status = NICInitializeAdapter(pAd, TRUE); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status)); if (Status != NDIS_STATUS_SUCCESS) goto err6; } // Read parameters from Config File Status = RTMPReadParametersHook(pAd); DBGPRINT(RT_DEBUG_OFF, ("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("RTMPReadParametersHook failed, Status[=0x%08x]\n",Status)); goto err6; } #ifdef DOT11_N_SUPPORT //Init Ba Capability parameters. // RT28XX_BA_INIT(pAd); pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable; pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; // UPdata to HT IE pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; #endif // DOT11_N_SUPPORT // // after reading Registry, we now know if in AP mode or STA mode // Load 8051 firmware; crash when FW image not existent // Status = NICLoadFirmware(pAd); // if (Status != NDIS_STATUS_SUCCESS) // break; DBGPRINT(RT_DEBUG_OFF, ("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); // We should read EEPROM for all cases. rt2860b NICReadEEPROMParameters(pAd, (PUCHAR)pDefaultMac); #ifdef CONFIG_STA_SUPPORT #endif // CONFIG_STA_SUPPORT // DBGPRINT(RT_DEBUG_OFF, ("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); NICInitAsicFromEEPROM(pAd); //rt2860b #ifdef RTMP_INTERNAL_TX_ALC // // Initialize the desired TSSI table // InitDesiredTSSITable(pAd); #endif // RTMP_INTERNAL_TX_ALC // // Set PHY to appropriate mode TmpPhy = pAd->CommonCfg.PhyMode; pAd->CommonCfg.PhyMode = 0xff; RTMPSetPhyMode(pAd, TmpPhy); #ifdef DOT11_N_SUPPORT SetCommonHT(pAd); #endif // DOT11_N_SUPPORT // // No valid channels. if (pAd->ChannelListNum == 0) { DBGPRINT(RT_DEBUG_ERROR, ("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n")); goto err6; } #ifdef DOT11_N_SUPPORT DBGPRINT(RT_DEBUG_OFF, ("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0], pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2], pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4])); #endif // DOT11_N_SUPPORT // #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef AP_QLOAD_SUPPORT /* init QBSS Element */ QBSS_LoadInit(pAd); #endif // AP_QLOAD_SUPPORT // } #endif // CONFIG_AP_SUPPORT // // APInitialize(pAd); #ifdef IKANOS_VX_1X0 VR_IKANOS_FP_Init(pAd->ApCfg.BssidNum, pAd->PermanentAddress); #endif // IKANOS_VX_1X0 // // // Initialize RF register to default value // AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); /* Some modules init must be called before APStartUp(). Or APStartUp() will make up beacon content and call other modules API to get some information to fill. */ #ifdef WMM_ACM_SUPPORT #ifdef CONFIG_AP_SUPPORT ACMP_Init(pAd, pAd->CommonCfg.APEdcaParm.bACM[0], pAd->CommonCfg.APEdcaParm.bACM[1], pAd->CommonCfg.APEdcaParm.bACM[2], pAd->CommonCfg.APEdcaParm.bACM[3], 0); #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT ACMP_Init(pAd); #endif // CONFIG_STA_SUPPORT // #endif // WMM_ACM_SUPPORT // if (pAd && (Status != NDIS_STATUS_SUCCESS)) { // // Undo everything if it failed // if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { // NdisMDeregisterInterrupt(&pAd->Interrupt); RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); } // RTMPFreeAdapter(pAd); // we will free it in disconnect() } else if (pAd) { // Microsoft HCT require driver send a disconnect event after driver initialization. OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); // pAd->IndicateMediaState = NdisMediaStateDisconnected; RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE); DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n")); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { if (pAd->ApCfg.bAutoChannelAtBootup || (pAd->CommonCfg.Channel == 0)) { UINT8 BBPValue = 0; // Enable Interrupt first due to we need to scan channel to receive beacons. RTMP_IRQ_ENABLE(pAd); // Now Enable RxTx RTMPEnableRxTx(pAd); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP); // Let BBP register at 20MHz to do scan RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); BBPValue &= (~0x18); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); DBGPRINT(RT_DEBUG_ERROR, ("SYNC - BBP R4 to 20MHz.l\n")); // Now we can receive the beacon and do the listen beacon // use default BW to select channel pAd->CommonCfg.Channel = AP_AUTO_CH_SEL(pAd, pAd->ApCfg.AutoChannelAlg); pAd->ApCfg.bAutoChannelAtBootup = FALSE; } #ifdef DOT11_N_SUPPORT // If phymode > PHY_11ABGN_MIXED and BW=40 check extension channel, after select channel N_ChannelCheck(pAd); #ifdef DOT11N_DRAFT3 /* We only do this Overlapping BSS Scan when system up, for the other situation of channel changing, we depends on station's report to adjust ourself. */ if (pAd->CommonCfg.bForty_Mhz_Intolerant == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("Disable 20/40 BSSCoex Channel Scan(BssCoex=%d, 40MHzIntolerant=%d)\n", pAd->CommonCfg.bBssCoexEnable, pAd->CommonCfg.bForty_Mhz_Intolerant)); } else if(pAd->CommonCfg.bBssCoexEnable == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("Enable 20/40 BSSCoex Channel Scan(BssCoex=%d)\n", pAd->CommonCfg.bBssCoexEnable)); APOverlappingBSSScan(pAd); } RTMP_11N_D3_TimerInit(pAd); // RTMPInitTimer(pAd, &pAd->CommonCfg.Bss2040CoexistTimer, GET_TIMER_FUNCTION(Bss2040CoexistTimeOut), pAd, FALSE); #endif // DOT11N_DRAFT3 // #endif // DOT11_N_SUPPORT // #ifdef RELASE_EXCLUDE /* 3090, 3090A and 3390 all support hadware tone radar function. But the soluation of those are different. 3090 is the old one. */ #endif // RELASE_EXCLUDE // APStartUp(pAd); DBGPRINT(RT_DEBUG_OFF, ("Main bssid = %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pAd->ApCfg.MBSSID[BSS0].Bssid))); } #endif // CONFIG_AP_SUPPORT // }// end of else #ifdef WSC_INCLUDED #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { INT apidx; #ifdef HOSTAPD_SUPPORT if (pAd->ApCfg.Hostapd == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("WPS is control by hostapd now.\n")); } else #endif //HOSTAPD_SUPPORT// for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { PWSC_CTRL pWscControl; UCHAR zeros16[16]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl; DBGPRINT(RT_DEBUG_TRACE, ("Generate UUID for apidx(%d)\n", apidx)); if (NdisEqualMemory(&pWscControl->Wsc_Uuid_E[0], zeros16, UUID_LEN_HEX)) WscGenerateUUID(pAd, &pWscControl->Wsc_Uuid_E[0], &pWscControl->Wsc_Uuid_Str[0], apidx, FALSE); WscInit(pAd, FALSE, apidx); if (pWscControl->WscEnrolleePinCode == 0) { pWscControl->WscEnrolleePinCode = GenerateWpsPinCode(pAd, FALSE, apidx); pWscControl->WscEnrolleePinCodeLen = 8; } } } #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { PWSC_CTRL pWscControl = &pAd->StaCfg.WscControl; WscGenerateUUID(pAd, &pWscControl->Wsc_Uuid_E[0], &pWscControl->Wsc_Uuid_Str[0], 0, FALSE); WscInit(pAd, BSS0); if (pWscControl->WscEnrolleePinCode == 0) { pWscControl->WscEnrolleePinCode = GenerateWpsPinCode(pAd, BSS0); pWscControl->WscEnrolleePinCodeLen = 8; } } #endif // CONFIG_STA_SUPPORT // /* WSC hardware push button function 0811 */ WSC_HDR_BTN_Init(pAd); #endif // WSC_INCLUDED // // Set up the Mac address RtmpOSNetDevAddrSet(pAd->net_dev, &pAd->CurrentAddress[0]); // Various AP function init #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef MBSS_SUPPORT /* the function can not be moved to RT2860_probe() even register_netdev() is changed as register_netdevice(). Or in some PC, kernel will panic (Fedora 4) */ RT28xx_MBSS_Init(pAd, pAd->net_dev); #endif // MBSS_SUPPORT // #ifdef WDS_SUPPORT RT28xx_WDS_Init(pAd, pAd->net_dev); #endif // WDS_SUPPORT // #ifdef APCLI_SUPPORT RT28xx_ApCli_Init(pAd, pAd->net_dev); #endif // APCLI_SUPPORT // } #endif // CONFIG_AP_SUPPORT // #ifdef RTMP_RBUS_SUPPORT #ifdef VIDEO_TURBINE_SUPPORT VideoTurbineDynamicTune(pAd); #endif // VIDEO_TURBINE_SUPPORT // #endif // RTMP_RBUS_SUPPORT // #ifdef RTMP_RBUS_SUPPORT #ifdef RT3XXX_ANTENNA_DIVERSITY_SUPPORT RT3XXX_AntDiversity_Init(pAd); #endif // RT3XXX_ANTENNA_DIVERSITY_SUPPORT // #endif // RTMP_RBUS_SUPPORT // #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef MAT_SUPPORT MATEngineInit(pAd); #endif // MAT_SUPPORT // #ifdef CLIENT_WDS CliWds_ProxyTabInit(pAd); #endif // CLIENT_WDS // } #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { #ifdef DOT11Z_TDLS_SUPPORT TDLS_Table_Init(pAd); #endif // DOT11Z_TDLS_SUPPORT // #ifdef WPA_SUPPLICANT_SUPPORT #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT // send wireless event to wpa_supplicant for infroming interface up. RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_INTERFACE_UP, NULL, NULL, 0); #endif // NATIVE_WPA_SUPPLICANT_SUPPORT // #endif // WPA_SUPPLICANT_SUPPORT // } #endif // CONFIG_STA_SUPPORT // #if defined(RT2883) || defined(RT3883) #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { if (IS_RT2883(pAd) || IS_RT3883(pAd)) { #ifdef RANGE_EXT_SUPPORT RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, 0xedcba980); #endif // RANGE_EXT_SUPPORT // RTMP_IO_WRITE32(pAd, TX_FBK_CFG_3S_0, 0x12111008); RTMP_IO_WRITE32(pAd, TX_FBK_CFG_3S_1, 0x16151413); } #ifdef STREAM_MODE_SUPPORT if (pAd->CommonCfg.StreamMode > 0) { ULONG streamWord = StreamModeRegVal(pAd); RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR0_L, (ULONG)(pAd->CommonCfg.StreamModeMac[0][0]) | (ULONG)(pAd->CommonCfg.StreamModeMac[0][1] << 8) | (ULONG)(pAd->CommonCfg.StreamModeMac[0][2] << 16) | (ULONG)(pAd->CommonCfg.StreamModeMac[0][3] << 24)); RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR0_H, streamWord | (ULONG)(pAd->CommonCfg.StreamModeMac[0][4]) | (ULONG)(pAd->CommonCfg.StreamModeMac[0][5] << 8)); RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR1_L, (ULONG)(pAd->CommonCfg.StreamModeMac[1][0]) | (ULONG)(pAd->CommonCfg.StreamModeMac[1][1] << 8) | (ULONG)(pAd->CommonCfg.StreamModeMac[1][2] << 16) | (ULONG)(pAd->CommonCfg.StreamModeMac[1][3] << 24)); RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR1_H, streamWord | (ULONG)(pAd->CommonCfg.StreamModeMac[1][4]) | (ULONG)(pAd->CommonCfg.StreamModeMac[1][5] << 8)); RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR2_L, (ULONG)(pAd->CommonCfg.StreamModeMac[2][0]) | (ULONG)(pAd->CommonCfg.StreamModeMac[2][1] << 8) | (ULONG)(pAd->CommonCfg.StreamModeMac[2][2] << 16) | (ULONG)(pAd->CommonCfg.StreamModeMac[2][3] << 24)); RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR2_H, streamWord | (ULONG)(pAd->CommonCfg.StreamModeMac[2][4]) | (ULONG)(pAd->CommonCfg.StreamModeMac[2][5] << 8)); RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR3_L, (ULONG)(pAd->CommonCfg.StreamModeMac[3][0]) | (ULONG)(pAd->CommonCfg.StreamModeMac[3][1] << 8) | (ULONG)(pAd->CommonCfg.StreamModeMac[3][2] << 16) | (ULONG)(pAd->CommonCfg.StreamModeMac[3][3] << 24)); RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR3_H, streamWord | (ULONG)(pAd->CommonCfg.StreamModeMac[3][4]) | (ULONG)(pAd->CommonCfg.StreamModeMac[3][5] << 8)); } #endif // STREAM_MODE_SUPPORT // } #endif // CONFIG_AP_SUPPORT // if (pAd->CommonCfg.FineAGC) { UINT8 BBPValue = 0; BBP_IO_READ8_BY_REG_ID(pAd, BBP_R65, &BBPValue); BBPValue |= 0x40; // turn on fine AGC BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R65, BBPValue); } else { UINT8 BBPValue = 0; BBP_IO_READ8_BY_REG_ID(pAd, BBP_R65, &BBPValue); BBPValue &= ~0x40; // turn off fine AGC BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R65, BBPValue); } #endif // defined(RT2883) || defined(RT3883) // #ifdef DOT11_N_SUPPORT #ifdef TXBF_SUPPORT if (pAd->CommonCfg.ITxBfTimeout) { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R179, 0x02); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R180, 0); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R182, pAd->CommonCfg.ITxBfTimeout & 0xFF); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R180, 1); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R182, (pAd->CommonCfg.ITxBfTimeout>>8) & 0xFF); }
int rt28xx_init( IN PRTMP_ADAPTER pAd, IN PSTRING pDefaultMac, IN PSTRING pHostName) { UINT index; UCHAR TmpPhy; NDIS_STATUS Status; UINT32 MacCsr0 = 0; UINT16 ChipId = 0; // reset Adapter flags RTMP_CLEAR_FLAGS(pAd); // Init BssTab & ChannelInfo tabbles for auto channel select. #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { //#ifdef AUTO_CH_SELECT_ENHANCE AutoChBssTableInit(pAd); ChannelInfoInit(pAd); //#endif // AUTO_CH_SELECT_ENHANCE // } #endif // CONFIG_AP_SUPPORT // #ifdef DOT11_N_SUPPORT // Allocate BA Reordering memory if (ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM) != TRUE) goto err1; #endif // DOT11_N_SUPPORT // // Make sure MAC gets ready. index = 0; do { RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0); pAd->MACVersion = MacCsr0; /* The purpose is to identify RT5390H */ RT28xx_EEPROM_READ16(pAd, 0x00, ChipId); pAd->ChipId = ChipId; if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF)) break; if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) goto err1; RTMPusecDelay(10); } while (index++ < 100); DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion)); #ifdef RT5390 if (IS_RT5390H(pAd)) DBGPRINT(RT_DEBUG_ERROR, ("The chip belongs to 0x%04x\n", pAd->ChipId)); #endif /* RT5390 */ #ifdef SPECIFIC_BCN_BUF_SUPPORT pAd->BcnCB.DYN_MAX_MBSSID_NUM = 1; if (IS_RT5390(pAd) || IS_RT3593(pAd)) { pAd->BcnCB.bHighShareMemSupport = 1; pAd->BcnCB.DYN_HW_BEACON_BASE0 = 0x4000; pAd->BcnCB.DYN_HW_BEACON_MAX_SIZE = 0x2000; pAd->BcnCB.DYN_HW_BEACON_MAX_COUNT = 16; #ifdef MBSS_SUPPORT #ifdef APCLI_SUPPORT pAd->BcnCB.DYN_MAX_MBSSID_NUM = 8 - MAX_MESH_NUM; #else pAd->BcnCB.DYN_MAX_MBSSID_NUM = 16 - MAX_MESH_NUM; #endif // APCLI_SUPPORT // #endif // MBSS_SUPPORT // } else { pAd->BcnCB.bHighShareMemSupport = 0; pAd->BcnCB.DYN_HW_BEACON_BASE0 = 0x7800; pAd->BcnCB.DYN_HW_BEACON_MAX_SIZE = 0x1000; pAd->BcnCB.DYN_HW_BEACON_MAX_COUNT = 8; #ifdef MBSS_SUPPORT pAd->BcnCB.DYN_MAX_MBSSID_NUM = (pAd->BcnCB.DYN_HW_BEACON_MAX_COUNT - MAX_MESH_NUM - MAX_APCLI_NUM); #endif // MBSS_SUPPORT // } #endif // SPECIFIC_BCN_BUF_SUPPORT // #ifdef RTMP_MAC_PCI #if defined(RT3090) || defined(RT3592) || defined(RT3390) || defined(RT3593) || defined(RT5390) /*Iverson patch PCIE L1 issue to make sure that driver can be read,write ,BBP and RF register at pcie L.1 level */ if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd) || IS_RT3593(pAd) || IS_RT5390(pAd))&&pAd->infType==RTMP_DEV_INF_PCIE) { RTMP_IO_READ32(pAd, AUX_CTRL, &MacCsr0); MacCsr0 |= 0x402; RTMP_IO_WRITE32(pAd, AUX_CTRL, MacCsr0); DBGPRINT(RT_DEBUG_TRACE, ("AUX_CTRL = 0x%x\n", MacCsr0)); } #endif // RT3090 // // To fix driver disable/enable hang issue when radio off RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x2); #endif // RTMP_MAC_PCI // // Disable DMA RT28XXDMADisable(pAd); // Load 8051 firmware Status = NICLoadFirmware(pAd); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status)); goto err1; } NICLoadRateSwitchingParams(pAd); // Disable interrupts here which is as soon as possible // This statement should never be true. We might consider to remove it later #ifdef RTMP_MAC_PCI if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) { RTMP_ASIC_INTERRUPT_DISABLE(pAd); } #endif // RTMP_MAC_PCI // #ifdef RESOURCE_PRE_ALLOC Status = RTMPInitTxRxRingMemory(pAd); #else Status = RTMPAllocTxRxRingMemory(pAd); #endif // RESOURCE_PRE_ALLOC // if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("RTMPAllocTxRxMemory failed, Status[=0x%08x]\n", Status)); goto err2; } RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); // initialize MLME // Status = RtmpMgmtTaskInit(pAd); if (Status != NDIS_STATUS_SUCCESS) goto err3; Status = MlmeInit(pAd); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status)); goto err4; } #ifdef RMTP_RBUS_SUPPORT #ifdef VIDEO_TURBINE_SUPPORT VideoConfigInit(pAd); #endif // VIDEO_TURBINE_SUPPORT // #endif // RMTP_RBUS_SUPPORT // // Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default // UserCfgInit(pAd); Status = RtmpNetTaskInit(pAd); if (Status != NDIS_STATUS_SUCCESS) goto err5; // COPY_MAC_ADDR(pAd->ApCfg.MBSSID[apidx].Bssid, netif->hwaddr); // pAd->bForcePrintTX = TRUE; CfgInitHook(pAd); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) APInitialize(pAd); #endif // CONFIG_AP_SUPPORT // #ifdef BLOCK_NET_IF initblockQueueTab(pAd); #endif // BLOCK_NET_IF // Status = MeasureReqTabInit(pAd); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("MeasureReqTabInit failed, Status[=0x%08x]\n",Status)); goto err6; } Status = TpcReqTabInit(pAd); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("TpcReqTabInit failed, Status[=0x%08x]\n",Status)); goto err6; } // // Init the hardware, we need to init asic before read registry, otherwise mac register will be reset // Status = NICInitializeAdapter(pAd, TRUE); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status)); if (Status != NDIS_STATUS_SUCCESS) goto err6; } #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { } #endif // CONFIG_AP_SUPPORT // // Read parameters from Config File /* unknown, it will be updated in NICReadEEPROMParameters */ pAd->RfIcType = RFIC_UNKNOWN; Status = RTMPReadParametersHook(pAd); DBGPRINT(RT_DEBUG_OFF, ("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("RTMPReadParametersHook failed, Status[=0x%08x]\n",Status)); goto err6; } #ifdef DOT11_N_SUPPORT //Init Ba Capability parameters. // RT28XX_BA_INIT(pAd); pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable; pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; // UPdata to HT IE pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; #endif // DOT11_N_SUPPORT // // after reading Registry, we now know if in AP mode or STA mode // Load 8051 firmware; crash when FW image not existent // Status = NICLoadFirmware(pAd); // if (Status != NDIS_STATUS_SUCCESS) // break; DBGPRINT(RT_DEBUG_OFF, ("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); // We should read EEPROM for all cases. rt2860b NICReadEEPROMParameters(pAd, (PUCHAR)pDefaultMac); DBGPRINT(RT_DEBUG_OFF, ("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); NICInitAsicFromEEPROM(pAd); //rt2860b #ifdef RTMP_INTERNAL_TX_ALC // // Initialize the desired TSSI table // InitDesiredTSSITable(pAd); #endif // RTMP_INTERNAL_TX_ALC // #if defined(RT5390) || defined(RT5370) // // Temperature compensation, initialize the lookup table // DBGPRINT(RT_DEBUG_ERROR, ("IS_RT5392 = %d, bAutoTxAgcG = %d\n", IS_RT5392(pAd), pAd->bAutoTxAgcG)); if (IS_RT5392(pAd) && pAd->bAutoTxAgcG && pAd->CommonCfg.TempComp != 0) { InitLookupTable(pAd); } #endif // defined(RT5390) || defined(RT5370) // // Set PHY to appropriate mode TmpPhy = pAd->CommonCfg.PhyMode; pAd->CommonCfg.PhyMode = 0xff; RTMPSetPhyMode(pAd, TmpPhy); #ifdef DOT11_N_SUPPORT SetCommonHT(pAd); #endif // DOT11_N_SUPPORT // // No valid channels. if (pAd->ChannelListNum == 0) { DBGPRINT(RT_DEBUG_ERROR, ("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n")); goto err6; } #ifdef DOT11_N_SUPPORT DBGPRINT(RT_DEBUG_OFF, ("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0], pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2], pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4])); #endif // DOT11_N_SUPPORT // #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef AP_QLOAD_SUPPORT /* init QBSS Element */ QBSS_LoadInit(pAd); #endif // AP_QLOAD_SUPPORT // //#ifdef DOT11K_RRM_SUPPORT // RRM_CfgInit(pAd); //#endif // DOT11K_RRM_SUPPORT // } #endif // CONFIG_AP_SUPPORT // // APInitialize(pAd); #ifdef IKANOS_VX_1X0 VR_IKANOS_FP_Init(pAd->ApCfg.BssidNum, pAd->PermanentAddress); #endif // IKANOS_VX_1X0 // #ifdef CONFIG_AP_SUPPORT // // Initialize RF register to default value // if (pAd->OpMode == OPMODE_AP) { AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); } #endif // CONFIG_AP_SUPPORT // /* Some modules init must be called before APStartUp(). Or APStartUp() will make up beacon content and call other modules API to get some information to fill. */ #ifdef WMM_ACM_SUPPORT #ifdef CONFIG_AP_SUPPORT ACMP_Init(pAd, pAd->CommonCfg.APEdcaParm.bACM[0], pAd->CommonCfg.APEdcaParm.bACM[1], pAd->CommonCfg.APEdcaParm.bACM[2], pAd->CommonCfg.APEdcaParm.bACM[3], 0); #endif // CONFIG_AP_SUPPORT // #endif // WMM_ACM_SUPPORT // if (pAd && (Status != NDIS_STATUS_SUCCESS)) { // // Undo everything if it failed // if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { // NdisMDeregisterInterrupt(&pAd->Interrupt); RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); } // RTMPFreeAdapter(pAd); // we will free it in disconnect() } else if (pAd) { // Microsoft HCT require driver send a disconnect event after driver initialization. OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE); DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n")); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { if (pAd->ApCfg.bAutoChannelAtBootup || (pAd->CommonCfg.Channel == 0)) { UINT8 BBPValue = 0; // Enable Interrupt first due to we need to scan channel to receive beacons. RTMP_IRQ_ENABLE(pAd); // Now Enable RxTx RTMPEnableRxTx(pAd); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP); // Let BBP register at 20MHz to do scan RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); BBPValue &= (~0x18); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); DBGPRINT(RT_DEBUG_ERROR, ("SYNC - BBP R4 to 20MHz.l\n")); // Now we can receive the beacon and do the listen beacon // use default BW to select channel pAd->CommonCfg.Channel = AP_AUTO_CH_SEL(pAd, pAd->ApCfg.AutoChannelAlg); pAd->ApCfg.bAutoChannelAtBootup = FALSE; } #ifdef DOT11_N_SUPPORT // If phymode > PHY_11ABGN_MIXED and BW=40 check extension channel, after select channel N_ChannelCheck(pAd); #ifdef DOT11N_DRAFT3 /* We only do this Overlapping BSS Scan when system up, for the other situation of channel changing, we depends on station's report to adjust ourself. */ if (pAd->CommonCfg.bForty_Mhz_Intolerant == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("Disable 20/40 BSSCoex Channel Scan(BssCoex=%d, 40MHzIntolerant=%d)\n", pAd->CommonCfg.bBssCoexEnable, pAd->CommonCfg.bForty_Mhz_Intolerant)); } else if(pAd->CommonCfg.bBssCoexEnable == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("Enable 20/40 BSSCoex Channel Scan(BssCoex=%d)\n", pAd->CommonCfg.bBssCoexEnable)); APOverlappingBSSScan(pAd); } RTMP_11N_D3_TimerInit(pAd); // RTMPInitTimer(pAd, &pAd->CommonCfg.Bss2040CoexistTimer, GET_TIMER_FUNCTION(Bss2040CoexistTimeOut), pAd, FALSE); #endif // DOT11N_DRAFT3 // #endif // DOT11_N_SUPPORT // #ifdef RT3090 #ifdef TONE_RADAR_DETECT_SUPPORT if (IS_RT3090A(pAd) || IS_RT3390(pAd) || IS_RT5390(pAd)) pAd->CommonCfg.carrier_func=TONE_RADAR_V2; else pAd->CommonCfg.carrier_func=TONE_RADAR_V1; #endif // TONE_RADAR_DETECT_SUPPORT // #endif // RT3090 // APStartUp(pAd); DBGPRINT(RT_DEBUG_OFF, ("Main bssid = %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pAd->ApCfg.MBSSID[BSS0].Bssid))); } #endif // CONFIG_AP_SUPPORT // }// end of else #ifdef WSC_INCLUDED #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { INT apidx; #ifdef HOSTAPD_SUPPORT if (pAd->ApCfg.Hostapd == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("WPS is control by hostapd now.\n")); } else #endif //HOSTAPD_SUPPORT// for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { PWSC_CTRL pWscControl; UCHAR zeros16[16]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl; DBGPRINT(RT_DEBUG_TRACE, ("Generate UUID for apidx(%d)\n", apidx)); if (NdisEqualMemory(&pWscControl->Wsc_Uuid_E[0], zeros16, UUID_LEN_HEX)) WscGenerateUUID(pAd, &pWscControl->Wsc_Uuid_E[0], &pWscControl->Wsc_Uuid_Str[0], apidx, FALSE); WscInit(pAd, FALSE, apidx); } } #endif // CONFIG_AP_SUPPORT // /* WSC hardware push button function 0811 */ WSC_HDR_BTN_Init(pAd); #endif // WSC_INCLUDED // // Set up the Mac address RtmpOSNetDevAddrSet(pAd->net_dev, &pAd->CurrentAddress[0]); // Various AP function init #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef MBSS_SUPPORT /* the function can not be moved to RT2860_probe() even register_netdev() is changed as register_netdevice(). Or in some PC, kernel will panic (Fedora 4) */ RT28xx_MBSS_Init(pAd, pAd->net_dev); #endif // MBSS_SUPPORT // #ifdef WDS_SUPPORT RT28xx_WDS_Init(pAd, pAd->net_dev); #endif // WDS_SUPPORT // #ifdef APCLI_SUPPORT RT28xx_ApCli_Init(pAd, pAd->net_dev); #endif // APCLI_SUPPORT // } #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef MAT_SUPPORT MATEngineInit(pAd); #endif // MAT_SUPPORT // #ifdef CLIENT_WDS CliWds_ProxyTabInit(pAd); #endif // CLIENT_WDS // } #endif // CONFIG_AP_SUPPORT // #ifdef RT33xx if (IS_RT3390(pAd)) { RTMP_TxEvmCalibration(pAd); } #endif // RT33xx // DBGPRINT_S(Status, ("<==== rt28xx_init, Status=%x\n", Status)); return TRUE; err6: MeasureReqTabExit(pAd); TpcReqTabExit(pAd); err5: RtmpNetTaskExit(pAd); UserCfgExit(pAd); err4: MlmeHalt(pAd); err3: RtmpMgmtTaskExit(pAd); err2: #ifdef RESOURCE_PRE_ALLOC RTMPResetTxRxRingMemory(pAd); #else RTMPFreeTxRxRingMemory(pAd); #endif // RESOURCE_PRE_ALLOC // err1: #ifdef DOT11_N_SUPPORT if(pAd->mpdu_blk_pool.mem) os_free_mem(pAd, pAd->mpdu_blk_pool.mem); // free BA pool #endif // DOT11_N_SUPPORT // // shall not set priv to NULL here because the priv didn't been free yet. //net_dev->priv = 0; #ifdef INF_AMAZON_SE err0: #endif // INF_AMAZON_SE // #ifdef ST err0: #endif // ST // DBGPRINT(RT_DEBUG_ERROR, ("!!! rt28xx Initialized fail !!!\n")); return FALSE; }
/**************************************************************************//** * @brief Setup the ACMP *****************************************************************************/ void setupACMP(void) { /* ACMP configuration constant table. */ static const ACMP_Init_TypeDef initACMP = { .fullBias = false, /* fullBias */ .halfBias = true, /* halfBias */ .biasProg = 0xE, /* biasProg */ .interruptOnFallingEdge = false, /* interrupt on rising edge */ .interruptOnRisingEdge = false, /* interrupt on falling edge */ .warmTime = acmpWarmTime512, /* 512 cycle warmup to be safe */ .hysteresisLevel = acmpHysteresisLevel0, /* hysteresis level 0 */ .inactiveValue = false, /* inactive value */ .lowPowerReferenceEnabled = false, /* low power reference */ .vddLevel = 0x0D /* VDD level */ }; /* Initialize ACMP */ ACMP_Init(ACMP0, &initACMP); ACMP_ChannelSet(ACMP0, acmpChannelVDD, acmpChannel7); /* don't disable ACMP so that output can be routed out to a pin */ ACMP0->CTRL &= ~ACMP_CTRL_EN; } /**************************************************************************//** * @brief Setup the LESENSE *****************************************************************************/ void setupLESENSE(void) { /* LESENSE channel configuration constant table. */ static const LESENSE_ChAll_TypeDef initChs = LESENSE_LCSENSE_SCAN_CONF; /* LESENSE central configuration constant table. */ static const LESENSE_Init_TypeDef initLESENSE = { .coreCtrl = { .scanStart = lesenseScanStartPeriodic, .prsSel = lesensePRSCh0, .scanConfSel = lesenseScanConfDirMap, .invACMP0 = false, .invACMP1 = false, .dualSample = false, .storeScanRes = false, .bufOverWr = true, .bufTrigLevel = lesenseBufTrigHalf, .wakeupOnDMA = lesenseDMAWakeUpDisable, .biasMode = lesenseBiasModeDutyCycle, .debugRun = false }, .timeCtrl = { .startDelay = 0U }, .perCtrl = { .dacCh0Data = lesenseDACIfData, .dacCh0ConvMode = lesenseDACConvModeSampleOff, .dacCh0OutMode = lesenseDACOutModeDisable, .dacCh1Data = lesenseDACIfData, .dacCh1ConvMode = lesenseDACConvModeSampleOff, .dacCh1OutMode = lesenseDACOutModePin, .dacPresc = 31U, .dacRef = lesenseDACRefVdd, .acmp0Mode = lesenseACMPModeMux, .acmp1Mode = lesenseACMPModeDisable, .warmupMode = lesenseWarmupModeNormal }, .decCtrl =
/**************************************************************************//** * @brief Sets up the DAC *****************************************************************************/ void setupDAC(void) { /* Configuration structure for the DAC */ static const DAC_Init_TypeDef dacInit = { .refresh = dacRefresh8, .reference = dacRefVDD, .outMode = dacOutputPin, .convMode = dacConvModeContinuous, .prescale = 0, .lpEnable = false, .ch0ResetPre = false, .outEnablePRS = false, .sineEnable = false, .diff = false }; /* Initialize DAC */ DAC_Init(DAC0, &dacInit); /* Set data for DAC channel 0 */ writeDataDAC(DAC0, (unsigned int) DAC_DATA, DAC_CHANNEL); } /**************************************************************************//** * @brief Write DAC conversion value *****************************************************************************/ void writeDataDAC(DAC_TypeDef *dac, unsigned int value, unsigned int ch) { /* Write data output value to the correct register. */ if (!ch) { /* Write data to DAC ch 0 */ dac->CH0DATA = value; } else { /* Write data to DAC ch 1 */ dac->CH1DATA = value; } } /**************************************************************************//** * @brief Sets up the ACMP *****************************************************************************/ void setupACMP(void) { /* There is no default configuration for this */ static const ACMP_Init_TypeDef acmpInit = { .fullBias = false, .halfBias = true, .biasProg = 0xF, .interruptOnFallingEdge = false, .interruptOnRisingEdge = false, .warmTime = acmpWarmTime4, .hysteresisLevel = acmpHysteresisLevel0, .inactiveValue = false, .lowPowerReferenceEnabled = false, .vddLevel = ACMP_VDD_SCALE, .enable = false }; /* Initialize ACMPs */ ACMP_Init(ACMP0, &acmpInit); ACMP_Init(ACMP1, &acmpInit); /* Select Vdd as negative reference * Positive reference is controlled by LESENSE */ ACMP_ChannelSet(ACMP0, acmpChannelVDD, acmpChannel6); ACMP_ChannelSet(ACMP1, acmpChannelVDD, acmpChannel4); } /**************************************************************************//** * @brief Sets up the LESENSE *****************************************************************************/ void setupLESENSE(void) { static const LESENSE_Init_TypeDef initLesense = { .coreCtrl = { .scanStart = lesenseScanStartPeriodic, .prsSel = lesensePRSCh0, .scanConfSel = lesenseScanConfDirMap, .invACMP0 = false, .invACMP1 = false, .dualSample = false, .storeScanRes = false, .bufOverWr = true, .bufTrigLevel = lesenseBufTrigHalf, .wakeupOnDMA = lesenseDMAWakeUpDisable, .biasMode = lesenseBiasModeDutyCycle, .debugRun = false }, .timeCtrl = { .startDelay = 0 }, .perCtrl = { .dacCh0Data = lesenseDACIfData, .dacCh0ConvMode = lesenseDACConvModeSampleOff, .dacCh0OutMode = lesenseDACOutModeDisable, .dacCh1Data = lesenseDACIfData, .dacCh1ConvMode = lesenseDACConvModeSampleOff, .dacCh1OutMode = lesenseDACOutModePin, .dacPresc = 31, .dacRef = lesenseDACRefVdd, .acmp0Mode = lesenseACMPModeMux, .acmp1Mode = lesenseACMPModeMux, .warmupMode = lesenseWarmupModeNormal }, .decCtrl = { .decInput = lesenseDecInputSensorSt, .initState = 0, .chkState = true, .intMap = false, .hystPRS0 = false, .hystPRS1 = false, .hystPRS2 = false, .hystIRQ = false, .prsCount = true, .prsChSel0 = lesensePRSCh0, .prsChSel1 = lesensePRSCh1, .prsChSel2 = lesensePRSCh2, .prsChSel3 = lesensePRSCh3 } };
/**************************************************************************//** * @brief Setup the ACMP *****************************************************************************/ void setupACMP(void) { /* ACMP configuration constant table. */ static const ACMP_Init_TypeDef initACMP = { .fullBias = false, /* fullBias */ .halfBias = true, /* halfBias */ .biasProg = 0x0, /* biasProg */ .interruptOnFallingEdge = false, /* interrupt on rising edge */ .interruptOnRisingEdge = false, /* interrupt on falling edge */ .warmTime = acmpWarmTime512, /* 512 cycle warmup to be safe */ .hysteresisLevel = acmpHysteresisLevel5, /* hysteresis level 5 */ .inactiveValue = false, /* inactive value */ .lowPowerReferenceEnabled = false, /* low power reference */ .vddLevel = 0x00, /* VDD level */ .enable = false /* Don't request enabling. */ }; /* Configure ACMP. */ ACMP_Init(ACMP0, &initACMP); /* Disable ACMP0 out to a pin. */ ACMP_GPIOSetup(ACMP0, 0, false, false); /* Set up ACMP negSel to VDD, posSel is controlled by LESENSE. */ ACMP_ChannelSet(ACMP0, acmpChannelVDD, acmpChannel0); /* LESENSE controls ACMP thus ACMP_Enable(ACMP0) should NOT be called in order * to ensure lower current consumption. */ } /**************************************************************************//** * @brief Setup the LESENSE *****************************************************************************/ void setupLESENSE(void) { /* LESENSE channel configuration constant table. */ static const LESENSE_ChAll_TypeDef initChs = LESENSE_LIGHTSENSE_SCAN_CONF; /* LESENSE alternate excitation channel configuration constant table. */ static const LESENSE_ConfAltEx_TypeDef initAltEx = LESENSE_LIGHTSENSE_ALTEX_CONF; /* LESENSE central configuration constant table. */ static const LESENSE_Init_TypeDef initLESENSE = { .coreCtrl = { .scanStart = lesenseScanStartPeriodic, .prsSel = lesensePRSCh0, .scanConfSel = lesenseScanConfDirMap, .invACMP0 = false, .invACMP1 = false, .dualSample = false, .storeScanRes = false, .bufOverWr = true, .bufTrigLevel = lesenseBufTrigHalf, .wakeupOnDMA = lesenseDMAWakeUpDisable, .biasMode = lesenseBiasModeDutyCycle, .debugRun = false }, .timeCtrl = { .startDelay = 0U }, .perCtrl = { .dacCh0Data = lesenseDACIfData, .dacCh0ConvMode = lesenseDACConvModeDisable, .dacCh0OutMode = lesenseDACOutModeDisable, .dacCh1Data = lesenseDACIfData, .dacCh1ConvMode = lesenseDACConvModeDisable, .dacCh1OutMode = lesenseDACOutModeDisable, .dacPresc = 0U, .dacRef = lesenseDACRefBandGap, .acmp0Mode = lesenseACMPModeMuxThres, .acmp1Mode = lesenseACMPModeMuxThres, .warmupMode = lesenseWarmupModeNormal }, .decCtrl =