Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - kb1gtt

Pages: 1 [2] 3 4 5
16
I got it to work, and wanted to share. It appears the -lm needs to be after my-first-task.o. Here's a snippet of my make file.
Code: [Select]
$(CC) $(C_FLAGS)    blah blah     uTaskerV1.4.elf $(OBJS)-lm
$(CC) $(C_FLAGS)    blah blah     uTaskerV1.4_BM.elf $(OBJS) -lm
I would have caught that sooner, but I didn't update it for both the BM and normal version. So the BM version would produce an error message very similar to my normal message. Oops, but I got it figured out.

It now compiles and appears to work with the asin function. Yeah, I'm back to the normally scheduled program.

17
I'm using arm-none-eabi-gcc for the compiler. I believe it was installed via Olimex CD, and used by the default gnu make file that came with utasker. It appears that asin is in libm.a which can be specified with -lm.

http://www.network-theory.co.uk/docs/gccintro/gccintro_17.html
http://www.codesourcery.com/archives/arm-gnu/msg01877.html

I've tried a variety of absolute links and such to ensure it pointed to a specific libm.a. I have 4 under the codesourercy directory. They didn't work. I also wonder how the pre-compiled .a files would know flags like -mthumb, ect. Wouldn't those .a files need to have similar compile fags? I don't have a subscription to codesourercy, so I can't ask them on the forums.

I'm trying to modify the make file and see what happens with the yartago version of the compiler. However that can't find the files for some reason. On the command prompt I've been trying a variety of ../ vs ..\ placed in "s, ect. No luck getting the yartago to compile yet.

I'm still unable to get the .a files to work with either gnu compiler.

18
I'm having some trouble with the math.h library. This may be the same issue I had with the stio.h. When compiled for the target, it flops. Perhaps I need a command like -lm for link math library, or similar. I tried adding that to the build process, but no dice. This is the messages I get when I compile for target using a asin function. This also compiles just fine for the simulator.

Code: [Select]
arm-none-eabi-gcc -march=armv4t -mlittle-endian -mthumb -mthumb-interwork -Wall -Wstrict-prototypes -lm -I../../uTaskerV1.4 -D _GNU -D _LPC23XX -g -Os -Wl,-Map=uTaskerV1.4.map --no-gc-sections -nostartfiles -TuTaskerLPC23XX.ld -o uTaskerV1.4.elf Build/my-first-task.o Build/application.o Build/debug.o Build/webInterface.o Build/KeyScan.o Build/LCD.o Build/TFT.o Build/NetworkIndicator.o Build/startup_gnu.o Build/LPC23XX.o Build/GLCD.o Build/MODBUS.o Build/modbus_app.o Build/mass_storage.o Build/eth_drv.o Build/Driver.o Build/uMalloc.o Build/uTasker.o Build/Tty_drv.o Build/iic_drv.o Build/uFile.o Build/Watchdog.o Build/GlobalTimer.o Build/low_power.o Build/Ethernet.o Build/arp.o Build/dhcp.o Build/dns.o Build/ftp.o Build/http.o Build/icmp.o Build/ip_utils.o Build/ip.o Build/pop3.o Build/smtp.o Build/tcp.o Build/telnet.o Build/tftp.o Build/udp.o Build/webutils.o Build/NetBIOS.o
Build/my-first-task.o: In function `fnMyFirstTask':
C:\uTaskerV1.4_LPC_take2\Applications\uTaskerV1.4\GNU_LPC23XX/../my-first-task.c:137: undefined reference to `asin'
collect2: ld returned 1 exit status
cs-make: *** [uTaskerV1.4.elf] Error 1
It appears #include <math.h> isn't working as I would expect. Any suggestions on how to get the math lib included such that it will compile?

19
I tried sprintf, which recommended using sprintf_s. However, that also flops when used to build the target, and works fine when compiled for the simulator. Here's some messages when using the target build.
Code: [Select]
c:\utaskerv1.4_lpc_take2\applications\utaskerv1.4\my-first-task.c(130) : warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
        c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(366) : see declaration of 'sprintf'
Linking...

blah blah

arm-none-eabi-gcc -march=armv4t -mlittle-endian -mthumb -mthumb-interwork -Wall -Wstrict-prototypes -I../../uTaskerV1.4 -D _GNU -D _LPC23XX -g -Os -Wl,-Map=uTaskerV1.4.map --no-gc-sections -nostartfiles -TuTaskerLPC23XX.ld -o uTaskerV1.4.elf Build/my-first-task.o Build/application.o Build/debug.o Build/webInterface.o Build/KeyScan.o Build/LCD.o Build/TFT.o Build/NetworkIndicator.o Build/startup_gnu.o Build/LPC23XX.o Build/GLCD.o Build/MODBUS.o Build/modbus_app.o Build/mass_storage.o Build/eth_drv.o Build/Driver.o Build/uMalloc.o Build/uTasker.o Build/Tty_drv.o Build/iic_drv.o Build/uFile.o Build/Watchdog.o Build/GlobalTimer.o Build/low_power.o Build/Ethernet.o Build/arp.o Build/dhcp.o Build/dns.o Build/ftp.o Build/http.o Build/icmp.o Build/ip_utils.o Build/ip.o Build/pop3.o Build/smtp.o Build/tcp.o Build/telnet.o Build/tftp.o Build/udp.o Build/webutils.o Build/NetBIOS.o
c:/gccfd/codesourcery-arm-2008q1/bin/../lib/gcc/arm-none-eabi/4.2.3/../../../../arm-none-eabi/bin/ld.exe: section .ARM.exidx [00000000 -> 0000000f] overlaps section .vectors [00000000 -> 0000002f]
c:/gccfd/codesourcery-arm-2008q1/bin/../lib/gcc/arm-none-eabi/4.2.3/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text+0xc): undefined reference to `_sbrk'
c:/gccfd/codesourcery-arm-2008q1/bin/../lib/gcc/arm-none-eabi/4.2.3/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text+0x10): undefined reference to `_write'

