STM32F103xxxx In Application Programming Using Arduino

0

I am using Arduino_STM32 rogerclark's library.https://github.com/rogerclarkmelbourne/Arduino_STM32 . Now I want to Develop an In Application Programming(IAP) like a bootloader. Take Code from SD card and Store in Controller flash at 0x8010000 and then jump to that location and run the loaded new application.

the code took from SD and stored into flash successfully done but after jump function called its printing null like this

13:29:04.933 [RX] - Starts............

13:29:07.970 [RX] - 20480 uploaded successfully.

NULNULNULNUL NULNUL

my Main IAP code is

Header file

#include <SPI.h>
#include <SD.h>
#include <EEPROM.h>
#include <stdint.h>
#include "libmaple/scb.h"
#include "usb_lib.h"

typedef void (*FuncPtr)(void);
#define SCS_BASE   ((u32)0xE000E000)
#define NVIC_BASE  (SCS_BASE + 0x0100)
#define SCB_BASE   (SCS_BASE + 0x0D00)
#define SCS      0xE000E000
#define NVIC     (SCS+0x100)
#define SCB      (SCS+0xD00)
#define STK      (SCS+0x10)

#define SCB_VTOR (SCB+0x08)
#define STK_CTRL (STK+0x00)

#define RCC   ((u32)0x40021000)
#define RCC_CR      RCC
#define RCC_CFGR    (RCC + 0x04)
#define RCC_CIR     (RCC + 0x08)

#define USB_LP_IRQ  ((u8)0x14)
#define SET_REG(addr,val) do{ *(volatile uint32_t*)(addr)=val;} while(0)
#define GET_REG(addr)     (*(vu32*)(addr))

#define pRCC ((rcc_reg_map *) RCC)

typedef struct {
  u8 NVIC_IRQChannel;
  u8 NVIC_IRQChannelPreemptionPriority;
  u8 NVIC_IRQChannelSubPriority;
  bool NVIC_IRQChannelCmd; /* TRUE for enable */
} NVIC_InitTypeDef;

#define RegBase  (0x40005C00L)
#define CNTR    ((volatile unsigned *)(RegBase + 0x40))
#define _SetCNTR(wRegValue)  (*CNTR   = (u16)wRegValue)
#define _GetCNTR()   ((u16) *CNTR)
#define ISTR    ((volatile unsigned *)(RegBase + 0x44))
#define _SetISTR(wRegValue)  (*ISTR   = (u16)wRegValue)
#define _GetISTR()   ((u16) *ISTR)

void setupFLASH();
void usbDsbISR(void);
void nvicInit(NVIC_InitTypeDef *NVIC_InitStruct);
void nvicDisableInterrupts();
void setMspAndJump(u32 usrAddr);
void systemReset(void);
RESULT usbPowerOff(void);



void setupFLASH()
{
  /* configure the HSI oscillator */
  if ((pRCC->CR & 0x01) == 0x00)
  {
    u32 rwmVal = pRCC->CR;
    rwmVal |= 0x01;
    pRCC->CR = rwmVal;
  }

  /* wait for it to come on */
  while ((pRCC->CR & 0x02) == 0x00) {}
}

 void usbDsbISR(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  NVIC_InitStructure.NVIC_IRQChannel = USB_LP_IRQ;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = FALSE;
  nvicInit(&NVIC_InitStructure);
}

