|
|
View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Feb 03, 2017 12:06 pm |
|
|
Bug.
Quote: | void glcd_refresh() {
int8 y, x;
.
.
.
for (x = 0; x < 128; x++) {
glcd_data(glcd_buffer[y * 128 + x]);
|
Change the y, x declaration to int16.
Basically, Hemnath found a driver for Hi-Tech C on the net and posted it.
Then you assumed it was compatible with CCS, but it's not. Hi-Tech C
uses 'int' to mean "signed 16-bit integer", but in CCS it means unsigned
8-bit integer. So your math result was getting truncated to 8 bits in
the array index calculation. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19255
|
|
Posted: Fri Feb 03, 2017 12:50 pm |
|
|
He might be better to change them to signed int16.
Though none of the code shown would need signed, if there is code to draw lines, and these can run either way across the screen, the sign would then become necessary to handle these parts. |
|
|
jamalavedra
Joined: 25 Oct 2016 Posts: 62
|
|
Posted: Mon Feb 06, 2017 10:42 am |
|
|
I did change the definition of the variable and now it doesn't repeat pattern. So thanks for that, but now I can only show things at the upper zone of the display. When trying to display things at the lower zone it gets displayed at the upper zone anyway somehow. Any ideas why? |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1903
|
|
Posted: Mon Feb 06, 2017 10:53 am |
|
|
Some LCD modules will have two controller chips, with each chip responsible for half the display. Does the display have 2 enable lines? |
|
|
jamalavedra
Joined: 25 Oct 2016 Posts: 62
|
|
Posted: Mon Feb 06, 2017 11:14 am |
|
|
newguy wrote: | Some LCD modules will have two controller chips, with each chip responsible for half the display. Does the display have 2 enable lines? |
No, I believe it has to be something to do witht the dirty pages of the display. Furthermore, i can write only at one upper quarter of the display, not exactly the half of it
thanks
jaume |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 06, 2017 11:20 am |
|
|
1. Post your complete current driver.
2. Also post your complete current test program that calls the driver.
Don't post code fragments or a few routines. Post your complete driver
and test program.
My guess is that you still have some place where 'int' is used, and it
should be int16. |
|
|
jamalavedra
Joined: 25 Oct 2016 Posts: 62
|
|
Posted: Mon Feb 06, 2017 12:27 pm |
|
|
attached is my full driver. I have checked and haven't found any "int" error. So I still have the following 2 problems:
1) I can only write things on the upper part of the display. When trying to write things in the lowers part the kinda"mirror" themselfs to the upper part.
2) i havent been able to write readable letters despite the library of the graphic part of the display looks fine to me.
main.c
Code: |
#use delay(internal=8M)
//#include <string.h>
//#define OLED 0x78
#INCLUDE <stdlib.h>
#include "st7565.h"
#include "st7565-config.h"
#include "st7565.c"
#include "graphics.h"
#include "graphics.c"
#include "font_tahoma.h"
#include "font_verdana.h"
void main()
{
// setup_adc_ports(NO_ANALOGS|VSS_VDD); // No analogs
// setup_adc(ADC_OFF|ADC_TAD_MUL_0);
// setup_comparator(NC_NC_NC_NC); // Disable comparator
output_high(PIN_C2);
glcd_init();
delay_ms(200);
glcd_blank();
delay_ms(200);
glcd_contrast(6, 25);
output_low(PIN_C2);
delay_ms(200);
while(1)
{
output_high(PIN_C2); //this is an LED debugger
// draw_line(0,0,120,60,1);
glcd_pixel(120, 60, 1);
glcd_pixel(20, 10, 1);
// draw_text("Hello World", 10, 10, Tahoma10, 1); //the font Tahoma won't //be attached, I dont think the is an error there.
draw_circle(62, 10, 5, 1);
output_low(PIN_C2); //this is an LED debugger
delay_ms(100);
// Clear a pixel in the RAM buffer
// glcd_pixel(64, 64, 0);
glcd_refresh();
}
}
|
st7565.h
Code: |
#ifndef _ST7565_H_
#define _ST7565_H_
#define GLCD_CMD_ADCREV 0b10100001 //ADC reverse
#define GLCD_CMD_A6 0b10100110 //display normal, not mirrored
#define GLCD_CMD_2F 0b101111 //possible error. Booster, regulator and follower on
#define GLCD_CMD_27 0b100111 //contrast set
#define GLCD_CMD_16 0b10110 //contrast set
#define GLCD_CMD_AC 0b10101100 //no indicator
#define GLCD_CMD_AF 0b10101111 //no indicator
#define GLCD_CMD_DISPLAY_ON 0b10101111
#define GLCD_CMD_DISPLAY_OFF 0b10101110
#define GLCD_CMD_ALL_NORMAL 0b10100100
#define GLCD_CMD_ALL_ON 0b10100101
#define GLCD_CMD_DISPLAY_NORMAL 0b10100110
#define GLCD_CMD_DISPLAY_REVERSE 0b10100111
#define GLCD_CMD_BIAS_9 0b10100010
#define GLCD_CMD_BIAS_7 0b10100011
#define GLCD_CMD_HORIZONTAL_NORMAL 0b10100000
#define GLCD_CMD_HORIZONTAL_REVERSE 0b10100001
#define GLCD_CMD_VERTICAL_NORMAL 0b11000000
#define GLCD_CMD_VERTICAL_REVERSE 0b11001000
#define GLCD_CMD_POWER_CONTROL 0b00101000
#define GLCD_CMD_RESISTOR 0b00100000
#define GLCD_CMD_VOLUME_MODE 0b10000001
#define GLCD_CMD_DISPLAY_START 0b01000000
#define GLCD_CMD_COLUMN_LOWER 0b00000000
#define GLCD_CMD_COLUMN_UPPER 0b00010000
#define GLCD_CMD_SET_PAGE 0b10110000
#define GLCD_CMD_RESET 0b11100010
#define GLCD_CMD_NOP 0b11100011
#define GLCD_CMD_RATIO 0b11111000
void glcd_init();
void glcd_command(char);
void glcd_data(char);
void glcd_refresh();
void glcd_blank();
void glcd_pixel(unsigned char x, unsigned char y, unsigned char colour);
void glcd_flip_screen(unsigned char flip);
void glcd_inverse_screen(unsigned char inverse);
void glcd_test_card();
void glcd_contrast(char resistor_ratio, char contrast);
unsigned char glcd_flipped = 0;
#endif // _ST7565_H_
|
st7565-config.h
Code: |
#define GLCD_CS1 PIN_C5
#define GLCD_RESET PIN_C3
#define GLCD_A0 PIN_A0
#define GLCD_SCL PIN_A2
#define GLCD_SDA PIN_A5
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define ST7565_REVERSE
|
st7565.c
Code: |
unsigned char glcd_buffer[SCREEN_WIDTH * SCREEN_HEIGHT / 8];
#ifdef ST7565_DIRTY_PAGES
unsigned char glcd_dirty_pages;
#endif
void glcd_pixel(unsigned char x, unsigned char y, unsigned char colour) {
if (x > SCREEN_WIDTH || y > SCREEN_HEIGHT) return;
// Real screen coordinates are 0-63, not 1-64.
x -= 1;
y -= 1;
unsigned int16 array_pos = x + ((y / 8) * 128);
#ifdef ST7565_DIRTY_PAGES
#warning ** ST7565_DIRTY_PAGES enabled, only changed pages will be written to the GLCD **
glcd_dirty_pages |= 1 << (array_pos / 128);
#endif
if (colour) {
glcd_buffer[array_pos] |= 1 << (y % 8);
} else {
glcd_buffer[array_pos] &= 0xFF ^ 1 << (y % 8);
}
}
void glcd_blank()
{
int16 n;
int8 x,y;
// Reset the internal buffer
for (n = 1; n <= (SCREEN_WIDTH * SCREEN_HEIGHT / 8) - 1; ++n) {
glcd_buffer[n] = 0;
}
// Clear the actual screen
for (y = 0; y < 8; y++) {
glcd_command(GLCD_CMD_SET_PAGE | y);
// Reset column to 0 (the left side)
glcd_command(GLCD_CMD_COLUMN_LOWER);
glcd_command(GLCD_CMD_COLUMN_UPPER);
// We iterate to 132 as the internal buffer is 65*132, not
// 64*124.
for (x = 0; x < 132; x++) {
glcd_data(0x00);
}
}
}
void glcd_refresh() {
unsigned int16 y, x;
for (y = 0; y < 8; y++) {
#ifdef ST7565_DIRTY_PAGES
// Only copy this page if it is marked as "dirty"
if (!(glcd_dirty_pages & (1 << y))) continue;
#endif
glcd_command(GLCD_CMD_SET_PAGE | y);
// Reset column to the left side. The internal memory of the
// screen is 132*64, we need to account for this if the display
// is flipped.
// Some screens seem to map the internal memory to the screen
// pixels differently, the ST7565_REVERSE define allows this to
// be controlled if necessary.
#ifdef ST7565_REVERSE
if (!glcd_flipped) {
#else
if (glcd_flipped) {
#endif
glcd_command(GLCD_CMD_COLUMN_LOWER | 4);
} else {
glcd_command(GLCD_CMD_COLUMN_LOWER);
}
glcd_command(GLCD_CMD_COLUMN_UPPER);
for (x = 0; x < 128; x++) {
glcd_data(glcd_buffer[y * 128 + x]);
}
}
#ifdef ST7565_DIRTY_PAGES
// All pages have now been updated, reset the indicator.
glcd_dirty_pages = 0;
#endif
}
void glcd_init()
{
// Select the chip
output_low(GLCD_CS1);
output_low(GLCD_RESET);
// Datasheet says "wait for power to stabilise" but gives
// no specific time!
Delay_Ms(50);
output_high(GLCD_RESET);
output_low(GLCD_CS1);
output_low(GLCD_A0);
// Datasheet says max 1ms here
//DelayMs(1);
// Set LCD bias to 1/9th
glcd_command(GLCD_CMD_BIAS_9);
// Horizontal output direction (ADC segment driver selection)
glcd_command(GLCD_CMD_HORIZONTAL_REVERSE);
// Vertical output direction (common output mode selection)
glcd_command(GLCD_CMD_VERTICAL_NORMAL);
// The screen is the "normal" way up
glcd_flipped = 1;
// Set internal resistor. A suitable middle value is used as
// the default.
glcd_command(GLCD_CMD_RESISTOR | 0x3);
// Power control setting (datasheet step 7)
// Note: Skipping straight to 0x7 works with my hardware.
// glcd_command(GLCD_CMD_POWER_CONTROL | 0x4);
// Delay_Ms(50);
// glcd_command(GLCD_CMD_POWER_CONTROL | 0x6);
// Delay_Ms(50);
glcd_command(GLCD_CMD_POWER_CONTROL | 0x7);
// Delay_Ms(10);
// Volume set (brightness control). A middle value is used here
// also.
glcd_command(GLCD_CMD_VOLUME_MODE);
glcd_command(31);
// Reset start position to the top
glcd_command(GLCD_CMD_DISPLAY_START);
// Turn the display on
glcd_command(GLCD_CMD_DISPLAY_ON);
// Unselect the chip
output_high(GLCD_CS1);
}
void glcd_data(unsigned char data) {
int16 n;
// A0 is high for display data
output_high(GLCD_A0);
// Select the chip
output_low(GLCD_CS1);
for (n = 0; n < 8; n++) {
if (data & 0x80) {
output_high(GLCD_SDA);
} else {
output_low(GLCD_SDA);
}
// Pulse SCL
output_high(GLCD_SCL);
output_low(GLCD_SCL);
data <<= 1;
}
// Unselect the chip
output_high(GLCD_CS1);
}
void glcd_command(char command) {
int16 n;
// A0 is low for command data
output_low(GLCD_A0);
// Select the chip
output_low(GLCD_CS1);
for (n = 0; n < 8; n++) {
if (command & 0x80) {
output_high(GLCD_SDA);
} else {
output_low(GLCD_SDA);
}
// Pulse SCL
output_high(GLCD_SCL);
output_low(GLCD_SCL);
command <<= 1;
}
// Unselect the chip
output_high(GLCD_CS1);
}
void glcd_flip_screen(unsigned char flip) {
if (flip) {
glcd_command(GLCD_CMD_HORIZONTAL_NORMAL);
glcd_command(GLCD_CMD_VERTICAL_REVERSE);
glcd_flipped = 0;
} else {
glcd_command(GLCD_CMD_HORIZONTAL_REVERSE);
glcd_command(GLCD_CMD_VERTICAL_NORMAL);
glcd_flipped = 1;
}
}
void glcd_inverse_screen(unsigned char inverse) {
if (inverse) {
glcd_command(GLCD_CMD_DISPLAY_REVERSE);
} else {
glcd_command(GLCD_CMD_DISPLAY_NORMAL);
}
}
void glcd_test_card() {
int16 n;
unsigned char p = 0xF0;
for (n = 1; n <= (SCREEN_WIDTH * SCREEN_HEIGHT / 8); ++n) {
glcd_buffer[n - 1] = p;
if (n % 4 == 0) {
unsigned char q = p;
p = p << 4;
p |= q >> 4;
}
}
glcd_refresh();
}
void glcd_contrast(char resistor_ratio, char contrast) {
if (resistor_ratio > 7 || contrast > 63) return;
glcd_command(GLCD_CMD_RESISTOR | resistor_ratio);
glcd_command(GLCD_CMD_VOLUME_MODE);
glcd_command(contrast);
}
|
graphics.h
Code: |
#ifndef _GRAPHICS_H_
#define _GRAPHICS_H_
#define FONT_HEADER_TYPE 0
#define FONT_HEADER_ORIENTATION 1
#define FONT_HEADER_START 2
#define FONT_HEADER_LETTERS 3
#define FONT_HEADER_HEIGHT 4
#define FONT_TYPE_FIXED 0
#define FONT_TYPE_PROPORTIONAL 1
#define FONT_ORIENTATION_VERTICAL_CEILING 2
typedef struct {
unsigned char x1;
unsigned char y1;
unsigned char x2;
unsigned char y2;
} bounding_box_t;
bounding_box_t draw_text(char *string, unsigned char x, unsigned char y, unsigned char *font, unsigned char spacing);
bounding_box_t draw_char(unsigned char c, unsigned char x, unsigned char y, unsigned char *font);
void draw_rectangle(int16 x1, int16 y1, int16 x2, int16 y2, char colour);
void draw_box(int16 x1, int16 y1, int16 x2, int16 y2, char colour);
unsigned char text_width(unsigned char *string, unsigned char *font, unsigned char spacing);
unsigned char text_height(unsigned char *string, unsigned char *font);
m colour 0 = OFF, any other value = ON
void draw_line(int16 x1, int16 y1, int16 x2, int16 y2, char colour);
void draw_circle(unsigned char centre_x, unsigned char centre_y, unsigned char radius, unsigned char colour);
void draw_filled_circle(unsigned char centre_x, unsigned char centre_y, unsigned char radius, unsigned char colour);
extern void glcd_pixel(unsigned char x, unsigned char y, unsigned char colour);
#endif // _GRAPHICS_H_
|
graphics.c
Code: |
//stdlib.h for abs()
#include <stdlib.h>
#include "graphics.h"
//#include "main.h"
unsigned char j;
bounding_box_t draw_text(char *string, unsigned char x, unsigned char y, unsigned char *font, unsigned char spacing) {
bounding_box_t ret;
bounding_box_t tmp;
ret.x1 = x;
ret.y1 = y;
spacing += 1;
// BUG: As we move right between chars we don't actually wipe the space
while (*string != 0) {
tmp = draw_char(*string++, x, y, font);
// Leave a single space between characters
x = tmp.x2 + spacing;
}
ret.x2 = tmp.x2;
ret.y2 = tmp.y2;
return ret;
}
bounding_box_t draw_char(unsigned char c, unsigned char x, unsigned char y, unsigned char *font) {
unsigned int16 pos;
unsigned char width;
bounding_box_t ret;
ret.x1 = x;
ret.y1 = y;
ret.x2 = x;
ret.y2 = y;
// Read first byte, should be 0x01 for proportional
if (font[FONT_HEADER_TYPE] != FONT_TYPE_PROPORTIONAL) return ret;
// Check second byte, should be 0x02 for "vertical ceiling"
if (font[FONT_HEADER_ORIENTATION] != FONT_ORIENTATION_VERTICAL_CEILING) return ret;
// Check that font start + number of bitmaps contains c
if (!(c >= font[FONT_HEADER_START] && c <= font[FONT_HEADER_START] + font[FONT_HEADER_LETTERS])) return ret;
// Adjust for start position of font vs. the char passed
c -= font[FONT_HEADER_START];
// Work out where in the array the character is
pos = font[c * FONT_HEADER_START + 5];
pos <<= 8;
pos |= font[c * FONT_HEADER_START + 6];
// Read first byte from this position, this gives letter width
width = font[pos];
// Draw left to right
unsigned char i;
for (i = 0; i < width; i++) {
// Draw top to bottom
for (j = 0; j < font[FONT_HEADER_HEIGHT]; j++) {
// Increment one data byte every 8 bits, or
// at the start of a new column HiTech optimizes
// the modulo, so no need to try and avoid it.
if (j % 8 == 0) pos++;
if (font[pos] & 1 << (j % 8)) {
glcd_pixel(x + i, y + j, 1);
} else {
glcd_pixel(x + i, y + j, 0);
}
}
}
ret.x2 = ret.x1 + width - 1;
// TODO: Return the actual height drawn, rather than the height of the
// font.
// ret.y2 = ret.y1 + height;
ret.y2 = ret.y1 + font[FONT_HEADER_HEIGHT];
return ret;
}
unsigned char text_height(unsigned char *string, unsigned char *font) {
// TODO: Possibly work out the actual pixel height. Letters with
// descenders (like 'g') are taller than letters without (like 'k')
// Height is stored in the header
return font[FONT_HEADER_HEIGHT];
}
unsigned char text_width(unsigned char *string, unsigned char *font, unsigned char spacing) {
unsigned char width = 0;
unsigned int16 pos;
unsigned char c;
// TODO: Implement for fixed width fonts
// Check font type, should be 0x01 for proportional
if (font[FONT_HEADER_TYPE] != FONT_TYPE_PROPORTIONAL) return 0;
while (*string != 0) {
c = *string++;
// Check that font start + number of bitmaps contains c
// TODO: Should we continue here but add 0 to width?
if (!(c >= font[FONT_HEADER_START] && c <= font[FONT_HEADER_START] + font[FONT_HEADER_LETTERS])) return 0;
// Adjust for start position of font vs. the char passed
c -= font[FONT_HEADER_START];
// Work out where in the array the character is
pos = font[c * FONT_HEADER_START + 5];
pos <<= 8;
pos |= font[c * FONT_HEADER_START + 6];
// Read first byte from this position, this gives letter width
width += font[pos];
// Allow for space between letters
width += spacing;
}
// The last letter wont have a space after it
return width - spacing;
}
void draw_rectangle(int16 x1, int16 y1, int16 x2, int16 y2, char colour)
{
// Top
draw_line(x1, y1, x2, y1, colour);
// Left
draw_line(x1, y1, x1, y2, colour);
// Bottom
draw_line(x1, y2, x2, y2, colour);
// Right
draw_line(x2, y1, x2, y2, colour);
}
// A rounded box
void draw_box(int16 x1, int16 y1, int16 x2, int16 y2, char colour)
{
// Top
draw_line(x1 + 1, y1, x2 - 1, y1, colour);
// Left
draw_line(x1, y1 + 1, x1, y2 - 1, colour);
// Bottom
draw_line(x1 + 1, y2, x2 - 1, y2, colour);
// Right
draw_line(x2, y1 + 1, x2, y2 - 1, colour);
}
// Implementation of Bresenham's line algorithm
//
// This code credit Tom Ootjers, originally obtained from:
// http://tinyurl.com/czok7vx
void draw_line(int16 x1, int16 y1, int16 x2, int16 y2, char colour)
{
int16 xinc1, yinc1, den, num, numadd, numpixels, curpixel, xinc2, yinc2;
int16 deltax = abs(x2 - x1); // The difference between the x's
int16 deltay = abs(y2 - y1); // The difference between the y's
int16 x = x1; // Start x off at the first pixel
int16 y = y1; // Start y off at the first pixel
if (x2 >= x1) { // The x-values are increasing
xinc1 = 1;
xinc2 = 1;
} else { // The x-values are decreasing
xinc1 = -1;
xinc2 = -1;
}
if (y2 >= y1) // The y-values are increasing
{
yinc1 = 1;
yinc2 = 1;
}
else // The y-values are decreasing
{
yinc1 = -1;
yinc2 = -1;
}
if (deltax >= deltay) // There is at least one x-value for every y-value
{
xinc1 = 0; // Don't change the x when numerator >= denominator
yinc2 = 0; // Don't change the y for every iteration
den = deltax;
num = deltax / 2;
numadd = deltay;
numpixels = deltax; // There are more x-values than y-values
}
else // There is at least one y-value for every x-value
{
xinc2 = 0; // Don't change the x for every iteration
yinc1 = 0; // Don't change the y when numerator >= denominator
den = deltay;
num = deltay / 2;
numadd = deltax;
numpixels = deltay; // There are more y-values than x-values
}
for (curpixel = 0; curpixel <= numpixels; curpixel++)
{
glcd_pixel(x, y, colour); // Draw the current pixel
num += numadd; // Increase the numerator by the top of the fraction
if (num >= den) // Check if numerator >= denominator
{
num -= den; // Calculate the new numerator value
x += xinc1; // Change the x as appropriate
y += yinc1; // Change the y as appropriate
}
x += xinc2; // Change the x as appropriate
y += yinc2; // Change the y as appropriate
}
}
// Implementation of Bresenham's circle algorithm
void draw_circle(unsigned char centre_x, unsigned char centre_y, unsigned char radius, unsigned char colour)
{
signed char x = 0;
signed char y = radius;
signed char p = 1 - radius;
if (!radius) return;
for (x = 0; x < y; x++) {
if (p < 0) {
p += x * 2 + 3;
} else {
p += x * 2 - y * 2 + 5;
y--;
}
glcd_pixel(centre_x - x, centre_y - y, colour);
glcd_pixel(centre_x - y, centre_y - x, colour);
glcd_pixel(centre_x + y, centre_y - x, colour);
glcd_pixel(centre_x + x, centre_y - y, colour);
glcd_pixel(centre_x - x, centre_y + y, colour);
glcd_pixel(centre_x - y, centre_y + x, colour);
glcd_pixel(centre_x + y, centre_y + x, colour);
glcd_pixel(centre_x + x, centre_y + y, colour);
}
}
// Implementation of Bresenham's circle algorithm, filled.
void draw_filled_circle(unsigned char centre_x, unsigned char centre_y, unsigned char radius, unsigned char colour)
{
signed char x = 0;
signed char y = radius;
signed char p = 1 - radius;
if (!radius) return;
for (x = 0; x < y; x++) {
if (p < 0) {
p += x * 2 + 3;
} else {
p += x * 2 - y * 2 + 5;
y--;
}
draw_line(centre_x - x, centre_y - y, centre_x + x, centre_y - y, colour);
draw_line(centre_x - y, centre_y - x, centre_x + y, centre_y - x, colour);
draw_line(centre_x + x, centre_y + y, centre_x - x, centre_y + y, colour);
draw_line(centre_x + y, centre_y + x, centre_x - y, centre_y + x, colour);
}
}
|
stdlib.h
Code: |
#ifndef _STDLIB
#define _STDLIB
//---------------------------------------------------------------------------
// Definitions and types
//---------------------------------------------------------------------------
#ifndef RAND_MAX
#define RAND_MAX 32767 // The value of which is the maximum value
// ... returned by the rand function
#endif
#IF (sizeof(int16*)>1)
#DEFINE LONG_POINTERS 1
#ELSE
#DEFINE LONG_POINTERS 0
#ENDIF
typedef struct {
signed int quot;
signed int rem;
} div_t;
typedef struct {
signed long quot;
signed long rem;
} ldiv_t;
#include <stddef.h>
//---------------------------------------------------------------------------
// String conversion functions
//---------------------------------------------------------------------------
/* Standard template: signed int atoi(char * s)
* converts the initial portion of the string s to a signed int
* returns the converted value if any, 0 otherwise
*/
signed int atoi(char *s);
/* Syntax: signed int32 atoi32(char * s)
converts the initial portion of the string s to a signed int32
returns the converted value if any, 0 otherwise*/
#if (sizeof(long)==4)
#define atoi32(s) atol(s)
#else
signed int32 atoi32(char *s);
#endif
#if defined(__PCD__)
// The following functions only work on the 24 bit compiler
// for the 30F, 33F, 24F and 24H parts
/* Syntax: signed int48 atoi48(char * s)
converts the initial portion of the string s to a signed int48
returns the converted value if any, 0 otherwise*/
signed int48 atoi48(char *s);
/* Syntax: signed int64 atoi64(char * s)
converts the initial portion of the string s to a signed int64
returns the converted value if any, 0 otherwise*/
signed int64 atoi64(char *s);
#endif
/* Syntax: char * itoa(signed int32 num, int8 base, char * s)
converts the signed int32 to a string and
returns the converted value if any, 0 otherwise*/
char * itoa(signed int32 num, unsigned int base, char * s);
/* Standard template: signed int16 atol(char * s)
* converts the initial portion of the string s to a signed int16
* returns the converted value if any, 0 otherwise
*/
signed long atol(char *s);
/* Standard template: int16 strtoul(char * s,char *endptr,signed int base)
* converts the initial portion of the string s, represented as an
* integral value of radix base to a signed long.
* Returns the converted value if any, 0 otherwise
* the final string is returned in the endptr, if endptr is not null
*/
signed long strtol(char *s,char *endptr, signed int base);
/* Standard template: int16 strtoul(char * s,char *endptr,signed int base)
* converts the initial portion of the string s, represented as an
* integral value of radix base to a unsigned long.
* returns the converted value if any, 0 otherwise
* the final string is returned in the endptr, if endptr is not null
*/
unsigned long strtoul(char *s,char *endptr, signed int base);
/* Standart template: float strtof(char * s,char *endptr)
float48 strtof48(char *s,char *endptr);
float64 strtod(char *s,char *endptr);
* converts the initial portion of the string s to a float32, float48 or float64,
* returns the converted value if any, 0 otherwise
* the final string is returned in the endptr, if endptr is not null
*/
float strtof(char *s,char *endptr);
#if defined(__PCD__)
float48 strtof48(char *s,char *endptr);
float64 strtod(char *s,char *endptr);
#else
//provided for compatibility
#define strtof48(s, e) strtof(s, e)
#define strtod(s, e) strtof(s, e)
#endif
/* Standard template: float32 atof(char * s)
* converts the initial portion of the string s to a float.
* returns the converted value if any, 0 otherwise
*/
#define atof(s) strtof(s, 0)
#if defined(__PCD__)
// The following functions only work on the 24 bit compiler
// for the 30F, 33F, 24F and 24H parts
/* Standard template: float48 atof48(char * s)
* converts the initial portion of the string s to a float.
* returns the converted value if any, 0 otherwise
*/
#define atof48(s) strtof48(s, 0)
/* Standard template: float64 atof64(char * s)
* converts the initial portion of the string s to a float.
* returns the converted value if any, 0 otherwise
*/
#define atof64(s) strtod(s, 0)
#endif
/* Standard template: float32 atoe(char * s)
* converts the initial portion of the string s to a float.
* returns the converted value if any, 0 otherwise
* also handles E format numbers
*/
#if !defined(__PCD__)
float atoe(char * s);
#endif
#if defined(__PCD__)
float32 atoe(char * s);
#endif
//---------------------------------------------------------------------------
// Pseudo-random sequence generation functions
//---------------------------------------------------------------------------
/* The rand function computes a sequence of pseudo-random integers in
* the range 0 to RAND_MAX
*
* Parameters:
* (none)
*
* Returns:
* The pseudo-random integer
*/
unsigned int16 rand(void);
/* The srand function uses the argument as a seed for a new sequence of
* pseudo-random numbers to be returned by subsequent calls to rand.
*
* Parameters:
* [in] seed: The seed value to start from. You might need to pass
*
* Returns:
* (none)
*
* Remarks
* The srand function sets the starting point for generating
* a series of pseudorandom integers. To reinitialize the
* generator, use 1 as the seed argument. Any other value for
* seed sets the generator to a random starting point. rand
* retrieves the pseudorandom numbers that are generated.
* Calling rand before any call to srand generates the same
* sequence as calling srand with seed passed as 1.
* Usually, you need to pass a time here from outer source
* so that the numbers will be different every time you run.
*/
void srand(unsigned int32 seed);
//---------------------------------------------------------------------------
// Memory management functions
//---------------------------------------------------------------------------
// Comming soon
//---------------------------------------------------------------------------
// Communication with the environment
//---------------------------------------------------------------------------
/* The function returns 0 always
*/
signed int8 system(char *string);
//---------------------------------------------------------------------------
// Searching and sorting utilities
//---------------------------------------------------------------------------
/* Performs a binary search of a sorted array..
*
* Parameters:
* [in] key: Object to search for
* [in] base: Pointer to base of search data
* [in] num: Number of elements
* [in] width: Width of elements
* [in] compare: Function that compares two elements
*
* Returns:
* bsearch returns a pointer to an occurrence of key in the array pointed
* to by base. If key is not found, the function returns NULL. If the
* array is not in order or contains duplicate records with identical keys,
* the result is unpredictable.
*/
//void *bsearch(const void *key, const void *base, size_t num, size_t width,
// int (*compare)(const void *, const void *));
/* Performs the shell-metzner sort (not the quick sort algorithm). The contents
* of the array are sorted into ascending order according to a comparison
* function pointed to by compar.
*
* Parameters:
* [in] base: Pointer to base of search data
* [in] num: Number of elements
* [in] width: Width of elements
* [in] compare: Function that compares two elements
*
* Returns:
* (none)
*/
//void *qsort(const void *base, size_t num, size_t width,
// int (*compare)(const void *, const void *));
//---------------------------------------------------------------------------
// Integer arithmetic functions
//---------------------------------------------------------------------------
#define labs abs
div_t div(signed int numer, signed int denom);
ldiv_t ldiv(signed long numer, signed long denom);
//---------------------------------------------------------------------------
// Multibyte character functions
//---------------------------------------------------------------------------
// Not supported
//---------------------------------------------------------------------------
// Multibyte string functions
//---------------------------------------------------------------------------
// Not supported
//---------------------------------------------------------------------------
// Internal implementation
//---------------------------------------------------------------------------
#include <stddef.h>
#include <string.h>
div_t div(signed int numer, signed int denom)
{
div_t val;
val.quot = numer / denom;
val.rem = numer - (denom * val.quot);
return (val);
}
ldiv_t ldiv(signed long numer, signed long denom)
{
ldiv_t val;
val.quot = numer / denom;
val.rem = numer - (denom * val.quot);
return (val);
}
#if defined(__PCD__)
float32 atoe(char * s)
{
float32 pow10 = 1.0;
float32 result = 0.0;
unsigned int8 sign = 0;
unsigned int8 expsign = 0;
char c;
unsigned int8 ptr = 0;
unsigned int8 i;
float32 exp = 1.0;
unsigned int8 expcnt = 0;
c = s[ptr++];
if ((c>='0' && c<='9') || c=='+' || c=='-' || c=='.' || c=='E' || c=='e') {
if(c == '-') {
sign = 1;
c = s[ptr++];
}
if(c == '+')
c = s[ptr++];
while((c >= '0' && c <= '9')) {
result = 10*result + c - '0';
c = s[ptr++];
}
if (c == '.') {
c = s[ptr++];
while((c >= '0' && c <= '9')) {
pow10 = pow10*10;
result += (c - '0')/pow10;
c = s[ptr++];
}
}
// Handling the exponent
if (c=='e' || c=='E') {
c = s[ptr++];
if(c == '-') {
expsign = 1;
c = s[ptr++];
}
if(c == '+')
c = s[ptr++];
while((c >= '0' && c <= '9')) {
expcnt = 10*expcnt + c - '0';
c = s[ptr++];
}
for(i=0;i<expcnt;i++)
exp*=10;
if(expsign==1)
result/=exp;
else
result*=exp;
}
}
if (sign == 1)
result = -1*result;
return(result);
}
#endif
#if !defined(__PCD__)
float atoe(char * s)
{
float pow10 = 1.0;
float result = 0.0;
unsigned int8 sign = 0;
unsigned int8 expsign = 0;
char c;
unsigned int8 ptr = 0;
unsigned int8 i;
float exp = 1.0;
unsigned int8 expcnt = 0;
c = s[ptr++];
if ((c>='0' && c<='9') || c=='+' || c=='-' || c=='.' || c=='E' || c=='e') {
if(c == '-') {
sign = 1;
c = s[ptr++];
}
if(c == '+')
c = s[ptr++];
while((c >= '0' && c <= '9')) {
result = 10*result + c - '0';
c = s[ptr++];
}
if (c == '.') {
c = s[ptr++];
while((c >= '0' && c <= '9')) {
pow10 = pow10*10;
result += (c - '0')/pow10;
c = s[ptr++];
}
}
// Handling the exponent
if (c=='e' || c=='E') {
c = s[ptr++];
if(c == '-') {
expsign = 1;
c = s[ptr++];
}
if(c == '+')
c = s[ptr++];
while((c >= '0' && c <= '9')) {
expcnt = 10*expcnt + c - '0';
c = s[ptr++];
}
for(i=0;i<expcnt;i++)
exp*=10;
if(expsign==1)
result/=exp;
else
result*=exp;
}
}
if (sign == 1)
result = -1*result;
return(result);
}
#endif
signed int atoi(char *s)
{
signed int result;
unsigned int sign, base, index;
char c;
index = 0;
sign = 0;
base = 10;
result = 0;
if (!s)
return 0;
// Omit all preceeding alpha characters
c = s[index++];
// increase index if either positive or negative sign is detected
if (c == '-')
{
sign = 1; // Set the sign to negative
c = s[index++];
}
else if (c == '+')
{
c = s[index++];
}
if (c >= '0' && c <= '9')
{
// Check for hexa number
if (c == '0' && (s[index] == 'x' || s[index] == 'X'))
{
base = 16;
index++;
c = s[index++];
}
// The number is a decimal number
if (base == 10)
{
while (c >= '0' && c <= '9')
{
result = 10*result + (c - '0');
c = s[index++];
}
}
else if (base == 16) // The number is a hexa number
{
c = toupper(c);
while ( (c >= '0' && c <= '9') || (c >= 'A' && c<='F'))
{
if (c >= '0' && c <= '9')
result = (result << 4) + (c - '0');
else
result = (result << 4) + (c - 'A' + 10);
c = s[index++];
c = toupper(c);
}
}
}
if (sign == 1 && base == 10)
result = -result;
return(result);
}
signed long atol(char *s)
{
signed long result;
unsigned int sign, base, index;
char c;
index = 0;
sign = 0;
base = 10;
result = 0;
if (!s)
return 0;
c = s[index++];
// increase index if either positive or negative sign is detected
if (c == '-')
{
sign = 1; // Set the sign to negative
c = s[index++];
}
else if (c == '+')
{
c = s[index++];
}
if (c >= '0' && c <= '9')
{
if (c == '0' && (s[index] == 'x' || s[index] == 'X'))
{
base = 16;
index++;
c = s[index++];
}
// The number is a decimal number
if (base == 10)
{
while (c >= '0' && c <= '9')
{
result = 10*result + (c - '0');
c = s[index++];
}
}
else if (base == 16) // The number is a hexa number
{
c = toupper(c);
while ( (c >= '0' && c <= '9') || (c >= 'A' && c <='F'))
{
if (c >= '0' && c <= '9')
result = (result << 4) + (c - '0');
else
result = (result << 4) + (c - 'A' + 10);
c = s[index++];c = toupper(c);
}
}
}
if (base == 10 && sign == 1)
result = -result;
return(result);
}
/* A fast routine to multiply by 10
*/
signed int32 mult_with10(int32 num)
{
return ( (num << 1) + (num << 3) );
}
#if sizeof(long)==2
signed int32 atoi32(char *s)
{
signed int32 result;
int8 sign, base, index;
char c;
index = 0;
sign = 0;
base = 10;
result = 0;
if (!s)
return 0;
c = s[index++];
// increase index if either positive or negative sign is detected
if (c == '-')
{
sign = 1; // Set the sign to negative
c = s[index++];
}
else if (c == '+')
{
c = s[index++];
}
if (c >= '0' && c <= '9')
{
if (c == '0' && (s[index] == 'x' || s[index] == 'X'))
{
base = 16;
index++;
c = s[index++];
}
// The number is a decimal number
if (base == 10)
{
while (c >= '0' && c <= '9') {
result = (result << 1) + (result << 3); // result *= 10;
result += (c - '0');
c = s[index++];
}
}
else if (base == 16) // The number is a hexa number
{
c = toupper(c);
while ((c >= '0' && c <= '9') || (c >= 'A' && c <='F'))
{
if (c >= '0' && c <= '9')
result = (result << 4) + (c - '0');
else
result = (result << 4) + (c - 'A' + 10);
c = s[index++];c = toupper(c);
}
}
}
if (base == 10 && sign == 1)
result = -result;
return(result);
}
#endif
#if defined(__PCD__)
signed int48 atoi48(char *s)
{
signed int48 result;
int8 sign, base, index;
char c;
index = 0;
sign = 0;
base = 10;
result = 0;
if (!s)
return 0;
c = s[index++];
// increase index if either positive or negative sign is detected
if (c == '-')
{
sign = 1; // Set the sign to negative
c = s[index++];
}
else if (c == '+')
{
c = s[index++];
}
if (c >= '0' && c <= '9')
{
if (c == '0' && (s[index] == 'x' || s[index] == 'X'))
{
base = 16;
index++;
c = s[index++];
}
// The number is a decimal number
if (base == 10)
{
while (c >= '0' && c <= '9') {
result = (result << 1) + (result << 3); // result *= 10;
result += (c - '0');
c = s[index++];
}
}
else if (base == 16) // The number is a hexa number
{
c = toupper(c);
while ((c >= '0' && c <= '9') || (c >= 'A' && c <='F'))
{
if (c >= '0' && c <= '9')
result = (result << 4) + (c - '0');
else
result = (result << 4) + (c - 'A' + 10);
c = s[index++];c = toupper(c);
}
}
}
if (base == 10 && sign == 1)
result = -result;
return(result);
}
signed int64 atoi64(char *s)
{
signed int64 result;
int8 sign, base, index;
char c;
index = 0;
sign = 0;
base = 10;
result = 0;
if (!s)
return 0;
c = s[index++];
// increase index if either positive or negative sign is detected
if (c == '-')
{
sign = 1; // Set the sign to negative
c = s[index++];
}
else if (c == '+')
{
c = s[index++];
}
if (c >= '0' && c <= '9')
{
if (c == '0' && (s[index] == 'x' || s[index] == 'X'))
{
base = 16;
index++;
c = s[index++];
}
// The number is a decimal number
if (base == 10)
{
while (c >= '0' && c <= '9') {
result = (result << 1) + (result << 3); // result *= 10;
result += (c - '0');
c = s[index++];
}
}
else if (base == 16) // The number is a hexa number
{
c = toupper(c);
while ((c >= '0' && c <= '9') || (c >= 'A' && c <='F'))
{
if (c >= '0' && c <= '9')
result = (result << 4) + (c - '0');
else
result = (result << 4) + (c - 'A' + 10);
c = s[index++];c = toupper(c);
}
}
}
if (base == 10 && sign == 1)
result = -result;
return(result);
}
#endif
char * itoa(signed int32 num, unsigned int base, char * s)
{
unsigned int32 temp=1;
unsigned int8 i,sign=0,cnt=0;
char c;
if(num<0) {
sign=1; // Check for negative number
num*=-1;
}
while(temp>0) {
temp=(num/base);
s[cnt]=(num%base)+'0'; // Conversion
if(s[cnt]>0x39)
s[cnt]+=0x7;
cnt++;
num=temp;
}
if(sign==1) {
s[cnt]=0x2D; // Negative sign
cnt++;
}
for(i = 0;i<(int8)(cnt/2);i++) {
c=s[i];
s[i]=s[cnt-i-1]; // Reverse the number
s[cnt-i-1]=c;
}
s[cnt]='\0'; // End the string
return s;
}
float strtof(char *s, char *endptr)
{
float pow10 = 1.0;
float result = 0.0;
int1 skip = 1, sign = 0, point = 0;
char c;
unsigned int8 ptr = 0;
if (!s)
return 0;
for(c=s[ptr++]; c!=0; c=s[ptr++])
{
if (skip && !isspace(c))
{
skip = 0;
if (c == '+')
{
sign = 0;
continue;
}
else if (c == '-')
{
sign = 1;
continue;
}
}
if (!skip && (c == '.') && !point)
point = 1;
else if (!skip && isdigit(c))
{
c -= '0';
if (point)
{
pow10 = pow10 * 10.0;
result += (float)c / pow10;
}
else
{
result = 10.0 * result + (float)c;
}
}
else if (!skip)
break;
}
if (sign)
result = -1*result;
if(endptr)
{
if (ptr) {
ptr--;
#IF LONG_POINTERS
*((long *)endptr)= s+ptr;
#ELSE
*((char *)endptr)=s+ptr;
#ENDIF
}
else
{
#IF LONG_POINTERS
*((long *)endptr)= s;
#ELSE
*((char *)endptr)=s;
#ENDIF
}
}
return(result);
}
#if defined(__PCD__)
float48 strtof48(char *s, char *endptr)
{
float48 pow10 = 1.0;
float48 result = 0.0;
int1 skip = 1, sign = 0, point = 0;
char c;
unsigned int8 ptr = 0;
if (!s)
return 0;
for(c=s[ptr++]; c!=0; c=s[ptr++])
{
if (skip && !isspace(c))
{
skip = 0;
if (c == '+')
{
sign = 0;
continue;
}
else if (c == '-')
{
sign = 1;
continue;
}
}
if (!skip && (c == '.') && !point)
point = 1;
else if (!skip && isdigit(c))
{
c -= '0';
if (point)
{
pow10 = pow10 * 10.0;
result += (float48)c / pow10;
}
else
{
result = 10.0 * result + (float48)c;
}
}
else if (!skip)
break;
}
if (sign)
result = -1*result;
if(endptr)
{
if (ptr) {
ptr--;
#IF LONG_POINTERS
*((long *)endptr)= s+ptr;
#ELSE
*((char *)endptr)=s+ptr;
#ENDIF
}
else
{
#IF LONG_POINTERS
*((long *)endptr)= s;
#ELSE
*((char *)endptr)=s;
#ENDIF
}
}
return(result);
}
float64 strtod(char *s, char *endptr)
{
float64 pow10 = 1.0;
float64 result = 0.0;
int1 skip = 1, sign = 0, point = 0;
char c;
unsigned int8 ptr = 0;
if (!s)
return 0;
for(c=s[ptr++]; c!=0; c=s[ptr++])
{
if (skip && !isspace(c))
{
skip = 0;
if (c == '+')
{
sign = 0;
continue;
}
else if (c == '-')
{
sign = 1;
continue;
}
}
if (!skip && (c == '.') && !point)
point = 1;
else if (!skip && isdigit(c))
{
c -= '0';
if (point)
{
pow10 = pow10 * 10.0;
result += (float64)c / pow10;
}
else
{
result = 10.0 * result + (float64)c;
}
}
else if (!skip)
break;
}
if (sign)
result = -1*result;
if(endptr)
{
if (ptr) {
ptr--;
#IF LONG_POINTERS
*((long *)endptr)= s+ptr;
#ELSE
*((char *)endptr)=s+ptr;
#ENDIF
}
else
{
#IF LONG_POINTERS
*((long *)endptr)= s;
#ELSE
*((char *)endptr)=s;
#ENDIF
}
}
return(result);
}
#endif
unsigned long strtoul(char *s, char *endptr, signed int base)
{
char *sc,*s1,*sd;
unsigned long x=0;
char sign;
char digits[]="0123456789abcdefghijklmnopqstuvwxyz";
for(sc=s;isspace(*sc);++sc);
sign=*sc=='-'||*sc=='+'?*sc++:'+';
if(sign=='-' || base <0 || base ==1|| base >36) // invalid base
goto StrtoulGO;
else if (base)
{
if(base==16 && *sc =='0'&&(sc[1]=='x' || sc[1]=='X'))
sc+=2;
if(base==8 && *sc =='0')
sc+=1;
if(base==2 && *sc =='0'&&sc[1]=='b')
sc+=2;
}
else if(*sc!='0') // base is 0, find base
base=10;
else if (sc[1]=='x' || sc[1]=='X')
base =16,sc+=2;
else if(sc[1]=='b')
base=2,sc+=2;
else
base=8;
for (s1=sc;*sc=='0';++sc);// skip leading zeroes
sd=memchr(digits,tolower(*sc),base);
for(; sd!=0; )
{
x=x*base+(int16)(sd-digits);
++sc;
sd=memchr(digits,tolower(*sc),base);
}
if(s1==sc)
{
StrtoulGO:
if (endptr)
{
#IF LONG_POINTERS
*((long *)endptr)= s;
#ELSE
*((char *)endptr)=s;
#ENDIF
}
return 0;
}
if (endptr)
{
#IF LONG_POINTERS
*((long *)endptr)= sc;
#ELSE
*((char *)endptr)=sc;
#ENDIF
}
return x;
}
signed long strtol(char *s,char *endptr, signed int base)
{
char *sc,*s1,*sd;
signed long x=0;
char sign;
char digits[]="0123456789abcdefghijklmnopqstuvwxyz";
for(sc=s;isspace(*sc);++sc);
sign=*sc=='-'||*sc=='+'?*sc++:'+';
if (base <0 || base ==1|| base >36) // invalid base
goto StrtolGO;
else if (base)
{
if(base==16 && *sc =='0'&&(sc[1]=='x' || sc[1]=='X'))
sc+=2;
if(base==8 && *sc =='0')
sc+=1;
if(base==2 && *sc =='0'&&sc[1]=='b')
sc+=2;
}
else if(*sc!='0') // base is 0, find base
base=10;
else if (sc[1]=='x' || sc[1]=='X')
base =16,sc+=2;
else if(sc[1]=='b')
base=2,sc+=2;
else
base=8;
for (s1=sc;*sc=='0';++sc);// skip leading zeroes
sd=memchr(digits,tolower(*sc),base);
for(;sd!=0;)
{
x=x*base+(int16)(sd-digits);
++sc;
sd=memchr(digits,tolower(*sc),base);
}
if(s1==sc)
{
StrtolGO:
if (endptr)
{
#IF LONG_POINTERS
*((long *)endptr)= s;
#ELSE
*((char *)endptr)=s;
#ENDIF
}
return 0;
}
if(sign=='-')
x =-x;
if (endptr)
{
#IF LONG_POINTERS
*((long *)endptr)= sc;
#ELSE
*((char *)endptr)=sc;
#ENDIF
}
return x;
}
signed int8 system(char *string)
{
return 0;
}
int8 mblen(char *s,size_t n)
{
return strlen(s);
}
int8 mbtowc(wchar_t *pwc,char *s,size_t n)
{
*pwc=*s;
return 1;
}
int8 wctomb(char *s,wchar_t wchar)
{
*s=wchar;
return 1;
}
size_t mbstowcs(wchar_t *pwcs,char *s,size_t n)
{
strncpy(pwcs,s,n);
return strlen(pwcs);
}
size_t wcstombs(char *s,wchar_t *pwcs,size_t n)
{
strncpy(s,pwcs,n);
return strlen(s);
}
unsigned int32 _Randseed;
unsigned int16 rand(void)
{
_Randseed = _Randseed * 1103515245 + 12345;
return ((unsigned int16)(_Randseed >> 16) % RAND_MAX);
}
void srand(unsigned int32 seed)
{
_Randseed = seed;
}
#if !defined(__PCD__)
typedef signed int8 (*_Cmpfun)(char * p1,char * p2);
#else
typedef signed int16 (*_Cmpfun)(char * p1,char * p2);
#endif
void qsort(char * qdata, unsigned int qitems, unsigned int qsize, _Cmpfun cmp) {
unsigned int m,j,i,l;
int1 done;
unsigned int8 t[16];
m = qitems/2;
while( m > 0 ) {
for(j=0; j<(qitems-m); ++j) {
i = j;
do
{
done=1;
l = i+m;
if( (*cmp)(qdata+i*qsize, qdata+l*qsize) > 0 ) {
memcpy(t, qdata+i*qsize, qsize);
memcpy(qdata+i*qsize, qdata+l*qsize, qsize);
memcpy(qdata+l*qsize, t, qsize);
if(m <= i)
i -= m;
done = 0;
}
} while(!done);
}
m = m/2;
}
}
char *bsearch(char *key, char *base, size_t num, size_t width,_Cmpfun cmp)
{
char *p, *q;
size_t n;
size_t pivot;
signed int val;
p = base;
n = num;
while (n > 0)
{
pivot = n >> 1;
q = p + width * pivot;
val = (*cmp)(key, q);
if (val < 0)
n = pivot;
else if (val == 0)
return ((char *)q);
else {
p = q + width;
n -= pivot + 1;
}
}
return NULL; // There's no match
}
#endif
|
Any comments will be appreciated
thank you
jaume
Last edited by jamalavedra on Mon Feb 06, 2017 1:28 pm; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19255
|
|
Posted: Mon Feb 06, 2017 12:38 pm |
|
|
Straight away, this was what I was talking about:
xinc1 = -1;
xinc2 = -1;
Yet these are declared as int16.
These need to be _signed int16_. As does anything else where signs are used, or may occur.
There are several other similar places. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 06, 2017 12:51 pm |
|
|
I made a few changes to the glcd_pixel() function. The only real important
one is to type cast the 'array_pos' math to be 16-bit. It was doing 8-bit
math and truncating the result. This is probably the cause of writing
only occuring in the upper zone.
I cleaned up your code a little bit by moving the 'array_pos' declaration
to the start of the routine. I added a test to make sure the input x,y
are not 0, since this is illegal.
Ttelmah, since there are range checks on the input x, y, I don't see the
need for signed math here, so I didn't specify it.
Quote: | void glcd_pixel(unsigned char x, unsigned char y, unsigned char colour)
{
unsigned int16 array_pos; // *** Put declaration here
if (x > SCREEN_WIDTH || y > SCREEN_HEIGHT) return;
if ((x == 0) || (y == 0)) return; // *** ADD THIS LINE ***
// Real screen coordinates are 0-63, not 1-64.
x -= 1;
y -= 1;
array_pos = (int16)x + (((int16)y / 8) * 128); // *** ADD (int16) in 2 places
.
.
.
} |
|
|
|
jamalavedra
Joined: 25 Oct 2016 Posts: 62
|
|
Posted: Mon Feb 06, 2017 1:04 pm |
|
|
PCM programmer wrote: | I made a few changes to the glcd_pixel() function. The only real important
one is to type cast the 'array_pos' math to be 16-bit. It was doing 8-bit
math and truncating the result. This is probably the cause of writing
only occuring in the upper zone.
I cleaned up your code a little bit by moving the 'array_pos' declaration
to the start of the routine. I added a test to make sure the input x,y
are not 0, since this is illegal.
Ttelmah, since there are range checks on the input x, y, I don't see the
need for signed math here, so I didn't specify it.
Quote: | void glcd_pixel(unsigned char x, unsigned char y, unsigned char colour)
{
unsigned int16 array_pos; // *** Put declaration here
if (x > SCREEN_WIDTH || y > SCREEN_HEIGHT) return;
if ((x == 0) || (y == 0)) return; // *** ADD THIS LINE ***
// Real screen coordinates are 0-63, not 1-64.
x -= 1;
y -= 1;
array_pos = (int16)x + (((int16)y / 8) * 128); // *** ADD (int16) in 2 places
.
.
.
} |
|
I tried out your guess and it worked perfectly. Thank you
Any thoughts on why the text part isn't working? where the text should be a random pattern of pixels appear.
thanks
jaume |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19255
|
|
Posted: Mon Feb 06, 2017 1:36 pm |
|
|
The one I was pointing out, will cause problems according to the gradient of lines. It's the handling for lines that work in the opposite direction (so go from a high X to low X for example).
The delta's need to be declared as signed, or these won't work.
I guessed this one would exist, since the code is always assuming that the integers are signed, and this particular one was 'bound' to exist in the line handling. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 06, 2017 1:38 pm |
|
|
What happens if you just write one letter, as shown below ?
Does it work ? I'm trying to determine if the text is not actually
random dots, but it's over-writing the previous text. If we just
write one letter and it works, then that's probably what is happening.
If it works, try it with some other characters, not just "A".
Quote: | draw_text("A", 10, 10, Tahoma10, 1); |
Where do these font files come from ? Did you make them ?
Can you provide a link, or post the Tahoma font file ? |
|
|
jamalavedra
Joined: 25 Oct 2016 Posts: 62
|
|
Posted: Mon Feb 06, 2017 1:48 pm |
|
|
this is the link where I got the Fonts from https://github.com/edeca/Electronics/tree/master/Include/fonts
When I only write one letter, such as "A", nothing appears. When I write several letters, such as "ABCde" random pattern appears. I believe it is random because the pattern changes reardless if I change or not the letters on the message.
thanks |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9133 Location: Greensville,Ontario
|
|
Posted: Mon Feb 06, 2017 5:53 pm |
|
|
That link to those fonts was NOT written in CCS C, actually it's a driver not just a font file.so a LOT of that code HAS to be converted into CCS C.
You should go back to square one. Using the datasheet for the GLCD, create a simple program to turn on a pixel and confirm it is at the correct location. The PDF file does show the command set and it's fairly close to a CGLD( Character LCD). Doing this 'low level' programming will confirm the display does function properly. Ther'es even a simple 'all on / all off' command, does THAT work ?
I really think you've got a LOT of NON CCS compatible code and the 'numbers' are not correct,thus giving you garbage or random data on the GLCD.
Jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 06, 2017 5:56 pm |
|
|
There appears to be a problem with fetching the correct data from the
array if it's declared as 'const'. Based on my tests, if it's in ram, it
should work. The array is 1176 bytes so it will take up about 1/3 of
the ram in your 18LF2685.
Edit the font file, font_tahoma.h, and remove 'const' from the array
declaration. This will put the font data in RAM:
Code: | unsigned char Tahoma10[] = |
temtronic wrote: |
That link to those fonts was NOT written in CCS C, actually it's a driver
not just a font file.so a LOT of that code HAS to be converted into CCS C. |
Temtronic,
His draw_char() function does actually use a font file of the type
that he has listed on the Github website. I changed the font array
declaration to RAM (removed 'const') and I edited the glcd_pixel()
routine to merely print out the x,y coordinates of the "dot" and the
color (on or off). This allowed me to generate the vertical line
of dots for each column of the character box, and display it in the
MPLAB vs. 8.92 Simulator using the UART1 output window.
Here is the function, modified for debugging purposes:
Code: |
void glcd_pixel(unsigned char x, unsigned char y, unsigned char colour)
{
printf("x:%x, y:%x, color:%x \r", x, y, colour);
} |
Thus for the final character in the font table, the tilde '~', I got the
output given below. Each block represents a column in the font cell.
The width of the font cell is 7 pixels, so there are 7 columns. The dots
in each column start at the top of the font cell and go to the bottom.
Thus you can see the tilde '~' starts with a short vertical up-stroke
(that's the two 01's) in the first column. The it goes sideways to
the right for a couple dots and then squiggles around and finishes
with a vertical upstroke in the final column. So, I think the routine
is working OK, temtronic. It just requires the font array to be
declared in RAM instead of as 'const'. I don't currently know why
that is, and I'm not actively investigating it at this time.
Code: | width = 07
x:0a, y:0a, color:00
x:0a, y:0b, color:00
x:0a, y:0c, color:00
x:0a, y:0d, color:00
x:0a, y:0e, color:00
x:0a, y:0f, color:01
x:0a, y:10, color:01
x:0a, y:11, color:00
x:0a, y:12, color:00
x:0a, y:13, color:00
x:0a, y:14, color:00
x:0b, y:0a, color:00
x:0b, y:0b, color:00
x:0b, y:0c, color:00
x:0b, y:0d, color:00
x:0b, y:0e, color:01
x:0b, y:0f, color:00
x:0b, y:10, color:00
x:0b, y:11, color:00
x:0b, y:12, color:00
x:0b, y:13, color:00
x:0b, y:14, color:00
x:0c, y:0a, color:00
x:0c, y:0b, color:00
x:0c, y:0c, color:00
x:0c, y:0d, color:00
x:0c, y:0e, color:01
x:0c, y:0f, color:00
x:0c, y:10, color:00
x:0c, y:11, color:00
x:0c, y:12, color:00
x:0c, y:13, color:00
x:0c, y:14, color:00
x:0d, y:0a, color:00
x:0d, y:0b, color:00
x:0d, y:0c, color:00
x:0d, y:0d, color:00
x:0d, y:0e, color:00
x:0d, y:0f, color:01
x:0d, y:10, color:00
x:0d, y:11, color:00
x:0d, y:12, color:00
x:0d, y:13, color:00
x:0d, y:14, color:00
x:0e, y:0a, color:00
x:0e, y:0b, color:00
x:0e, y:0c, color:00
x:0e, y:0d, color:00
x:0e, y:0e, color:00
x:0e, y:0f, color:00
x:0e, y:10, color:01
x:0e, y:11, color:00
x:0e, y:12, color:00
x:0e, y:13, color:00
x:0e, y:14, color:00
x:0f, y:0a, color:00
x:0f, y:0b, color:00
x:0f, y:0c, color:00
x:0f, y:0d, color:00
x:0f, y:0e, color:00
x:0f, y:0f, color:00
x:0f, y:10, color:01
x:0f, y:11, color:00
x:0f, y:12, color:00
x:0f, y:13, color:00
x:0f, y:14, color:00
x:10, y:0a, color:00
x:10, y:0b, color:00
x:10, y:0c, color:00
x:10, y:0d, color:00
x:10, y:0e, color:01
x:10, y:0f, color:01
x:10, y:10, color:00
x:10, y:11, color:00
x:10, y:12, color:00
x:10, y:13, color:00
x:10, y:14, color:00
Done |
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|