blah blah
I read that as sprintf wasn't well supported because it wants you to use sprintf_s. However sprintf_s has the library/include issue. It seems like sprintf just isn't all that well supported for the target build. Also I like your version because of the bloat thing you mentioned.

Looks like your fnBufferDec() will work for me. Now I just need to get the data from the AIS226 formated into a normal number. One part of the data sheet notes "16 bit internal representation, 14 bit resolution" while another area notes "(0: 12 bit right justified; 1: 16 bit left justified)" So I'm doing some testing to get a feel for if it's 12 bit, 14 bit, ect.

Thanks for the reply, again spot on and I'm back off and running.

20
I'm still trying to figure out the bits that are coming out of this AIS226 chip. It appears the data is a signed number vs unsigned, and there are some interesting effects of the higher level bits. I'm trying to calculate the accumulated acceleration and display it such that I can look for the over all noise floor. I'm trying to do this with the sprintf command, which recommends using sprintf_s. It compiles and runs with out warning or issue on the simulator, but it won't compile for the target. Here's a snippet from my-task.c

Code: [Select]
#include <stdio.h>

blah blah

sprintf_s(mybuf, 10, "%d",(char *)x_now);
//sprintf(mybuf, "%d",(char *)n);
//mybuf = sprintf("%d",(char *)x_now);
fnDoLCD_text(&text_pos, mybuf);//display
The sprintf_s is line 124. When I compile, I get these messages.
Code: [Select]
arm-none-eabi-gcc -march=armv4t -mlittle-endian -mthumb -mthumb-interwork -Wall -Wstrict-prototypes -I../../uTaskerV1.4 -D _GNU -D _LPC23XX -g -c -Os ../my-first-task.c -o Build/my-first-task.o
../my-first-task.c: In function 'fnMyFirstTask':
../my-first-task.c:127: warning: cast to pointer from integer of different size
../my-first-task.c:21: warning: unused variable 'n'
../my-first-task.c: At top level:
../../../hardware/LPC23XX/spi_acc_lpc_AIS226_2.h:70: warning: 'fnLCD_display_bits' defined but not used
../../../hardware/LPC23XX/spi_acc_lpc_AIS226_2.h:113: warning: 'fnLCD_display_hex' defined but not used
arm-none-eabi-gcc -march=armv4t -mlittle-endian -mthumb -mthumb-interwork -Wall -Wstrict-prototypes -I../../uTaskerV1.4 -D _GNU -D _LPC23XX -g -c -Os ../application.c -o Build/application.o
arm-none-eabi-gcc -march=armv4t -mlittle-endian -mthumb -mthumb-interwork -Wall -Wstrict-prototypes -I../../uTaskerV1.4 -D _GNU -D _LPC23XX -g -c -Os ../debug.c -o Build/debug.o

blah blah

arm-none-eabi-gcc -march=armv4t -mlittle-endian -mthumb -mthumb-interwork -Wall -Wstrict-prototypes -I../../uTaskerV1.4 -D _GNU -D _LPC23XX -g -Os -Wl,-Map=uTaskerV1.4.map --no-gc-sections -nostartfiles -TuTaskerLPC23XX.ld -o uTaskerV1.4.elf Build/my-first-task.o Build/application.o Build/debug.o Build/webInterface.o Build/KeyScan.o Build/LCD.o Build/TFT.o Build/NetworkIndicator.o Build/startup_gnu.o Build/LPC23XX.o Build/GLCD.o Build/MODBUS.o Build/modbus_app.o Build/mass_storage.o Build/eth_drv.o Build/Driver.o Build/uMalloc.o Build/uTasker.o Build/Tty_drv.o Build/iic_drv.o Build/uFile.o Build/Watchdog.o Build/GlobalTimer.o Build/low_power.o Build/Ethernet.o Build/arp.o Build/dhcp.o Build/dns.o Build/ftp.o Build/http.o Build/icmp.o Build/ip_utils.o Build/ip.o Build/pop3.o Build/smtp.o Build/tcp.o Build/telnet.o Build/tftp.o Build/udp.o Build/webutils.o Build/NetBIOS.o
Build/my-first-task.o: In function `fnMyFirstTask':
C:\uTaskerV1.4_LPC_take2\Applications\uTaskerV1.4\GNU_LPC23XX/../my-first-task.c:127: undefined reference to `sprintf_s'
collect2: ld returned 1 exit status
cs-make: *** [uTaskerV1.4.elf] Error 1

