Merged in janlmulder/ostc4/div-fixes-6 (pull request #23)
Cleanup VPM, NDL to 240 min, and more cleanup
line source
/**
******************************************************************************
* @file externCPU2bootloader.c Template
* @author heinrichs weikamp gmbh
* @version V0.0.1
* @date 23-Oct-2014
* @version V0.0.1
* @since 23-Oct-2014
* @brief Main Template to communicate with the second CPU in bootloader mode
* bootloader ROM build by ST and defined in AN4286
*
@verbatim
==============================================================================
##### How to use #####
==============================================================================
@endverbatim
******************************************************************************
* @attention
*
* <h2><center>© COPYRIGHT(c) 2016 heinrichs weikamp</center></h2>
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
#include "stdio.h"
#include "ostc.h"
#include "settings.h"
#include "externCPU2bootloader.h"
#include "externLogbookFlash.h"
#include "tComm.h"
/* Exported variables --------------------------------------------------------*/
/* Private types -------------------------------------------------------------*/
#define BOOTLOADSPITIMEOUT 5000
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
uint8_t boot_sync_frame(void);
uint8_t boot_ack(void);
uint8_t boot_get(uint8_t *RxBuffer);
uint8_t boot_get_id(uint8_t *RxBuffer);
uint8_t boot_get_version(uint8_t *RxBuffer);
//uint8_t boot_go(uint32_t address);
uint8_t boot_write_memory(uint32_t address, uint8_t length_minus_1, uint8_t *data);
//uint8_t boot_erase_memory(uint16_t data_frame, uint16_t *page_numbers);
uint8_t boot_erase_memory(void);
uint8_t boot_write_protect(uint8_t number_of_sectors_minus_one, uint8_t *sector_codes);
/*
uint8_t boot_write_unprotect(void);
uint8_t boot_readout_protect(void);
uint8_t boot_readout_unprotect(void);
*/
void Bootoader_send_command(uint8_t command);
void Bootloader_spi_single(uint8_t TxByte);
void Bootloader_spi(uint16_t lengthData, uint8_t *aTxBuffer, uint8_t *aRxBuffer);
void Bootloader_Error_Handler(void);
/* Exported functions --------------------------------------------------------*/
uint8_t extCPU2bootloader_start(uint8_t *version, uint16_t *chipID)
{
// uint8_t aTxBuffer[256] = { 0 };
uint8_t aRxBuffer[256] = { 0 };
HAL_GPIO_WritePin(SMALLCPU_CSB_GPIO_PORT,SMALLCPU_CSB_PIN,GPIO_PIN_RESET);
boot_sync_frame();
boot_get_version(aRxBuffer);
*version = aRxBuffer[1];
HAL_Delay(10);
boot_get_id(aRxBuffer);
*chipID = ((uint16_t)aRxBuffer[2]) << 8;
*chipID += (uint16_t)aRxBuffer[3];
HAL_Delay(10);
if((*chipID == 0x431) && (*version > 10) && (*version < 32))
return 1;
else
return 0;
}
uint8_t extCPU2bootloader_internal(uint8_t* buffer, uint32_t length, char* display_text)
{
uint8_t version = 0;
uint16_t chipID = 0;
// uint8_t ret;
if(!extCPU2bootloader_start(&version,&chipID))
return 0;
if(!boot_erase_memory())
return 0;
HAL_Delay(100);
uint16_t i=0;
uint32_t lengthsave = length;
uint8_t percent = 0;
while(length)
{
percent = (100 * (i * 256)) /lengthsave;
tComm_verlauf(percent);
if(length > 256)
{
if( !boot_write_memory(0x08000000 + (i * 256), 255, &buffer[i * 256]) )
return 0;;
length -= 256;
}
else
{
if(!boot_write_memory(0x08000000 + (i * 256), length - 1, &buffer[i * 256]))
return 0;
length = 0;
}
i++;
}
return 2;
}
uint8_t extCPU2bootloader(uint8_t* buffer, uint32_t length, char* display_text)
{
uint8_t result = 0;
MX_SmallCPU_Reset_To_Boot();
result = extCPU2bootloader_internal(buffer,length,display_text);
MX_SmallCPU_Reset_To_Standard();
return result;
}
/* Private functions --------------------------------------------------------*/
uint8_t boot_sync_frame(void)
{
Bootloader_spi_single(0x5a);
return boot_ack();
}
uint8_t boot_get(uint8_t *RxBuffer)
{
Bootloader_spi_single(0x5a);
Bootoader_send_command(0x00);
if(!boot_ack())
return 0;
Bootloader_spi(14, NULL, RxBuffer);
return boot_ack();
}
uint8_t boot_get_version(uint8_t *RxBuffer)
{
Bootloader_spi_single(0x5a);
Bootoader_send_command(0x01);
if(!boot_ack())
return 0;
Bootloader_spi(3, NULL, RxBuffer);
return boot_ack();
}
uint8_t boot_get_id(uint8_t *RxBuffer)
{
Bootloader_spi_single(0x5a);
Bootoader_send_command(0x02);
if(!boot_ack())
return 0;
Bootloader_spi(5, NULL, RxBuffer);
return boot_ack();
}
/*
uint8_t boot_go(uint32_t address)
{
}
*/
uint8_t boot_write_memory(uint32_t address, uint8_t length_minus_1, uint8_t *data)
{
uint8_t addressNew[4];
uint8_t checksum = 0;
uint16_t length;
Bootloader_spi_single(0x5a);
Bootoader_send_command(0x31);
if(!boot_ack())
return 1;
HAL_Delay(5);
addressNew[0] = (uint8_t)((address >> 24) & 0xFF);
addressNew[1] = (uint8_t)((address >> 16) & 0xFF);
addressNew[2] = (uint8_t)((address >> 8) & 0xFF);
addressNew[3] = (uint8_t)((address >> 0) & 0xFF);
Bootloader_spi(4, addressNew, NULL);
checksum = 0;
checksum ^= addressNew[0];
checksum ^= addressNew[1];
checksum ^= addressNew[2];
checksum ^= addressNew[3];
Bootloader_spi_single(checksum);
if(!boot_ack())
return 0;
HAL_Delay(1);
Bootloader_spi_single(length_minus_1);
length = ((uint16_t)length_minus_1) + 1;
Bootloader_spi(length, data, NULL);
HAL_Delay(26);
checksum = 0;
checksum ^= length_minus_1;
for(int i=0;i<length;i++)
checksum ^= data[i];
Bootloader_spi_single(checksum);
if(!boot_ack())
return 0;
HAL_Delay(1);
return 1;
}
//uint8_t boot_erase_memory(uint16_t data_frame, uint16_t *page_numbers)
uint8_t boot_erase_memory(void)
{
uint8_t special_erase_with_checksum[3] = {0xFF, 0xFF, 0x00};
Bootloader_spi_single(0x5a);
Bootoader_send_command(0x44);
if(!boot_ack())
return 0;
Bootloader_spi(3, special_erase_with_checksum, NULL);
HAL_Delay(11000); /* 5.5 to 11 seconds */
if(!boot_ack())
return 0;
return 1;
}
/* write unprotect does reset the system !! */
uint8_t boot_write_unprotect(void)
{
Bootloader_spi_single(0x5a);
Bootoader_send_command(0x73);
if(!boot_ack())
return 0;
return boot_ack();
}
/*
uint8_t boot_write_protect(uint8_t number_of_sectors_minus_one, uint8_t *sector_codes)
{
}
uint8_t boot_readout_protect(void)
{
}
uint8_t boot_readout_unprotect(void)
{
}
*/
uint8_t boot_ack(void)
{
uint8_t answer = 0;
Bootloader_spi_single(0x00);
for(int i=0; i< 1000; i++)
{
Bootloader_spi(1, NULL, &answer);
if((answer == 0x79) || (answer == 0x1F))
{
Bootloader_spi_single(0x79);
break;
}
HAL_Delay(10);
}
if(answer == 0x79)
return 1;
else
return 0;
}
void Bootoader_send_command(uint8_t command)
{
uint8_t send[2];
uint8_t receive[2];
send[0] = command;
send[1] = 0xFF ^ command;
Bootloader_spi(2, send, receive);
}
void Bootloader_spi_single(uint8_t TxByte)
{
Bootloader_spi(1,&TxByte, 0);
}
void Bootloader_spi(uint16_t lengthData, uint8_t *aTxBuffer, uint8_t *aRxBuffer)
{
uint8_t dummy[256] = { 0 };
uint8_t *tx_data;
uint8_t *rx_data;
tx_data = aTxBuffer;
rx_data = aRxBuffer;
if(aTxBuffer == NULL)
tx_data = dummy;
if(aRxBuffer == NULL)
rx_data = dummy;
//HAL_GPIO_WritePin(OSCILLOSCOPE_GPIO_PORT,OSCILLOSCOPE_PIN,GPIO_PIN_RESET); // only for testing with Oscilloscope
HAL_SPI_TransmitReceive(&cpu2DmaSpi, (uint8_t *)tx_data, (uint8_t *)rx_data, (uint16_t)lengthData,1000);
/*
if(HAL_SPI_TransmitReceive_DMA(&cpu2DmaSpi, (uint8_t *)tx_data, (uint8_t *)rx_data, (uint16_t)lengthData) != HAL_OK)
if(HAL_SPI_TransmitReceive_DMA(&cpu2DmaSpi, (uint8_t *)tx_data, (uint8_t *)rx_data, (uint16_t)lengthData) != HAL_OK)
Bootloader_Error_Handler();
while (HAL_SPI_GetState(&cpu2DmaSpi) != HAL_SPI_STATE_READY)// only for testing with Oscilloscope
{
}
HAL_GPIO_WritePin(OSCILLOSCOPE_GPIO_PORT,OSCILLOSCOPE_PIN,GPIO_PIN_SET); // only for testing with Oscilloscope
*/
}
void Bootloader_Error_Handler(void)
{
while(1);
}