Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 07:28 27 Nov 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : ArmmiteF4 CSUBs and LCD drivers

Author Message
disco4now

Guru

Joined: 18/12/2014
Location: Australia
Posts: 896
Posted: 11:20am 13 Sep 2021
Copy link to clipboard 
Print this post

CSUBs ArmmiteF4
This post covers CSUBs on the ArmmiteF4.It is mostly derived from information in the CMM2 CSUBs thread and a bit of trial and error. The examples from the CMM2 compile for the ArmmiteF4 with just the change of the compiler options. A bitbanged SPI driver for the ST7789 240x240 1.3" IPS display was developed and this highlighted the need for a few changes in the ARMF4CFunctions.h header file used to access the internal MMBasic functions. Relevant information from the CMM2 thread is repeated here so this is a complete reference for the ArmmiteF4.

Setting Up the Development Environment
GCC ARM compiler
To use  Cfunctions (CSUBs) you need to install the GCC ARM compiler
Select gcc-arm-none-eabi-9-2020-q2-update-win32.exe which is down the page a little bit as it is known to work.

The ARMMite F4 uses the same compiler options as the CMM2 except  -mcpu=cortex-m7 is replaced by  -mcpu=cortex-m4
e.g.

  Quote  
arm-none-eabi-gcc -c -mcpu=cortex-m4 -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb -Wall -Wno-main -ffunction-sections -O0 -fPIC -I. main.c -o main.o
arm-none-eabi-ld -nostartfiles -T arm-gcc-link.ld -o main.elf main.o


ARMF4CFunctions.h
The ARMF4CFunctions.h file needed a few changes to overcome some compile errors and to force the correct calculation of the addresses when calling the inbuilt MMBasic functions. The updated version is included in the Installation file zip below. It is added separately here as it is all you need along with the changed command line parameter if you are already setup for CMM2 CSUBs.ARMF4CFunctions.zip



The required linker file is the same one used for CMM2
arm-gcc-link.zip
It is included in the Installation file zip below.

ARMCFGENV143.BAS
To convert the .elf file to the Basic CSUB code the MMBASIC for DOS program armcfgenV143.bas is used.
This  armcfgenV143.bas  can be used, although I have included a slightly modified version that accepts the filename and mode on the command line and allows the function names to be up to 60 characters long in the Installation files zip below.

The Installation Files
This zip file contains all the required files other than the GCC ARM compiler. Just unzip in a suitable directory and follow the directions in the readme.txt file.
Includes ARMCFGENV143a.BAS,arm-gcc-link.ld,ARMF4CFunctions.h and several batch files.
ARMMITECSUBS.zip

Creating/Editting main.c
You create your CSUB by editting the main.c file. This can be done with any text editor, however it is much easier to install STM32CubeIDE and use this to create the main.c and even test compile it to remove any errors before you attempt to create the CSUB.
STM32CubeIDE can be downloaded from here I use version 1.6.0 You will need to register but it is free.
This zip myF4CSUBS.zip
 contains a project myF4CSUBS you can import into STM32CubeIDE  to get you started.


Some things learned while developing the LCDPANEL driver

ARMCFunctions.h changes
  Changes to ARMCFunctions.h said  
V1.6  
Added parenthesis around (BaseAddress+0xx) expressions to force correct evaluation
Option Macro now -->  #define Option (*(struct option_s *)(unsigned int)Vector_Option)
In struct_s changed PIN to unsigned int      --> unsigned int PIN;
In struct_s changed Baudrate to unsigned int --> unsigned int Baudrate;

Added two useful #defines
#define NOP()  __asm volatile ("nop")
#define USERLCDPANEL            19
 
NOP(); can be used to get a one instruction delay, can also be used to pad a function to a 4 byte boundary.
USERLCDPANEL can be used to set the Option.DISPLAY_TYPE when writing LCDPANEL drivers. e.g.
Option.DISPLAY_TYPE=USERLCDPANEL ;
It is placed in the header file in case it changes in a future release. In current release (Beta15 and RC1) it is 19.


16 Bit Instructions
This quote from the CMM2 thread explains why you might need to pad a function with NOP();
  GerryL said  Just a FYI in case you also see this when building CMM2 CSUBS,

Whilst writing a large CSUB for the CMM2 I noticed a minor issue with armcfgenV143.bas, which I assume is due to the fact that 16 bit and 32 bit instructions can be generated by the compiler. As armcfgenV143 reads the '.text' section of the ELF file in 32 bit chunks its possible, in the case where a function does not finish on a 32 bit boundary due to an uneven number of 16 bit instructions, that the start of the next function is missed in armcfgenV143.  In the case of a MERGE all the code is there so it runs OK but you wont see in the generated CSUB text the commented name of the function directly after this missed 32 bit boundary function  and the missing function code gets appended to this previous function that didn't finish on the 32 bit boundary. All not an issue as its all relative branches.  In the case of a JOIN where you have multiple functions in the source a missing function could  be a problem, but a quick fix would be to go to the function directly before the missing function (i.e. the one with the uneven 16 bit instructions) and add asm("nop"); to even up the 16 bit instructions or you could just ensure your source only has a single function. In my experience its not often you end up with an uneven number of 16 bit instructions and if using MERGE of no consequence to it running.

