void ToggleLed(LED_TYPE led) { switch(led) { case CONNECT_LED : GpioToggle(APP_CONNECT_LED);break; case CONTROL_LED : GpioToggle(PURIFIER_LED_PIN_NO);break; case WARN_LED : break; case AQI_LED : break; default : break; } }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file startup_stm32f446xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ uint32_t address = 0, step = 0x00; /* Configure QSPI GPIO */ QSPI_GPIO_Config(); /* Initialize DMA ----------------------------------------------------------*/ DMA_StructInit(&DMA_InitStructure); DMA_DeInit(QSPI_DMA_STREAM); /*DMA configuration*/ DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&QUADSPI->DR ; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Channel = DMA_Channel_3; /* Initialize QuadSPI ------------------------------------------------------*/ QSPI_StructInit(&QSPI_InitStructure); QSPI_InitStructure.QSPI_SShift = QSPI_SShift_HalfCycleShift; QSPI_InitStructure.QSPI_Prescaler = 0x01; /* 90 MHZ */ QSPI_InitStructure.QSPI_CKMode = QSPI_CKMode_Mode0; QSPI_InitStructure.QSPI_CSHTime = QSPI_CSHTime_2Cycle; QSPI_InitStructure.QSPI_FSize = 0x18; QSPI_InitStructure.QSPI_FSelect = QSPI_FSelect_1; QSPI_InitStructure.QSPI_DFlash = QSPI_DFlash_Disable; QSPI_Init(&QSPI_InitStructure); /* Initialize Command Config -----------------------------------------------*/ QSPI_ComConfig_StructInit(&QSPI_ComConfig_InitStructure); QSPI_ComConfig_InitStructure.QSPI_ComConfig_ADSize = QSPI_ComConfig_ADSize_24bit; QSPI_ComConfig_InitStructure.QSPI_ComConfig_IMode = QSPI_ComConfig_IMode_1Line; QSPI_ComConfig_InitStructure.QSPI_ComConfig_ABMode = QSPI_ComConfig_ABMode_NoAlternateByte; QSPI_ComConfig_InitStructure.QSPI_ComConfig_DDRMode = QSPI_ComConfig_DDRMode_Disable; QSPI_ComConfig_InitStructure.QSPI_ComConfig_SIOOMode = QSPI_ComConfig_SIOOMode_Disable; QSPI_ComConfig_InitStructure.QSPI_ComConfig_DHHC = QSPI_ComConfig_DHHC_Enable; QSPI_ComConfig_StructInit(&QSPI_ComConfig_InitStructure); QSPI_Cmd(ENABLE); while(1) { switch(step) { case 0: /* Enable write operations ---------------------------------------------*/ QSPI_Cmd(ENABLE); QSPI_WriteEnable(); /* Erasing Sequence ----------------------------------------------------*/ QSPI_ComConfig_StructInit(&QSPI_ComConfig_InitStructure); QSPI_ComConfig_InitStructure.QSPI_ComConfig_ADSize = QSPI_ComConfig_ADSize_24bit; QSPI_ComConfig_InitStructure.QSPI_ComConfig_IMode = QSPI_ComConfig_IMode_1Line; QSPI_ComConfig_InitStructure.QSPI_ComConfig_ADMode = QSPI_ComConfig_ADMode_1Line; QSPI_ComConfig_InitStructure.QSPI_ComConfig_DMode = QSPI_ComConfig_DMode_NoData; QSPI_ComConfig_InitStructure.QSPI_ComConfig_FMode = QSPI_ComConfig_FMode_Indirect_Write; QSPI_ComConfig_InitStructure.QSPI_ComConfig_Ins = SECTOR_ERASE_CMD; QSPI_ComConfig_Init(&QSPI_ComConfig_InitStructure); /* Set sector address to erase */ QSPI_SetAddress(address); while(QSPI_GetFlagStatus(QSPI_FLAG_TC) == RESET) {} step++; break; case 1: /* Configure automatic polling mode to wait for end of erase -----------*/ QSPI_AutoPollingMemReady(); #if defined(__CC_ARM) FlashAddr = (uint8_t *)(&Load$$QSPI$$Base); MAXTransferSize = (uint32_t)(&Load$$QSPI$$Length); #elif defined(__ICCARM__) FlashAddr = (uint8_t *)(__section_begin(".qspi_init")); MAXTransferSize = __section_size(".qspi_init"); #elif defined(__GNUC__) FlashAddr = (uint8_t *)(&_qspi_init_base); MAXTransferSize = (uint32_t)((uint8_t *)(&_qspi_init_length)); #endif step++; break; case 2: /* Enable write operations ---------------------------------------------*/ QSPI_WriteEnable(); QSPI_DMACmd(ENABLE); /* Writing Sequence ----------------------------------------------------*/ QSPI_SetDataLength(MAXTransferSize); QSPI_ComConfig_StructInit(&QSPI_ComConfig_InitStructure); QSPI_ComConfig_InitStructure.QSPI_ComConfig_IMode = QSPI_ComConfig_IMode_1Line; QSPI_ComConfig_InitStructure.QSPI_ComConfig_ADMode = QSPI_ComConfig_ADMode_1Line; QSPI_ComConfig_InitStructure.QSPI_ComConfig_DMode = QSPI_ComConfig_DMode_4Line; QSPI_ComConfig_InitStructure.QSPI_ComConfig_FMode = QSPI_ComConfig_FMode_Indirect_Write; QSPI_ComConfig_InitStructure.QSPI_ComConfig_ADSize = QSPI_ComConfig_ADSize_32bit; QSPI_ComConfig_InitStructure.QSPI_ComConfig_Ins = QUAD_IN_FAST_PROG_CMD; QSPI_ComConfig_InitStructure.QSPI_ComConfig_DummyCycles = 0; QSPI_ComConfig_Init(&QSPI_ComConfig_InitStructure); /* DMA channel Tx Configuration */ DMA_InitStructure.DMA_BufferSize = MAXTransferSize; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)FlashAddr; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_Priority = DMA_Priority_Low; DMA_Init(QSPI_DMA_STREAM, &DMA_InitStructure); DMA_Cmd(QSPI_DMA_STREAM, ENABLE); /* Wait for the end of Transfer */ while(DMA_GetFlagStatus(QSPI_DMA_STREAM, QSPI_DMA_FLAG_TC) == RESET) {} DMA_ClearFlag(QSPI_DMA_STREAM, QSPI_DMA_FLAG_TC); QSPI_AbortRequest(); DMA_Cmd(QSPI_DMA_STREAM, DISABLE); QSPI_DMACmd(DISABLE); step++; break; case 3: /* Configure automatic polling mode to wait for end of program ---------*/ QSPI_AutoPollingMemReady(); step++; break; case 4: /* Reading Sequence ----------------------------------------------------*/ QSPI_TimeoutCounterCmd(DISABLE); QSPI_MemoryMappedMode_SetTimeout(0); QSPI_ComConfig_InitStructure.QSPI_ComConfig_ADSize = QSPI_ComConfig_ADSize_32bit; QSPI_ComConfig_InitStructure.QSPI_ComConfig_FMode = QSPI_ComConfig_FMode_Memory_Mapped; QSPI_ComConfig_InitStructure.QSPI_ComConfig_ADMode = QSPI_ComConfig_ADMode_4Line; QSPI_ComConfig_InitStructure.QSPI_ComConfig_IMode = QSPI_ComConfig_IMode_1Line; QSPI_ComConfig_InitStructure.QSPI_ComConfig_DMode = QSPI_ComConfig_DMode_4Line; QSPI_ComConfig_InitStructure.QSPI_ComConfig_Ins = QUAD_INOUT_FAST_READ_4_BYTE_ADDR_CMD; QSPI_ComConfig_InitStructure.QSPI_ComConfig_DummyCycles = DUMMY_CLOCK_CYCLES_READ_QUAD; QSPI_ComConfig_Init(&QSPI_ComConfig_InitStructure); GpioToggle(); break; default : TransferStatus = FAILED; break; } } }
/** * Main application entry point. */ int main( void ) { bool isMaster = true; uint8_t i; // Target board initialization BoardInitMcu( ); BoardInitPeriph( ); // Radio initialization RadioEvents.TxDone = OnTxDone; RadioEvents.RxDone = OnRxDone; RadioEvents.TxTimeout = OnTxTimeout; RadioEvents.RxTimeout = OnRxTimeout; RadioEvents.RxError = OnRxError; Radio.Init( &RadioEvents ); Radio.SetChannel( RF_FREQUENCY ); #if defined( USE_MODEM_LORA ) Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, LORA_CODINGRATE, LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); #elif defined( USE_MODEM_FSK ) Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0, FSK_DATARATE, 0, FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON, true, 0, 0, 0, 3000 ); Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, 0, 0,false, true ); #else #error "Please define a frequency band in the compiler options." #endif Radio.Rx( RX_TIMEOUT_VALUE ); while( 1 ) { switch( State ) { case RX: if( isMaster == true ) { if( BufferSize > 0 ) { if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 ) { // Indicates on a LED that the received frame is a PONG GpioToggle( &Led1 ); // Send the next PING frame Buffer[0] = 'P'; Buffer[1] = 'I'; Buffer[2] = 'N'; Buffer[3] = 'G'; // We fill the buffer with numbers for the payload for( i = 4; i < BufferSize; i++ ) { Buffer[i] = i - 4; } DelayMs( 1 ); Radio.Send( Buffer, BufferSize ); } else if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) { // A master already exists then become a slave isMaster = false; GpioWrite( &Led2, 1 ); // Set LED off Radio.Rx( RX_TIMEOUT_VALUE ); } else // valid reception but neither a PING or a PONG message { // Set device as master ans start again isMaster = true; Radio.Rx( RX_TIMEOUT_VALUE ); } } } else { if( BufferSize > 0 ) { if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) { // Indicates on a LED that the received frame is a PING GpioToggle( &Led1 ); // Send the reply to the PONG string Buffer[0] = 'P'; Buffer[1] = 'O'; Buffer[2] = 'N'; Buffer[3] = 'G'; // We fill the buffer with numbers for the payload for( i = 4; i < BufferSize; i++ ) { Buffer[i] = i - 4; } DelayMs( 1 ); Radio.Send( Buffer, BufferSize ); } else // valid reception but not a PING as expected { // Set device as master and start again isMaster = true; Radio.Rx( RX_TIMEOUT_VALUE ); } } } State = LOWPOWER; break; case TX: // Indicates on a LED that we have sent a PING [Master] // Indicates on a LED that we have sent a PONG [Slave] GpioToggle( &Led2 ); Radio.Rx( RX_TIMEOUT_VALUE ); State = LOWPOWER; break; case RX_TIMEOUT: case RX_ERROR: if( isMaster == true ) { // Send the next PING frame Buffer[0] = 'P'; Buffer[1] = 'I'; Buffer[2] = 'N'; Buffer[3] = 'G'; for( i = 4; i < BufferSize; i++ ) { Buffer[i] = i - 4; } DelayMs( 1 ); Radio.Send( Buffer, BufferSize ); } else { Radio.Rx( RX_TIMEOUT_VALUE ); } State = LOWPOWER; break; case TX_TIMEOUT: Radio.Rx( RX_TIMEOUT_VALUE ); State = LOWPOWER; break; case LOWPOWER: default: // Set low power break; } TimerLowPowerHandler( ); } }
/** * @brief Main program * @param None * @retval None */ int main(void) { QSPI_CommandTypeDef sCommand; QSPI_MemoryMappedTypeDef sMemMappedCfg; __IO uint32_t qspi_addr = 0; uint8_t *flash_addr; __IO uint8_t step = 0; uint32_t max_size, size; /* STM32F4xx HAL library initialization: - Configure the Flash prefetch, instruction and Data caches - Systick timer is configured by default as source of time base, but user can eventually implement his proper time base source (a general purpose timer for example or other time source), keeping in mind that Time base duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and handled in milliseconds basis. - Set NVIC Group Priority to 4 - Low Level Initialization: global MSP (MCU Support Package) initialization */ HAL_Init(); /* Configure the system clock to 180 MHz */ SystemClock_Config(); BSP_LED_Init(LED1); BSP_LED_Init(LED3); /* Initialize QuadSPI ------------------------------------------------------ */ QSPIHandle.Instance = QUADSPI; HAL_QSPI_DeInit(&QSPIHandle); QSPIHandle.Init.ClockPrescaler = 1; QSPIHandle.Init.FifoThreshold = 4; QSPIHandle.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE; QSPIHandle.Init.FlashSize = QSPI_FLASH_SIZE; QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_2_CYCLE; QSPIHandle.Init.ClockMode = QSPI_CLOCK_MODE_0; if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK) { Error_Handler(); } sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; sCommand.AddressSize = QSPI_ADDRESS_24_BITS; sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; flash_addr = 0; size = 0 ; #if defined(__CC_ARM) max_size = (uint32_t)(&Load$$QSPI$$Length); #elif defined(__ICCARM__) max_size = __section_size(".qspi_init"); #elif defined(__GNUC__) max_size = (uint32_t)((uint8_t *)(&_qspi_init_length)); #endif while(1) { switch(step) { case 0: CmdCplt = 0; /* Enable write operations ------------------------------------------- */ QSPI_WriteEnable(&QSPIHandle); /* Erasing Sequence -------------------------------------------------- */ sCommand.Instruction = SECTOR_ERASE_CMD; sCommand.AddressMode = QSPI_ADDRESS_1_LINE; sCommand.Address = qspi_addr; sCommand.DataMode = QSPI_DATA_NONE; sCommand.DummyCycles = 0; if (HAL_QSPI_Command_IT(&QSPIHandle, &sCommand) != HAL_OK) { Error_Handler(); } step++; break; case 1: if(CmdCplt != 0) { CmdCplt = 0; StatusMatch = 0; /* Configure automatic polling mode to wait for end of erase ------- */ QSPI_AutoPollingMemReady(&QSPIHandle); /* Initialize the variables for the data writing ------------------- */ #if defined(__CC_ARM) flash_addr = (uint8_t *)(&Load$$QSPI$$Base); #elif defined(__ICCARM__) flash_addr = (uint8_t *)(__section_begin(".qspi_init")); #elif defined(__GNUC__) flash_addr =(uint8_t *)(&_qspi_init_base); #endif /* Copy only one page if the section is bigger */ if (max_size > QSPI_PAGE_SIZE) { size = QSPI_PAGE_SIZE; } else { size = max_size; } step++; } break; case 2: if(StatusMatch != 0) { StatusMatch = 0; TxCplt = 0; /* Enable write operations ----------------------------------------- */ QSPI_WriteEnable(&QSPIHandle); /* Writing Sequence ------------------------------------------------ */ sCommand.Instruction = EXT_QUAD_IN_FAST_PROG_CMD; sCommand.AddressMode = QSPI_ADDRESS_4_LINES; sCommand.Address = qspi_addr; sCommand.DataMode = QSPI_DATA_4_LINES; sCommand.NbData = size; if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { Error_Handler(); } if (HAL_QSPI_Transmit_DMA(&QSPIHandle, flash_addr) != HAL_OK) { Error_Handler(); } step++; } break; case 3: if(TxCplt != 0) { TxCplt = 0; StatusMatch = 0; /* Configure automatic polling mode to wait for end of program ----- */ QSPI_AutoPollingMemReady(&QSPIHandle); step++; } break; case 4: if(StatusMatch != 0) { qspi_addr += size; flash_addr += size; /* Check if a new page writing is needed */ if (qspi_addr < max_size) { /* Update the remaining size if it is less than the page size */ if ((qspi_addr + size) > max_size) { size = max_size - qspi_addr; } step = 2; } else { StatusMatch = 0; RxCplt = 0; /* Configure Volatile Configuration register (with new dummy cycles) */ QSPI_DummyCyclesCfg(&QSPIHandle); /* Reading Sequence ------------------------------------------------ */ sCommand.Instruction = QUAD_INOUT_FAST_READ_CMD; sCommand.DummyCycles = DUMMY_CLOCK_CYCLES_READ_QUAD; sMemMappedCfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE; if (HAL_QSPI_MemoryMapped(&QSPIHandle, &sCommand, &sMemMappedCfg) != HAL_OK) { Error_Handler(); } step++; } } break; case 5: /* Execute the code from QSPI memory ------------------------------- */ GpioToggle(); break; default : Error_Handler(); } } }