I tried to create a prototype for sprintf_s, but it still didn't link correctly and failed to compile. Are there any suggestions on how to get the prototype for sprintf_s to work? I'm not sure why this would be different from the simulator to the target build.

21
I let this run last night, for about 8 hrs. This morning it claimed a variation on X of 4 and on Y of 2. Right now just a couple minutes later, it's X of 0xB and Y of 0x10. So it would appear that wondering I was concerned about is just local vibration. If it's this accurate, I would wager a guess that the 4 and 2 variations are also local vibrations. 

Also I did some tests looking to see how accurate it was. I propped up one end of the demo board with a piece of paper, aprox .005 inch thick, and it changed the reading by 1 bit. I used a thicker piece of paper, about .010 inch thick, and it changed by 3 bits. Each time after I removed the paper prop, it came back to the original value.

22
That wasn't that hard to tune. I changed the Decimation factor to a sampling rate to 40 Hz, it was 2560 Hz for some reason. That chopped out allot of the noise issues. I now write to it's register making it 40 Hz, so it shouldn't wonder unexpectedly. After about 10 seconds the difference between my min and max readings on x is 0, and on Y it's 2. After about 5 minutes of sitting here, the difference on X is 7 and on Y it's also 7. Seems to wonder a little bit there. Not sure why. It's just sitting here on my desk, perhaps it's picking up some vibrations, it seems fairly solid where it's sitting. I wouldn't expect vibration noise, but on the other hand, 0.25mg/bit isn't much of an acceleration.

Rotating the board around by hand I get a full scale of about 7FF on both axis's. I'm a bit concerned about this wondering, I wonder what's causing it and if it can be minimized some how.

23
The LCD buffer issue is fixed. Upping the que to (LARGE_QUE + 1024) did it. Now all the printed lines are displaying. I guess that an increase to LARGE_QUE simply wasn't enough.

I started getting data out of the accelerometer, and it's a bit disappoint. The error bracket appears to be about 0xA0 which is higher than expected on a device that claims 14bit resolution. I'll have to look at the accelerometer internal settings and see if I can tune out the noise. I'm back on track and digging deeper into the AIS226.

24
The simulator is awesome, and I was surprised at how easy it was to emulated the accelerometer. I did my emulation with this code.
Code: [Select]
SET_AIS226_CS_LOW(); // assert SS low before starting
//FIO0PIN &= 0xffffffbf; // assert SS low before starting

SSPDR_X = (cmd | rw); // send command
SSPDR_X = SPI_data; // send blank bits to allow clocks for return command
while (!(SSPSR_X & SSP_RNE)){//};//first byte is blank
#ifdef _WINDOWS
    SSPSR_X |= SSP_RNE; // SET flag for simulator
#endif
}
null = SSPDR_X;
while (!(SSPSR_X & SSP_RNE)){};//second byte is the returned data
#ifdef _WINDOWS
if (cmd == OUTY_L) SSPDR_X = (unsigned char)fnRandom();// simulate AIS226 data
if (cmd == OUTY_H) SSPDR_X = 0x01;// simulate AIS226 data
#endif
temp2 = SSPDR_X;
while (SSPSR_X & (SSP_BSY | SSP_RNE)) {// wait for all transfers to complete and clear rx buffer
null = SSPDR_X; //save it to ulDummy
#ifdef _WINDOWS
SSPSR_X &= ~SSP_RNE; // CLEAR flag for simulator
SSPSR_X &= ~SSP_BSY; // CLEAR flag for simulator
#endif
    }
SET_AIS226_CS_HIGH(); // assert SS high after done transmission
Now it's going to be a while before I flash the target. Awesome.

25
Here's my-first-task.c as it stands now.
Code: [Select]
#include "config.h" // include all headers in case a new file
#include "application_lcd.h"                                             // {46} LCD tests
#include "../../hardware/LPC23XX/spi_acc_lpc_AIS226_2.h"                                          // AIS226 accelerometer

