diff Discovery/Src/externCPU2bootloader.c @ 38:5f11787b4f42

include in ostc4 repository
author heinrichsweikamp
date Sat, 28 Apr 2018 11:52:34 +0200
parents
children f64cf099a7f5
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Discovery/Src/externCPU2bootloader.c	Sat Apr 28 11:52:34 2018 +0200
@@ -0,0 +1,343 @@
+/**
+  ******************************************************************************
+  * @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>&copy; 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, uint16_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;
+	uint16_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, uint16_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);
+}
+
+
+