Author Topic: Help porting 2 functions from C++ to C  (Read 1736 times)

0 Members and 1 Guest are viewing this topic.

Offline kgavionicsTopic starter

  • Regular Contributor
  • *
  • Posts: 203
  • Country: ca
Help porting 2 functions from C++ to C
« on: May 02, 2024, 01:00:41 pm »
Hello guys
I have a working N5110 library on my Stm32F401 which using plain C, but recently, I came across this Arduino library:
https://github.com/cbm80amiga/N5110_SPI
What I like about this library is the extensive fonts that it has. So, I wanted to just port 2 function from this library which are  (N5110_SPI::setFont) and (N5110_SPI::printChar) , and use my library to initialize the display and send data using SPI.
Bellow, is the C++ code:
Code: [Select]
//------------------------------------------------------------------------
void N5110_SPI::setFont(const uint8_t* f)
{
  font     = f;
  xSize    =-pgm_read_byte(font+0);
  ySize    = pgm_read_byte(font+1);
  firstCh  = pgm_read_byte(font+2);
  lastCh   = pgm_read_byte(font+3);
  ySize8   = (ySize+7)/8;
  minCharWd  = 0;
  minDigitWd = 0;
  cr = 0;
  invertCh = 0;
  invertMask = 0xff;
}
//--------------------------------------------------------------------------

int N5110_SPI::printChar(int x, uint8_t row, uint8_t _ch)
{

  int ch = _ch;

 
  if(!font || ch<firstCh || ch>lastCh || x>=SCR_WD || row>=SCR_HT/8) return 0;

  int j,i, idx = 4 + (ch - firstCh)*(xSize*ySize8+1);
  int wd = pgm_read_byte(font + idx++);
  int wdL = 0, wdR = 1; // default spacing before and behind char
  if((*isNumberFun)(ch)) {
    if(minDigitWd>wd) {
      wdL = (minDigitWd-wd)/2;
      wdR += (minDigitWd-wd-wdL);
    }
  } else
  if(minCharWd>wd) {
    wdL = (minCharWd-wd)/2;
    wdR += (minCharWd-wd-wdL);
  }
  if(x+wd+wdL+wdR>SCR_WD) wdR = max(SCR_WD-x-wdL-wd, 0);
  if(x+wd+wdL+wdR>SCR_WD) wd = max(SCR_WD-x-wdL, 0);
  if(x+wd+wdL+wdR>SCR_WD) wdL = max(SCR_WD-x, 0);
  for(j=0; j<ySize8; j++) {
    gotoXY(x, row+j);
    setDat();
    startCS();
    if(!invertCh) {
      for(i=0; i<wdL; i++) sendData(0);
      for(i=0; i<wd; i++)  sendData(pgm_read_byte(font+idx+i*ySize8+j));
      for(i=0; i<wdR; i++) sendData(0);
    } else {
      for(i=0; i<wdL; i++) sendData(invertMask);
      for(i=0; i<wd; i++)  sendData(pgm_read_byte(font+idx+i*ySize8+j)^invertMask);
      for(i=0; i<wdR; i++) sendData(invertMask);
    }
    stopCS();
  }
  return wd+wdL+wdR;
}

My code is below, that compiles, but doesn't display anything on the display:
Code: [Select]
//------------------------------------------------------------------
void N5110_setFont(const uint8_t* f)
{
  font     = f;
  xSize    =-(font[0]+0);
  ySize    = (font[0]+1);
  firstCh  = (font[0]+2);
  lastCh   = (font[0]+3);
  ySize8   = (ySize+7)/8;
  minCharWd  = 0;
  minDigitWd = 0;
  cr = 0;
  invertCh = 0;
  invertMask = 0xff;
}