extern void fnMyFirstTask(TTASKTABLE *ptrTaskTable)
{
//vars
static int iState = 0;
int y_high = 0;
int y_low = 0;
int y_now = 0;

// init some stuff
GLCD_TEXT_POSITION text_pos;
GLCD_RECT_BLINK rectjah;

// setup some task stuff / initialize code based on task state
if (!iState) {
// LCD PWM to dim.
fnSetLCDContrast();

// print something to LCD
text_pos.ucMode = PAINT_LIGHT;
text_pos.usX = 2;
text_pos.usY = 40;
text_pos.ucFont = (FONT_FIVE_DOT);
// an ack is requested when this has been completely displayed
text_pos.ucMode = (REDRAW | GIVE_ACK);                   
fnDoLCD_text(&text_pos, "my first task sais hellow");

// print blinking LCD heart beat indicator box
text_pos.usX = 2;
text_pos.usY = 0;
text_pos.ucFont = FONT_NINE_DOT;
rectjah.ucMode = BLINKING_OBJECT;
rectjah.rect_corners.usX_start = 120;
rectjah.rect_corners.usY_start = 120;
rectjah.rect_corners.usX_end = 125;
rectjah.rect_corners.usY_end = 125;
rectjah.blink_half_period = (DELAY_LIMIT)(0.3*SEC);
fnDoLCD_rect(&rectjah);

//config the SPI for the AIS226
fnConfigSPI_AIS226();

// set starting points for min and max indicators
y_high = fnSPI_AIS226(OUTY_L, SPI_READ, 0x00);
y_high = y_high + (fnSPI_AIS226(OUTY_H, SPI_READ, 0x00) << 8);
y_low = y_high;

fnLCD_display_hex(95,100,"high Y",y_high);
fnLCD_display_hex(85,100,"",(y_high >> 8));
// fnLCD_display_hex(85,110,"",(y_low >> 8));
// fnLCD_display_hex(95,110,"low Y",y_low);

iState = 1;
}

// read acceleration and display on screen
//fnLCD_display_hex(95,50,"hex X",fnSPI_AIS226(OUTX_L, SPI_READ, 0x00));
//fnLCD_display_hex(85,50,"",fnSPI_AIS226(OUTX_H, SPI_READ, 0x00));
y_now = fnSPI_AIS226(OUTY_L, SPI_READ, 0x00);
y_now = y_now + (fnSPI_AIS226(OUTY_H, SPI_READ, 0x00) << 8);
if (y_now > y_high) y_high = y_now;
if (y_now < y_low) y_low = y_now;

fnLCD_display_hex(95,60,"high Y",y_high);
fnLCD_display_hex(85,60,"",(y_high >> 8));
fnLCD_display_hex(95,70,"now Y",y_now);
// fnLCD_display_hex(85,70,"",(y_now >> 8));
// fnLCD_display_hex(95,80,"low Y",y_low);
// fnLCD_display_hex(85,80,"",(y_now >> 8));
//fnLCD_display_hex(85,60,"",yh_high);

//fnLCD_display_hex(85,70,"",fnSPI_AIS226(STATUS_REG, SPI_READ, 0x00));

//fnLCD_display_bits(95,50,"PCLKSEL0",*(unsigned long *)0xE01FC1A8 >> 4);// >> 0&0xE0020000);
}
I have modified TaskConfig.h like this
Code: [Select]
#if defined SUPPORT_LCD
  { "LCD",       fnLCD,          LARGE_QUE/*MEDIUM_QUE*/,  (DELAY_LIMIT)(NO_DELAY_RESERVE_MONO), 0, UTASKER_STOP},  //
#elif defined SUPPORT_GLCD || defined SUPPORT_OLED || defined SUPPORT_TFT || defined GLCD_COLOR // {2}{4}
    #ifdef GLCD_COLOR
  { "LCD",       fnLCD,          LARGE_QUE/*SMALL_QUEUE*/, (DELAY_LIMIT)(NO_DELAY_RESERVE_MONO), 0, UTASKER_ACTIVATE}, // runs immediately
    #else
  { "LCD",       fnLCD,          (LARGE_QUE + 128),  (DELAY_LIMIT)(NO_DELAY_RESERVE_MONO), 0, UTASKER_STOP}, // large queue for queuing text
    #endif
The above code is grey, but appears to be compiled. Here's spi_acc_lpc_AIS226_2.h
Code: [Select]
//prototypes
int fnSPI_AIS226(int, int, int);

//defines
#define SET_AIS226_CS_LOW()      _CLEARBITS(0, PORT0_BIT6) // assert the CS line of the AIS226
#define SET_AIS226_CS_HIGH()     _SETBITS(0, PORT0_BIT6)   // negate the CS line of the AIS226

#define WHO_AM_I   0x0F //memory location 0x0F should read as 0x3A
#define STATUS_REG 0x27
#define CTRL_REG1  0x20
#define OUTX_L    0x28
#define OUTX_H     0x29
#define OUTY_L    0x2A
#define OUTY_H     0x2B
#define SPI_READ   0x80 //memory location 0x0F should read as 0x3A
#define SPI_WRITE  0x00 //memory location 0x0F should read as 0x3A


static void fnConfigSPI_AIS226(void)//
{
//pg 436 setup
    POWER_UP(PCSSP1); // power up the SPI on SSP port
//clock note, PCLK_SEL0 select PCLK_SPI default is cclk/4, set bits 16:17 (11) for cclk/8
PCLKSEL0 |= PCLK_SSP1_CCLK_8;// set for /8
    CONFIGURE_SPI_PINS(); //SET PINSEL0 BITS to make pins SPI
    CONFIGURE_CS_LINES(); //FIO0SET and FIO0DIR for software driven CS line
//PINMODE0 |= PINMODE_NO_PULLS_6;//PINMODE_PULLDOWN_6;
//PINMODE0 |= PINMODE_NO_PULLS_7;//PINMODE_PULLDOWN_7;
//PINMODE0 |= PINMODE_NO_PULLS_8;// P0.8 is driven by the slave, so don't drive it here
//PINMODE0 |= PINMODE_NO_PULLS_9;//PINMODE_PULLDOWN_9;
//irq's
//NA verified as off

//other setup
    SSPCPSR_X = 16; // set clock prescaler (even prescale 2..254)
    SSPCR0_X = (DSS_8_BIT); //| FRS_MICROWIRE); // set 8 bit words
    SSPCR1_X = SSP_SSE;         // enable

//make sure AIS226 is set to read a value
fnSPI_AIS226(CTRL_REG1, SPI_WRITE, (0xC0 | fnSPI_AIS226(CTRL_REG1, SPI_READ, 0x00)));
}


