Sunday, May 24, 2020

Executing with in Ram

After working out how to get the SDRAM working on the new hardware via the FMC (Stm32). Now testing and It APPEARS to be working.
Thats 8 Megabyte of RAM!.

Inside the 2 Meg ROM I have written something that will load a BIN file into the RAM and execute.
After that would perform a CPU jump!

The following section is called to jump to the program that is stored at memory location!

#define APPLICATION_ADDRESS 0xD0000000
typedef  void (*pFunction)(void);
pFunction JumpToApplication;
void Jump( void ) {
	GPIOD->BSRR = (1 << 11);// << 16;
	HAL_Delay(500);
	//CPU_CACHE_Disable();
	SysTick->CTRL = 0;
	//__disable_irq();
	JumpToApplication = (pFunction) (*(__IO uint32_t*) (APPLICATION_ADDRESS + 4));
	__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
	SCB->VTOR = APPLICATION_ADDRESS;
	flogf("Address to Application: %lXrn", JumpToApplication);
	JumpToApplication();
}

—————
The LINKER file for the “bootloader” - our program that is in 2MB Rom -
IN the linker there is a memory section named MADDI, this is where the external ram is located, the FMC takes care of the bus and signals needed, basically this is a SDRAM memory controller - it allows for very large variables and arrays[s].

eg…
MADDI (xrw) : ORIGIN = 0xD0000000, LENGTH = 8M

/**
 ******************************************************************************
 * @file      LinkerScript.ld
 * @author    Auto-generated by STM32CubeIDE
 * @brief     Linker script for STM32F767IGTx Device from STM32F7 series
 *                      1024Kbytes FLASH
 *                      512Kbytes RAM
 *
 *            Set heap size, stack size and stack location according
 *            to application requirements.
 *
 *            Set memory bank area and size if external memory is used
 ******************************************************************************
 * @attention
 *
 * <h2><center>© Copyright (c) 2020 STMicroelectronics.
 * All rights reserved.</center></h2>
 *
 * This software component is licensed by ST under BSD 3-Clause license,
 * the "License"; You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                        opensource.org/licenses/BSD-3-Clause
 *
 ******************************************************************************
 */

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM);	/* end of "RAM" Ram type memory */

_Min_Heap_Size = 0x200 ;	/* required amount of heap  */
_Min_Stack_Size = 0x400 ;	/* required amount of stack */

/* Memories definition */
MEMORY
{
  RAM   (xrw) : ORIGIN = 0x20000000, LENGTH = 512K
  FLASH (rx)  : ORIGIN = 0x8000000,  LENGTH = 1024K
  MADDI (xrw) : ORIGIN = 0xD0000000, LENGTH = 8M
}

/* Sections */
SECTIONS
{
  /* The startup code into "FLASH" Rom type memory */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH

  /* The program code and other data into "FLASH" Rom type memory */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)

    KEEP (*(.init))
    KEEP (*(.fini))

    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH

  /* Constant data into "FLASH" Rom type memory */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >FLASH

  .ARM.extab   : { 
    . = ALIGN(4);
    *(.ARM.extab* .gnu.linkonce.armextab.*)
    . = ALIGN(4);
  } >FLASH
  
  .ARM : {
    . = ALIGN(4);
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
    . = ALIGN(4);
  } >FLASH

  .preinit_array     :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
    . = ALIGN(4);
  } >FLASH
  
  .init_array :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
    . = ALIGN(4);
  } >FLASH
  
  .fini_array :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
    . = ALIGN(4);
  } >FLASH

  /* Used by the startup to initialize data */
  _sidata = LOADADDR(.data);

  /* Initialized data sections into "RAM" Ram type memory */
  .data : 
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */

    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
    
  } >RAM AT> FLASH

  /* Uninitialized data section into "RAM" Ram type memory */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss section */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)

    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >RAM

  /* User_heap_stack section, used to check that there is enough "RAM" Ram  type memory left */
  ._user_heap_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >RAM
  
  	.extram :
    {
    	//. = ALIGN(8);
        *(.extram)           /* .data sections */
    	*(.extram*)          /* .data* sections */
    	KEEP (*(SORT(.extram.*)))
    	KEEP (*(.extram*))
    } >MADDI
  

  /* Remove information from the compiler libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }

  .ARM.attributes 0 : { *(.ARM.attributes) }
}

if you notice the “ROM” area is in 0xD0000000 THIS is where the FMC bus looks up the SDRAM-BANK1

/**
 ******************************************************************************
 * @file      LinkerScript.ld
 * @author    Auto-generated by STM32CubeIDE
 * @brief     Linker script for STM32F767IGTx Device from STM32F7 series
 *                      1024Kbytes FLASH
 *                      512Kbytes RAM
 *
 *            Set heap size, stack size and stack location according
 *            to application requirements.
 *
 *            Set memory bank area and size if external memory is used
 ******************************************************************************
 * @attention
 *
 * <h2><center>© Copyright (c) 2020 STMicroelectronics.
 * All rights reserved.</center></h2>
 *
 * This software component is licensed by ST under BSD 3-Clause license,
 * the "License"; You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                        opensource.org/licenses/BSD-3-Clause
 *
 ******************************************************************************
 */

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM);	/* end of "RAM" Ram type memory */