int N5110_printChar(int x, uint8_t row, uint8_t _ch)
{

  int ch = _ch;

 
  if(!font || ch<firstCh || ch>lastCh || x>=SCR_WD || row>=SCR_HT/8) return 0;

  int j,i, idx = 4 + (ch - firstCh)*(xSize*ySize8+1);
int  wd = (font[0] + idx++);
  int wdL = 0, wdR = 1; // default spacing before and behind char

  if((*isNumberFun)(ch)) {
    if(minDigitWd>wd) {
      wdL = (minDigitWd-wd)/2;
      wdR += (minDigitWd-wd-wdL);
    }
  } else
  if(minCharWd>wd) {
    wdL = (minCharWd-wd)/2;
    wdR += (minCharWd-wd-wdL);
  }


  if(x+wd+wdL+wdR>SCR_WD) wdR = max(SCR_WD-x-wdL-wd, 0);
  if(x+wd+wdL+wdR>SCR_WD) wd = max(SCR_WD-x-wdL, 0);
  if(x+wd+wdL+wdR>SCR_WD) wdL = max(SCR_WD-x, 0);
  for(j=0; j<ySize8; j++) {
    gotoXY(x, row+j);
    setDat();
  startCS();
    if(!invertCh) {
      for(i=0; i<wdL; i++) glcd_data(0);
      for(i=0; i<wd; i++)  glcd_data((font[0]+idx+i*ySize8+j));
      for(i=0; i<wdR; i++) glcd_data(0);
    } else {
      for(i=0; i<wdL; i++) glcd_data(invertMask);
      for(i=0; i<wd; i++)  glcd_data((font[0]+idx+i*ySize8+j)^invertMask);
      for(i=0; i<wdR; i++) glcd_data(invertMask);

    }
    stopCS();

  }

  return wd+wdL+wdR;
}
for the "max" function, because it doesn't exist in C, I found online which is:
Code: [Select]
int max(int a, int b) {

return (a > b) ? a : b;

}
I sure something is wrong with my code, but I can't figure it out by my self. Please, guys don't be hard on me, as I'm just a hobbyist, not an expert in programming. Can someone guide me how to port these 2 functions to plain C please?
Thank you in advance
« Last Edit: May 02, 2024, 03:23:50 pm by kgavionics »
 

Offline eutectique

  • Frequent Contributor
  • **
  • Posts: 404
  • Country: be
Re: Help porting 2 functions from C++ to C
« Reply #1 on: May 02, 2024, 01:33:13 pm »
I sure something is wrong with my code

What exactly? In which way? How do you know? Are there any visible signs of it being wrong?
 

Offline radiolistener

  • Super Contributor
  • ***
  • Posts: 3441
  • Country: ua
Re: Help porting 2 functions from C++ to C
« Reply #2 on: May 02, 2024, 01:40:26 pm »
  xSize    =-pgm_read_byte(font+0);
  ySize    = pgm_read_byte(font+1);
  firstCh  = pgm_read_byte(font+2);
  lastCh   = pgm_read_byte(font+3);

  xSize    =-(font[0]+0);
  ySize    = (font[0]+1);
  firstCh  = (font[0]+2);
  lastCh   = (font[0]+3);

At least here is mistake. font is a pointer.
Original code reads byte from address font+x, while your code reads byte from address font and then add x to the result of read operation.

The correct replacement should be something like this:
Code: [Select]
  xSize    =-(uint8_t)font[0];
  ySize    = (uint8_t)font[1];
  firstCh  = (uint8_t)font[2];
  lastCh   = (uint8_t)font[3];

uint8_t is defined in stdint.h, this is cross-platform unsigned byte.

« Last Edit: May 02, 2024, 01:46:41 pm by radiolistener »
 

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 3792
  • Country: nl
Re: Help porting 2 functions from C++ to C
« Reply #3 on: May 02, 2024, 01:51:47 pm »
You can't just take these two functions and translate them to C. You have to analyze the functionality and also make sure the supporting functions are taken into account.

The comment of radiolistener points out what I mean with my remark. You overlooked what the pgm_read_byte function does, and what the type of font is. (const uint8_t* font;)

Converting it to C also means you have to declare a lot of global variables, and it would be clearer when a structure is used for this. So convert the variables in the class to a structure and make that a global variable.

