/***************************************************************************** * FUNCTION: ChipReset * * RETURNS: N/A * * PARAMS: * N/A * * * NOTES: Performs the necessary SPI operations to cause the MRF24WB0M to reset. * This function also implements a delay so that it will not return until * the WiFi device is ready to receive messages again. The delay time will * vary depending on the amount of code that must be loaded from serial * flash. *****************************************************************************/ static void ChipReset(void) { UINT16 value; UINT32 timeoutPeriod; UINT32 startTickCount; timeoutPeriod = TICKS_PER_SECOND; /* 1000 ms */ /* needed for Microchip PICTail (chip enable active low) */ WF_SetCE_N(WF_LOW); /* set low to enable regulator */ /* Configure reset pin */ WF_SetRST_N(WF_HIGH); /* Let SPI lines settle before first SPI transaction */ DelayMs(1); /* clear the power bit to disable low power mode on the MRF24WB0M */ Write16BitWFRegister(WF_PSPOLL_H_REG, 0x0000); /* Set HOST_RESET bit in register to put device in reset */ Write16BitWFRegister(WF_HOST_RESET_REG, Read16BitWFRegister(WF_HOST_RESET_REG) | WF_HOST_RESET_MASK); /* Clear HOST_RESET bit in register to take device out of reset */ Write16BitWFRegister(WF_HOST_RESET_REG, Read16BitWFRegister(WF_HOST_RESET_REG) & ~WF_HOST_RESET_MASK); /* after reset is started poll register to determine when HW reset has completed */ startTickCount = (UINT32)TickGet(); do { Write16BitWFRegister(WF_INDEX_ADDR_REG, WF_HW_STATUS_REG); value = Read16BitWFRegister(WF_INDEX_DATA_REG); if (TickGet() - startTickCount >= timeoutPeriod) { WF_ASSERT(FALSE); } } while ( (value & WF_HW_STATUS_NOT_IN_RESET_MASK) == 0); /* if SPI not connected will read all 1's */ WF_ASSERT(value != 0xffff); /* now that chip has come out of HW reset, poll the FIFO byte count register */ /* which will be set to a non-zero value when the MRF24WB0M initialization is */ /* complete. */ startTickCount = (UINT32)TickGet(); do { value = Read16BitWFRegister(WF_HOST_WFIFO_BCNT0_REG); if (TickGet() - startTickCount >= timeoutPeriod) { WF_ASSERT(FALSE); } } while (value == 0); }
/***************************************************************************** * FUNCTION: WFHardwareInit * * RETURNS: error code * * PARAMS: None * * NOTES: Initializes CPU Host hardware interfaces (SPI, External Interrupt). * Also resets the MRF24W. *****************************************************************************/ void WFHardwareInit(void) { UINT8 mask8; UINT16 mask16; g_MgmtReadMsgReady = FALSE; g_ExIntNeedsServicing = FALSE; RawMoveState.rawInterrupt = 0; RawMoveState.waitingForRawMoveCompleteInterrupt = FALSE; /* not waiting for RAW move complete */ /* initialize the SPI interface */ WF_SpiInit(); #if defined(__Digilent_Build__) WF_SetRST_N(WF_LOW); // put module into reset; should already be there. // we have taken out the next 3 lines as MarkW says we do not need to toggle HIB to competely reset the part. // WF_SetCE_N(WF_HIGH); // disable module, turn off regulators // DelayMs(200); // 200ms to allow decoupling caps to discharge, between the 70uF in the MRF , this can take some time. // WF_SetCE_N(WF_LOW); // enable module, turn on regulators; careful this has an inrush that can drag the Power supply below min. if the MRF is not decoupled well enough. DelayMs(2); // Spec says at least 1ms to let the regulators settle, leave this here to ensure timing from board powerup. WF_SetRST_N(WF_HIGH); // take module out of of reset DelayMs(5); // Per MarkW’s email, leave 5ms here before accessing the SPI port #else /* Toggle the module into and then out of hibernate */ WF_SetCE_N(WF_HIGH); /* disable module */ WF_SetCE_N(WF_LOW); /* enable module */ /* Toggle the module into and out of reset */ WF_SetRST_N(WF_LOW); // put module into reset WF_SetRST_N(WF_HIGH); // take module out of of reset #endif /* Silicon work-around -- needed for A1 silicon to initialize PLL values correctly */ ResetPll(); /* Soft reset the MRF24W (using SPI bus to write/read MRF24W registers */ ChipReset(); /* disable the interrupts gated by the 16-bit host int register */ HostInterrupt2RegInit(WF_HOST_2_INT_MASK_ALL_INT, (UINT16)WF_INT_DISABLE); /* disable the interrupts gated the by main 8-bit host int register */ HostInterruptRegInit(WF_HOST_INT_MASK_ALL_INT, WF_INT_DISABLE); /* Initialize the External Interrupt for the MRF24W allowing the MRF24W to interrupt */ /* the Host from this point forward. */ WF_EintInit(); WF_EintEnable(); /* enable the following MRF24W interrupts in the INT1 8-bit register */ mask8 = (WF_HOST_INT_MASK_FIFO_1_THRESHOLD | /* Mgmt Rx Msg interrupt */ WF_HOST_INT_MASK_FIFO_0_THRESHOLD | /* Data Rx Msg interrupt */ WF_HOST_INT_MASK_RAW_0_INT_0 | /* RAW0 Move Complete (Data Rx) interrupt */ WF_HOST_INT_MASK_RAW_1_INT_0 | /* RAW1 Move Complete (Data Tx) interrupt */ WF_HOST_INT_MASK_INT2); /* Interrupt 2 interrupt */ HostInterruptRegInit(mask8, WF_INT_ENABLE); /* enable the following MRF24W interrupts in the INT2 16-bit register */ mask16 = (WF_HOST_INT_MASK_RAW_2_INT_0 | /* RAW2 Move Complete (Mgmt Rx) interrupt */ WF_HOST_INT_MASK_RAW_3_INT_0 | /* RAW3 Move Complete (Mgmt Tx) interrupt */ WF_HOST_INT_MASK_RAW_4_INT_0 | /* RAW4 Move Complete (Scratch) interrupt */ WF_HOST_INT_MASK_RAW_5_INT_0 | /* RAW5 Move Complete (Scratch) interrupt */ WF_HOST_INT_MASK_MAIL_BOX_0_WRT); HostInterrupt2RegInit(mask16, WF_INT_ENABLE); /* Disable PS-Poll mode */ WFConfigureLowPowerMode(WF_LOW_POWER_MODE_OFF); }