_Min_Heap_Size = 0x200 ;	/* required amount of heap  */
_Min_Stack_Size = 0x400 ;	/* required amount of stack */

/* Memories definition */
MEMORY
{
  RAM    (xrw)     : ORIGIN = 0xD0400000,   LENGTH = 2M
  FLASH    (rx)    : ORIGIN = 0xD0000000,    LENGTH = 2M
}

/* Sections */
SECTIONS
{
  /* The startup code into "FLASH" Rom type memory */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH

  /* The program code and other data into "FLASH" Rom type memory */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)

    KEEP (*(.init))
    KEEP (*(.fini))

    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH

  /* Constant data into "FLASH" Rom type memory */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >FLASH

  .ARM.extab   : { 
    . = ALIGN(4);
    *(.ARM.extab* .gnu.linkonce.armextab.*)
    . = ALIGN(4);
  } >FLASH
  
  .ARM : {
    . = ALIGN(4);
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
    . = ALIGN(4);
  } >FLASH

  .preinit_array     :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
    . = ALIGN(4);
  } >FLASH
  
  .init_array :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
    . = ALIGN(4);
  } >FLASH
  
  .fini_array :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
    . = ALIGN(4);
  } >FLASH

  /* Used by the startup to initialize data */
  _sidata = LOADADDR(.data);

  /* Initialized data sections into "RAM" Ram type memory */
  .data : 
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */

    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
    
  } >RAM AT> FLASH

  /* Uninitialized data section into "RAM" Ram type memory */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss section */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)

    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >RAM

  /* User_heap_stack section, used to check that there is enough "RAM" Ram  type memory left */
  ._user_heap_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >RAM

  /* Remove information from the compiler libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }

  .ARM.attributes 0 : { *(.ARM.attributes) }
}

with the Application it appears that you just create something as you would normally!

NOTE: compile to the BIN file, this wont work with .HEX or .ELF file!
the bin file contains OP codes

also this is said to run at about 5 times slow.. but have to rememeber, each step, the processor has to fetch a command, the fetch the data, then act upon the data, then store the result in one pipe.

where was program runs from the ROM and stores thigns in ram, this can be done with in just 2 cycles.

Sunday, May 17, 2020

A working DMA AUDIO output

sidboxv5begin.png The project begins to take life now; While its taken me a LONG time and most of my hair is still present!
I still have a long way to go, but I do have something that is causing us some excitement!

While working on the SDCARD (which now appears to be fully working now) I wanted to see if I could get the SDCARD to stream some audio.

At first I did this the old way as the Sidbox 4 does this, uses an interupt with a read and write audio buffer positions. While this works really well on the Sidbox 4 OS, this chip has 400Mhz and a few DMA channels, one of which is a DAC.

I can setup an audio buffer, and have that memory transferred at 441khz to the DAC, leaving the CPU free to do something else! The issue I got with this though is the DMA seems to collide a bit while using the FatFS (but thats just a current bug for now)

So the while it plays it just choses to put the new data in to the audio buffer

To Get this to work I had to wire up the following.

Note that this has NO Card Select! I was confused by this, but I found that I had to find away to tie the CS to 3.3v, the SDMMC1 port onthe STM32 takes care of everything else.

wiring-the-sdcard.jpg

So Now I have the SDCARD playing 8Bit Wav Files at 44100Hz and its done via the DMA,
all the CPU has to do when called via an interupt is to fetch another 1k of audio and stuff it in to the audio buffer.

Wednesday, May 13, 2020

SDCARD - Nucleoboard

nucleo.jpg The Nucleo-H743ZI2 - How much did I just bite off!!! Been at this problem for almost 2 weeks now, the SDCARD reader, VIA the SPI and SDMMC1 while they both worked with the example code, but those example code had other parts i didn’t need. So removing the parts that were’nt relevent to me my project, I ended up breaking the code.

IT was clearly required to create a whole new project - Now I’ve done this multiple times and each time the sodding FatFS didn’t work!

After I Found the debug infomation and actually a HUGE amount of info from a Facebook user by the name of Jeff, lent me his code for the sdcard, it wasn’t completed and didn’t work for what I needed, HOWEVER It did point me to the directions of the missing commands!

In the file

bsp_driver_sd.c
__weak uint8_t BSP_SD_Init(void)
{
  uint8_t sd_state = MSD_OK;
  /* Check if the SD card is plugged in the slot */
  //if (BSP_SD_IsDetected() != SD_PRESENT)
  //{
    //return MSD_ERROR_SD_NOT_PRESENT;
  //}
  /* HAL SD initialization */
  sd_state = HAL_SD_Init(&hsd1);

  return sd_state;
}