Edit: For better help you should attach your full project as an archive to your original post. The code sniplets don't show what is done in for instance "glcd_data".
« Last Edit: May 02, 2024, 01:57:15 pm by pcprogrammer »
 

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 3792
  • Country: nl
Re: Help porting 2 functions from C++ to C
« Reply #4 on: May 02, 2024, 01:54:15 pm »
I sure something is wrong with my code

What exactly? In which way? How do you know? Are there any visible signs of it being wrong?

Well he did write that nothing is shown on the display, which to me seems something is indeed wrong.  :-DD

Quote
My code is below, that compiles, but doesn't display anything on the display:

Offline kgavionicsTopic starter

  • Regular Contributor
  • *
  • Posts: 203
  • Country: ca
Re: Help porting 2 functions from C++ to C
« Reply #5 on: May 02, 2024, 03:24:39 pm »
Hello
I attached the whole project in the first post.
 

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 3792
  • Country: nl
Re: Help porting 2 functions from C++ to C
« Reply #6 on: May 02, 2024, 04:13:38 pm »
I have looked at the code and have to say that it is a bit of a mess.

You should try to adapt a more structured and cleaner way of programming. This will improve readability and also maintainability.

There might be an issue with the SPI transfer not checking for the correct finishing state. Take a look at a project of mine here. In the file "stm32f103_nrf905.c" there is the function "nrf905_write_spi" that sends data through an SPI port that works for sure. During development of that code I ran into some issues with the behavior of the SPI peripheral that was not clearly specified in the manuals and needed to make sure to wait for a proper finish after the data was send to keep it working.

The archive you attached is missing a make file and a linker script.

Offline kgavionicsTopic starter

  • Regular Contributor
  • *
  • Posts: 203
  • Country: ca
Re: Help porting 2 functions from C++ to C
« Reply #7 on: May 02, 2024, 05:45:14 pm »
I have looked at the code and have to say that it is a bit of a mess.

You should try to adapt a more structured and cleaner way of programming. This will improve readability and also maintainability.

There might be an issue with the SPI transfer not checking for the correct finishing state. Take a look at a project of mine here. In the file "stm32f103_nrf905.c" there is the function "nrf905_write_spi" that sends data through an SPI port that works for sure. During development of that code I ran into some issues with the behavior of the SPI peripheral that was not clearly specified in the manuals and needed to make sure to wait for a proper finish after the data was send to keep it working.

The archive you attached is missing a make file and a linker script.
Thank you for taking a look to the code,but I can guarantee that the spi function is working fine.Try to send something with the command glcd_data(0xff) it will show a bar in the display.
 

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 3792
  • Country: nl
Re: Help porting 2 functions from C++ to C
« Reply #8 on: May 02, 2024, 06:05:49 pm »
Thank you for taking a look to the code,but I can guarantee that the spi function is working fine.Try to send something with the command glcd_data(0xff) it will show a bar in the display.

I don't have a setup ready to test this, but I will take your word for that part working. Still leaves you with non working code. In what you attached the error with the font reading is still faulty.

Check radiolistener his post and fix that first and see what else is not reading the font data in a correct manner.

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5970
  • Country: es
Re: Help porting 2 functions from C++ to C
« Reply #9 on: May 02, 2024, 08:54:13 pm »
First of all, check the compiler warnings, for sure you'll be getting plenty of them, like the mistake with the font pointer.
They're not there to just be ignored!
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline darkspr1te

  • Frequent Contributor
  • **
  • Posts: 301
  • Country: zm
Re: Help porting 2 functions from C++ to C
« Reply #10 on: May 03, 2024, 12:30:19 pm »
it could be the way your code refers to the font variable, i often found that in one library i would refer to it as font, another as font[] another as *font (pointer),
a trick i also learned is that in a function thats not working you should also send out the data to serial port to confirm your function has access to the data, i've had situations where i did not pass the pointer too the data but just a empty var and was able to confirm it by sending it to the serial port.