static void fnLCD_display_bits(int x, int y, const CHAR *LCD_text, unsigned long bits_displayed){
// init some stuff
GLCD_TEXT_POSITION text_pos;// = {PAINT_LIGHT, 2, 0, FONT_NINE_DOT};

// print something to LCD
text_pos.ucMode = PAINT_LIGHT;
text_pos.ucFont = (FONT_FIVE_DOT);

text_pos.usY = y;
text_pos.usX = x;
fnDoLCD_text(&text_pos, LCD_text);

text_pos.usX = x-47;
fnDoLCD_text(&text_pos, "                     ");//clear display area

text_pos.usX = x-10;
if (bits_displayed & 0x0001) fnDoLCD_text(&text_pos, "1");
else fnDoLCD_text(&text_pos, "0");
text_pos.usX = x-15;
if (bits_displayed & 0x0002) fnDoLCD_text(&text_pos, "1");
else fnDoLCD_text(&text_pos, "0");
text_pos.usX = x-20;
if (bits_displayed & 0x0004) fnDoLCD_text(&text_pos, "1");
else fnDoLCD_text(&text_pos, "0");
text_pos.usX = x-25;
if (bits_displayed & 0x0008) fnDoLCD_text(&text_pos, "1");
else fnDoLCD_text(&text_pos, "0");

text_pos.usX = x-32;
if (bits_displayed & 0x0010) fnDoLCD_text(&text_pos, "1");
else fnDoLCD_text(&text_pos, "0");
text_pos.usX = x-37;
if (bits_displayed & 0x0020) fnDoLCD_text(&text_pos, "1");
else fnDoLCD_text(&text_pos, "0");
text_pos.usX = x-42;
if (bits_displayed & 0x0040) fnDoLCD_text(&text_pos, "1");
else fnDoLCD_text(&text_pos, "0");
text_pos.usX = x-47;
if (bits_displayed & 0x0080) fnDoLCD_text(&text_pos, "1");
else fnDoLCD_text(&text_pos, "0");
}


static void fnLCD_display_hex(int x, int y, const CHAR *LCD_text, int hex_displayed){
// init some stuff
GLCD_TEXT_POSITION text_pos;// = {PAINT_LIGHT, 2, 0, FONT_NINE_DOT};
text_pos.ucMode = PAINT_LIGHT;
text_pos.ucFont = (FONT_FIVE_DOT);

text_pos.usY = y;
text_pos.usX = x;
fnDoLCD_text(&text_pos, LCD_text);

text_pos.usX = x-20;
fnDoLCD_text(&text_pos, "       ");//clear display area

text_pos.usX = x-10;
if (hex_displayed & 0x1) fnDoLCD_text(&text_pos, "1");
else if (hex_displayed & 0x2) fnDoLCD_text(&text_pos, "2");
else if (hex_displayed & 0x3) fnDoLCD_text(&text_pos, "3");
else if (hex_displayed & 0x4) fnDoLCD_text(&text_pos, "4");
else if (hex_displayed & 0x5) fnDoLCD_text(&text_pos, "5");
else if (hex_displayed & 0x6) fnDoLCD_text(&text_pos, "6");
else if (hex_displayed & 0x7) fnDoLCD_text(&text_pos, "7");
else if (hex_displayed & 0x8) fnDoLCD_text(&text_pos, "8");
else if (hex_displayed & 0x9) fnDoLCD_text(&text_pos, "9");
else if (hex_displayed & 0xA) fnDoLCD_text(&text_pos, "A");
else if (hex_displayed & 0xB) fnDoLCD_text(&text_pos, "B");
else if (hex_displayed & 0xC) fnDoLCD_text(&text_pos, "C");
else if (hex_displayed & 0xD) fnDoLCD_text(&text_pos, "D");
else if (hex_displayed & 0xE) fnDoLCD_text(&text_pos, "E");
else if (hex_displayed & 0xF) fnDoLCD_text(&text_pos, "F");
else fnDoLCD_text(&text_pos, "0");

text_pos.usX = x-15;
if (hex_displayed & 0x10) fnDoLCD_text(&text_pos, "1");
else if (hex_displayed & 0x20) fnDoLCD_text(&text_pos, "2");
else if (hex_displayed & 0x30) fnDoLCD_text(&text_pos, "3");
else if (hex_displayed & 0x40) fnDoLCD_text(&text_pos, "4");
else if (hex_displayed & 0x50) fnDoLCD_text(&text_pos, "5");
else if (hex_displayed & 0x60) fnDoLCD_text(&text_pos, "6");
else if (hex_displayed & 0x70) fnDoLCD_text(&text_pos, "7");
else if (hex_displayed & 0x80) fnDoLCD_text(&text_pos, "8");
else if (hex_displayed & 0x90) fnDoLCD_text(&text_pos, "9");
else if (hex_displayed & 0xA0) fnDoLCD_text(&text_pos, "A");
else if (hex_displayed & 0xB0) fnDoLCD_text(&text_pos, "B");
else if (hex_displayed & 0xC0) fnDoLCD_text(&text_pos, "C");
else if (hex_displayed & 0xD0) fnDoLCD_text(&text_pos, "D");
else if (hex_displayed & 0xE0) fnDoLCD_text(&text_pos, "E");
else if (hex_displayed & 0xF0) fnDoLCD_text(&text_pos, "F");
else fnDoLCD_text(&text_pos, "0");
}