what I did was the comment the check to see if the card was inserted, while I will put this in later, i just wanted to know if the card worked.

The SDCard has 2.2K resistor pull-ups, connected to MOSI, and MISO - the MX IDE calls these, SDMMC1_CMD (mosi), SDMMC1_DO (miso).

on the Nucleoboard there are red, green and a yellow.

#define GREEN_PIN                                GPIO_PIN_0
#define GREEN_GPIO_PORT                          GPIOB

#define YELLOW_PIN                                GPIO_PIN_1
#define YELLOW_GPIO_PORT                          GPIOE

#define RED_PIN                                GPIO_PIN_14
#define RED_GPIO_PORT                          GPIOB

void PrepUserOI(){

	  __HAL_RCC_GPIOB_CLK_ENABLE();
	  __HAL_RCC_GPIOC_CLK_ENABLE();
	  __HAL_RCC_GPIOD_CLK_ENABLE();
	  __HAL_RCC_GPIOE_CLK_ENABLE();

	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.Pin = GPIO_PIN_1;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

	GPIO_InitStruct.Pin = GPIO_PIN_0;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

	GPIO_InitStruct.Pin = GPIO_PIN_14;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

inside the main file
the annoypart was to tell the system to START the sd_init();
sadly i couldn’t find this in the information documenations normally provided by ST.

here is how I got it working

 /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SDMMC1_SD_Init();
  MX_FATFS_Init();
  /* USER CODE BEGIN 2 */
  PrepUserOI();
  char res;
  res=0;
  //res = disk_initialize(0);
	res = BSP_SD_Init();
	if (res == FR_OK) {
		res = disk_initialize(0);
		if (res == FR_OK) {
			res = f_mount(&fs, "0:/", 0);
			if (res == FR_OK) {
				strcpy(buffer, "Hello world, this is a test");
				if (f_open(&fil, "hello world test file.txt", FA_CREATE_ALWAYS | FA_WRITE)
						== FR_OK) {

					f_write(&fil, buffer, sizeof(buffer), &bytes);
					f_close(&fil);

				}

			}
		}

	}

the code uploaded and begin to run, and instead of the yellow pulse range of around 200khz, i got the fill 12Mhz and some Blue pulses (this is the Data to the SDcard - MOSI)

sdcard_win1.png

with this I made a backup of this as the whole ordeal was awful!

BUT I concluded that while messy, the IDE and MX did do a good job of filling in the SDMMC1 and paring up to the SDCARD FatFS 0.12C

I have included the download of this project (its only for the Fat32 access)
CubeIDE GCC - C (not C++) Download Source

I’ll write up a more detailed what I found, how I figured out how to get this system to work!

Monday, May 4, 2020

And So, It begins!

sidboxv5begin.png AND so it begins, this is the info being returned from the new processor.

Took me all night, and I finally got it to do something!

The process of learning and being eager to get started and having some problems with the new IDE and methods for getting chips to turn on legs and not as fast as possible.

My Targets here is to get the following working…

  • Working: Serial port via a interupt.
  • Working: A Flashing light.
  • Working: BASIC: DAC with a basic Sawtooth output, i want to make this a DMA so I just dump audio into the DAC buffers.
  • TO DO: Display Driver.
  • TO DO: Buttons interfacing.
  • TO DO: SDCARD interfacing (this will be its own blog I believe. alot of work will be needed here I think.

sidbox5scope1.png

I hope to keep everyone updated here.

Sunday, May 3, 2020

STM32F767IG Begins!

ge64lqfp_stm32-40.jpg So it begins! New hardware, new programming, new struggles and NO HAIR.

I’ve been working on a board that has 2 items on it, 8MB Ram, and an STM32F767IG, while I have a long way to go I am learning alot in a few short days.

The IDE and the CubeMX is clunky and slow, but its a way into the evinronment. I am finding aspects of the chip confusing and hard to read manuals, I am from the envinronment of the Microchip controllers. Microchip have been good to me and while they offer some very good products and support, the fact that I would have to pay a subscription for using a GCC compiler if I wanted to have optimised for speed.

While looking for alternatives We came across this ST company doing some frightfully fast MCU’s. We found that MCUS for our project would be good. This allows for external ram and a whole host of peripherals.

I decided to make a log of the things I learn and figure out. Snippets of code and advise and things I found out along the way.
I am on day 2 of just working out how the Internal Clock is configured.. and using the MX it configures a lot, I would recommend saving your work if you use this as it likes to create the code for you and sometimes over writes the main().

// Testing the max speed of the GPIO pins
for (;;) {
		GPIOA->BSRR = (0xffff)<<16;	GPIOA->BSRR = (0xffff); 
		GPIOA->BSRR = (0xffff)<<16;	GPIOA->BSRR = (0xffff);
		GPIOA->BSRR = (0xffff)<<16;	GPIOA->BSRR = (0xffff);
		GPIOA->BSRR = (0xffff)<<16;	GPIOA->BSRR = (0xffff);
		GPIOA->BSRR = (0xffff)<<16;	GPIOA->BSRR = (0xffff);
		GPIOA->BSRR = (0xffff)<<16;	GPIOA->BSRR = (0xffff);
		GPIOA->BSRR = (0xffff)<<16;	GPIOA->BSRR = (0xffff);
		GPIOA->BSRR = (0xffff)<<16;	GPIOA->BSRR = (0xffff);
	}

the speed of this is QUICK at the CPU running (or should I say the clock settings) are set to 216Mhz. I’ve had to test.

it works, but I am still fuzzy on how things got setup and how they worked.

Right now. I am struggling with just getting a basic UART to work.

Programming the chip was a nightmare to setup until someone in the facebook group pointed out I needed to use or was better to use the CubeProgrammer, Which worked, using a TTL Serial to USB device I was able to use the OnBoard Serial Port BootLoader.

Got the first program working, which was the hello world blinky light.
Its not much but it at least is a start and away to help me believe I didn’t bite off more than I could chew!

I hope to progress.

resources to links i found:
https://gist.github. … 22a268ce890a118571ca

Sunday, April 26, 2020

Put your thoughts here!

While I am working towards bettering the Blogging system, I am hoping to have good discussion base here.

Please keep it clean, no spam, no links to other websites (unless its related to the topic)

Thank you.