darkspr1te

 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11695
  • Country: my
  • reassessing directives...
Re: Help porting 2 functions from C++ to C
« Reply #11 on: May 03, 2024, 04:07:47 pm »
Thank you for taking a look to the code,but I can guarantee that the spi function is working fine.Try to send something with the command glcd_data(0xff) it will show a bar in the display.
have you fix your code as advised by radiolistener? its called semantic error and semantic errors wont show up in compiler error nor warning.
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline kgavionicsTopic starter

  • Regular Contributor
  • *
  • Posts: 203
  • Country: ca
Re: Help porting 2 functions from C++ to C
« Reply #12 on: May 03, 2024, 05:38:11 pm »
Yes! I have tried his suggestion, but still no joy!
 

Offline kgavionicsTopic starter

  • Regular Contributor
  • *
  • Posts: 203
  • Country: ca
Re: Help porting 2 functions from C++ to C
« Reply #13 on: May 03, 2024, 11:18:46 pm »
I just found out how the font arrays are formatted, so I'm going to write my own char and string functions. Thank you everybody for your help
« Last Edit: May 03, 2024, 11:51:01 pm by kgavionics »
 

Offline radiolistener

  • Super Contributor
  • ***
  • Posts: 3441
  • Country: ua
Re: Help porting 2 functions from C++ to C
« Reply #14 on: May 04, 2024, 12:00:28 am »
Yes! I have tried his suggestion, but still no joy!

Did you fixed the same mistake which is present all around your code?

For example, your code has the same issue in this line:

C++
Code: [Select]
int wd = pgm_read_byte(font + idx++);
Your incorrect replacement:
Code: [Select]
int  wd = (font[0] + idx++);
Should be:
Code: [Select]
int wd = font[ idx++ ];

Also exactly the same mistake in this line:
Code: [Select]
      for(i=0; i<wd; i++)  glcd_data((font[0]+idx+i*ySize8+j));

should be:
Code: [Select]
      for(i=0; i<wd; i++)  sendData( font[ idx+i*ySize8+j ]);

and exactly the same mistake in this line:
Code: [Select]
for(i=0; i<wd; i++)  glcd_data((font[0]+idx+i*ySize8+j)^invertMask);
should be:
Code: [Select]
      for(i=0; i<wd; i++)  sendData( font[ idx+i*ySize8+j] ^ invertMask);


As you can see, there is exactly the same mistake all around your code.

In order to avoid it, I recommend you to copy original C++ code and just implement function pgm_read_byte to avoid code changes:
Code: [Select]
uint8_t pgm_read_byte(uint8_t* ptr) {
   return *ptr;
}

Here is example:
Code: [Select]
uint8_t pgm_read_byte(uint8_t* ptr) {
   return *ptr;
}

void N5110_setFont(const uint8_t* f)
{
  font     = f;
  xSize    =-pgm_read_byte(font+0);
  ySize    = pgm_read_byte(font+1);
  firstCh  = pgm_read_byte(font+2);
  lastCh   = pgm_read_byte(font+3);
  ySize8   = (ySize+7)/8;
  minCharWd  = 0;
  minDigitWd = 0;
  cr = 0;
  invertCh = 0;
  invertMask = 0xff;
}