static void fnSetLCDContrast(void){
// configure PWM output for contrast control
    TIMER_INTERRUPT_SETUP timer_setup = {0};                             // PWM Timer Init Struct
    timer_setup.int_type = TIMER_INTERRUPT;                              // timer setup type
    timer_setup.int_priority = 0;
    timer_setup.int_handler = 0;                                         // no interrupts used
    timer_setup.timer_reference = PWM1;                                  // use PWM module
    timer_setup.timer_mode  = (TIMER_PWM_6 | PWM_OUTPUT_PORT_1);         // use PWM channel 1 on port 1 output location
    timer_setup.timer_value = TIMER_US_DELAY(TIMER_FREQUENCY_VALUE(200));// 10000 Hz contrast frequency
    timer_setup.pwm_value   = _PWM_PERCENT(27,timer_setup.timer_value);//temp_pars->temp_parameters.ucGLCDContrastPWM, timer_setup.timer_value); // contrast as PWM value
    fnConfigureInterrupt((void *)&timer_setup);   
}


int fnSPI_AIS226(int cmd, int rw, int SPI_data){
unsigned long temp;
int temp2, null;
temp = SSP0CR0; //appears something else uses this SPI reg, so lets save it and restore it when done with this process
SSP0CR0 = (SSP0CR0 & 0xfff0) | 0x07;//clear the lower 4 bits, and set an 8 bit word
SET_AIS226_CS_LOW(); // assert SS low before starting
//FIO0PIN &= 0xffffffbf; // assert SS low before starting

SSPDR_X = (cmd | rw); // send command the 0x80 sets the read vs write bit.
SSPDR_X = SPI_data; // send blank bits to allow clocks for return command
while (!(SSPSR_X & SSP_RNE)){};//first byte is blank
null = SSPDR_X;
while (!(SSPSR_X & SSP_RNE)){};//second byte is the address
temp2 = SSPDR_X;
while (SSPSR_X & (SSP_BSY | SSP_RNE)) {// wait for all transfers to complete and clear rx buffer
    null = SSPDR_X; //save it to ulDummy
    }

SET_AIS226_CS_HIGH(); // assert SS high after done transmission
//FIO0PIN |= 0x00000040; // assert SS high after done transmission
SSP0CR0 = temp; //return to the normally scheduled program.
return temp2;
}
I changed application_LCD.h like this
Code: [Select]
        case TASK_LCD:
            fnRead( PortIDInternal, ucInputMessage, ucInputMessage[MSG_CONTENT_LENGTH]); // read the complete message
            if (E_LCD_INITIALISED == ucInputMessage[0]) {
#if !defined SUPPORT_TFT
                GLCD_TEXT_POSITION text_pos;// = {PAINT_LIGHT, 2, 0, FONT_NINE_DOT};
                text_pos.ucMode = PAINT_LIGHT;
                text_pos.usX = 2;
                text_pos.usY = 15;
                text_pos.ucFont = (FONT_FIVE_DOT);
                fnDoLCD_text(&text_pos, "We'll show you how");
                text_pos.usY = 40;
                text_pos.ucFont = (FONT_FIVE_DOT);
                text_pos.ucMode = (REDRAW | GIVE_ACK);                   // an ack is requested when this has been completely displayed
                fnDoLCD_text(&text_pos, "started");
    #endif
            }
            /*else if (E_LCD_READY == ucInputMessage[0]) {                 // an  acknowledgement from the display task (last job has been completed)

blah, blah

}*/
            break;
#endif
I know there are bugs in my-first-task.c. Currently it doesn't display the high and low values as expected. They appear, but appear to be incorrect numbers. It seems to ignore the if statement and always runs y_high = y_now. I believe that issue is separate from the display issues. I think I'm just using the logic operator incorrectly.

I believe I have increased the buffer size in the TaskConfig.h. Also my SPI coms send two bytes, then waits for completion of those two. So I believe it should send a max of 2 out of the 8 deep fifo. Is the 8 fifo shared with the LCD's I2C? I have to confess some ignorance about the details of the fifo.

26
So my programming stills get better every day. It appears that

static unsigned char ucCounter = 0;

is a lot different than

static unsigned char ucCounter = 0;
ucCounter = 0;

That's a neat trick for handling the initialization / normal operation of my_task. Now that my_task only displays information to the LCD that it needs to display, it still appears I'm having problems when I try to write to much to the display. It appears like I'm exceeding a buffer or something. I'm still a bit baffeled about the LCD thing. The display commands are great, but there's some black magic going on that I'm ignorant about. Are there any tips about how to display text on the LCD? I have read uTaskerLCD.PDF.