void nvicInit(NVIC_InitTypeDef *NVIC_InitStruct)
{
  u32 tmppriority = 0x00;
  u32 tmpreg      = 0x00;
  u32 tmpmask     = 0x00;
  u32 tmppre      = 0;
  u32 tmpsub      = 0x0F;

  scb_reg_map *rSCB = (scb_reg_map *) SCB_BASE;
  nvic_reg_map *rNVIC = (nvic_reg_map *) NVIC_BASE;


  /* Compute the Corresponding IRQ Priority --------------------------------*/
  tmppriority = (0x700 - (rSCB->AIRCR & (u32)0x700)) >> 0x08;
  tmppre = (0x4 - tmppriority);
  tmpsub = tmpsub >> tmppriority;

  tmppriority = (u32)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;
  tmppriority |=  NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub;

  tmppriority = tmppriority << 0x04;
  tmppriority = ((u32)tmppriority) << ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08);

  tmpreg = rNVIC->IP[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)];
  tmpmask = (u32)0xFF << ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08);
  tmpreg &= ~tmpmask;
  tmppriority &= tmpmask;
  tmpreg |= tmppriority;

  rNVIC->IP[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)] = tmpreg;

   /* Enable the Selected IRQ Channels --------------------------------------*/
    rNVIC->ISER[(NVIC_InitStruct->NVIC_IRQChannel >> 0x05)] =
    (u32)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (u8)0x1F);
}

 void nvicDisableInterrupts()
{
  nvic_reg_map *rNVIC = (nvic_reg_map *) NVIC_BASE;
  rNVIC->ICER[0] = 0xFFFFFFFF;
  rNVIC->ICER[1] = 0xFFFFFFFF;
  rNVIC->ICPR[0] = 0xFFFFFFFF;
  rNVIC->ICPR[1] = 0xFFFFFFFF;

  SET_REG(STK_CTRL, 0x04); /* disable the systick, which operates separately from nvic */
}

void usbDsbBus(void)
{
  // setPin(USB_DISC_BANK,USB_DISC_PIN);
  usbPowerOff();
  // SET_REG(USB_DISC_CR,
  // (GET_REG(USB_DISC_CR) & USB_DISC_CR_MASK) | USB_DISC_CR_OUTPUT);
  // resetPin(USB_DISC_BANK, USB_DISC_PIN); /* Pull DP+ down */
  // volatile unsigned x = 500000; do { ; }while(--x);
  // SET_REG(USB_DISC_CR,
  // (GET_REG(USB_DISC_CR) & USB_DISC_CR_MASK) | USB_DISC_CR_INPUT); //Sets the PA12 as floating 
input
}

RESULT usbPowerOff(void)
{
   #define CNTR_PDWN   (0x0002) /* Power DoWN */
   #define CNTR_FRES   (0x0001) /* Force USB RESet */
  _SetCNTR(CNTR_FRES);
  _SetISTR(0);
  _SetCNTR(CNTR_FRES + CNTR_PDWN);

  /* note that all weve done here is powerdown the
     usb peripheral. we have no disabled the clocks,
     pulled the USB_DISC_PIN pin back up, or reset the
     application state machines */

  return USB_SUCCESS;
}

void systemReset(void)
{
  SET_REG(RCC_CR, GET_REG(RCC_CR) | 0x00000001);
  SET_REG(RCC_CFGR, GET_REG(RCC_CFGR) & 0xF8FF0000);
  SET_REG(RCC_CR, GET_REG(RCC_CR) & 0xFEF6FFFF);
  SET_REG(RCC_CR, GET_REG(RCC_CR) & 0xFFFBFFFF);
  SET_REG(RCC_CFGR, GET_REG(RCC_CFGR) & 0xFF80FFFF);
  SET_REG(RCC_CIR, 0x00000000);  /* disable all RCC interrupts */
}

void setMspAndJump(u32 usrAddr)
{
  // Dedicated function with no call to any function (appart the last call)
  // This way, there is no manipulation of the stack here, ensuring that GGC
  // didn't insert any pop from the SP after having set the MSP.
  typedef void (*funcPtr)(void);
  u32 jumpAddr = *(vu32 *)(usrAddr + 0x04); /* reset ptr in vector table */

  funcPtr usrMain = (funcPtr) jumpAddr;

  SET_REG(SCB_VTOR, (vu32) (usrAddr));

  asm volatile("msr msp, %0"::"g"(*(volatile u32 *)usrAddr));

  usrMain();                                /* go! */
}

main code is

    #include "core_test.h"

#define CS          PB9
File myFile;
char Name[15] = "ASCII.bin";