int N5110_printChar(int x, uint8_t row, uint8_t _ch)
{

  int ch = _ch;

 
  if(!font || ch<firstCh || ch>lastCh || x>=SCR_WD || row>=SCR_HT/8) return 0;

  int j,i, idx = 4 + (ch - firstCh)*(xSize*ySize8+1);
  int wd = pgm_read_byte(font + idx++);
  int wdL = 0, wdR = 1; // default spacing before and behind char
  if((*isNumberFun)(ch)) {
    if(minDigitWd>wd) {
      wdL = (minDigitWd-wd)/2;
      wdR += (minDigitWd-wd-wdL);
    }
  } else
  if(minCharWd>wd) {
    wdL = (minCharWd-wd)/2;
    wdR += (minCharWd-wd-wdL);
  }
  if(x+wd+wdL+wdR>SCR_WD) wdR = max(SCR_WD-x-wdL-wd, 0);
  if(x+wd+wdL+wdR>SCR_WD) wd = max(SCR_WD-x-wdL, 0);
  if(x+wd+wdL+wdR>SCR_WD) wdL = max(SCR_WD-x, 0);
  for(j=0; j<ySize8; j++) {
    gotoXY(x, row+j);
    setDat();
    startCS();
    if(!invertCh) {
      for(i=0; i<wdL; i++) sendData(0);
      for(i=0; i<wd; i++)  sendData(pgm_read_byte(font+idx+i*ySize8+j));
      for(i=0; i<wdR; i++) sendData(0);
    } else {
      for(i=0; i<wdL; i++) sendData(invertMask);
      for(i=0; i<wd; i++)  sendData(pgm_read_byte(font+idx+i*ySize8+j)^invertMask);
      for(i=0; i<wdR; i++) sendData(invertMask);
    }
    stopCS();
  }
  return wd+wdL+wdR;
}

Also, make sure that the font content is properly linked and the pointer is correctly pointing on the memory which contains the font data.
« Last Edit: May 04, 2024, 12:33:20 am by radiolistener »
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4211
  • Country: us
Re: Help porting 2 functions from C++ to C
« Reply #15 on: May 04, 2024, 12:36:06 am »
Quote
Code: [Select]
int wd = pgm_read_byte(font + idx++);
This isn't even a C++ thing, although it IS an Arduino thing.
pgm_read_byte() is needed on an AVR to read data from the program memory, which is in a separate address space.
a definition of pgm_read_byte() (and related stuff) has been propagated to other platforms, even when they don't need it, for reasons of portability and compatibility.

In the case of STM boards, the pgm_ macros are defined somewhere like .../packages/STMicroelectronics/hardware/stm32/2.3.0/cores/arduino/avr/pgmspace.h, and look like:

Code: [Select]
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))

You would have been better off copying that (entirely plain C) file into your STM C project, instead of editing the individual pgm_read_byte() calls (especially since you did it incorrectly)
(but probably all you need is the above definition of pgm_read_byte() )
 
The following users thanked this post: kgavionics

Offline kgavionicsTopic starter

  • Regular Contributor
  • *
  • Posts: 203
  • Country: ca
Re: Help porting 2 functions from C++ to C
« Reply #16 on: May 04, 2024, 06:43:59 pm »
Quote
Code: [Select]
int wd = pgm_read_byte(font + idx++);
This isn't even a C++ thing, although it IS an Arduino thing.
pgm_read_byte() is needed on an AVR to read data from the program memory, which is in a separate address space.
a definition of pgm_read_byte() (and related stuff) has been propagated to other platforms, even when they don't need it, for reasons of portability and compatibility.

In the case of STM boards, the pgm_ macros are defined somewhere like .../packages/STMicroelectronics/hardware/stm32/2.3.0/cores/arduino/avr/pgmspace.h, and look like:

Code: [Select]
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))

You would have been better off copying that (entirely plain C) file into your STM C project, instead of editing the individual pgm_read_byte() calls (especially since you did it incorrectly)
(but probably all you need is the above definition of pgm_read_byte() )
Thank you very much, westfw. So, by defining the pgm_read_byte you suggested, I made a lot of progress, but I had to comment the (*isNumberFun)  section out to make the code work:

Code: [Select]

#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
  const uint8_t* font;
  uint8_t xSize;
  uint8_t ySize;
  uint8_t ySize8;
  uint8_t firstCh;
  uint8_t lastCh;
  uint8_t minCharWd;
  uint8_t minDigitWd;
  uint8_t cr;  // carriage return mode for printStr
  uint8_t dualChar;
  uint8_t invertCh,invertMask;
bool (*isNumberFun)(uint8_t ch);
//----max function-------------------------
int max(int a, int b) {

return (a > b) ? a : b;

}