27
I just did that _CLEARBITS(ref, mask) and _SETBITS(ref, mask) thing, that was easy. I see another feature I should learn more about. It appears utasker has a nice feature to identify the initial run of a task as noted in the task table ucTaskState. I'm thumbing through the PDF's to see if I can find some insight into the task state thing. I know I saw something about that in one of those PDF's.

28
It's working great now, I've got it reading both X and Y axis's, which required me to write to the AIS226 at least once. I'm hitting a small problem, it appears I'm buggering the LCD some how. I've seen this before, but was ignoring it. It appears that if I write too many commands to the LCD it will lock up. For example, the below code displays as expected.
Code: [Select]
//fnLCD_display_hex(95,50,"hex X",fnSPI_AIS226(OUTX_L, READ, 0x00));
//fnLCD_display_hex(85,50,"",fnSPI_AIS226(OUTX_H, READ, 0x00));
fnLCD_display_hex(95,60,"hex Y",fnSPI_AIS226(OUTY_L, READ, 0x00));
fnLCD_display_hex(85,60,"",fnSPI_AIS226(OUTY_H, READ, 0x00));
If I uncomment the X and comment the Y, it also works. However if I uncomment both the X and the Y, the LCD locks up. I still get the heartbeat LED, but the LCD stop reacting. I set a small blinking box on the LCD, which functions as a LCD heartbeat indicator. When the LCD locks up, this blinking box stops blinking. I'm curious what causes the LCD to stop reacting. Perhaps I shouldn't be constantly refreshing nearly the entire screen every .2 seconds. I might guess I'm exceeding a buffer limit or something. Perhaps I should check a buffer before I write an LCD command.

Another thing I'd like to iron out if possible, is how to fix the mild watch dog issues. I seem to recall a note that if you reboot while in the middle of a watch dog event, it won't boot up. This is simply resolved on this board via reset switch. That seems to bring it back out of this issue. Is there a way to make it always work?

29
Also, don't forget the port macros (see LPC23XX.h: Eg. _CLEARBITS(ref, mask) and _SETBITS(ref, mask)) which can make code easier and more portable.

Thanks, I'll keep that in mind. For now it works, so I'll likely do that later down the road.

Per your notes I got it reading a reliable 3A, yeah, it now does the extreme basics. Here the code that got it displaying.
Code: [Select]
// read mfg from spi chip and display on screen
fnConfigSPI_jah();

#define WHO_AM_I 0x0F //memory location 0x0F should read as 0x3A

temp = SSP0CR0; //appears something else uses this SPI reg, so lets save it and restore it when done with this process
SSP0CR0 = (SSP0CR0 & 0xfff0) | 0x07;//clear the lower 4 bits, and set an 8 bit word
FIO0PIN &= 0xffffffbf; // assert SS low before starting

SSPDR_X = WHO_AM_I | 0x80; // send command the 0x80 sets the read vs write bit.
SSPDR_X = 0x00; // send blank bits to allow clocks for return command
while (!(SSPSR_X & SSP_RNE)){};//first byte is blank
ulDummy = SSPDR_X;
while (!(SSPSR_X & SSP_RNE)){};//second byte is the address
ulDummy2 = SSPDR_X;
while (SSPSR_X & (SSP_BSY | SSP_RNE)) {// wait for all transfers to complete and clear rx buffer
    ulDummy = SSPDR_X;//save it to ulDummy
    }

FIO0PIN |= 0x00000040; // assert SS high after done transmission
SSP0CR0 = temp; //return to the normally scheduled program.

fnLCD_display_bits(95,50,"ul 2",ulDummy2); //>> 24);

//fnLCD_display_bits(95,60,"S0SPCR",S0SPCR);
//fnLCD_display_bits(95,50,"PCLKSEL0",*(unsigned long *)0xE01FC1A8 >> 4);// >> 0&0xE0020000);
//fnLCD_display_bits(95,70,"S0SPSR",S0SPSR);
//fnLCD_display_bits(95,80,"S0SPSR8",S0SPSR >> 8);
//fnLCD_display_bits(95,90,"S0SPCCR",S0SPCCR);
//fnLCD_display_bits(95,100,"S0SPCCR8",S0SPCCR >> 8);

}

Now to see if I can get it to give me a reading for the accelerometer. Thanks for the note, again spot on.

30
The SPI registers are not included since only the SSP have been used to date.
It turns out that MOSI1 is on the SSP interface, not the SPI interface. So I ended up using the original SSP stuff. I did add the SPI stuff as you noted, and it appears to have been working OK, with the exception of being on the wrong pins for my application. Thanks for sending that along.

Right now, I see the clock and MOSI pins wiggle as expected. The slave device even wiggles the MISO lines as expected. However I'm having trouble getting the proto board to display those wiggled bits on the LCD correctly. Here are some snippets of my current code.

From app_hw_lpc23xx.h
Code: [Select]
#define CONFIGURE_SPI_PINS()        PINSEL0 |= (PINSEL0_P0_8_MISO1 | PINSEL0_P0_9_MOSI1 | PINSEL0_P0_7_SCK1);// | PINSEL0_P0_6_SSEL1); // MOSI, MISO and SCK pins enabled - on SSP1

