/******************************************************************************* * 函数名称: FLASH_ErasePage * 功能描述: 擦除一个FLASH页. * 输入参数: FLASH_Page:需要擦除的页. * 输出参数: 无 * 返回参数: FLASH 状态: 返回值可以是: FLASH_BUSY, * FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or * FLASH_TIMEOUT. *******************************************************************************/ FLASH_Status FLASH_ErasePage(u32 Page_Address) { FLASH_Status status = FLASH_COMPLETE; /* Check the parameters [检查参数]*/ assert_param(IS_FLASH_ADDRESS(Page_Address)); /* Wait for last operation to be completed [等待最后一个操作完成]*/ status = FLASH_WaitForLastOperation(EraseTimeout); if(status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to erase the page [如果前一个操作已经完成,]*/ FLASH->CR|= CR_PER_Set; FLASH->AR = Page_Address; FLASH->CR|= CR_STRT_Set; /* Wait for last operation to be completed [等待最后一个操作完成]*/ status = FLASH_WaitForLastOperation(EraseTimeout); if(status != FLASH_BUSY) { /* if the erase operation is completed, disable the PER Bit [如果擦除操作完成,禁止PER位]*/ FLASH->CR &= CR_PER_Reset; } } /* Return the Erase Status [返回擦除状态]*/ return status; }
/** * @brief Programs a word at a specified address. * @param Address: specifies the address to be programmed. * @param Data: specifies the data to be programmed. * @retval : FLASH Status: The returned value can be: FLASH_BUSY, * FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or * FLASH_TIMEOUT. */ FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data) { FLASH_Status status = FLASH_COMPLETE; /* Check the parameters */ assert_param(IS_FLASH_ADDRESS(Address)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(ProgramTimeout); if(status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to program the new first half word */ FLASH->CR |= CR_PG_Set; *(__IO uint16_t*)Address = (uint16_t)Data; /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(ProgramTimeout); if(status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to program the new second half word */ *(__IO uint16_t*)(Address + 2) = Data >> 16; /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(ProgramTimeout); if(status != FLASH_BUSY) { /* Disable the PG Bit */ FLASH->CR &= CR_PG_Reset; } } else {
/** * @brief Programs a half word (16-bit) at a specified address. * @note This function must be used when the device voltage range is from 2.1V to 3.6V. * @param Address: specifies the address to be programmed. * This parameter can be any address in Program memory zone or in OTP zone. * @param Data: specifies the data to be programmed. * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. */ FLASH_Status FLASH_ProgramHalfWord(uint32 Address, uint16 Data) { FLASH_Status status = FLASH_BAD_ADDRESS; if (IS_FLASH_ADDRESS(Address)) { /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(ProgramTimeout); if(status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to program the new data */ FLASH->CR &= CR_PSIZE_MASK; FLASH->CR |= FLASH_PSIZE_HALF_WORD; FLASH->CR |= FLASH_CR_PG; *(__io uint16*)Address = Data; /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(ProgramTimeout); if(status != FLASH_TIMEOUT) { /* if the program operation is completed, disable the PG Bit */ FLASH->CR &= (~FLASH_CR_PG); } } } /* Return the Program Status */ return status; }
/** * @brief Erases a specified FLASH page. * @param Page_Address: The page address to be erased. * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. */ FLASH_Status FLASH_ErasePage(uint32_t Page_Address) { FLASH_Status status = FLASH_COMPLETE; /* Check the parameters */ assert_param(IS_FLASH_ADDRESS(Page_Address)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(EraseTimeout); if(status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to erase the page */ FLASH->CR|= CR_PER_Set; FLASH->AR = Page_Address; FLASH->CR|= CR_STRT_Set; /* Wait for last operation to be completed */ #if 0 /* testing erratum bsy - MOD_MTHOMAS_STMLIB */ #ifdef MOD_MTHOMAS_STMLIB for (volatile int i=0;i<1000;i++); #endif #endif status = FLASH_WaitForLastOperation(EraseTimeout); if(status != FLASH_TIMEOUT) { /* if the erase operation is completed, disable the PER Bit */ FLASH->CR &= CR_PER_Reset; } } /* Return the Erase Status */ return status; }
/** * @brief Erases a specified FLASH page. * @param Page_Address: The page address to be erased. * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. */ FLASH_Status FLASH_ErasePage(uint32 Page_Address) { FLASH_Status status = FLASH_COMPLETE; /* Check the parameters */ ASSERT(IS_FLASH_ADDRESS(Page_Address)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(EraseTimeout); if(status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to erase the page */ FLASH_BASE->CR |= FLASH_CR_PER; FLASH_BASE->AR = Page_Address; FLASH_BASE->CR |= FLASH_CR_STRT; /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(EraseTimeout); if(status != FLASH_TIMEOUT) { /* if the erase operation is completed, disable the PER Bit */ FLASH_BASE->CR &= ~FLASH_CR_PER; } FLASH_BASE->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPRTERR); } /* Return the Erase Status */ return status; }
/** * @brief Erases a specified FLASH page. * @param Page_Address: The page address to be erased. * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. */ FLASH_Status FLASH_ErasePage(uint32 Page_Address) { FLASH_Status status = FLASH_COMPLETE; /* Check the parameters */ ASSERT(IS_FLASH_ADDRESS(Page_Address)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(EraseTimeout); if(status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to erase the page */ __set_bits(FLASH_CR, CR_PER_Set); __write(FLASH_AR, Page_Address); __set_bits(FLASH_CR, CR_STRT_Set); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(EraseTimeout); if(status != FLASH_TIMEOUT) { /* if the erase operation is completed, disable the PER Bit */ __clear_bits(FLASH_CR, ~CR_PER_Reset); } __write(FLASH_SR, (FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR)); } /* Return the Erase Status */ return status; }
/** * @brief Programs a byte (8-bit) at a specified address. * @note This function can be used within all the device supply voltage ranges. * @param Address: specifies the address to be programmed. * This parameter can be any address in Program memory zone or in OTP zone. * @param Data: specifies the data to be programmed. * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. */ FLASH_Status FLASH_ProgramByte(uint32_t Address, uint8_t Data) { FLASH_Status status = FLASH_COMPLETE; /* Check the parameters */ assert_param(IS_FLASH_ADDRESS(Address)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(); if(status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to program the new data */ FLASH->CR &= CR_PSIZE_MASK; FLASH->CR |= FLASH_PSIZE_BYTE; FLASH->CR |= FLASH_CR_PG; *(__IO uint8_t*)Address = Data; /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(); /* if the program operation is completed, disable the PG Bit */ FLASH->CR &= (~FLASH_CR_PG); } /* Return the Program Status */ return status; }
/** * @brief Programs a half word at a specified address. * @param Address: specifies the address to be programmed. * @param Data: specifies the data to be programmed. * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. */ FLASH_Status FLASH_ProgramHalfWord(uint32 Address, uint16 Data) { FLASH_Status status = FLASH_BAD_ADDRESS; if (IS_FLASH_ADDRESS(Address)) { /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(ProgramTimeout); if(status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to program the new data */ __set_bits(FLASH_CR, CR_PG_Set); *(__io uint16*)Address = Data; /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(ProgramTimeout); if(status != FLASH_TIMEOUT) { /* if the program operation is completed, disable the PG Bit */ __clear_bits(FLASH_CR, ~CR_PG_Reset); } __write(FLASH_SR, (FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR)); } } return status; }
/** * @brief Programs one byte in program or data EEPROM memory * @param Address : Address where the byte will be programmed * @param Data : Value to be programmed * @retval None */ void FLASH_ProgramByte(uint32_t Address, uint8_t Data) { /* Check parameters */ assert_param(IS_FLASH_ADDRESS(Address)); *(PointerAttr uint8_t*) (uint16_t)Address = Data; }
/** * @brief Erases one byte in the program or data EEPROM memory * @param Address : Address of the byte to erase * @retval None */ void FLASH_EraseByte(uint32_t Address) { /* Check parameter */ assert_param(IS_FLASH_ADDRESS(Address)); *(PointerAttr uint8_t*) (uint16_t)Address = FLASH_CLEAR_BYTE; /* Erase byte */ }
/* * Erases a specified FLASH page. * @param Page_Address: The page address to be erased. * @retval : FLASH Status: The returned value can be: FLASH_BUSY, * FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or * FLASH_TIMEOUT. */ FLASH_Status FLASH_ErasePage(uint32_t Page_Address) { FLASH_Status status = FLASH_COMPLETE; /* Check the parameters */ assert_param(IS_FLASH_ADDRESS(Page_Address)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(EraseTimeout); if (status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to erase the page */ FLASH->CR|= CR_PER_Set; FLASH->AR = Page_Address; FLASH->CR|= CR_STRT_Set; /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(EraseTimeout); if (status != FLASH_BUSY) { /* if the erase operation is completed, disable the PER Bit */ FLASH->CR &= CR_PER_Reset; } /* if (status != FLASH_BUSY) */ } /* if (status == FLASH_COMPLETE) */ /* Return the Erase Status */ return status; }
/** * @brief Programs a half word at a specified address. * @param Address: specifies the address to be programmed. * @param Data: specifies the data to be programmed. * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. */ FLASH_Status FLASH_ProgramHalfWord(uint32 Address, uint16 Data) { FLASH_Status status = FLASH_BAD_ADDRESS; if (IS_FLASH_ADDRESS(Address)) { /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(ProgramTimeout); if(status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to program the new data */ FLASH_BASE->CR |= FLASH_CR_PG; *(__io uint16*)Address = Data; /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(ProgramTimeout); if(status != FLASH_TIMEOUT) { /* if the program operation is completed, disable the PG Bit */ FLASH_BASE->CR &= ~FLASH_CR_PG; } FLASH_BASE->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPRTERR); } } return status; }
/** * @brief Reads one byte from flash memory * @param Address: Address to read * @retval Value of the byte */ uint8_t FLASH_ReadByte(uint16_t Address) { /* Check parameter */ assert_param(IS_FLASH_ADDRESS(Address)); /* Read byte */ return(*(PointerAttr uint8_t *) (uint16_t)Address); }
void MacBase::onSend(NetEventDescriptor& ned) { // must be an ethernet send request if(ned.eventType!=NetEventDescriptor::NetEventType::ETHERNET_TRANSMIT_REQUEST) return; EthernetTransmitRequestEvent& event=static_cast<EthernetTransmitRequestEvent&>(ned); EthernetFrameData *efd; // we cannot transmit data out of flash memory because the flash banks are // not connected to the Ethernet DMA bus on the STM32. More's the pity. uint32_t ub=reinterpret_cast<uint32_t>(event.networkBuffer->getUserBuffer()); if(ub && IS_FLASH_ADDRESS(ub)) { delete event.networkBuffer; this->setError(ErrorProvider::ERROR_PROVIDER_NET_MAC,E_NO_FLASH_DATA); return; } // the NetBuffer needs to get an ethernet header efd=reinterpret_cast<EthernetFrameData *>(event.networkBuffer->moveWritePointerBack(getDatalinkTransmitHeaderSize())); efd->eth_destinationAddress=event.macAddress; efd->eth_sourceAddress=_params.mac_address; efd->eth_etherType=NetUtil::htons(static_cast<uint16_t>(event.etherType)); uint32_t now=MillisecondTimer::millis(); while(!sendBuffer(event.networkBuffer)) { if(errorProvider.isLastError(ErrorProvider::ERROR_PROVIDER_NET_MAC,E_BUSY)) { // DMA still has our TX descriptor. If we're not running in an IRQ context then we // can wait to see if it frees up if(Nvic::isAnyIrqActive()) { delete event.networkBuffer; return; } if(MillisecondTimer::hasTimedOut(now,_params.mac_txWaitMillis)) { delete event.networkBuffer; return; } } else { delete event.networkBuffer; return; // other error } } // it was sent and the net buffer will be deleted when the TX interrupt is processed event.succeeded=true; }
/** * @brief Program byte (8-bit) at a specified address. * @note This function must be used when the device voltage range is from * 1.8V to 3.6V. * * @note If an erase and a program operations are requested simultaneously, * the erase operation is performed before the program one. * * @param Address: specifies the address to be programmed. * @param Data: specifies the data to be programmed. * @retval None */ static void FLASH_Program_Byte(uint32_t Address, uint8_t Data) { /* Check the parameters */ assert_param(IS_FLASH_ADDRESS(Address)); /* If the previous operation is completed, proceed to program the new data */ CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE); FLASH->CR |= FLASH_PSIZE_BYTE; FLASH->CR |= FLASH_CR_PG; *(__IO uint8_t*)Address = Data; }
/** * @brief Program a half-word (16-bit) at a specified address. * @note This function must be used when the device voltage range is from * 2.7V to 3.6V. * * @note If an erase and a program operations are requested simultaneously, * the erase operation is performed before the program one. * * @param Address: specifies the address to be programmed. * @param Data: specifies the data to be programmed. * @retval None */ static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data) { /* Check the parameters */ assert_param(IS_FLASH_ADDRESS(Address)); /* If the previous operation is completed, proceed to program the new data */ FLASH->CR &= CR_PSIZE_MASK; FLASH->CR |= FLASH_PSIZE_HALF_WORD; FLASH->CR |= FLASH_CR_PG; *(__IO uint16_t*)Address = Data; }
/** * @brief Program a double word (64-bit) at a specified address. * @note This function must be used when the device voltage range is from * 2.7V to 3.6V and Vpp in the range 7V to 9V. * * @note If an erase and a program operations are requested simultaneously, * the erase operation is performed before the program one. * * @param Address specifies the address to be programmed. * @param Data specifies the data to be programmed. * @retval None */ static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data) { /* Check the parameters */ assert_param(IS_FLASH_ADDRESS(Address)); /* If the previous operation is completed, proceed to program the new data */ CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE); FLASH->CR |= FLASH_PSIZE_DOUBLE_WORD; FLASH->CR |= FLASH_CR_PG; /* Program the double-word */ *(__IO uint32_t*)Address = (uint32_t)Data; *(__IO uint32_t*)(Address+4) = (uint32_t)(Data >> 32); }
/** * @brief Program byte (8-bit) at a specified address. * @note This function must be used when the device voltage range is from * 2.7V to 3.6V. * * @note If an erase and a program operations are requested simultaneously, * the erase operation is performed before the program one. * * @param Address: specifies the address to be programmed. * @param Data: specifies the data to be programmed. * @retval None */ static void FLASH_Program_Byte(uint32_t Address, uint8_t Data) { /* Check the parameters */ assert_param(IS_FLASH_ADDRESS(Address)); /* If the previous operation is completed, proceed to program the new data */ FLASH->CR &= CR_PSIZE_MASK; FLASH->CR |= FLASH_PSIZE_BYTE; FLASH->CR |= FLASH_CR_PG; *(__IO uint8_t*)Address = Data; /* Data synchronous Barrier (DSB) Just after the write operation This will force the CPU to respect the sequence of instruction (no optimization).*/ __DSB(); }
/** * @brief Programs one word (4 bytes) in program or data EEPROM memory * @param Address : The address where the data will be programmed * @param Data : Value to be programmed * @retval None */ void FLASH_ProgramWord(uint32_t Address, uint32_t Data) { /* Check parameters */ assert_param(IS_FLASH_ADDRESS(Address)); /* Enable Word Write Once */ FLASH->CR2 |= FLASH_CR2_WPRG; /* Write one byte - from lowest address*/ *((PointerAttr uint8_t*)(uint16_t)Address) = *((uint8_t*)(&Data)); /* Write one byte*/ *(((PointerAttr uint8_t*)(uint16_t)Address) + 1) = *((uint8_t*)(&Data) + 1); /* Write one byte*/ *(((PointerAttr uint8_t*)(uint16_t)Address) + 2) = *((uint8_t*)(&Data) + 2); /* Write one byte - from higher address*/ *(((PointerAttr uint8_t*)(uint16_t)Address) + 3) = *((uint8_t*)(&Data) + 3); }
/** * @brief Program a double word (64-bit) at a specified address. * @note This function must be used when the device voltage range is from * 2.7V to 3.6V and an External Vpp is present. * * @note If an erase and a program operations are requested simultaneously, * the erase operation is performed before the program one. * * @param Address specifies the address to be programmed. * @param Data specifies the data to be programmed. * @retval None */ static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data) { /* Check the parameters */ assert_param(IS_FLASH_ADDRESS(Address)); /* If the previous operation is completed, proceed to program the new data */ FLASH->CR &= CR_PSIZE_MASK; FLASH->CR |= FLASH_PSIZE_DOUBLE_WORD; FLASH->CR |= FLASH_CR_PG; /* Program the double-word */ *(__IO uint32_t*)Address = (uint32_t)Data; *(__IO uint32_t*)(Address+4) = (uint32_t)(Data >> 32); /* Data synchronous Barrier (DSB) Just after the write operation This will force the CPU to respect the sequence of instruction (no optimization).*/ __DSB(); }
/******************************************************************************* * 函数名称: FLASH_ProgramWord * 功能描述: 在特定地址编程一个字. * 输入参数: (1)Address:将要编程的地址. * (2)Data:指定被编程的数据. * 输出参数: 无 * 返回参数: FLASH状态:这个返回值可以是: FLASH_BUSY, * FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or * FLASH_TIMEOUT. *******************************************************************************/ FLASH_Status FLASH_ProgramWord(u32 Address, u32 Data) { FLASH_Status status = FLASH_COMPLETE; /* Check the parameters [检查参数]*/ assert_param(IS_FLASH_ADDRESS(Address)); /* Wait for last operation to be completed [等待最后一个操作完成]*/ status = FLASH_WaitForLastOperation(ProgramTimeout); if(status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to program the new first half word [如果前一个操作完成,编程新的第一个半字]*/ FLASH->CR |= CR_PG_Set; *(vu16*)Address = (u16)Data; /* Wait for last operation to be completed [等待最后一个操作完成]*/ status = FLASH_WaitForLastOperation(ProgramTimeout); if(status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to program the new second half word [如果前一个操作完成,编程新的第二个半字]*/ *(vu16*)(Address + 2) = Data >> 16; /* Wait for last operation to be completed [等待最后一个操作完成]*/ status = FLASH_WaitForLastOperation(ProgramTimeout); if(status != FLASH_BUSY) { /* Disable the PG Bit [禁止PG位]*/ FLASH->CR &= CR_PG_Reset; } }