uint32_t Count = 0;
uint32_t total = 0;

#define FLASH_FLAG_EOP                 ((uint32_t)0x00000020)  /* FLASH End of Operation flag */
#define FLASH_FLAG_PGERR               ((uint32_t)0x00000004)  /* FLASH Program error flag */
#define FLASH_FLAG_WRPRTERR            ((uint32_t)0x00000010)  /* FLASH Write protected error flag */

#define myFLASH_APP_ADDR 0x08000000
#define FLASH_APP_ADDR 0x08010000 //The first application start address (stored in FLASH)
#define STM_PAGE_SIZE 2048         //Note: The FLASH page size of STM32F103ZET6 is 2K.

//****************************************************************************************************
// Global variable declaration
char buff[STM_PAGE_SIZE];
int res;
unsigned int br;

void Jump2App(uint32_t Addr)
{
  if (((*(uint32_t*)Addr) & 0x2FFE0000) == 0x20000000) //Check if the top address of the stack is legal.
  {
    //    FLASH_Lock();
    usbDsbISR(); //Serial1.println("1");
    nvicDisableInterrupts(); //Serial1.println("2");
    usbDsbBus(); //Serial1.println("3");
    // Does nothing, as PC12 is not connected on teh Maple mini according to the schemmatic     setPin(GPIOC, 12); // disconnect usb from host. todo, macroize pin
    systemReset(); // resets clocks and periphs, not core regs
    //Serial1.println("4");
    setMspAndJump(Addr);
  }
}
void FirmwareUpdate(void)
{
  int PageOffest = 0;
  int ByteOffest;
  if (! IsFileExists(Name)) return;
  myFile = SD.open(Name);

  while (1)
  {
    if (Read_data_from_File(buff))
    {
      FLASH_Unlock();
      //      FLASH_ClearFlag(((uint16_t)0x00000034));
      //      FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
      FLASH_ErasePage(FLASH_APP_ADDR + PageOffest);
      for (ByteOffest = 0; ByteOffest < STM_PAGE_SIZE; ByteOffest += 2)
      {
        total = total + 2;
        FLASH_ProgramHalfWord(FLASH_APP_ADDR + PageOffest + ByteOffest, *(uint16_t*)(buff + ByteOffest));
      }
      FLASH_Lock();
      PageOffest += STM_PAGE_SIZE;
      //      Serial1.println(PageOffest);
    }
    else if (myFile.size() <= total) break;
  }
  myFile.close();
  Serial1.println(total);
  //myFile.close();
}

void setup()
{
  afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY);
  Serial1.begin(9600);
  if (!SD.begin(CS))
  {
    Serial1.println("No SD............");
    Jump2App(FLASH_APP_ADDR);
  }
  delay(1000);
  Serial1.println("Starts............"); delay(2000);
  FirmwareUpdate();
  Jump2App(FLASH_APP_ADDR);
  while (1);
}

void loop()
{}

bool IsFileExists(char FileName[])
{
  if (SD.exists(FileName)) return 1;
  else  return 0;
}

bool Read_data_from_File(char str[])
{
  memset(str, 255, 2048);
  uint16_t i = 0;
  if (myFile.size() < total)
  {
    //memset(str, 255, 2048);
    //    Serial1.println("File Closed");
    //    Serial1.println(total);
    return 0;
  }
  if (myFile)
  {
    while (i < 2048)
    {
      str[i++] = myFile.read();
      Count = Count + 1;
      if (myFile.size() < Count)
      {
        //memset(str, 255, 2048);
        //        Serial1.println("File Closed");
        //        Serial1.println(Count);
        return 1;
      }
    }
  }
  else return 0;
}

my user Application code is ASCIItable example code which is given in arduino

before generation this ASCII.bin file i have changed ROM location address 0x8000000 to 0x8010000 and compiled the file. Is this process correct, please help me where I am doing wrong

arduino
stm32
asked on Stack Overflow Nov 28, 2019 by saiGSK • edited Nov 28, 2019 by saiGSK

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0