//--------------------------------------

bool N5110_isNumber(uint8_t ch)
{
  return isdigit(ch) || ch==' ';
}
//--------------------------------

//---------------------------------
void setDat() {gpio_write(DC, 1); }
void setCmd() { gpio_write(DC, 0); }
void startCS() { gpio_write(CS, 0); }
void stopCS() { gpio_write(CS, 1); }


//------------------------------------------------------------------
void N5110_setFont(const uint8_t* f)
{
  font     = f;
  xSize    =-pgm_read_byte(font+0);
  ySize    = pgm_read_byte(font+1);
  firstCh  = pgm_read_byte(font+2);
  lastCh   = pgm_read_byte(font+3);
  ySize8   = (ySize+7)/8;
  minCharWd  = 0;
  minDigitWd = 0;
  cr = 0;
  invertCh = 0;
  invertMask = 0xff;
}

int N5110_printChar(int x, uint8_t row, uint8_t _ch)
{

  int ch = _ch;

 
  if(!font || ch<firstCh || ch>lastCh || x>=SCR_WD || row>=SCR_HT/8) return 0;

  int j,i, idx = 4 + (ch - firstCh)*(xSize*ySize8+1);
  int wd = pgm_read_byte(font + idx++);
  int wdL = 0, wdR = 1; // default spacing before and behind char
 /* if((*isNumberFun)(ch)) {
    if(minDigitWd>wd) {
      wdL = (minDigitWd-wd)/2;
      wdR += (minDigitWd-wd-wdL);
    }
  } else
  if(minCharWd>wd) {
    wdL = (minCharWd-wd)/2;
    wdR += (minCharWd-wd-wdL);
  }*/
  if(x+wd+wdL+wdR>SCR_WD) wdR = max(SCR_WD-x-wdL-wd, 0);
  if(x+wd+wdL+wdR>SCR_WD) wd = max(SCR_WD-x-wdL, 0);
  if(x+wd+wdL+wdR>SCR_WD) wdL = max(SCR_WD-x, 0);
  for(j=0; j<ySize8; j++) {
    gotoXY(x, row+j);
    setDat();
    startCS();
    if(!invertCh) {
      for(i=0; i<wdL; i++) glcd_data(0);
      for(i=0; i<wd; i++)  glcd_data(pgm_read_byte(font+idx+i*ySize8+j));
      for(i=0; i<wdR; i++) glcd_data(0);
    } else {
      for(i=0; i<wdL; i++) glcd_data(invertMask);
      for(i=0; i<wd; i++)  glcd_data(pgm_read_byte(font+idx+i*ySize8+j)^invertMask);
      for(i=0; i<wdR; i++) glcd_data(invertMask);
    }
    stopCS();
  }
  return wd+wdL+wdR;
}

 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5970
  • Country: es
Re: Help porting 2 functions from C++ to C
« Reply #17 on: May 04, 2024, 06:52:44 pm »
Where is isNumberFun declared?
« Last Edit: May 04, 2024, 08:18:39 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline m k

  • Super Contributor
  • ***
  • Posts: 2064
  • Country: fi
Re: Help porting 2 functions from C++ to C
« Reply #18 on: May 04, 2024, 07:17:29 pm »
Maybe you can use a simple ASCII digit test.
Advance-Aneng-Appa-AVO-Beckman-Data Tech-Fluke-General Radio-H. W. Sullivan-Heathkit-HP-Kaise-Kyoritsu-Leeds & Northrup-Mastech-REO-Simpson-Sinclair-Tektronix-Tokyo Rikosha-Triplett-YFE
(plus lesser brands from the work shop of the world)
 

Offline kgavionicsTopic starter

  • Regular Contributor
  • *
  • Posts: 203
  • Country: ca
Re: Help porting 2 functions from C++ to C
« Reply #19 on: May 04, 2024, 08:36:05 pm »
Where is isNumberFun declared?
Here's the complete .c file
Code: [Select]
#include <stm32f401xc.h>
#include <stdint.h>
#include "delay.h"
#include "nokia_glcd.h"
#include "gpio.h"
#include "ctype.h"

