/*------------------------------------------------------------ * Function Name : SD_ProgramFlashOperation * Description : 编程flash操作 * Input : None * Output : None * Return : None *------------------------------------------------------------*/ ErrorStatus SD_ProgramFlashOperation( const uint8_t *data, uint32_t addr, uint16_t len ) { uint32_t WriteData = 0; const uint8_t *pos = data; uint16_t len_offset = 0; uint8_t i = 0; uint32_t uwAddress = 0; if (!len) { return SUCCESS; } /* Unlock the Flash *********************************************************/ /* Enable the flash control register access */ FLASH_Unlock(); /* Erase the user Flash area ************************************************/ /* area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR */ /* Clear pending flags (if any) */ FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR); /* Program the user Flash area word by word ********************************/ /* area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR */ len_offset = len % 4; len -= len_offset; while (uwAddress < len) { WriteData = (pos[0] | (pos[1]<<8) | (pos[2]<<16) | (pos[3]<<24)); WriteData ^= 0x55555555; if (FLASH_ProgramWord(USER_FLASH_FIRST_PAGE_ADDRESS + addr + uwAddress, WriteData) == FLASH_COMPLETE) { if (*(uint32_t*)(USER_FLASH_FIRST_PAGE_ADDRESS + addr + uwAddress) != WriteData) { FLASH_Lock(); return ERROR; } uwAddress += 4; pos += 4; } else { /* Error occurred while writing data in Flash memory. User can add here some code to deal with this error */ FLASH_Lock(); return ERROR; } } if ( len_offset ) { for (i=0; i<len_offset; ++i) { if (FLASH_ProgramByte(USER_FLASH_FIRST_PAGE_ADDRESS + addr + uwAddress, *pos) == FLASH_COMPLETE) { uwAddress++; pos++; } else { /* Error occurred while writing data in Flash memory. User can add here some code to deal with this error */ FLASH_Lock(); return ERROR; } } } /* Lock the Flash to disable the flash control register access (recommended to protect the FLASH memory against possible unwanted operation) */ FLASH_Lock(); return SUCCESS; }
FLASH_Status flash_open_program_word(uint32_t word, uint32_t address){ FLASH_ProgramWord(address, word); }
/******************************************************************************* * @函数名称 Ymodem_Receive * @函数说明 通过 ymodem协议接收一个文件 * @输入参数 buf: 首地址指针 * @输出参数 无 * @返回参数 文件长度 *******************************************************************************/ int32_t Ymodem_Receive (uint8_t *buf) { uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr; int32_t i, j, packet_length, session_done, file_done, packets_received, errors, session_begin; uint32_t receive_file_size = 0; uint8_t receive_result; //初始化Flash地址变量 FlashDestination = ApplicationAddress; for (session_done = 0, errors = 0, session_begin = 0; ;) //死循环,初始化 { for (packets_received = 0, file_done = 0, buf_ptr = buf; ;) //死循环,初始化 { //0: 正常返回 //-1: 超时或者数据包错误 //1: 用户取消 receive_result=Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT); //for debug // Send_Byte(receive_result); // Send_Byte(packet_length); switch (receive_result) //从发送端接收一个数据包 { case 0: //0:正常返回 errors = 0; switch (packet_length) { //发送端终止 case - 1: Send_Byte(ACK); return 0; //结束传输 case 0: Send_Byte(ACK); file_done = 1; break; //正常的数据包 default: if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff)) //数据包编号错误 { Send_Byte(NAK); } else //包编号正确 { //表示第0帧,即文件名数据包 if (packets_received == 0) { //文件名数据包 if (packet_data[PACKET_HEADER] != 0) { //文件名数据包有效数据区域 for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);) { file_name[i++] = *file_ptr++; } file_name[i++] = '\0'; //上位机发送的文件名 for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH);) { file_size[i++] = *file_ptr++; } file_size[i++] = '\0'; Str2Int(file_size, &receive_file_size); //size表示上位机发送过来的文件的大小 //for debug // Send_Byte(size); //测试数据包是否过大 if (receive_file_size > (FLASH_SIZE - 1)) { //结束 Send_Byte(CA); Send_Byte(CA); return -1; } //计算需要擦除Flash的页 NbrOfPage = FLASH_PagesMask(receive_file_size); //for debug // Send_Byte(0xfd); //擦除Flash for (EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++) { FLASHStatus = FLASH_ErasePage(FlashDestination + (PageSize * EraseCounter)); } //for debug // Send_Byte(0xfe); Send_Byte(ACK); //收到上位机发送的第0帧之后发送ACK命令 Send_Byte(CRC16); //接着再发送C,表示等待上位机发送数据帧 //for debug // Send_Byte(0xff); } //文件名数据包空,结束传输 else { Send_Byte(ACK); file_done = 1; session_done = 1; break; } } //非第0帧的协议数据包 else { memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length); RamSource = (uint32_t)buf; //内层for循环初始化buf_ptr = buf for (j = 0; (j < packet_length) && (FlashDestination < ApplicationAddress + receive_file_size); j += 4) { //把接收到的数据编写到Flash中 FLASH_ProgramWord(FlashDestination, *(uint32_t*)RamSource); if (*(uint32_t*)FlashDestination != *(uint32_t*)RamSource) //检查写flash是否成功 { //结束 Send_Byte(CA); Send_Byte(CA); return -2; } FlashDestination += 4; RamSource += 4; }//非第0帧的协议数据包结束 Send_Byte(ACK); //接受到第非0帧数据帧之后,发送ACK命令 } packets_received ++; //不管是第0帧还是第非0帧,数据包编号自增 session_begin = 1; //接受数据包成功则会话开始 }//包编号正确结束 }//内层switch循环结束 break; case 1: //1: 用户取消 Send_Byte(CA); Send_Byte(CA); return -3; default: //-1: 超时或者数据包错误 if (session_begin > 0) { errors ++; } if (errors > MAX_ERRORS) //如果错误次数大于MAX_ERRORS=5 { Send_Byte(CA); Send_Byte(CA); return 0; } Send_Byte(CRC16); //发送C break; }//外层switch结束 if (file_done != 0) { break; } }//内层for循环结束 if (session_done != 0) { break; } }//外层for循环结束 return (int32_t)receive_file_size; }
/** * @brief Main program. * @param None * @retval None */ int main(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG , ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOA, ENABLE ); RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM3, ENABLE ); volatile int i; int n = 1; GPIO_StructInit(&GPIO_InitStructure); // Reset init structure GPIO_StructInit(&GPIO_InitStructure2); // Reset init structure GPIO_StructInit(&GPIO_InitStructure3); // Reset init structure GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_TIM3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_TIM3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_TIM3); //GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_TIM3); //GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_TIM3); /** PWM Output PortC 6 7 8 9 AF TIM3 **/ // Setup Servo on STM32-Discovery Board to use PWM. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7| GPIO_Pin_8| GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // Alt Function - Push Pull GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init( GPIOC, &GPIO_InitStructure ); /** Button Output PortB 4 5 **/ /* GPIOA Configuration: CH1 (PB4) and CH2 (PB5) */ GPIO_InitStructure2.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 ; GPIO_InitStructure2.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure2.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure2.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure2.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &GPIO_InitStructure2); GPIOB->BSRRL = GPIO_Pin_4; GPIOB->BSRRL = GPIO_Pin_5; /** Button Input PortA 2 3 **/ /* GPIOA Configuration: (PA2) and (PA3) */ //input GPIO_InitStructure2.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 ; GPIO_InitStructure2.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure2.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure2.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure2.GPIO_PuPd = GPIO_PuPd_DOWN ; GPIO_Init(GPIOA, &GPIO_InitStructure2); /** Button A2 A3 Interrupt EXTI 2 3 **/ //清空中断标志 EXTI_ClearITPendingBit(EXTI_Line2); EXTI_ClearITPendingBit(EXTI_Line3); //选择中断管脚PA.2 PA.3 SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource2); SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource3); // SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0); // SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0); EXTI_InitStructure.EXTI_Line = EXTI_Line2 ; //选择中断线路2 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //设置为中断请求,非事件请求 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //设置中断触发方式为上下降沿触发 EXTI_InitStructure.EXTI_LineCmd = ENABLE; //外部中断使能 EXTI_Init(&EXTI_InitStructure); EXTI_GenerateSWInterrupt(EXTI_Line2); EXTI_InitStructure.EXTI_Line = EXTI_Line3 ; //选择中断线路2 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //设置为中断请求,非事件请求 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //设置中断触发方式为上下降沿触发 EXTI_InitStructure.EXTI_LineCmd = ENABLE; //外部中断使能 EXTI_Init(&EXTI_InitStructure); EXTI_GenerateSWInterrupt(EXTI_Line3); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //选择中断分组2 NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn ; //选择中断通道2 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占式中断优先级设置为0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应式中断优先级设置为0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断 NVIC_Init(&NVIC_InitStructure); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //选择中断分组2 NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn; //选择中断通道2 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占式中断优先级设置为0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应式中断优先级设置为0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断 NVIC_Init(&NVIC_InitStructure); /** Timer setting Tim3 **/ PrescalerValue = (uint16_t) ((SystemCoreClock /4) / 100000) - 1; // Let PWM frequency equal 100Hz. // Let period equal 1000. Therefore, timer runs from zero to 1000. Gives 0.1Hz resolution. // Solving for prescaler gives 240. TIM_TimeBaseStructInit( &TIM_TimeBaseInitStruct ); TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period = 3360 - 1; // 0..2000 TIM_TimeBaseInitStruct.TIM_Prescaler = 500; TIM_TimeBaseInit( TIM3, &TIM_TimeBaseInitStruct ); /** TIM_Prescaler = 500-1, TIM_Period = 1680-1 , TIMxCLK = 84MHz 輸出脈波週期 = (TIM_Period + 1) * (TIM_Prescaler + 1) / TIMxCLK = ( 1680 - 1 +1 ) * ( 500 - 1 + 1 ) / 84000000 = 0.01s(100Hz) **/ TIM_OCStructInit( &TIM_OCInitStruct ); TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; // Initial duty cycle equals 0%. Value can range from zero to 1000. TIM_OCInitStruct.TIM_Pulse = 3360 -1; // 0 .. 1680 (0=Always Off, 1680=Always On) TIM_OC1Init( TIM3, &TIM_OCInitStruct ); // Channel 1 Servo TIM_OC2Init( TIM3, &TIM_OCInitStruct ); // Channel 2 Servo TIM_OC3Init( TIM3, &TIM_OCInitStruct ); // Channel 3 PB7 Servo L TIM_OC4Init( TIM3, &TIM_OCInitStruct ); // Channel 4 PB8 Servo R TIM_Cmd( TIM3, ENABLE ); /** Project Testing **/ while(1) // Do not exit { //Test 1 if(TIM3->CCR4>0){ for(i=0;i<16000000;i++); TIM3->CCR4 = 0; } /* //Test 2 TIM3->CCR4 = 168; for(i=0;i<16000000;i++); TIM3->CCR4 = 336; for(i=0;i<16000000;i++); TIM3->CCR4 = 252; for(i=0;i<16000000;i++); /* //Test 3 if (((brightness + n) >= 3000) || ((brightness + n) <= 0)) n = -n; // if brightness maximum/maximum change direction brightness += n; TIM3->CCR1 = brightness; // set brightness TIM3->CCR2 = 1000 - brightness; // set brightness TIM3->CCR3 = 3000 - brightness; // set brightness TIM3->CCR4 = 3000 - brightness; // set brightness for(i=0;i<10000;i++); // delay //Delay(250000); //Delay(1000000); //Delay(1000000); */ } return(0); // System will implode /** Others **/ if (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET) { if ((*(__IO uint32_t*) TESTRESULT_ADDRESS) == ALLTEST_PASS) { /* Waiting User Button is pressed or Test Program condition verified */ while ((STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET)&&(TimingDelay != 0x00)) {} } else { /* Waiting User Button is Released or TimeOut*/ while ((STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET)&&(TimingDelay != 0x00)) {} if (STM_EVAL_PBGetState(BUTTON_USER) == Bit_RESET) { } } if (TimingDelay == 0x00) { /* Turn off LEDs available on STM32F4-Discovery ------------------------*/ /* Waiting User Button is released */ while (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET) {} /* Unlocks the FLASH control register access */ FLASH_Unlock(); /* Move discovery kit to detect negative and positive acceleration values on X, Y and Z axis */ Accelerometer_MEMS_Test(); /* USB Hardware connection */ USB_Test(); /* Audio Hardware connection */ Audio_Test(); /* Microphone MEMS Hardware connection */ Microphone_MEMS_Test(); /* Write PASS code at last word in the flash memory */ FLASH_ProgramWord(TESTRESULT_ADDRESS, ALLTEST_PASS); while(1) { /* Toggle Green LED: signaling the End of the Test program */ STM_EVAL_LEDToggle(LED4); Delay(41999/2); } } else { Demo_Exec(); } } else { Demo_Exec(); } }
void Flash_Program_Test(void) { FLASHStatus = FLASH_COMPLETE; MemoryProgramStatus = PASSED; Flash_Data1 = 0x0001; Flash_Data2 = 0x12345678; Flash_Data3 = 0xabcd; Flash_Data4 = 0x5678; Flash_Data5 = 0x1234; Flash_Data6 = 0xab12; /* Unlock the Flash Program Erase controller */ FLASH_Unlock(); /* Define the number of page to be erased */ NbrOfPage = (EndAddr - StartAddr) / FLASH_PAGE_SIZE; /* Clear All pending flags */ FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); ReadDataAddr = DataStartAddr; while( ReadDataAddr < DataEndAddr) { ReadDataBuf[Address] = *(__IO uint32_t*)(ReadDataAddr); ReadDataAddr +=1; Address += 1; printf("\n\rThe Flash Data is 0x%02X\n\r",ReadDataBuf[Address-1]); } /* Erase the FLASH pages */ for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++) { FLASHStatus = FLASH_ErasePage(StartAddr + (FLASH_PAGE_SIZE * EraseCounter)); } /* FLASH Word program of Flash_Data1 at define addresses*/ Address = DataStartAddr; while((Address < DataStartAddr+2) && (FLASHStatus == FLASH_COMPLETE)) { FLASHStatus = FLASH_ProgramHalfWord(Address, Flash_Data1); Address = Address + 2; } /* FLASH Word program of Flash_Data2 at define addresses*/ while((Address < DataStartAddr+6) && (FLASHStatus == FLASH_COMPLETE)) { FLASHStatus = FLASH_ProgramWord(Address, Flash_Data2); Address = Address + 4; } /* FLASH Word program of Flash_Data3 at define addresses*/ while((Address < DataStartAddr+8) && (FLASHStatus == FLASH_COMPLETE)) { FLASHStatus = FLASH_ProgramHalfWord(Address, Flash_Data3); Address = Address + 2; } /* FLASH Word program of Flash_Data4 at define addresses*/ while((Address < DataStartAddr+10) && (FLASHStatus == FLASH_COMPLETE)) { FLASHStatus = FLASH_ProgramHalfWord(Address, Flash_Data4); Address = Address + 2; } /* FLASH Word program of Flash_Data5 at define addresses*/ while((Address < DataStartAddr+12) && (FLASHStatus == FLASH_COMPLETE)) { FLASHStatus = FLASH_ProgramHalfWord(Address, Flash_Data5); Address = Address + 2; } /* FLASH Word program of Flash_Data6 at define addresses*/ while((Address < DataStartAddr+14) && (FLASHStatus == FLASH_COMPLETE)) { FLASHStatus = FLASH_ProgramHalfWord(Address, Flash_Data6); Address = Address + 2; } }
/** * @brief Main program. * @param None * @retval None */ int main(void) { RCC_ClocksTypeDef RCC_Clocks; /*Initialize IO*/ IO_Init(); /* Initialize LEDs and User_Button on STM32F4-Discovery --------------------*/ STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_EXTI); STM_EVAL_LEDInit(LED4); STM_EVAL_LEDInit(LED3); STM_EVAL_LEDInit(LED5); STM_EVAL_LEDInit(LED6); /* SysTick end of count event each 2.5ms */ RCC_GetClocksFreq(&RCC_Clocks); SysTick_Config(RCC_Clocks.HCLK_Frequency / TimeDev); if (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET) { /* Turn on LEDs available on STM32F4-Discovery ---------------------------*/ STM_EVAL_LEDOn(LED4); STM_EVAL_LEDOn(LED3); STM_EVAL_LEDOn(LED5); STM_EVAL_LEDOn(LED6); if ((*(__IO uint32_t*) TESTRESULT_ADDRESS) == ALLTEST_PASS) { TimingDelay = 300; /* Waiting User Button is pressed or Test Program condition verified */ while ((STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET)&&(TimingDelay != 0x00)) {} } else { /* Waiting User Button is Released or TimeOut*/ TimingDelay = 300; while ((STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET)&&(TimingDelay != 0x00)) {} if (STM_EVAL_PBGetState(BUTTON_USER) == Bit_RESET) { TimingDelay = 0x00; } } if (TimingDelay == 0x00) { /* Turn off LEDs available on STM32F4-Discovery ------------------------*/ STM_EVAL_LEDOff(LED4); STM_EVAL_LEDOff(LED3); STM_EVAL_LEDOff(LED5); STM_EVAL_LEDOff(LED6); /* Waiting User Button is released */ while (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET) {} /* Unlocks the FLASH control register access */ FLASH_Unlock(); /* Move discovery kit to detect negative and positive acceleration values on X, Y and Z axis */ Accelerometer_MEMS_Test(); /* Write PASS code at last word in the flash memory */ FLASH_ProgramWord(TESTRESULT_ADDRESS, ALLTEST_PASS); while(1) { /* Toggle Green LED: signaling the End of the Test program */ STM_EVAL_LEDToggle(LED4); Delay(10); } } else { Demo_Exec(); } } else { Demo_Exec(); } }
/******************************************************************************* * Function Name : FLASH_If_Write * Description : Write sectors * Input : None * Output : None * Return : None *******************************************************************************/ uint16_t FLASH_If_Write(uint32_t SectorAddress, uint32_t DataLength) { uint32_t idx = 0; #ifdef STM32L1XX_MD __IO uint32_t* malPointer = (uint32_t *)MAL_Buffer; __IO uint32_t* memPointer = (uint32_t *)SectorAddress; __IO uint32_t memBuffer[32]; /* Temporary buffer holding data that will be written in a half-page space */ __IO uint32_t* mempBuffer = memBuffer; __IO uint32_t* tmp; #endif /* STM32L1XX_MD */ if (DataLength & 0x3) /* Not an aligned data */ { for (idx = DataLength; idx < ((DataLength & 0xFFFC) + 4); idx++) { MAL_Buffer[idx] = 0xFF; } } #ifdef STM32L1XX_MD /* Reinitialize the intermediate buffer pointer */ mempBuffer = memBuffer; /* If the address is not aligned to half-page fill the first location with existing data */ if (((uint32_t)memPointer & 0x7F) != 0) { /* get the aligned address */ tmp = (uint32_t *)((uint32_t)memPointer & 0xFFFFFF80); /* Read the first part from the memory */ while (tmp < memPointer) { *(uint32_t *)(mempBuffer++) = *(uint32_t *)(tmp++); } } while (malPointer < (uint32_t*)(MAL_Buffer + DataLength)) { /* Fill with the received buffer */ while (mempBuffer < (memBuffer + 32)) { /* If there are still data available in the received buffer */ if (malPointer < ((uint32_t *)MAL_Buffer + DataLength)) { *(uint32_t *)(mempBuffer++) = *(uint32_t *)(malPointer++); } else /* no more data available in the received buffer: fill remaining with dummy 0 */ { *(uint32_t *)(mempBuffer++) = 0; } } /* Write the buffer to the memory*/ FLASH_ProgramHalfPage(((uint32_t)memPointer & 0xFFFFFF80), (uint32_t *)(memBuffer)); /* Increment the memory pointer */ memPointer = (uint32_t *)(((uint32_t)memPointer & 0xFFFFFF80) + (32*4)); /* Reinitialize the intermediate buffer pointer */ mempBuffer = memBuffer; } #else /* Data received are Word multiple */ for (idx = 0; idx < DataLength; idx = idx + 4) { FLASH_ProgramWord(SectorAddress, *(uint32_t *)(MAL_Buffer + idx)); SectorAddress += 4; } #endif /* STM32L1XX_MD */ return MAL_OK; }
u8 WriteConfigurationBlock(void) { // load all of the config RAM registers into one big array ConfigData[0] = BOARDCONFIG_ram; ConfigData[1] = MIDI0MODE_ram; ConfigData[2] = MIDI1MODE_ram; ConfigData[3] = MIDI2MODE_ram; ConfigData[4] = MIDI3MODE_ram; ConfigData[5] = MIDI4MODE_ram; ConfigData[6] = MIDI5MODE_ram; ConfigData[7] = MIDI6MODE_ram; ConfigData[8] = MIDI7MODE_ram; ConfigData[9] = MIDI8MODE_ram; ConfigData[10] = MIDI9MODE_ram; ConfigData[11] = MIDI10MODE_ram; ConfigData[12] = MIDI11MODE_ram; ConfigData[13] = MIDI12MODE_ram; ConfigData[14] = MIDI13MODE_ram; ConfigData[15] = MIDI0POL_ram; ConfigData[16] = MIDI1POL_ram; ConfigData[17] = MIDI2POL_ram; ConfigData[18] = MIDI3POL_ram; ConfigData[19] = MIDI4POL_ram; ConfigData[20] = MIDI5POL_ram; ConfigData[21] = MIDI6POL_ram; ConfigData[22] = MIDI7POL_ram; ConfigData[23] = MIDI8POL_ram; ConfigData[24] = MIDI9POL_ram; ConfigData[25] = MIDI10POL_ram; ConfigData[26] = MIDI11POL_ram; ConfigData[27] = MIDI12POL_ram; ConfigData[28] = MIDI13POL_ram; ConfigData[29] = MIDI0SENS_ram; ConfigData[30] = MIDI1SENS_ram; ConfigData[31] = MIDI2SENS_ram; ConfigData[32] = MIDI3SENS_ram; ConfigData[33] = MIDI4SENS_ram; ConfigData[34] = MIDI5SENS_ram; ConfigData[35] = MIDI6SENS_ram; ConfigData[36] = MIDI7SENS_ram; ConfigData[37] = MIDI8SENS_ram; ConfigData[38] = MIDI9SENS_ram; ConfigData[39] = MIDI10SENS_ram; ConfigData[40] = MIDI11SENS_ram; ConfigData[41] = MIDI12SENS_ram; ConfigData[42] = MIDI13SENS_ram; ConfigData[43] = MIDI0CURVE_ram; ConfigData[44] = MIDI1CURVE_ram; ConfigData[45] = MIDI2CURVE_ram; ConfigData[46] = MIDI3CURVE_ram; ConfigData[47] = MIDI4CURVE_ram; ConfigData[48] = MIDI5CURVE_ram; ConfigData[49] = MIDI6CURVE_ram; ConfigData[50] = MIDI7CURVE_ram; ConfigData[51] = MIDI8CURVE_ram; ConfigData[52] = MIDI9CURVE_ram; ConfigData[53] = MIDI10CURVE_ram; ConfigData[54] = MIDI11CURVE_ram; ConfigData[55] = MIDI12CURVE_ram; ConfigData[56] = MIDI13CURVE_ram; ConfigData[57] = MIDI0NOTE_ram; ConfigData[58] = MIDI1NOTE_ram; ConfigData[59] = MIDI2NOTE_ram; ConfigData[60] = MIDI3NOTE_ram; ConfigData[61] = MIDI4NOTE_ram; ConfigData[62] = MIDI5NOTE_ram; ConfigData[63] = MIDI6NOTE_ram; ConfigData[64] = MIDI7NOTE_ram; ConfigData[65] = MIDI8NOTE_ram; ConfigData[66] = MIDI9NOTE_ram; ConfigData[67] = MIDI10NOTE_ram; ConfigData[68] = MIDI11NOTE_ram; ConfigData[69] = MIDI12NOTE_ram; ConfigData[70] = MIDI13NOTE_ram; FLASH_UnlockBank1(); /* Define the number of page to be erased */ NbrOfPage = (BANK1_WRITE_END_ADDR - BANK1_WRITE_START_ADDR) / FLASH_PAGE_SIZE; /* Clear All pending flags */ FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); /* Erase the FLASH pages */ for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++) { FLASHStatus = FLASH_ErasePage(BANK1_WRITE_START_ADDR + (FLASH_PAGE_SIZE * EraseCounter)); } // Write the blocks uint32_t flashAddress = 0x08007800; uint8_t *dataaddress = &ConfigData[0]; uint32_t data; dataaddress = &ConfigData[0]; for(u8 i = 0; i<18; i++){ uint8_t j = i*4; // dataaddress = &ConfigData[j]; // data = (uint32_t)*(dataaddress + j); data = ConfigData[j]+(ConfigData[j+1]*0x00000100)+(ConfigData[j+2]*0x00010000)+(ConfigData[j+3]*0x01000000); FLASHStatus = FLASH_ProgramWord(flashAddress + j, data); } FLASH_LockBank1(); // lock the Flash memory again ConfigurePorts(); // reconfigure the Ports any time you update the configuration return OK; }
void Flash_Write_Word(uint32_t Address, uint32_t Data) { FLASH_Unlock(); FLASH_ProgramWord(Address, (uint32_t) Data); FLASH_Lock(); }
/** * @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_stm32f4xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* Unlock the Flash to enable the flash control register access *************/ FLASH_Unlock(); /* Erase the user Flash area (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/ /* Clear pending flags (if any) */ FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR); /* Get the number of the start and end sectors */ StartSector = GetSector(FLASH_USER_START_ADDR); EndSector = GetSector(FLASH_USER_END_ADDR); for (SectorCounter = StartSector; SectorCounter < EndSector; SectorCounter += 8) { /* Device voltage range supposed to be [2.7V to 3.6V], the operation will be done by word */ if (FLASH_EraseSector(SectorCounter, VoltageRange_3) != FLASH_COMPLETE) { /* Error occurred while sector erase. User can add here some code to deal with this error */ while (1) { } } } /* Program the user Flash area word by word (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/ Address = FLASH_USER_START_ADDR; while (Address < FLASH_USER_END_ADDR) { if (FLASH_ProgramWord(Address, DATA_32) == FLASH_COMPLETE) { Address = Address + 4; } else { /* Error occurred while writing data in Flash memory. User can add here some code to deal with this error */ while (1) { } } } /* Lock the Flash to disable the flash control register access (recommended to protect the FLASH memory against possible unwanted operation) *********/ FLASH_Lock(); /* Check if the programmed data is OK MemoryProgramStatus = 0: data programmed correctly MemoryProgramStatus != 0: number of words not programmed correctly ******/ Address = FLASH_USER_START_ADDR; MemoryProgramStatus = 0x0; while (Address < FLASH_USER_END_ADDR) { data32 = *(__IO uint32_t*)Address; if (data32 != DATA_32) { MemoryProgramStatus++; } Address = Address + 4; } while (1) { } }
void process_spi_request(void) { const struct pios_board_info * bdinfo = &pios_board_info_blob; bool msg_to_process = FALSE; PIOS_IRQ_Disable(); /* Figure out if we're in an interesting stable state */ switch (lfsm_get_state()) { case LFSM_STATE_USER_BUSY: msg_to_process = TRUE; break; case LFSM_STATE_INACTIVE: /* Queue up a receive buffer */ lfsm_user_set_rx_v0(&user_rx_v0); lfsm_user_done(); break; case LFSM_STATE_STOPPED: /* Get things going */ lfsm_set_link_proto_v0(&link_tx_v0, &link_rx_v0); break; default: /* Not a stable state */ break; } PIOS_IRQ_Enable(); if (!msg_to_process) { /* Nothing to do */ //PIOS_COM_SendFormattedString(PIOS_COM_AUX, "."); return; } if (user_rx_v0.tail.magic != OPAHRS_MSG_MAGIC_TAIL) { return; } switch (user_rx_v0.payload.user.t) { case OPAHRS_MSG_V0_REQ_FWUP_VERIFY: opahrs_msg_v0_init_user_tx(&user_tx_v0, OPAHRS_MSG_V0_RSP_FWUP_STATUS); Fw_crc = PIOS_BL_HELPER_CRC_Memory_Calc(); lfsm_user_set_tx_v0(&user_tx_v0); boot_status = idle; PIOS_LED_Off(LED1); user_tx_v0.payload.user.v.rsp.fwup_status.status = boot_status; break; case OPAHRS_MSG_V0_REQ_RESET: PIOS_DELAY_WaitmS(user_rx_v0.payload.user.v.req.reset.reset_delay_in_ms); PIOS_SYS_Reset(); break; case OPAHRS_MSG_V0_REQ_VERSIONS: //PIOS_LED_On(LED1); opahrs_msg_v0_init_user_tx(&user_tx_v0, OPAHRS_MSG_V0_RSP_VERSIONS); user_tx_v0.payload.user.v.rsp.versions.bl_version = BOOTLOADER_VERSION; user_tx_v0.payload.user.v.rsp.versions.hw_version = (BOARD_TYPE << 8) | BOARD_REVISION; user_tx_v0.payload.user.v.rsp.versions.fw_crc = Fw_crc; lfsm_user_set_tx_v0(&user_tx_v0); break; case OPAHRS_MSG_V0_REQ_MEM_MAP: opahrs_msg_v0_init_user_tx(&user_tx_v0, OPAHRS_MSG_V0_RSP_MEM_MAP); user_tx_v0.payload.user.v.rsp.mem_map.density = bdinfo->hw_type; user_tx_v0.payload.user.v.rsp.mem_map.rw_flags = (BOARD_READABLE | (BOARD_WRITABLE << 1)); user_tx_v0.payload.user.v.rsp.mem_map.size_of_code_memory = bdinfo->fw_size; user_tx_v0.payload.user.v.rsp.mem_map.size_of_description = bdinfo->desc_size; user_tx_v0.payload.user.v.rsp.mem_map.start_of_user_code = bdinfo->fw_base; lfsm_user_set_tx_v0(&user_tx_v0); break; case OPAHRS_MSG_V0_REQ_SERIAL: opahrs_msg_v0_init_user_tx(&user_tx_v0, OPAHRS_MSG_V0_RSP_SERIAL); PIOS_SYS_SerialNumberGet( (char *) &(user_tx_v0.payload.user.v.rsp.serial.serial_bcd)); lfsm_user_set_tx_v0(&user_tx_v0); break; case OPAHRS_MSG_V0_REQ_FWUP_STATUS: opahrs_msg_v0_init_user_tx(&user_tx_v0, OPAHRS_MSG_V0_RSP_FWUP_STATUS); user_tx_v0.payload.user.v.rsp.fwup_status.status = boot_status; lfsm_user_set_tx_v0(&user_tx_v0); break; case OPAHRS_MSG_V0_REQ_FWUP_DATA: PIOS_LED_On(LED1); opahrs_msg_v0_init_user_tx(&user_tx_v0, OPAHRS_MSG_V0_RSP_FWUP_STATUS); if (!(user_rx_v0.payload.user.v.req.fwup_data.adress < bdinfo->fw_base)) { for (uint8_t x = 0; x < user_rx_v0.payload.user.v.req.fwup_data.size; ++x) { if (FLASH_ProgramWord( (user_rx_v0.payload.user.v.req.fwup_data.adress + ((uint32_t)(x * 4))), user_rx_v0.payload.user.v.req.fwup_data.data[x]) != FLASH_COMPLETE) { boot_status = write_error; break; } } } else { boot_status = outside_dev_capabilities; } PIOS_LED_Off(LED1); user_tx_v0.payload.user.v.rsp.fwup_status.status = boot_status; lfsm_user_set_tx_v0(&user_tx_v0); break; case OPAHRS_MSG_V0_REQ_FWDN_DATA: opahrs_msg_v0_init_user_tx(&user_tx_v0, OPAHRS_MSG_V0_RSP_FWDN_DATA); uint32_t adr = user_rx_v0.payload.user.v.req.fwdn_data.adress; for (uint8_t x = 0; x < 4; ++x) { user_tx_v0.payload.user.v.rsp.fw_dn.data[x] = *PIOS_BL_HELPER_FLASH_If_Read(adr + x); } lfsm_user_set_tx_v0(&user_tx_v0); break; case OPAHRS_MSG_V0_REQ_FWUP_START: FLASH_Unlock(); opahrs_msg_v0_init_user_tx(&user_tx_v0, OPAHRS_MSG_V0_RSP_FWUP_STATUS); user_tx_v0.payload.user.v.rsp.fwup_status.status = boot_status; lfsm_user_set_tx_v0(&user_tx_v0); PIOS_LED_On(LED1); if (PIOS_BL_HELPER_FLASH_Start() == TRUE) { boot_status = started; PIOS_LED_Off(LED1); } else { boot_status = start_failed; break; } break; case OPAHRS_MSG_V0_REQ_BOOT: PIOS_DELAY_WaitmS(user_rx_v0.payload.user.v.req.boot.boot_delay_in_ms); FLASH_Lock(); jump_to_app(); break; default: break; } /* Finished processing the received message, requeue it */ lfsm_user_set_rx_v0(&user_rx_v0); lfsm_user_done(); return; }