blah blah

#define CONFIGURE_CS_LINES()        FIO0DIR |= CS0_LINE; _SIM_PORTS

blah blah

#define CS0_LINE            PORT0_BIT6//PORT0_BIT14                                  // CS0 line used when SPI FLASH is enabled


From my task.h
Code: [Select]
static void fnConfigSPI_jah(void)//unsigned char ucSpeed)
{
//pg 436 setup
    POWER_UP(PCSSP1); // power up the SPI on SSP port
//clock note, PCLK_SEL0 select PCLK_SPI default is cclk/4, set bits 16:17 (11) for cclk/8
PCLKSEL0 |= PCLK_SSP1_CCLK_8;// set for /8
    CONFIGURE_SPI_PINS(); //SET PINSEL0 BITS to make pins SPI
    CONFIGURE_CS_LINES(); //FIO0SET and FIO0DIR for software driven CS line
//PINMODE0 |= PINMODE_NO_PULLS_6;//PINMODE_PULLDOWN_6;
//PINMODE0 |= PINMODE_NO_PULLS_7;//PINMODE_PULLDOWN_7;
//PINMODE0 |= PINMODE_NO_PULLS_8;// P0.8 is driven by the slave, so don't drive it here
//PINMODE0 |= PINMODE_NO_PULLS_9;//PINMODE_PULLDOWN_9;
//irq's
//NA verified as off

//other setup
    SSPCPSR_X = 16; // set clock prescaler (even prescale 2..254)
    SSPCR0_X = DSS_8_BIT; // set 8 bit words
    SSPCR1_X = SSP_SSE;         // enable
}

from my task set to run 2 seconds after boot and every .1 seconds after that.
Code: [Select]
unsigned long temp;
unsigned long temp2;
volatile unsigned long ulDummy;
volatile unsigned long ulDummy2;
volatile unsigned long ulDummy3;
volatile unsigned long ulDummy4;
volatile unsigned long ulDummy5;


// read mfg from spi chip and display on screen
fnConfigSPI_jah();

//TIMER_US_DELAY(TIMER_FREQUENCY_VALUE(10000))
    //jah_delay();

#define WHO_AM_I 0x0F //memory location 0x0F should read as 0x3A

temp = SSP0CR0; //appears something else uses this SPI reg, so lets save it and restore it when done with this process
SSP0CR0 = (SSP0CR0 & 0xfff0) | 0x07;//clear the lower 4 bits, and set an 8 bit word
FIO0PIN &= 0xffffffbf; // assert SS low before starting

SSPDR_X = WHO_AM_I | 0x80; // send command
SSPDR_X = 0x00; // send blank bits to allow clocks for return command
//while (SSPSR_X & SSP_TFE) {}
//temp2 = SSPSR_X;
while (SSPSR_X & (SSP_BSY | SSP_RNE)) {// wait for transfer to complete and clear rx buffer
    ulDummy5 = ulDummy4;//save it to ulDummy
    ulDummy4 = ulDummy3;//save it to ulDummy
    ulDummy3 = ulDummy2;//save it to ulDummy
    ulDummy2 = ulDummy;//save it to ulDummy
    ulDummy = SSPDR_X;//save it to ulDummy
    }

FIO0PIN |= 0x00000040; // assert SS high after done transmission
SSP0CR0 = temp; //return to the normally scheduled program.

fnLCD_display_bits(95,50,"ul4",ulDummy4); //>> 24);

//fnLCD_display_bits(95,60,"S0SPCR",S0SPCR);
//fnLCD_display_bits(95,50,"PCLKSEL0",*(unsigned long *)0xE01FC1A8 >> 4);// >> 0&0xE0020000);
//fnLCD_display_bits(95,70,"S0SPSR",S0SPSR);
//fnLCD_display_bits(95,80,"S0SPSR8",S0SPSR >> 8);
//fnLCD_display_bits(95,90,"S0SPCCR",S0SPCCR);
//fnLCD_display_bits(95,100,"S0SPCCR8",S0SPCCR >> 8);

There is certainly some back magic going on when it comes to the ulDummy thing. Or at least it's black magic to me. I don't know exactly how to know when it should stop reading bytes of data.

I see the MISO line holds low for a while after the clk has stopped. It would appear the slave is holding it low until the CS line is again asserted high by my code. My assertion varies by about 1 byte for an unknown reason. This variation in the CS line makes the received 0x3A data most of the time show up in ulDummy4, and some times ulDummy3/5.

Why it keeps reading bits after the clock has stopped is some black magic to me. I don't know how my code can better identify when it finished sending bits. In this case, I know I will send one byte, then receive one byte. I'd like to force it to stop after those bytes have been sent, but I don't know how my software can know when it's finished sending a byte. I tried some stuff with the buffer cleared bit SSP_TFE, but that locked things up, stopped blinking the heartbeat LED kind of lockup. 

I've also tried to use SSEL instead of GPIO. This didn't work because after each SSPDR_X it brought CS high which prevented the slave from replying. Perhaps I can get a string into SSPDR_X, such that it sends multiple bytes and doesn't assert CS high. Not sure. I'm a bit baffled by the black magic at the moment.


Pages: 1 [2] 3 4 5