#define pgm_read_byte(addr) (*(const unsigned char *)(addr))

#define ALIGNMENT \
  if(x==-1)\
    x = SCR_WD-wd; \
  else if(x<0) \
    x = (SCR_WD-wd)/2; \
  if(x<0) x=0; \
  if(x>=SCR_WD || y8>=SCR_HT/8) return 0; \
  if(x+wd>SCR_WD) wd = SCR_WD-x; \
  if(y8+ht8>SCR_HT/8) ht8 = SCR_HT/8-y8


  const uint8_t* font;
  uint8_t xSize;
  uint8_t ySize;
  uint8_t ySize8;
  uint8_t firstCh;
  uint8_t lastCh;
  uint8_t minCharWd;
  uint8_t minDigitWd;
  uint8_t cr;  // carriage return mode for printStr
  uint8_t dualChar;
  uint8_t invertCh,invertMask;
bool (*isNumberFun)(uint8_t ch);
//----max function-------------------------
int max(int a, int b) {

return (a > b) ? a : b;

}

//--------------------------------------

bool N5110_isNumber(uint8_t ch)
{
  return isdigit(ch) || ch==' ';
}
//--------------------------------

//---------------------------------
void setDat() {gpio_write(DC, 1); }
void setCmd() { gpio_write(DC, 0); }
void startCS() { gpio_write(CS, 0); }
void stopCS() { gpio_write(CS, 1); }

//uint8_t x,y;
/* The function sends a byte of data through SPI */
/* argument d: the byte to be sent */
/* return value: the received data */
uint8_t spi2_transfer(uint8_t d)
{

gpio_write(CS,0);
SPI2->DR = d; /* send the contents of d */
while((SPI2->SR&(1<<0)) == 0); /* wait until RXNE is set */


 gpio_write(CS,1);
return SPI2->DR; /* return the received data */
}

void glcd_cmd(uint8_t cmd)
{

gpio_write(DC,0);
spi2_transfer(cmd);
}

void glcd_data(uint8_t data)
{

gpio_write(DC,1);
spi2_transfer(data);
}

void glcd_init(void)
{
//--------------------------------------
  //isNumberFun = &isNumber;
  cr = 0;
  font = NULL;
  dualChar = 0;
//--------------------------------------
RCC->APB1ENR |=RCC_APB1ENR_SPI2EN;
gpio_output(CS);
gpio_output(DC);
gpio_output(RESET);
gpio_init(MOSI, GPIO_MODE_AF, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_INSANE,GPIO_PULL_NONE, 5);
gpio_init(SLK, GPIO_MODE_AF, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_INSANE,GPIO_PULL_NONE, 5);

SPI2->CR1 = 0x35C; /* SPE = 1, BR = 3, FFD = 0, SSI and SSM = 1 */
//GPIOB->BSRR = (1<<GLCD_CS)|(1<<GLCD_RESET); /* make CS and RESET pins high */

SPI2->CR1 = 0x35C; /* SPE = 1, BR = 3, FFD = 0, SSI and SSM = 1 */
gpio_write(DC, 1);
gpio_write(RESET, 1); /* make CS and RESET pins high */

Delay_ms(10);
gpio_write(RESET, 0); /* reset the LCD (RESET = 0) */
Delay_ms(70);
gpio_write(RESET, 1); /* release the RESET pin */

glcd_cmd(0x21); /* switch to extended command mode */
glcd_cmd(0x06); /* set temp. coefficient 2 */
glcd_cmd(0x13); /* set LCD bias mode 1:48 */
glcd_cmd(0xC2); /* set VOP to 7V (VOP = 66) */
glcd_cmd(0x20); /* switch to basic mode */
glcd_cmd(0x0C); /* set lcd display to normal mode */

}

void gotoXY(uint8_t x, uint8_t y)
{

glcd_cmd(0x80 | x); /* set x */
glcd_cmd(0x40 | y); /* set y (bank) */
}