Gerry


Address of Functions
As discussed around page 5 on the CMM2 thread there is an issue when getting the address of a function. @epsilon has provided a solution.
  epsilon said  Interestingly, just declaring foo() static also seems to work:


static void foo(void) {
putConsole('*'); putConsole('\r'); putConsole('\n');  
}


For a static call, the compiler generates position independent code rather than going through a GOT:



For LCDPANEL drivers we need to get the address of the functions when reassigning the vectors for
DrawBitmapVector = (unsigned int)&DrawBitmapSPI;
DrawRectangleVector = (unsigned int)&DrawRectangleSPI;
As suggest by @epsilon setting  the functions to static will allow their address to be found. The address returned is the actual loaded address and does not need to be adjusted with the offset to where the CSUB is loaded.

    * ***** MUST BE static void for the ARMMITEF4 **********
    * ------------------------------------------------------
    * **********************************************************************/
    static void DrawBitmapSPI(int x1, int y1, int width, int height, int scale, int fc, int bc, unsigned char *bitmap){
   
    * ***** MUST BE static void for the ARMMITEF4 **********
    * ------------------------------------------------------
    * *********************************************************************/
    static void DrawRectangleSPI(int x1, int y1, int x2, int y2, int c){

getFPC Function NOT required
The use of function getFPC to determine where the CSUB is loaded used on the PIC32 does not work for the ARMMite F4 (and the CMM2 I suspect). It always returns 0. It is however not required because with the ARMMiteF4 the actual loaded address of the function is returned in any case.
/* **********************************************************************
* This function (getFPC) does NOT work and is also NOT required for ARMMITE F4
* It is shown here to document this fact. Do NOT include it.
* ********************************************************************/
// __attribute__((noinline)) void getFPC(void *a, void *b, volatile unsigned int *c)
//     {
//        *c = (unsigned int) (__builtin_return_address (0) - (b -a) - 1) ;
//     }

Printing a string
A string declared with static const char as below also seems to return it location using its actual loaded address.e.g.  

  static const char startup[]="ST7789 driver bitbanged SPI loaded\r\n";
  p_string(startup);

The function p_string() does not need to work out an offset to where the CSUB is loaded.

All we need because the string pointer is the real address is.

void p_string(const char *s){
   char  * testData    = ( char *)((void *)s );
   MMPrintString(testData);
}


Accessing Options Structure
The Option Macro that requires the syntax of Option->LCD_CS gave errors, the Option Macro in the header file was changed and now the syntax Option.LCD_CS seems to give access to the options structure without any errors.
#define Option (*(struct option_s *)(unsigned int)Vector_Option)

Dummy Function to Document the CSUB
In the driver for the ST7789 I have included as the first function a dummy function for the purpose of documentation. The symbols$() string length in armcfgenV143a.bas has been increased to allow up to 60 characters. (currently only 31 allowed.)
Can be omitted if you don't want to use it.I find it handy if you have various versions of a driver. e.g. different SPI pins etc
  Source code said  
/* *************************************************
* Optional dummy function to document the generated CSUB.
* Uses only a few bytes but allows identification of
* the CSUBs function/use. Up to 60 characters
* *************************************************/

void ST7789_LCD_IPS_240x240_1_3_INCH_v100(){
 NOP();   //Padding to make sure it ends on 4 byte boundary
}

  CSUB Comment said  
'File ST7789.bas written 10-09-2021 15:02:38 v1.43a
CSUB ST7789
000001C9
'ST7789_LCD_IPS_240x240_1_3_INCH_v100
AF00B480 BF00BF00 F85D46BD 47707B04
       ...


LCDPANEL Driver Details

***************************************************************
Here is again a list of Peters (old but useful) tutorials for CFunctions (for Micromites!):
CFunctions - learning by example (1)
CFunctions - learning by example (2)
CFunctions - learning by example (3)
CFunctions - learning by example (4)
**********************************************************************
OPTION LCDPANEL DISABLE before ST7789 Driver
The ST7789 driver will not assign the SPI pins if they are reserved. You must ensure you have issued an OPTION LCDPANEL DISABLE before the ST7789 driver is loaded to ensure that the SPI  pins are released when TOUCH is disabled. Once the ST7789 driver is loaded and the LCDPANEL is changed to USER then the OPTION LCDPANEL DISABLE will not release the TOUCH pins. OPTION RESET can be used to get to a known state where OPTION DISABLE will remove the TOUCH.

This file contains the source for the ST7789 bitbanged driver and the MMBasic test program.

ST7789Driver.zip
Latest F4 Latest H7
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9122
Posted: 12:37pm 13 Sep 2021
Copy link to clipboard 
Print this post

Great post  

Trivial issue. Compuiler option should be -mfpu=fpv4-d16

for the M4
 
disco4now

Guru

Joined: 18/12/2014
Location: Australia
Posts: 896
Posted: 11:53pm 13 Sep 2021
Copy link to clipboard 
Print this post

UPDATE to COMMANDLINE

The correct -mfpu parameter for the commandline -mfpu=fvp4-sp-d16 is now updated , command line for ArmmiteF4 now looks like this.


  Quote  
arm-none-eabi-gcc -c -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -Wall -Wno-main -ffunction-sections -O0 -fPIC -I. main.c -o main.o
arm-none-eabi-ld -nostartfiles -T arm-gcc-link.ld -o main.elf main.o


The install files now have the correct parameters included.
ARMMITECSUBS.zip

and the STM32CubeIDE project also now has correct parameter.
myF4CSUBS.zip
Latest F4 Latest H7
 
TrevorH
Senior Member

Joined: 06/04/2018
Location: United Kingdom
Posts: 144
Posted: 12:41pm 25 Nov 2023
Copy link to clipboard 
Print this post

Are the IO pins on the FSMC connector available to CSUBS?
I would like to try using a 16bit CPLD screen with the ArmmiteF407 as I have a couple
of 7" versions to use. I can't try these using a basic driver as pins not available.
Is there any reason why these can't be made available if NOT using a TFT?

Trevor
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 6798
Posted: 01:22pm 25 Nov 2023
Copy link to clipboard 
Print this post

The FSMC pins aren't GPIO pins. They are, basically, just the internal data bus and some address decoding. The display is effectively just hung off the internal bus like the RAM, flash and CPU.
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9122
Posted: 01:50pm 25 Nov 2023
Copy link to clipboard 
Print this post

  Quote  The FSMC pins aren't GPIO pins.


Yes they are. I just chose not to allow the flexibility to make them available through MMBasic as it is extra code and the F4 is very tight on space
 
TrevorH
Senior Member

Joined: 06/04/2018
Location: United Kingdom
Posts: 144
Posted: 02:36pm 25 Nov 2023
Copy link to clipboard 
Print this post

@matherp, I thought so as the exel pinout sheet suggests as much.
are thes pins available to CSUBS but NOT MMbasic?

Trevor
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9122
Posted: 02:39pm 25 Nov 2023
Copy link to clipboard 
Print this post

Yes, if you use direct register addressing.
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 6798
Posted: 02:40pm 25 Nov 2023
Copy link to clipboard 
Print this post

Interesting - I'll try to find the source of my information again. Someone had asked a similar question on another forum. Once again, it may have been a choice not to implement them.
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
TrevorH
Senior Member

Joined: 06/04/2018
Location: United Kingdom
Posts: 144
Posted: 02:52pm 25 Nov 2023
Copy link to clipboard 
Print this post

@matherp, could you please give me an example?

Trevor
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 6798
Posted: 03:33pm 25 Nov 2023
Copy link to clipboard 
Print this post

I understood that FSMC (flexible static memory controller) is a specialised high speed static RAM interface, which would imply that there wouldn't be the normal latches etc. that you'd associate with GPIO pins. ST link
Edited 2023-11-26 01:35 by Mixtel90
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9122
Posted: 03:47pm 25 Nov 2023
Copy link to clipboard 
Print this post

They are normal I/O pins and FSMC is just an alternate function. I do know what I'm talking about on this one
Edited 2023-11-26 01:49 by matherp
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 6798
Posted: 04:01pm 25 Nov 2023
Copy link to clipboard 
Print this post

Cool!  
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
TrevorH
Senior Member

Joined: 06/04/2018
Location: United Kingdom
Posts: 144
Posted: 05:38pm 25 Nov 2023
Copy link to clipboard 
Print this post

@matherp,
  Quote  Yes, if you use direct register addressing.


Do you mean using the arm's port numbers ie: PE02,PE03 etc or something else.
I understand the FSMC pin numbers are probably not needed.

Trevor.
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 6798
Posted: 05:52pm 25 Nov 2023
Copy link to clipboard 
Print this post

The FSC pins will be controlled by the values in a set of registers. MMBasic hasn't got a way to address those pins (yet) so you need to talk to the registers directly. You'd need to look at the chip data to see which registers and how to configure them.
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024