void glcd_setcontrast(uint8_t contrast)
{
/* Max Contrast */
if(contrast > 0x7F) contrast = 0x7F;

glcd_cmd(0x21);
glcd_cmd(0x80 | contrast);
glcd_cmd(0x20);

}
void glcd_clear(void)
{
uint16_t i;

gotoXY(0, 0);

for (i = 0 ; i < 504 ; i++)
glcd_data(0x00);
}
//------------------------------------------------------------------
void N5110_setFont(const uint8_t* f)
{
  font     = f;
  xSize    =-pgm_read_byte(font+0);
  ySize    = pgm_read_byte(font+1);
  firstCh  = pgm_read_byte(font+2);
  lastCh   = pgm_read_byte(font+3);
  ySize8   = (ySize+7)/8;
  minCharWd  = 0;
  minDigitWd = 0;
  cr = 0;
  invertCh = 0;
  invertMask = 0xff;
}

int N5110_printChar(int x, uint8_t row, uint8_t _ch)
{

  int ch = _ch;

 
  if(!font || ch<firstCh || ch>lastCh || x>=SCR_WD || row>=SCR_HT/8) return 0;

  int j,i, idx = 4 + (ch - firstCh)*(xSize*ySize8+1);
  int wd = pgm_read_byte(font + idx++);
  int wdL = 0, wdR = 1; // default spacing before and behind char
 /* if((*isNumberFun)(ch)) {
    if(minDigitWd>wd) {
      wdL = (minDigitWd-wd)/2;
      wdR += (minDigitWd-wd-wdL);
    }
  } else
  if(minCharWd>wd) {
    wdL = (minCharWd-wd)/2;
    wdR += (minCharWd-wd-wdL);
  }*/
  if(x+wd+wdL+wdR>SCR_WD) wdR = max(SCR_WD-x-wdL-wd, 0);
  if(x+wd+wdL+wdR>SCR_WD) wd = max(SCR_WD-x-wdL, 0);
  if(x+wd+wdL+wdR>SCR_WD) wdL = max(SCR_WD-x, 0);
  for(j=0; j<ySize8; j++) {
    gotoXY(x, row+j);
    setDat();
    startCS();
    if(!invertCh) {
      for(i=0; i<wdL; i++) glcd_data(0);
      for(i=0; i<wd; i++)  glcd_data(pgm_read_byte(font+idx+i*ySize8+j));
      for(i=0; i<wdR; i++) glcd_data(0);
    } else {
      for(i=0; i<wdL; i++) glcd_data(invertMask);
      for(i=0; i<wd; i++)  glcd_data(pgm_read_byte(font+idx+i*ySize8+j)^invertMask);
      for(i=0; i<wdR; i++) glcd_data(invertMask);
    }
    stopCS();
  }
  return wd+wdL+wdR;
}

 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5970
  • Country: es
Re: Help porting 2 functions from C++ to C
« Reply #20 on: May 04, 2024, 10:03:01 pm »
Delete all references to isNumberFun and isNumber.

Then:
Code: [Select]
}
//--------------------------------------------------------------------------

int N5110_SPI_printChar(int x, uint8_t row, uint8_t _ch)
{
  (...)
  if(N5110_isNumber(ch)) {
    if(minDigitWd>wd) {
      wdL = (minDigitWd-wd)/2;
      wdR += (minDigitWd-wd-wdL);
    }
  } else
  if(minCharWd>wd) {
    wdL = (minCharWd-wd)/2;
    wdR += (minCharWd-wd-wdL);
  }

Frankly, just use u8g2!
« Last Edit: May 04, 2024, 10:04:38 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 4466
  • Country: dk
 
The following users thanked this post: Dazed_N_Confused

Offline kgavionicsTopic starter

  • Regular Contributor
  • *
  • Posts: 203
  • Country: ca
Re: Help porting 2 functions from C++ to C
« Reply #22 on: May 05, 2024, 04:01:43 am »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf