µTasker Forum

µTasker Forum => NXPTM LPC2XXX and LPC17XX => Topic started by: kb1gtt on February 17, 2010, 11:49:44 AM

Title: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on February 17, 2010, 11:49:44 AM
I'm new here and currently reading the tutorials ect about how to use utasker. I've submitted my request for a hobby copy of utasker and should have that shortly. My first goal with utasker is to evaluate the MOD-SMB380 I just got from Olimex. I got this accelerometer because I found the on-board accelerometer had some noise issues.

So my first goal is to simply interface with the I2C and get accelerometer data out of this MOD board. I believe the digital interface of this chip will remove what I believe was analog noise issues with the original accelerometer. I'm curious if anyone one might have a recommended approach for this. I'm not sure if it's easier to get this data to show on a web page generated by utasker, or perhaps I can simply get it to display on the LCD. I'm still reading the docs and tutorials, so I'm very blind about what approach might be easiest.

I'm connecting it to an LPC2378-STK, and I can program / debug with ARM-USB-OCD both jtag and flash magic. I'm using the pre-configured windows based Eclipse and arm-elf-gcc that came with the 2378 board.

Thanks in advance.
Title: Re: MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on February 17, 2010, 03:27:55 PM
Hi Jared

Welcome to the forum - you should have received the project now so good luck with your first steps.

Start by following the tutorial using the simulator then move to your target - once you are happy with the project running there too you can activate I2C support and add the control for your specific device. Use the I2C document as guide (the accelerometer control will need to be added by setting its I2C address and sending the necessary specific commands but the basic interface should make this more comfortable - the references for EEPROM and RTC devices can be used as starting point).

The tutorial and project show how it is quite easy to interact with a web browser or else it also has some graphic support to allow you to display information on the LPC2378-STK's graphic display. Check out the uGLCDLIB in case you want to go this way: http://www.utasker.com/docs/uTasker/uTaskerLCD.PDF

Regards

Mark
Title: Re: MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on February 18, 2010, 02:47:22 AM
Great, I got the zip file and I'm currently downloading Visual Studio. That's going to take a while, it's a big file.

I'm reading the PDF's and getting familiar with this setup. Thanks and I look forward to jumping into this.
Title: Re: MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on February 18, 2010, 02:58:11 AM
I'm also new to Visual Studio. The I see the express comes in several variants, I'm think I want the C++ express. Is that correct? I can choose visual basic, C#, ect.
Title: Re: MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mhoneywill on February 18, 2010, 08:19:11 AM
Yes you want the C++ variant.

Cheers

Martin
Title: Re: MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on February 18, 2010, 12:32:21 PM
Things where going great, then I hit a mild hiccup and ran out of time to play with it this morning. I suspect my current ping hiccup isn't a huge deal.

It appears the express C++ version is around 100 to 200 megs. That downloaded just fine last night. I had originally thought I had to get the trail VS, which is a couple gigs. So I'm golden with VS now.

It took me a couple minutes to find preprocessor starting at pull down project --> uTasker properties --> configuration properties --> c/c++ --> preprocessor. I then saw this line "WIN32;_WINDOWS;_LPC23XX;ETHEREAL" which includes the _LPC23XX that I was looking to confirm. So I'm golden.

I changed the simulation IP to 10.10.10.3. Here's my ping attempt.

Code: [Select]
C:\>ping 10.10.10.3

Pinging 10.10.10.3 with 32 bytes of data:

Request timed out.
Request timed out.
Request timed out.
Request timed out.

Ping statistics for 10.10.10.3:
    Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),

C:\>ipconfig

Windows IP Configuration


Ethernet adapter Local Area Connection:

        Connection-specific DNS Suffix  . :
        IP Address. . . . . . . . . . . . : 10.10.10.10
        Subnet Mask . . . . . . . . . . . : 255.255.255.0
        Default Gateway . . . . . . . . . : 10.10.10.111

Also I set the simulation to look at my eth card that is used for my normal ether net activity. Here's my application.c.

Code: [Select]
static const NETWORK_PARAMETERS network_default = {
    (AUTO_NEGOTIATE /*| FULL_DUPLEX*/ | RX_FLOW_CONTROL),                // {42} usNetworkOptions - see driver.h for other possibilities
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},                                // ucOurMAC - when no other value can be read from parameters this will be used
    { 10, 10, 10, 3 },                                                  // ucOurIP - our default IP address
    { 255, 255, 255, 0 },                                                // ucNetMask - Our default network mask
    { 10, 10, 10, 1 },                                                  // ucDefGW - Our default gateway
    { 10, 10, 10, 111 },                                                  // ucDNS_server - Our default DNS server
};

I ran out of time, I might guess that that firewall is blocking traffic. I see the red an green lights on the simulation blink. Also I see it notes IP 10.10.10.3, so it appears it compiled in the new IP. Perhaps I have to assign a MAC to the simulation. Typically when my firewall has an issue, it will pop up a message inquiring if it should block or allow the traffic. I ran out of time this morning, so I'm a little blind about what the issue might be.

Any words of wisdom about this ping thing?
Title: Re: MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on February 19, 2010, 03:00:59 AM
Turns out my software firewall was blocking the ping ICMP data. It also appears that I have to disable the firewall to allow port 80 to pass through. Seems my PC is set to not operate as a gateway, and that type of traffic is blocked.

Now my problem is with the web page. I can get that orange 404, and I've got what appears to be a successful list of comments from the Copy_all.bat file. However, the simulation is still serving the 404 pages. I'd tried this with crtl, alt and shift reload, to flush the cache. No luck. Well it's off to bed tonight. I'm sure tomorrow with be filled with more delights. From what I've seen of this software, it's great.

Here's a snippet from my copy sequence.

Code: [Select]
drwxr-xr-x 1 502 502 0 Jan 03 2010 dir1
-rw-r--r-- 1 502 502 2219 Jan 00 1980 bmenu.htm
-rw-r--r-- 1 502 502 1146 Jan 00 1980 CTFT.htm
-rw-r--r-- 1 502 502 1689 Jan 00 1980 jstats.htm
-rw-r--r-- 1 502 502 2600 Jan 00 1980 dlan.htm
-rw-r--r-- 1 502 502 2007 Jan 00 1980 fback.jpg
-rw-r--r-- 1 502 502 3077 Jan 00 1980 HI_O.htm
-rw-r--r-- 1 502 502 2339 Jan 00 1980 kserial.htm
-rw-r--r-- 1 502 502 2365 Jan 00 1980 madmin.htm
-rw-r--r-- 1 502 502 1269 Jan 00 1980 ndynamic.htm
-rw-r--r-- 1 502 502 1723 Jan 00 1980 ohelp.htm
-rw-r--r-- 1 502 502 1534 Jan 00 1980 pemailse
-rw-r--r-- 1 502 502 30335 Jan 00 1980 hboard.jpg
-rw-r--r-- 1 502 502 2498 Jan 00 1980 2logo.gif
-rw-r--r-- 1 502 502 2603 Jan 00 1980 6_0menu.HTM
-rw-r--r-- 1 502 502 1114 Jan 00 1980 7LCD.htm
-rw-r--r-- 1 502 502 2600 Jan 00 1980 8lan.htm
-rw-r--r-- 1 502 502 2007 Jan 00 1980 alogo.jpg
-rw-r--r-- 1 502 502 2984 Jan 00 1980 CI_O.htm
-rw-r--r-- 1 502 502 1687 Jan 00 1980 estats.htm
-rw-r--r-- 1 502 502 2340 Jan 00 1980 fserial.htm
-rw-r--r-- 1 502 502 2268 Jan 00 1980 hadmin.htm
-rw-r--r-- 1 502 502 1338 Jan 00 1980 imultabl
-rw-r--r-- 1 502 502 1584 Jan 00 1980 jhelp.htm
-rw-r--r-- 1 502 502 1548 Jan 00 1980 kemailse
-rw-r--r-- 1 502 502 0 Jan 03 2010 imultabl
-rw-r--r-- 1 502 502 1338 Jan 00 1980 imultabl
-rw-r--r-- 1 502 502 1548 Jan 00 1980 kemailse
-rw-r--r-- 1 502 502 1338 Jan 00 1980 imultabl
-rw-r--r-- 1 502 502 1548 Jan 00 1980 kemailse
226 OK.
ftp: 1460 bytes received in 0.39Seconds 3.74Kbytes/sec.
ftp> quit
221 Bye

C:\uTaskerV1.4_LPC\Applications\uTaskerV1.4\WebPages\WebPagesLPC23xx\WebPagesDemo>
Title: Re: MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on February 19, 2010, 03:45:47 AM
Hi

I see your problem. The project is using a simulated SD card (define SDCARD_SUPPORT in config.h) and the defines FTP_UTFAT and HTTP_UTFAT are also active.
This means that any data copied via FTP is going to the SD card into the root directory.
When the web server is serving data it is looking for it relative to its root directory HTTP_ROOT              "dir1" on the SD card.

This means that there needs to be a directory called "dir1" and a start page called DEFAULT_HTTP_FILE      "index.htm" in that directory or else it reports a 404 error.

What you are seeing via FTP are all the files that have been copied to the simulated SD card. This doesn't match the tutorial so will be rather confusing.


Therefore I would do the following:
- either disable SDCARD_SUPPORT
or
- disable HTTP_UTFAT and FTP_UTFAT

The second will allow FTP and the HTTP servers to work with the uFileSystem in internal FLASH - as the tutorial describes. The SD card support will still be there so you can test that either using a virtual UART connection or with a TELNET connection. You will see that the files that you copied will still be there...

The SD card stuff is new (check out the patches at http://www.utasker.com/forum/index.php?topic=792.0) and confuses the tutorial if enabled, but it is good fun to test with the simulator and, once you are feeling comfortable with its workings, can be used to serve huge web side content from!!

Regards

Mark

P.S. The utFAT is described in http://www.utasker.com/docs/uTasker/uTasker_utFAT.PDF

Title: Re: MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on February 19, 2010, 12:21:46 PM
You hit that right on the head. I disabled the SD card and off it went. I finished the tutorial. I changed Build_LPC23XX.bat to include this line SET PATH=%PATH%;C:/gccfd/yagarto/bin which matches the yagarto gcc install I got from the default Olimex install. Compiled just fine and I was off to the races. I'm currently experiencing some mild power supply issues. Perhaps a ground loop with the USB and Ethernet or something like that. I'm currently powering this off the 5V ARM-USB-OCD device. I let someone use my bench supply, and I plan to pick that up this evening. With luck I'll have that power supply straightened out and I'll be back in business.

One thing that struck me as odd. I made a brief attempt at the GLCD thing. I defined SUPPORT_GLCD which failed with an error message. I then commented out CGLCD_GLCD_MODE and defined NOKIA_GLCD_MODE. Here's my application.c snippet.

Code: [Select]
//#define SUPPORT_LCD 

blah

#define SUPPORT_GLCD                                                   // enable the task for interfacing to a graphical LCD
#if defined SUPPORT_GLCD
    #define BIG_PIXEL                                                    // display double size in the simulator
  //#define OLED_GLCD_MODE                                               // use an OLED in GLCD compatible mode
  //#define TFT_GLCD_MODE                                                // use a TFT in GLCD compatible mode
    #define NOKIA_GLCD_MODE                                              // use Nokia 6100 LCD in compatible mode
    //#define CGLCD_GLCD_MODE                                              // use colour LCD in GLCD compatible mode

I compiled with the simulator compile process, and got this error message.

Code: [Select]
LPC23XX_ports.cpp
Linking...
GLCD.obj : error LNK2001: unresolved external symbol _CollectCommand
.\Debug/uTaskerV1-4.exe : fatal error LNK1120: 1 unresolved externals
Creating browse information file...
Microsoft Browse Information Maintenance Utility Version 9.00.30729
Copyright (C) Microsoft Corporation. All rights reserved.
Build log was saved at "file://c:\uTaskerV1.4_LPC\Applications\uTaskerV1.4\Simulator\Debug\BuildLog.htm"
uTasker - 2 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

I took a quick look at uTaskerLCD.PDF, and at least on a quick scan, nothing special jumped out at me. The build log basically tells me it built a bunch of stuff. Perhaps I need to define something. Not sure at this point. I ran out of time while looking for where this GLCD.obj object is being created. I see TFT.c and LCD.c, but no GLCD.c. Should I have a file like that?
Title: Re: MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on February 19, 2010, 12:55:48 PM
Hi

The GLCD problem looks like a strange thing with the new Visual Studio version(s). The missing routine is coming from the LCD simulator and it means that VS hasn't recompiled this file.

If you command a re-build (or clean) rather than just a build it will force it to recompile all files in the project and afterward it should work.

Regards

Mark
Title: Re: MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on February 20, 2010, 02:40:51 AM
Works great. I had to clean both the debug build, and the gnu build. I now see exactly the same thing on the LCD as I do in the simulation. Looks good.

With some luck, I'll be able to start the I2C tutorials on Sunday.
Title: Re: MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on February 24, 2010, 12:15:54 PM
Now that I've wondered through the initial demo, I'm starting to play with GLCD stuff such that I can get live data out of the device, then eventually I can get I2C data out of the device.

I'm trying to follow the GLCD code, but I'm having trouble. I think I should find the demo code in application_lcd.h. On the LCD screen I see some the text "tasker glcd" and it's only found in this header file. Sounds good, however, the section is grey and it won't let me add a break point. I believe it's gray because it requires an OLED define. I didn't define that because I don't have an OLED display. So this running demo code has to be somewhere else. When I look up and down this file, it's basically all grey. Indicating that the demo code is coming from a different file. By searching for NOKIA_GLCD_MODE I think I see the code in the LCDSim.cpp file.

To me it seems like there is probably a define some where that I should uncomment to make it run a different chunk of code. I don't think I should be modifying the LCDSim code. I tried creating a define for HANDLE_LCD_MESSAGES such that it would run the code under application_lcd.h, but no dice.

Any thoughts on how to get a chunk of LCD code where I can add or modify strings of data?
Title: Re: MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on February 24, 2010, 01:55:56 PM
Hi

All code to do with the GLCD demo is in application_lcd.h. I wouldn't always trust the VS display of defined code.

The way that it works is:
1) When the GLCD is completely initialised the code handles the event E_LCD_INITIALISED. In the demo this writes some text "Welcome to the" + "uTasker GLCD demo!" + "Starting..." [if this is appearing on the display of the simulator or the real target this will certainly be taking place].
2) Since an ACK was requested when the last text has been displayed the second event is E_LCD_READY.
This starts a 1s timer and its event, E_NEXT_PIC, starts the state-machine which continuously displays different pictures and then shapes, and finally scrolling fonts.

In order to use the LCD for other work simply do the following:

1) Remove the code in E_LCD_INITIALISED so that the demo is not started.
2) React to E_LCD_INITIALISED as you prefer - eg. to display your logo or your own welcome text.
3) Either use the ACK method to send further data or else simply send new text as you want to - in this case ensure that the LCD task's input queue is large enough to hold as much text as you send to it during the text processing and LCD writing (the LCDs are sometimes a bit slow to write to - although the NOKIA is quite fast and doesn't get polled). The task's input queue length is defined in TaskConfig.h.
In some cases a mixture of writing at any time and waiting for acks may be useful, but that depends on the application. (The idea of the ACK is that it allows a minimum LCD task queue since a new command/picture/text can be sent only after the LCD task acknowledges that the previous command has been fully completed).

With a small amount of practice you should find working with the LCD quite easy and flexible.

Regards

Mark
Title: Re: MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on February 25, 2010, 02:23:49 AM
What do you know, even though it's grey, I can add break points to that section. Also when I change it, the text on the screen changes. Seems like I'm back up and running. That should keep me occupied for a bit. Thanks.

Title: Re: AIS226DS SPI evaluation on LPC2378-STK
Post by: kb1gtt on March 07, 2010, 03:40:08 PM
I think it's time to start my next step. In this case, I'm looking to get data out of a chip using utasker's SPI capabilities, then display a number on the lpc2378stk LCD.

I have changed the plan some from what I mentioned above. I was looking to evaluated the MOD_SMB380 accelerometer from Olimex. I now have a better accelerometer in the works. So I guess I'll change my plan to work with that one. This new board is being assembled from a fellow that works at Sparkfun. Sparkfun tech support suggested him, and he been great to work with while making this breakout board. I believe he'll put these boards up for sale when they are done, so I'll put in a plug for him, if anyone is interested. He's posting the schematics and such, they can be found here.

http://www.aamicron.com/_jh_aamicron_proto_v10.html

It uses the AIS226DS from STmicro. Here's a link to it's data sheet.

http://www.st.com/stonline/products/literature/ds/15164/ais226ds.pdf

The AIS chip is currently set at evaluation status by STmicro, and is up for normal release in Q1 of 2010. ST was kind enough to send me samples for development purposes. It's a 14 bit .25mg/bit resolution 2 and 6 g scale SPI digital 2 axis accelerometer. This break out board is designed to work with Olimex's SPI bus on the Uext connector. However, it is also being setup such that it can be bread-boarded or other. It's a fairly flexible layout.

I looked over the flash tutorial, and I read the other thread where seulater was working with a 2378 and SPI. I don't have a flash device to experiment with, but with luck will have the AIS board in about a month perhaps less. Now that it's time for me to hurry up and wait, I figured it's time to start drafting code to read data from the AIS chip via SPI. I've already played with the LCD, so I feel confident I'll be in good shape for displaying this info once I get it out of the chip.

Are there any suggested SPI starting points that might be nicer than others? Perhaps there are already generic SPI read / write commands available that I'm not familiar with. From the PDF's I was thinking of copying parts of the SPI boot-loader, modifying them to get the right packet structure for the AIS chip. However, it feels like I might overlook something and wipe out the program. Perhaps there is an easier starting point.
Title: Re: MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on March 07, 2010, 06:33:13 PM
Hi

There is no generic SPI interface due to the fact that SPI use is generally of quite a low level nature and varies greatly between devices connected.

The best thing to do is the take an SPI FLASH interface (eg. spi_flash_lpc_atmel.h) and use the same HW accesses for your interface. The NXP SPI has an 8 buffer FIFO which enables copying up to 8 data bytes to the output and also reading up to 8 receive bytes. Generally it will be necessary to identify when tx and rx has completed - eg.         while (SSP0SR & SSP_BSY) {};                                    // wait for transfer to complete
and the rest is simply reading and writing the data register SSP0DR.

I don't think that the LPC23xx supports DMA on the SPIs.

Regards

Mark

Title: Re: MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on May 18, 2010, 03:59:05 AM
I've got the proto board on hand now and I'm trying to get back into this SPI eval thing. The SPI device  is attached to UEXT connector, and I had the LPC board displaying custom text via application_lcd.h's E_LCD_INITIALISED if statement.

I seem to be having some trouble figuring out this compiler. For example, in application_lcd.h, if I try to make the grey go away by commenting out the #if and matching #endif statements for this LCD section that includes code I know is being compiled, it will format correctly with green and blue, ect. However it won't compile. I get lots of syntax errors, and misc junk.

So I leave the define, statement, and the grey, and chock it to ignorance about why this is happening.

Then I copy most of spi_flash_lpc_atmel.h into applicaton_lcd.h below the if E_LCD_INITIALISED statement. Theory being that I can cut it down to something simple. My first goal is to simply read the status reg out of the AIS226 chip. I believe that's the same as the datasheet's noted STATUS_REG (0x27) which should read 0000. After a bit of chopping, I see SPI_FLASH_Danger which appears to be a first check before trying SPI stuff. I see it's defined in LPC23XX.c, however spi_flash_lpc_atmel.h file doesn't have an #include statement in the code. So I guess there must be some compiler config file that's allowing it to resolve when it's called in spi_flash_lpc_atmel.h. Another indicator that I don't understand how this compiler gets to point B. I tried to add an include file in my code just before it's called, but that really blew up. Again another indicator that I'm ignorant about this compile process.

So I try it another way. I copied spi_flash_lpc_atmel.h to spi_flash_lpc_AIS226.h in the same dir. Then started hacking out #define options I don't need. When I #include spi_flash_lpc_atmel.h in application_lcd.h, it compiles fine, but when I change that #include to spi_flash_lpc_AIS226.h, it produces a large pile of errors. It would appear that when I stripped out the define stuff, I took something important. It also looks like I can't declare things correctly. Line 5 is the first non-comment in the spi_flash_lpc_AIS226.h file, and looks like this.
Code: [Select]
static unsigned char fnCheckAIS226(void);I get this error.
Code: [Select]
c:\utaskerv1.4_lpc\hardware\lpc23xx\spi_flash_lpc_ais226.h(5) : error C2143: syntax error : missing ';' before 'type'It would appear to me that when it was behind the #define statement before, that changed the compile process, such that it could compile. However, I removed the #define's so it's broken.

So I should ask if using an #include statement in application_lcd.h is an appropriate method, or should I be calling fnSPI_command_AIS226 from spi_flash_lpc_AIS226.h a different way? If calling it that way is an OK theory of operation, how do I fix this syntax error?
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on May 18, 2010, 12:57:10 PM
Hi

I wouldn't recommend working in the header files. It is possible but it is easy to make a mistake. You need to be aware that these files are usually divided into sections and each section is linked in at a certain part of the main code (eg. application.c) - reminder: this technique is used to improved readability at the c file level (when the low level stuff is not of main interest) and avoids a rather large C file with many functions which make it hard to follow.

Some parts of the 'embedded' header files are included as standard code (like sub-routines) but others are 'inserted' into case statements. If you insert new code in the wrong section it may be being inserted into the middle of a case statement in the C-file and so even the simplest lines of code will result in syntax errors.

In your case, I don't see any reason to work in the header files so I would add a new file to the project and do all work there - call any subroutines from application.c if that makes sense - also add event handling etc. there. If you want to make it more modular (best as second step since first steps adding code to an existing task is easier) you can later add a new task of your own to do this dedicated work - handling its own timers and events as required.

Regards

Mark
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on May 19, 2010, 02:08:59 AM
I was working in the header, because I know I can get the LCD to update based on what is put in that section of code. I'm familiar with why headers are use, that's not the area where I'm ignorant about the compiler. I also understand #include or #define statements can be used to make pieces of code viewable or not viewable when compiling.

I'm more than willing to move my code to application.c, but I don't know how to write something there that will update the LCD from that location. Hmmm, perhaps fnDoLCD_text in application_lcd.h can be called from application.c to display text on the screen from the SPI device? So I create an infinite loop at the end of application.c to make my main loop?  I tried this at the end of application.c.
Code: [Select]
#define _CAN_INIT_CODE
    #include "can_tests.h"                                               // CAN initialiation code and transmission routine
#undef _CAN_INIT_CODE

if (1) {
// text_pos.usY = 45;
// 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, "application");
}
Ug, why does that produce a syntax error? If I comment out the if and the }, it compiles just fine.

I also tried it with our the loop attempt, and with only the four lines to update the LCD. That also produced several syntax errors.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on May 20, 2010, 09:11:59 PM
Hi

By placing the code at this location (I think at the end of the file) it is not within a function (or the task) so will result in a syntax error.

Note also that a while(1) {} should not be used in a task. Instead the task can be set to polling mode [uTaskerStateChange(OWN_TASK, UTASKER_GO);] and will be continuously called to achieve the same effect.

You can call the LCD interface routines from any code since they are global functions.

Regards

Mark


Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on May 21, 2010, 03:20:37 AM
I'm learning a bit more.

utasker.c appears to indicate that a task table is setup, and that fnApplication from application.c is one of these tasks that is run often. I think I can call an application_LCD.h function(s) from with in the fnApplication function. However my attempt is currently flopping. Here's my attempt to make this function call.
Code: [Select]
#define _PORT_NMI_CHECK                                                  // {53}
    #include "Port_Interrupts.h"                                         // port interrupt timer interrupt event handling - ranges
#undef _PORT_NMI_CHECK

fnDoLCD_com_text(TASK_LCD, "test", 4);
And here's the flop error.
Code: [Select]
Compiling...
application.c
c:\utaskerv1.4_lpc\applications\utaskerv1.4\application.c(799) : warning C4013: 'fnDoLCD_com_text' undefined; assuming extern returning int
I suspect that TASK_LCD is incorrect in this location, I was trying different things to see if it would compile. I think it's trying to declare itself at this line, and assumes it's something that it's not. I called it similar to how it's called a couple lines lower in application.c. I don't see any extra #includes or anything like that for those function calls. So I'm a bit confused about what I'm doing wrong.

Also am I on the right trail about calling this function from this area in application.c, and expecting to get some text to display on the screen?
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on May 21, 2010, 01:28:24 PM
Hi

The position of this code is basically correct (it will in fact cause the execution of your function each time that the application task is executed - you many not want it on every execution but this can be controlled using a state variable for its use - for example).

I think that your problem is however that you are using an LCD command rather than a GLCD command. fnDoLCD_com_text() is not for use with the GLCD (as on your board) and so its library is missing (and corresponding defines). fnDoLCD_text(&text_pos, "Starting..."); is an example of the GLCD text writing code.

Note also that sending a command to the GLCD as soon as the application task starts will also not work correctly because the application task first schedules the LCD task (note that the actual task is called LCD for both LCD and GLCD) and the GLCD task then configures the physical GLCD, which can take a few tens or hundreds if ms. When the initialisation is complete it send the event E_LCD_INITIALISED (the event handling code is then in 'hidden'  application_lcd.h), after which use is possible.

It may be easiest to copy the code segments from application_lcd.h to application.c so that you have a better overview (?).
Tip - probably the best place to start is in this code:

             if (E_LCD_INITIALISED == ucInputMessage[0]) {

This is the code that handles the event informing that the GLCD is ready. If you comment out the content and insert your own there instead it will allow you to start writing to the display without the demo application starting.


Regards

Mark
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on May 22, 2010, 03:00:01 AM
Thanks for pointing out the GLCD thing. I think I'm much closer to getting this to work.

A while back I modified if (E_LCD_INITIALISED == ucInputMessage[0]) { to show a custom splash screen, I also modified else if (E_LCD_READY == ucInputMessage[0]) { to include another small chunk of text, which I believe indicates it's initialized and working normal. Right now my key problem is that I'm not able to correctly initialize the struct in application.c Closest I've been able to get this struct setup is at the top of fnApplication, I've tried it closer to my code lower down the page, but it failed to compile.

Code: [Select]
extern void fnApplication(TTASKTABLE *ptrTaskTable)
{
//#include "config.h"
//#include "application_lcd.h"                                             // {46} LCD tests
typedef struct stGLCD_TEXT_POSITION {
unsigned char  ucMode;
unsigned short usX;
unsigned short usY;
unsigned char  ucFont;
//} GLCD_TEXT_POSITION;
} text_pos;

Lower in that function, this is how I have it drafted.
Code: [Select]
#define _PORT_NMI_CHECK                                                  // {53}
    #include "Port_Interrupts.h"                                         // port interrupt timer interrupt event handling - ranges
#undef _PORT_NMI_CHECK

//8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
//8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
//8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
//8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
//8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888

//    GLCD_TEXT_POSITION text_pos;// = {PAINT_LIGHT, 2, 0, FONT_NINE_DOT};
if (E_LCD_READY == ucInputMessage[0]) {
//typedef struct stGLCD_TEXT_POSITION {
// unsigned char  ucMode;
// unsigned short usX;
// unsigned short usY;
// unsigned char  ucFont;
//} text_pos;

text_pos.ucMode = PAINT_LIGHT;
text_pos.usX = 2;
text_pos.usY = 45;
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, "Starting...");
}
}

extern void fnSetDefaultNetwork(NETWORK_PARAMETERS *ptrNetPars)
You can see the declaration of text_pos is currently commented out in this location, I've tried putting it at the beginning of this file, at the beginning of the function, and some other places. Where it currently resides, is the only place I can get it to compile without generating syntax errors. However I get these lines, so it appears I'm not declaring it correctly.
Code: [Select]
c:\utaskerv1.4_lpc\applications\utaskerv1.4\application.c(816) : error C2143: syntax error : missing ';' before '.'
c:\utaskerv1.4_lpc\applications\utaskerv1.4\application.c(817) : error C2275: 'text_pos' : illegal use of this type as an expression
        c:\utaskerv1.4_lpc\applications\utaskerv1.4\application.c(517) : see declaration of 'text_pos'
I've also tried GLCD_TEXT_POSITION like how it was done in application_lcd.h. However, these attempts flopped. Right now and the most common way it flops is with a message very similar to those syntax messages.

There's apparently something I don't understand about the syntax formating. I think it's getting closer, but I'm still snagged on something.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on May 24, 2010, 08:32:27 PM
Hi

GLCD_TEXT_POSITION is defined in glcd.h.

As long as this is linked, which should always be the case via config.h, you shouldn't need to add an equivalent such typedef in any of the files. Just make sure that any new code is not before the include of config.h.

Regards

Mark

Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on May 25, 2010, 12:23:30 PM
I had done several tests that I felt I had correctly removed. Basically learning curve attempts that I then commented out. So I copied that old dir to a new name, and started over. At this point, I've changed some defines in config.h, change the splash screen and initialized screen in application_lcd.h and added this new code to applicaiton.c. I also made a backup copy of the basic config for my board and activated the LCD, so I can get back to a copy I haven't beat to bloody heck.

I found the same error message, but then I moved GLCD_TEXT_POSITION line into the if statement, and all is happy now. I don't know why that might have been the case, I don't see why it wouldn't be able to be stated one line higher in the code, but I guess it can't be done that way. I then found what appears to be some kind of conflict with fnDoLCD_text in both the initialized application_LCD.h code and my application.c code. So I commented out the initialized code in application_LCD.h.

Now that I'm running the LCD from applicaiton.c instead of the .h files, I should be good to try SPI com's. 
So the next step is to copy spi_flash_lpc_atmel.h, get it included while working in application.c then modify it for access to my proto board.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on May 26, 2010, 12:34:35 AM
I'm getting more syntax errors that I don't understand. Here's the current compile problem.
Code: [Select]
Compiling...
application.c
c:\utaskerv1.4_lpc\applications\utaskerv1.4\spi_acc_lpc_ais226.h(57) : error C2143: syntax error : missing ';' before 'type'
c:\utaskerv1.4_lpc\applications\utaskerv1.4\spi_acc_lpc_ais226.h(63) : error C2065: 'SPI_FLASH_Danger' : undeclared identifier
c:\utaskerv1.4_lpc\applications\utaskerv1.4\spi_acc_lpc_ais226.h(63) : error C2109: subscript requires array or pointer type
c:\utaskerv1.4_lpc\applications\utaskerv1.4\spi_acc_lpc_ais226.h(65) : error C2065: 'SPI_FLASH_Danger' : undeclared identifier
c:\utaskerv1.4_lpc\applications\utaskerv1.4\spi_acc_lpc_ais226.h(65) : error C2109: subscript requires array or pointer type
c:\utaskerv1.4_lpc\applications\utaskerv1.4\spi_acc_lpc_ais226.h(67) : warning C4013: 'fnSPI_command' undefined; assuming extern returning int
c:\utaskerv1.4_lpc\applications\utaskerv1.4\spi_acc_lpc_ais226.h(74) : error C2065: 'ucCommand' : undeclared identifier
c:\utaskerv1.4_lpc\applications\utaskerv1.4\spi_acc_lpc_ais226.h(91) : error C2065: 'SPI_FLASH_Danger' : undeclared identifier
c:\utaskerv1.4_lpc\applications\utaskerv1.4\spi_acc_lpc_ais226.h(91) : error C2109: subscript requires array or pointer type
c:\utaskerv1.4_lpc\applications\utaskerv1.4\spi_acc_lpc_ais226.h(94) : error C2065: 'READ_MANUFACTURER_ID' : undeclared identifier
c:\utaskerv1.4_lpc\applications\utaskerv1.4\spi_acc_lpc_ais226.h(94) : error C2051: case expression not constant
c:\utaskerv1.4_lpc\applications\utaskerv1.4\spi_acc_lpc_ais226.h(98) : error C2065: 'ucTxCount' : undeclared identifier
c:\utaskerv1.4_lpc\applications\utaskerv1.4\spi_acc_lpc_ais226.h(101) : error C2065: 'ucCommand' : undeclared identifier
c:\utaskerv1.4_lpc\applications\utaskerv1.4\spi_acc_lpc_ais226.h(102) : error C2065: 'ucTxCount' : undeclared identifier
c:\utaskerv1.4_lpc\applications\utaskerv1.4\spi_acc_lpc_ais226.h(105) : error C2065: 'ucTxCount' : undeclared identifier
c:\utaskerv1.4_lpc\applications\utaskerv1.4\application.c(797) : error C2143: syntax error : missing ')' before 'constant'
c:\utaskerv1.4_lpc\applications\utaskerv1.4\application.c(797) : error C2143: syntax error : missing '{' before 'constant'
c:\utaskerv1.4_lpc\applications\utaskerv1.4\application.c(797) : error C2059: syntax error : '<Unknown>'
c:\utaskerv1.4_lpc\applications\utaskerv1.4\application.c(797) : error C2059: syntax error : ')'
c:\utaskerv1.4_lpc\applications\utaskerv1.4\application.c(800) : error C2059: syntax error : 'if'
c:\utaskerv1.4_lpc\applications\utaskerv1.4\application.c(810) : error C2059: syntax error : '}'
Creating browse information file...
I copied C:\uTaskerV1.4_LPC\Hardware\LPC23XX\spi_flash_lpc_atmel.h and put it under C:\uTaskerV1.4_LPC\Applications\uTaskerV1.4\spi_acc_lpc_AIS226.h such that it was in the include path, and I could get it to actually include. By leaving it in the original directory, the compiler complained it didn't exist.

I added this to the config.h file
Code: [Select]
#define SPI_AIS226and this is the part I have added to application.c under the fnApplication function.
Code: [Select]
#define _PORT_NMI_CHECK                                                  // {53}
    #include "Port_Interrupts.h"                                         // port interrupt timer interrupt event handling - ranges
#undef _PORT_NMI_CHECK
//8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
//8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
//#if defined SPI_INTERFACE
#if defined  SPI_AIS226
#include "spi_acc_lpc_AIS226.h"                                         // port interrupt timer interrupt event handling - ranges
#endif
fnSPI_AIS226_command(READ_STATUS_REGISTER); // read busy status register
    fnSPI_AIS226_command(READ_MANUFACTURER_ID); // read MFG register
    //while (SSP0SR & SSP_BSY) {};                                    // wait for transfer to complete
if (E_LCD_READY == ucInputMessage[0]) {
GLCD_TEXT_POSITION text_pos;// = {PAINT_LIGHT, 2, 0, FONT_NINE_DOT};
text_pos.ucMode = PAINT_LIGHT;
text_pos.usX = 2;
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, "application.c sais hellow");
}
}

extern void fnSetDefaultNetwork(NETWORK_PARAMETERS *ptrNetPars)
Here's a snippet from spi_acc_lpc_ais226.h starting at line 51.
Code: [Select]
#define CONTINUOUS_ARRAY_READ    0xe8


// SPI AIS226 hardware interface
//
//#ifdef SPI_AIS226
static void fnSPI_AIS226_command(unsigned char ucCommand)
{
    #define ulChipSelectLine CS0_LINE  //po6 moso / mosi?
    #define iChipSelect 0
    unsigned char ucTxCount = 3;

    if (SPI_FLASH_Danger[iChipSelect] != 0) {                            // check whether the chip is ready to work, if not wait
        volatile unsigned char ucStatus;
        SPI_FLASH_Danger[iChipSelect] = 0;                               // device will no longer be busy after continuing
        do {
            fnSPI_command(READ_STATUS_REGISTER); // read busy status register
        } while (!(ucStatus & STATUS_READY));                            // until no longer busy
    }
I then hit F7 and get the errors noted on the top of this post. I've tried build clean, just in case, but no dice. I'm baffled about what the syntax issue is. I renamed the functions to make them unique because I found that the compiler "go to declaration" option was bringing me to a different piece of code than what I expected. Getting SPI_FLASH_Danger to include is something I can worry about after this basically compiles.

When in spi_acc_lpc_ais226.h and I right click the fnSPI_AIS226_command function, then "go to definition", I get an error message that notes it's not defined. So I believe there must be a syntax error relative to including this file. However the compiler found it, and produced error messages. It appears that application.c worked OK relative to the include, it also complained about the syntax, not that it couldn't find the fnSPI_AIS226_command function. So I believe that's being found OK. Line 798 in application.c is this line.
Code: [Select]
fnSPI_AIS226_command(READ_STATUS_REGISTER); // read busy status registerI'm not sure what the syntax issues is, or how to get this to compile correctly.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on May 26, 2010, 01:00:28 AM
Hi

The file \Hardware\LPC23XX\spi_flash_lpc_atmel.h is the SPI driver to the uFileSystem. This file acts as the Hardware Abstraction Layer between the standard part of the SPI FLASH part and the physical chip.
It is also included in the main HW driver LPC23XX.c because it shares some variables and its subroutines are called from there.

This means that it not possible to put thus code within application.c.

Since the driver that you are adding is for something else there is no advantage of using one of the SPI FLASH drivers directly. What you need to do is add your own code, which can be bases on the same commands.
For example:

..
    CS_CLR_PORT = ulChipSelectLine;                        // assert SS low before starting
    SSPDR_X = ucCommand;                                                 // send command
...
    case CONTINUOUS_ARRAY_READ:                                          // this is a legacy command for compatibility between B and D-devices
        SSPDR_X = (unsigned char)(ulPageNumberOffset >> 16);
        SSPDR_X = (unsigned char)(ulPageNumberOffset >> 8);
        SSPDR_X = (unsigned char)(ulPageNumberOffset);
        SSPDR_X = 0xff;                                                  // 4 dummy bytes needed before the device returns data
        SSPDR_X = 0xff;
        SSPDR_X = 0xff;
        SSPDR_X = 0xff;
...
        while (SSPSR_X & (SSP_BSY | SSP_RNE)) {                          // wait for transfer to complete and clear rx buffer
            volatile unsigned long ulDummy = SSPDR_X;
        } 
...
    CS_SET_PORT = ulChipSelectLine;
...


This extract is first sending a single byte (command) to the device that has been selected by the asserted CS line. Then some additional parameters are sent. It shows the use of the 8 byte deep FIFO in the LPC23XX since it is only waiting for the SPI transmission to complete at the end of the sequence, after which it negates the CS line once the transfer has completed.

In your new driver you can use the same commands and techniques to send commands and sequences to your chip and to read data back from your chip. There is probably no advantage in inserting the SPI FLASH driver code as it is.

I suggest first choosing a simple task like writing and reading a byte (or simple sequence) as appropriate for your SPI based device. Then simply add new code to do this in application.c (within the initialisation part so that it is executed only once). Once it is behaving correctly you can add additional sequences as required and possibly add a new *.c file containing such sub-routines to be used by general application code.

Note also that the SPI interface has to be initialised - This is done in static void fnConfigSPIFileSystem(unsigned char ucSpeed) in LPC23XX.c but is conditional on the SPI based uFileSystem. You can simply copy this routine locally for your own use.

Regards

Mark
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on May 26, 2010, 11:36:11 AM
Things are moving along nicely now. I have code that I think is almost working and it compiles. I'm doing things a bit more low level than I was doing it before. I'm currently testing it piece by piece. The first piece is to make sure I can assert PO.6 SSEL1 low and high. I see the simulation noted it's was an input. I also found fnConfigSPIFileSystem in LPC23xx.C. It appears I needed to change the CSO line to PO.6 so I modified this line in app_hw_lpc23xx.h.
Code: [Select]
#define CS0_LINE            PORT0_BIT6                                  // CS0 line used when SPI FLASH is enabled
I then copied and modified the apparent setup script like this.
Code: [Select]
POWER_UP(PCSSP_X);                                                   // {10} power up the SSP used
CONFIGURE_SPI_PINS();
CONFIGURE_CS_LINES();
SSPCR1_X = 0;                                                        // ensure disabled (master mode)
SSPCPSR_X = 2;                                                       // set clock prescaler (even prescale 2..254)
SSPCR0_X = (FRS_FREESCALE_SPI | DSS_8_BIT | (0 << SSP_SCR_SHIFT)); // set exact frequency and mode
SSPCR1_X = SSP_SSE;                                                  // enable
Now the simulation notes P0.6 is an output, and it's typically high. Also when I run this command
Code: [Select]
CS_CLR_PORT = PORT0_BIT6;// assert CS low before startingIt changes to low instead of high. So things appear to be moving along nicely. Then I had to go to work.

While I'm posting, is there a way to dim the LCD display? I'm using the 5V supply from my Olimex ARM-USB_OCD programming device. It appears to work fairly good, but it also appears my PC's USB port keeps blinking power. After a while it will reset. I suspect the PC is having trouble providing enough power and backs it down from time to time. Perhaps letting a chip cool down somewhere. If I can decrease the power draw from the LCD, I think that will make this work more reliably. If I can't decrease the power by dimming the display, I can connect it to an external supply, but that's kind of big and clunky, and it would be nice and compact if I can keep using the OCD device.

Thanks for the help mark, you've been a great help.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on May 26, 2010, 12:26:03 PM
Hi

When powering via USB the limit is 100mA before the device is enumerated and afterward (depending on mode) up to 500mA can be drawn.
If the 500mA limit is being reached the USB supply will start limiting the current.

To reduce LCD back-light consumption PWM can be used. However there is no PWM driver for the LPC23XX - there is one for the LPC2101..LPC2103 but this is not compatible with the LPC23XX as far as I know. Also adding a serial resistor in the LCD back-light 5V path will reduce its brightness.

Regards

Mark
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on May 27, 2010, 11:44:01 AM
The problem is that the ARM-USB-OCD device produces 5V/200mA, my meter claims it's using 204mA. So I've got a noisy supply for sure, and the fact that it works at all shows that the programmer MFG didn't push the spec to the absolute min.

Right now, I can assert the SPI pin high and low after doing the above noted setup. So that's looking good. I can also get the below code to compile.
Code: [Select]
CS_CLR_PORT = CS0_LINE;// assert CS low before starting 0001111 containing 00111010
SSPDR_X = 0x8f;//AIS226 PDF pg 18 SPI read bit 8 = 1, pg 21 "who am I" read only at 0001111 containing 00111010
while (SSPSR_X & (SSP_BSY | SSP_RNE)) {                          // wait for transfer to complete and clear rx buffer
volatile unsigned long ulDummy = SSPDR_X;                                     
}
CS_SET_PORT = CS0_LINE;//CS0_LINE;//ulChipSelectLine; // assert CS high end of trans
I believe that code should send 0x8f via SPI, then receive one byte which should contain 0x3A However, I don't know how to get that unsigned long to display on the LCD and I'm not sure I have this buffers and such correct. So what I receive in the unsigned long might be buggered in some manner. Perhaps it might say 8F3A, I'm not exactly sure. Is there a hex2bin until or similar that will let me see raw hex or raw binary?

So I changed gears for a minute and tried the LED PWM thing. I can make that LED PWM pin go low with this line.
Code: [Select]
PINSEL3 |=  1<<21;The simulation window claims that pin is set for PWM. I suspect the screen went blank because the PWM is 0% duty for some reason. So I first wanted to look at PCONP to see if PWM was turned on. I set a break point and tried to figure out how to poke registers to see what's going on inside, but I couldn't figure out how to see whats going on on PCONP or any other register for that matter. Can I see the internal registers in the simulation after a break point?
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on May 27, 2010, 11:53:53 AM
Hi

To display processor registers in the simulator follow the example at the bottom of page 5 of the following document:

http://www.utasker.com/docs/Coldfire/uTaskerM5282.PDF

Regards

Mark

Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on May 27, 2010, 10:51:29 PM
Now if utasker wasn't already cool enough, you had to go and put tricks like that in it. Simply drag and drop to the simulator when the simulator is paused, and you can see about any thing you want. Nice. I can't wait to try it out.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on May 28, 2010, 11:40:01 AM
I believe I'm having some trouble pausing the simulator. Right now when I select, then drag the text ucLPC23xx.ucSCM from LPC23XX.h, I get a circle with a line through it, indicating that this type of drag and drop isn't allowed by windows. I tried inserting a break point in the code then dragging and dropping, I also tried hitting the pause (Break All) button, but no dice.  I didn't see a pause command in the simulator pull downs.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on May 28, 2010, 12:03:42 PM
Hi

You need to pause the VS debugger and not the simulator itself - this automatically pauses the simulator and then the Watch Window will work.

Regards

Mark
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on May 29, 2010, 10:40:24 AM
I see it now, I hadn't noticed that when I ran the simulator, the debugger popped up a watch window. I was thinking the watch window was the simulator. I see it now and I can look at these nitty gritties.

Thanks for the help.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on May 29, 2010, 01:26:46 PM
I'm now looking at the registers and I think I found what you meant by there isn't a hardware driver for the 23XX chip. It appears it isn't defined in the LPC23XX.h or simLPC23XX.h. So I changed simLPC23XX.h to be like this.
Code: [Select]
unsigned long TER;
unsigned long PWM1MR; // ADDED BY JAH
unsigned long PWM1PCR; // added by jah
} LPC23XX_UART;
And LPC23XX.h looks like this.
Code: [Select]
#define U1TER                            *(volatile unsigned long*)(UART_BLOCK_1 + 0x30) // Transmit Enable Register
#define PWM1MR *(unsigned long*)(UART_BLOCK_1 + 0x8048) // PWM mod by JAH
#define PWM1PCR *(unsigned long*)(UART_BLOCK_1 + 0x804C) // PWM mod by JAH
Then I added this to application.c
Code: [Select]
PINSEL3 |=  1<<21;
PCONP |= 1<<6;
PCLKSEL0 |= 1<<12;
PWM1MR = 0xffffffff;
When I pause the debugger, ucLPC23xx.ucSimUart1 shows me both the PWM1MR and PWM1PCR as 0x00000000. That makes sense for PWM1PCR because it's default at boot is 0, and I appears utasker isn't changing that to something different. However, I wrote F's to PWM1MR so I expected to read back at a different value. Can I add registers like I have to the simulation, or is there other work that has to happen behind the scenes. Perhaps I need to add something to simLPC23XX.c?
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on August 12, 2010, 11:13:08 AM
I stepped away from this for a bit and I'm getting back into it again. I'm still having trouble figuring out how to see contents of registers that do not appear to be in LCP23XX.h. I'm looking to set the PWM 1.6 for the LCD such that I can dim the display on my LPC2378-STK dev board. Registers like PCONP and PINSEL3 work great. I wrote to them, and verified they work via the watch window. Also the simulator notes that pin is now PWM1.6, so it's looking great. However, I need to work with the below noted registers and I don't know how to set or verify bits of those registers.

From the UM10211 data sheet, I'm looking at PWM1TCR found on page 549, and PWM1MCR found on 550. The don't appear to be in the LPC23XX.h file, I've also looked under the timer section, and no dice. They start at 0xE001 8000 and it appears that UART_BLOCK_1 is 0xE001 0000, so I added the lines noted in the above thread to the watch window. This did not work, it would appear they are not supported in the dirver.c file. Right now it would appear that the PWM for this chip is not currently developed and falls outside of the memory range managed by the simulator. I may be wrong with that. My next attempt was to make it display on the physical LCD. However, I'm having some trouble getting that to work as well.

Is there a recommended way to view the contents of registers like PWM1TCR - 0xE001 8004 and PWM1MR - 0xE001 8048 ?
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on August 12, 2010, 09:25:56 PM
Hi

Any modules not yet build into the simulator cannot be accessed when simulating. This doesn't mean that they can not be used on the target though - just put code accessing the registers in a region using:
#ifndef _WINDOWS
...
#endif


I have nevertheless recently added PWM module support for the LPC23XX/LPC24XX. I will send you the latest LPC23XX.c and LPC23XX.h files by email as reference. For the simulator to be able to use them there are also changes to simLPC23XX.h also sent as reference.

I have been using this to control the contrast of an LCD (the same technique as required to control the display back-light intensity. Therefore here are a few details that should help you integrate it into your project.

1) The interface uses the timer interface (in fact the LPC21XX also supports PWM on the general purpose timers and use this interface already - it thus remains very similar, even if it uses a different module for the work):

static void fnSetContrast(void)
{
    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_1 | PWM_OUTPUT_PORT_1);         // use PWM channel 1 on port 1 output location
    timer_setup.timer_value = TIMER_US_DELAY(TIMER_FREQUENCY_VALUE(10000));// 10000 Hz contrast frequency
    timer_setup.pwm_value   = _PWM_PERCENT(temp_pars->temp_parameters.ucGLCDContrastPWM, timer_setup.timer_value); // contrast as PWM value
    fnConfigureInterrupt((void *)&timer_setup);                          // configure PWM output for contrast control
}


Note that PWM1 must be used with the LPC23XX since it doesn't have PWM0 (as the LPC24XX does).
TIMER_PWM_1 | PWM_OUTPUT_PORT_1 means that PWM channel 1 is used (there are 6 but they all operate from a single timer counter) and its output is to be connected on port 1. The PWM outputs can usually be mapped to several possible pins on different ports. [This is in fact P1.18 on the LPC23xx]]

2) The define SUPPORT_PWM_MODULE should be set to enable the driver code. The interface then powers up the PWM module, configures the pin, sets the timer base frequency (10kHz in the example above) and sets the PWM value (set using either _PWM_PERCENT() or _PWM_TENTH_PERCENT())

3) The PWM module can be used for generating more complex signals but the interface just sets standard PWM as it is.

4) The simulator will allow checking the code (stepping), the register values and the port pins but it won't generate any signals.

Good luck

Regards

Mark
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on August 14, 2010, 12:20:22 PM
Great, and again you were very helpful.

It currently shows PWM in the watch window, and allows me to verify the different bits. Lots of things look good, but I'm still not getting the PWM I expect. Perhaps my issue is that I don't fully understand the PWM_PERCENT call.

I used the the original LPC23XX.c and LPC23XX.h files then added the PWM sections of the files you sent along separately. I used the newer simLPC23XX.h with out compile problems. It now compiles and appears to work.

I don't know exactly how to use the temp_parameters.ucGLCDContrastPWM noted above, so I changed that line to be like this.
Code: [Select]
timer_setup.pwm_value   = _PWM_PERCENT(50,timer_setup.timer_value);//temp_pars->temp_parameters.ucGLCDContrastPWM, timer_setup.timer_value); // contrast as PWM valueI was aiming for a hard coded 50% PWM. I then called this function from in application.c under fnApplication. I'm probably calling this far more often than is required.

From the watch window I see

      PWMIR   0x00000000   unsigned long
      PWMTCR   0x00000009   unsigned long
      PWMTC   0x00000000   unsigned long
      PWMPR   0x00000000   unsigned long
      PWMPC   0x00000000   unsigned long
      PWMMCR   0x00000002   unsigned long
      PWMMR0   0x00000708   unsigned long
      PWMMR1   0x00000000   unsigned long
      PWMMR2   0x00000000   unsigned long
      PWMMR3   0x00000000   unsigned long
      PWMCCR   0x00000000   unsigned long
      PWMCR0   0x00000000   unsigned long
      PWMCR1   0x00000000   unsigned long
      PWMCR2   0x00000000   unsigned long
      PWMCR3   0x00000000   unsigned long
      ulRes0   0x00000000   unsigned long
      PWMMR4   0x00000000   unsigned long
      PWMMR5   0x00000000   unsigned long
      PWMMR6   0x00000000   unsigned long
      PWMPCR   0x00004000   unsigned long
      PWMLER   0x00000041   unsigned long
+      ulRes1   0x0054ad5c   unsigned long [7]
      PWMCTCR   0x00000000   unsigned long

These appear to me like channel 6 is set to PWM output, I believe that PWMMR6 indicates it's set to a 0% duty. This makes since as the LCD is dark, which leads me to believe that I'm not using PWM_PERCENT correctly. I've tried a handful of values large, small, hex, ect. PWMMR6 keeps coming back as 0. Perhaps I buggered something when I modified the LPC23XX files, I'm not sure. I searched for PWM_PERCENT to try and verify what it's expecting, but I didn't manage to find it. Just a define and a couple places where it's called.

Am I using PWM_PERCENT correctly? Is PWMMR indicating the duty?
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on August 14, 2010, 02:17:32 PM
Hi

The use of PWM_PERCENT(pwm, frequency) is with a first value between 0 and 100% and then the base frequency.
Eg. to set 65% PWM (65% '1', 35% '0') running at 5kHz this would be

PWM_PERCENT(65, TIMER_US_DELAY(TIMER_FREQUENCY_VALUE(5000)));

Note that the frequency value also uses its own macros since the idea is to allow the compiler to directly calculate the values to be written to the register when values are already known as fixed numbers (when variables are involved the calculation is performed at run time instead) - more details about frequency at the end.

In the example, the frequency value is directly timer_setup.timer_value since this is already the calculated frequency.

Since I only tested PWM1 - channel 1 I am not sure that there may be a problem when using channel 6. Therefore I tried simulating to see what happens in this case.

PWM1MR0 is the base frequency. In your case 0x00000708, which means that the timer is running at 10'000 Hz (assuming PCLK/4 and 72MHz PLL).
The PWMMR6 register controls channel 6 PWM so this should be set with the percentage value, but I also got the value 0x00000000. The value was in fact being written but to a location 3 long words after the PWMMR6 register. Presumably this would cause the PWM output to generate 0% duty cycle - i.e. output always '0'.

The source of the error is due to the fact that the PWM channel 1..3 and PWM channel 4..6 registers are not contiguous in the register memory. Therefore the following code is used to set a pointer to the register to be written:

        if (ulChannel >= 4) {
            ptrMatchRegister += (PWM1MR4_ADD - PWM1MR1_ADD);
        }


This code is however not correct for channels 4..6. It sets the pointer to PWM1MR4 but doesn't take into account that the channel is 3 higher than this reference. The correction (which I tested with all 6 channels) is:
        if (ulChannel >= 4) {
            ptrMatchRegister = (PWM1MR4_ADD - 3);
        }


This now sets the value 0x378 to PWM1MR6 (50% case) which is the value expected. As long as the pin is correctly set up I would expect it to then work correctly.
I the case of Port 1 which should be P1.26. In this case of port 2 this should be P2.5. There is no output for port 3.
The simulator shows P1.26 in the port 1 case as PWM1.6 so this looks good.

Regards

Mark



Note about frequency
===============

TIMER_US_DELAY(TIMER_FREQUENCY_VALUE(5000))

This uses two macros.
TIMER_FREQUENCY_VALUE(5000) converts the frequency into a period (i.e. 1/f) in us. In this case 200us is the period of 5kHz.
TIMER_US_DELAY(200) is then the value required in the timer match register to achieve a match after 200us and subsequently an output frequency of 5kHz/2 when the match causes an output pin to be toggled. This value is HW dependent and also processor frequency dependent. In the case of the LPC23XX running at 72MHz PLL and PCLK/4 clocking the timer module the match value is 0x708.

The match value used by PWM is a percentage of the period and so its calculation also requires the period to be known. That is why the period value is also passed to the PWM macro. A 50% duty cycle if therefore simply the period value/2, which can then also directly be written to the HW register.


Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on August 14, 2010, 06:40:33 PM
The correction (which I tested with all 6 channels) is:
Great and thanks. This now works both in the simulator/watch window, as well as the proto board. Here are what I measured for PWM and current draw.

when at 100%, it measures 203ma, and is very bright
when at     0%, it measures 159ma, and is very dim
when at    20% it measures 160ma, and is very dim
when at   30%, it measures 172ma, and is reasonably bright
when at   35%, it measures 196ma, and is very bright, but not as much as

So the range for LCD appears to be around 25% to 35%, with 30% being good enough for indoor applications.

I guess it's now time to get back to the SPI stuff.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on August 14, 2010, 08:43:33 PM
Hi

I would try also with lower switching rates (100..200Hz should be OK for back-light since it should not be detected as flicker by the eye).

I would expect the brightness to be more linear with PWM and it may be that the faster switching rate is causing problems with the semiconductor switch - it may not be saturating correctly (?).

I used 10kHz for my contrast control since I was filtering the PWM signal to a DC control value with an RC and 10kHz requires a smaller C - for direct switching 10kHz is possibly a bit fast.

Regards

Mark
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on August 14, 2010, 11:04:53 PM
Great, the 200hz works well, and 100hz has flicker. At 30% PWM it still draws 172ma. I haven't tried the other PWM rates yet.

I was digging into the LCD PWM in an attempt to resolve a problem I'm seeing. Unfortunately dimming the LCD didn't fix the problem, so perhaps this problem is sourced from somewhere else. The problem happens every 6.5 seconds when the proto board appears to reboot. The screen goes blank briefly and it appears to start the code again.

I had assumed this was due to the my supply being limited to 200ma via ARM-USB-OCD programmer device, and that the device may have been smart enough to notice I was drawing 203 ma when the LCD was on. Now I'm a fair bit under the max rating, and I'm still seeing this issue. I'm beginning to wonder if it might be a watch dog issue.

Are there any suggested areas where I should look to figure out why it might be rebooting every 6.5 seconds or so? My multimeter is telling me the min voltage drops to 4.77v while the normal voltage reads as 4.80v. So I don't think it's a power supply issue at this point.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on August 16, 2010, 03:19:11 AM
So it appears that great things happen to those that that can read....

I just re-found the uTaskerV1.4_user_guide.pdf section 5 about creating your own task. I followed those great instructions then copied my code into this new task and the rebooting issue is no longer. I'm currently learning more about how tasks are handled, and following the examples, ect.

Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on August 19, 2010, 11:21:07 AM
I just ran into a bit of a bugger. Flash magic was pointing to programming uTaskerV1.4.hex which  hasn't  been modified since the 15th. It appears that for some reason Visual Studio changed, and is compiling uTaskerBM.hex. I guess I'll have to go look over my configs. This BM version doesn't run on my proto board. However the simulator is working just fine. Could this be part of the recently modified simLPC23XX.h?

I see config.h is still set to #define OLIMEX_LPC2378_STK. A quick look down the project properties didn't cause anything to jump out at me. I'm not sure why the hex file changed, and it's time again to head out for the bump and grind. So until later this evening, I'll ponder what is going on.

Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on August 20, 2010, 11:01:37 AM
I'm posting this partly to share, partly to remind myself if I'm looking for a reminder about what happened on the above broken hex issue. The issue was sourced when I created my own task. The make file didn't include my-first-task.c and was producing a cs-make error, even though the output window reported success while compiling. I noticed the error message failed relative to and undefined my-first-task.

So I changed make_uTaskerV1.4_GNU_LPC23XX to read like this.
Code: [Select]
# All objects (Hardware, application, uTasker, stack)
#
OBJS = Build/my-first-task.o Build/application.o blah blah

# Application files
#
#added by jah
Build/my-first-task.o: ../my-first-task.c $(DEPENDS) ../application_lcd.h ../config.h
$(CC) $(C_FLAGS) $(INC) $(OPTS) ../my-first-task.c -o Build/my-first-task.o
#end added by jah

Build/application.o: ../application.c blah blah
It now again compiles the .hex file, and I'm back to debugging my code. Because it fails, but Visual Studio thinks is passed, you'll have to build clean each time you change the make file to get this to compile.

It might be handy to add a note in section 5 of the users guide about the make file.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on August 25, 2010, 03:17:47 AM
I think I may have found another memory mapping issue. I'm trying to use the UEXT connector on the LPC23478-stk. When I do this code
Code: [Select]
PINMODE0 |= PINMODE_PULLDOWN_6;I get this result in the watch window, also the real hardware doesn't seem strong enough to pull down the bit, so it would appear the pull down is not activated.
Code: [Select]
PINMODE0 0x00000000 unsigned long
PINMODE5 0x00003000 unsigned long
It appears it did those bits to the 5, not the 0 mode.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on August 25, 2010, 02:59:26 PM
Hi

Thanks. Yes, there is an error in the following struct in simLPC23XX.h

typedef struct stLPC23XX_PIN_CON
{
unsigned long PINSEL0;
unsigned long PINSEL1;
unsigned long PINSEL2;
unsigned long PINSEL3;
unsigned long PINSEL4;
unsigned long PINSEL5;
unsigned long PINSEL6;
unsigned long PINSEL7;
unsigned long PINSEL8;
unsigned long PINSEL9;
unsigned long PINSEL10;
unsigned long PINSEL11;                                                  // only LPC247X
unsigned long ulRes0[4];
unsigned long PINMODE0;
unsigned long PINMODE1;
unsigned long PINMODE2;
unsigned long PINMODE3;
unsigned long PINMODE4;
unsigned long PINMODE5;
unsigned long PINMODE6;
unsigned long PINMODE7;
unsigned long PINMODE8;
unsigned long PINMODE9;
} LPC23XX_PIN_CON;


Here PINSEL11 and ulRes0[4] have been added so that the PINMODEx registers are at correct locations.

This will mean that the simulator correctly displays the register content. It won't however make any difference on the target since the register addresses are correct - you may need to verify the pull-down strength that you are expecting since internal ones tend to be quite weak (say 25k or so).

Regards

Mark
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on August 26, 2010, 01:36:49 AM
Great the simulator is working and now several tests match what I'm seeing on the target and the simulator. Having it working helped me debug my code that simply lists bits to the screen, which allowed me to verify that bits are internally being set correctly.

I'm not seeing what I expect to see on the target pins. I have verified several bits via LCD. However, I can't seem to get P0.6 SSEL1, to go low. It has a 33K external pull up to 3.3v. I've tried enabling/disabling internal pulls, I've tried it as SSEL and GPIO. I don't appear to have enough drive to change the voltage at all. I would say I most likely don't have something configured correctly, so here's some code snippets. From "myfirsttask" which runs 2 seconds after boot, then each second after,

Code: [Select]
fnConfigSPI_jah();
#define WHO_AM_I 0x0F //memory location 0x0F should read as 0x3A
CS_CLR_PORT = CS0_LINE;  //ulChipSelectLine; // assert SS low before starting
SSPDR_X = WHO_AM_I; //request this reg
while (SSPSR_X & (SSP_BSY | SSP_RNE)) { // wait for transfer to complete and clear rx buffer
     volatile unsigned long ulDummy = SSPDR_X;
}
//CS_SET_PORT = CS0_LINE;//ulChipSelectLine;
And from the included header file.
Code: [Select]
static void fnConfigSPI_jah(void)//unsigned char ucSpeed)
{
//power
    POWER_UP(PCSPI);                                                   // {10} power up the SSP used
//clock  PCLK_SEL0 select PCLK_SPI
//currently it's got a clock rate, I'll deal with specifics later.
//pin sel / mode
    CONFIGURE_SPI_PINS();//sel
    CONFIGURE_CS_LINES();//FIO0SET and FIO0DIR
//PINMODE0 |= PINMODE_NO_PULLS_6;//PINMODE_PULLDOWN_6;
//irq's

    SSPCR1_X = 0;                                                        // ensure disabled (master mode)
    SSPCPSR_X = 8;                                                       // set clock prescaler (even prescale 2..254)

//    switch (ucSpeed) {
//    case MAX_SPI:                                                        // set maximum possible SPI speed
        SSPCR0_X = (FRS_FREESCALE_SPI | DSS_8_BIT | (0 << SSP_SCR_SHIFT)); // set exact frequency and mode
//     break;

//    case SPI_2MEG:
//        SSPCR0_X = (FRS_FREESCALE_SPI | DSS_8_BIT | ((((SSP_CLOCK/2 + 2000000/2)/2000000) - 1) << SSP_SCR_SHIFT)); // set exact frequency and mode
//     break;

//    case SPI_SLAVE:
//     return;
//    }
    SSPCR1_X = SSP_SSE;                                                  // enable
}
Also from app_hw_lpc23xx.h I added to this command, such that PO_6 is SSEL. This command comes and goes with my testing/debugging.
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

Because I've commented out //CS_SET_PORT, I expect it to pull PO.6 low and keep it there. The simulator currently shows this a lower case p, and if I comment out the SSEL thing, it shows as a O, or 1 based which CS_SET_PORT I comment out. However, it just stays there at 3.3v, doesn't budge a bit, I don't see any bumps on the scope.

Are there any suggestions or pointers? When configured for SSEL, I might guess this is automatic, such that I can't drive it high or low manually. This would make since why I can't git it to go high or low. When configured as GPIO, I believe the direction is set correctly, but no dice.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on August 26, 2010, 11:22:05 AM
I noticed FIOSET and FIOCLR are both set. Perhaps this is where things get buggered... Here's a snap shot of my watch window, just after it ran the CS_CLR_PORT = CS0_LINE command.
Code: [Select]
- [0x0] {FIODIR=0x00600040 res1=0x00539f6c FIOMASK=0x00000000 ...} stLPC23XX_FAST_GPIO
FIODIR 0x00600040 unsigned long
+ res1 0x00539f6c unsigned long [3]
FIOMASK 0x00000000 unsigned long
FIOPIN 0xffdfffff unsigned long
FIOSET 0x00400042 unsigned long
FIOCLR 0x00000040 unsigned long
I notice FIOPIN is a 1. I also read that "Writing 0s has no effect" on FIOSET. Perhaps I have to write a 0 to this such that FIOCLR can drive it low? I'm a bit baffled about why this isn't working.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on August 29, 2010, 01:48:24 AM
So it would appear that under FIOSET when the datasheet notes, "Writing 0s has no effect." What they really mean is that writing a 1, will cause the port to be pulled high, and writing a 0 will cause the port to not be driven by the high side drive. Disconnecting the high side drive is a lot different than no effect. Once I cleared both the FIOSET and FIOCLR, I was free to control the port via FIO0PIN. Now it's off to debugging SPI clocking.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on August 29, 2010, 04:34:50 AM
The datasheet wants me to look at S0SPCCR for the SPI clock settings. The example code I'm looking at uses SSPCPSR_X to set the clock, but appears to be using SSP not SPI registers. It appears that SSP can be used for SPI and I'm not sure if this type of SSP/SPI can be used with my device or not. Is there a way to get the simulator and device to work with the dedicated SPI hardware?

Under LPC23XX.h I see this.

  #define RTC_BLOCK                      0xe0024000
  #define LEGACY_GPIO_BLOCK              0xe0028000
  #define PIN_CONNECT_BLOCK              0xe002c000

I would guess I can add #define S0SPCCR 0xE002000C, but I don't think I'd get it in the simulator. Can I add this to the simulator?

Or even better what about adding 0xE002 0000, then the +000C thing more like the normal practice in other parts of this code.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on August 29, 2010, 04:13:47 PM
Hi

The SPI registers are not included since only the SSP have been used to date.

To add these do the following:

1) In LPC23XX.h

  #define SPI_BLOCK_0                    ((unsigned char *)(&ucLPC23xx.ucSPI0)) (for simulator)
  #define SPI_BLOCK_0                    0xe0020000 (for target)


// SPI
//
#define S0SPCR                           *(unsigned long*)(SPI_BLOCK_0 + 0x00)              // SPI Control Register
#define S0SPSR                           *(volatile unsigned long*)(SPI_BLOCK_0 + 0x04)     // SPI Status Register (read-only)
#define S0SPDR                           *(volatile unsigned long*)(SPI_BLOCK_0 + 0x08)     // SPI Data Register
#define S0SPCCR                          *(unsigned long*)(SPI_BLOCK_0 + 0x0c)              // SPI Clock Counter Register
#define S0SPINT                          *(volatile unsigned long*)(SPI_BLOCK_0 + 0x1c)     // SPI Interrupt Flag Register


Here the register bits are not yet defined but at least their locations are.

2) In simLPC23XX.h

In the struct LPC23XX_PERIPH add
    LPC23XX_SPI         ucSPI0;

Add a new struct:

typedef struct stLPC23XX_SPI
{
unsigned long SPISPCR;
unsigned long SPISPSR;
unsigned long SPISPDR;
unsigned long SPISPCCR;
unsigned long ulRes0[3];
unsigned long SPISPINT;
} LPC23XX_SPI;



Now you should be able to use the registers for the target and also check their content in the simulator.

Regards

Mark
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on September 06, 2010, 01:10:49 PM
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.

Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on September 06, 2010, 03:11:12 PM
Hi

The SSP has a FIFO depth of 8. When writing, up to 8 bytes can be simply written as fast as possible and then the complete transmission must be waited for. For each transmitted byte you also get a reception byte, which is dummy and so needs to be discarded. When there is something in teh FIFO input each read of the data register removes one of the received bytes.

It is important which flags are to be waited on. These examples may help:

while (SSPSR_X & SSP_BSY) {};                                    // wait for transfer to complete
while (!(SSPSR_X & SSP_RNE)) {}                          // wait only if no reception ready
while (SSPSR_X & (SSP_BSY | SSP_RNE)) {                      // wait for transfer to complete and clear rx buffer


- Only read a reception byte when you known that it is available otherwise it will return nothing of interest and the expected byte will arrive later.
- Make sure that you read the correct number of bytes - one for each complete transmission - and discard the ones that of not of interest.

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.

In your while loop the reception data is being read many times while the complete transmission takes place. This will result in a large amount of 'empty' reads since there is no data ready, and occasionally a real reception byte in between. Once all transmission has taken place and all reception is ready you don't read again (this may miss the final byte). Instead you could loop on the complete transmission/receptions flags and then simply read the number of bytes from the data register (as long as less than 8 ).

Regards

Mark
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on September 06, 2010, 08:43:08 PM
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.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on September 07, 2010, 02:57:39 AM
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?
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on September 07, 2010, 11:23:45 AM
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.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on September 09, 2010, 10:02:39 PM
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.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on September 09, 2010, 11:16:55 PM
Hi

There are 2 possible buffer problems. I am not exactly sure how you are sending text to the display task but, if it is via the input queue just ensure that the input queue is large enough to receive all waiting messages (the queue length is defined for the task in the task configuration table).

The second possibility is that it is a problem with the SSP buffer which is 8 bytes deep. When you write multiple bytes up to 8 then it is simple since you just need to wait for them to be sent. If your want to write longer stings it is necessary to copy up to 8 bytes and after that always wait until a TX FIFO entry becomes free before writing more. If you compare the SPI FLASH driver code when it writes more that 8 bytes in total you will see how it is done.

Regards

Mark

Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on September 10, 2010, 11:06:40 AM
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.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on September 12, 2010, 05:14:04 PM
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.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on September 12, 2010, 09:49:52 PM
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.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on September 12, 2010, 11:56:09 PM
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.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on September 13, 2010, 10:36:26 AM
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.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on September 25, 2010, 01:09:19 AM
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.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on September 25, 2010, 02:04:42 AM
Hi

When simulating, the function sprintf_s() is being taken from VisualStudio's library. When compiling for your target this routine probably doesn't exist (it sounds like a secure function). Try using the standard sprintf() so that the cross compiler's library can supply it.

You may also need to add extra libraries too.

If you don't find a solution you can use the uTasker string functions for output conversion and save needing to add libraries and the potential of code-bloat due to them bringing in other unnecessary stuff with them. See http://www.utasker.com/docs/Code.html - Operating System | String Output and Conversion

Regards

Mark
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on September 25, 2010, 10:15:55 AM
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.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on September 26, 2010, 04:42:03 PM
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?
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on September 26, 2010, 06:04:09 PM
Hi

You will almost certainly need to link a GCC library containing the missing function (and possibly sub-routines to it).
I don't think that this is a compiler issue and also the math.h include is probably OK since the compiler would probably otherwise generate a warning as the function is not prototyped. It looks to be the liker not being able to link the function from a library (adding a prototype of a function via  header will satisfy the compiler but will not allow the linker to work if it can't locate it).

Here it suggests that the function asin() is built-in according to ISO C90 and only specifying -fno-builtin would stop it. Probably this is assuming that the GCC libraries are otherwise being actively linked into the project (?):
http://coen.boisestate.edu/smloo/ece332fall2007/niosdocumentation/gnu-tools/gcc/Other-Builtins.html#Other%20Builtins

See which libraries are included in you GCC version and try to identify where the asin() is situated and then explicitly link that library.

Regards

Mark
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on September 28, 2010, 11:35:56 AM
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.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on September 28, 2010, 01:17:08 PM
Hi

I have never used these libraries so don't have any tips at the moment on what needs to be done.

The libraries can be compiled in ARM or THUMB mode and there may be two versions depending on which is preferred. However ARM and Thumb mode can be mixed (as long as inter-working is defined when compiling) so, even if only one is available (and its build is not known) this shouldn't be a problem.

Good luck with your efforts to get the library linked...

regards

Mark

Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on September 29, 2010, 01:31:53 PM
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.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on November 30, 2010, 01:39:19 PM
I'm now trying to use the dynamic http stuff such that I can stream a bunch of data from the AIS226DS chip. I have been trying to follow the uTaskerV1.4_LPC2XXX.PDF and I'm at the part where I expect to browse to http://10.10.10.3 and get a 404 message. However Chrome reports this.

Error 102 (net::ERR_CONNECTION_REFUSED): Unknown error.

Firefox and IE note the page can't be displayed. When I browse to ftp://10.10.10.3 I get this.

favicon.ico   1150 B   5/1/09 1:00:00 AM

I have tried uploading the pages as noted in the pdf, but I can't get FTP to upload. I have tried LeechFTP, Explorer, and a variety of browsers. They will show it, but what I try to upload I get via leechftp, I get this log.

~ Connected to 10.10.10.3, waiting for response...
< 220 Welcome LPC23XX FTP.
> USER anonymous
< 331 Enter pass.
> PASS *****
< 230 Log OK.
> REST 1
< 500 What?.
> SYST
< 215 UNIX Type: L8
> PWD
< 257 "/"
~ Login completed.
> PORT 10,10,10,10,12,200
< 200 OK.
> TYPE A
< 200 OK.
> LIST
< 150 Data.
< LISTERROR: -r-xr-xr-x 1 502 502 1150 May 1 2009 favicon.ico
< 226 OK.
> NOOP
< 200 OK.
> NOOP
< 200 OK.
> MKD adf
< 500 What?.
> PORT 10,10,10,10,12,219
< 200 OK.
> TYPE A
< 200 OK.
> LIST
< 150 Data.
< LISTERROR: -r-xr-xr-x 1 502 502 1150 May 1 2009 favicon.ico
< 226 OK.

When I try to create a directory with Explorer, it produces a dialog that notes "500 What?".

I have disabled the local software firewall, and I have commented out HTTP_UTFAT and FTP_UTFAT I'm not sure why it doesn't produce the 404 page as expected, and I'm unsure why the FTP is giving me trouble. Are there any suggestions on how to get this web page stuff working?
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on November 30, 2010, 06:11:58 PM
Hi

If the HTTP connection is being refusing it sounds as though the HTTP server is not running - otherwise it should return the 404 error (this will work with any browser). I would check that the server is being correctly started (and has enough memory to start - it only needs a small amount from heap - about 70 bytes per session). With wireshark check what the answer to the TCP SYN on the TCP port 80 is - if it as a RST it means that there is no HTTP server listening on that port.

FTP in internal FLASH (without SD card utFAT) doesn't support directories so it is normal that you get a "500 WHAT" back when trying to create one. The same is true for any other non-supported command. A "
Code: [Select]
500 WHAT" is not usually a problem, it is just telling the client that the command is not understood (a "WHAT" is in fact a "WHAT??? - don't known what you mean...". The client then known that it can't command that but this doesn't stop further operation with commands that are supported.

It looks like your main problem is that the FTP client is trying to create a directory called "adf" and, since this is not allowed, it doesn't transfer any files.
With DOS FTP client simply connect and command "PUT file.htm 0.htm" to upload a local file called file.htm (replace with the file to be loaded) to the uFileSystem file 0.htm.
If you use the bat file in the web server directory it will automatically copy each web page using the DOS FTP cleint (just make sure that the fiel contains teh IP address that you are using). This has never failed as far as I know.

Regards

Mark
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on November 30, 2010, 09:52:24 PM
It appears I had a half crashed windows. Wireshark indicated I wasn't sending http traffic to the device IP. After the reboot, it now produces the expected 404. Even better when I transfer files it got about 15k of the file copied out of an expected 25k. Then it produced this message.

Unhandled exception at 0x004a3d13 in uTaskerV1-4.exe: 0xC0000005: Access violation writing location 0x00000000.

It brings me to line 346 of LPC23XXSIim.c. I think this means it ran out of memory. I'm not sure what memory might be small, or how to make an adjustment to it.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on November 30, 2010, 10:53:34 PM
Hi

You need to see what routine this is happening in (check the call stack window to see where it came from).
What is happeing (as the error messages says) is that something is trying to write using a NULL pointer. This may be due to memory getting overwritten or due to a pointer not being set to a memory block since a uMalloc() failed.

Regards

Mark
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on November 30, 2010, 11:49:17 PM
I feel a bit sheepish. I used the Copy_all.bat file and it copied just fine. When I copy the files, then use dir via FTP, it replies with just the first letter of the uploaded file. I would guess the upload process renames the files when they get there. When I copied via explorer, I had it copy both ftp.txt and ftp_del.txt which would both get renamed to f.txt. I believe that's the point where it lost its brains. I can get the stack info if you would like for diag purposes. I'm back up and running, and it would appear using the command line ftp is a reliable solution, so I'll go with it. At this point I should be able to start experimenting with getting a stream of data from the AIS226 chip.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on December 01, 2010, 12:01:12 AM
Hi

The uFileSystem is described here: http://www.utasker.com/docs/uTasker/uTaskerFileSystem_3.PDF

It is normal that the files are displayed with only their first letter or number. The utFAT allows directories, long names and compatibility with PCS - the uFileSystem is a simple file system but it is extremely fast in comparison and is adequate for a large amount of file storage and manipulation requirements in embeded projects. Once you have used it you will probably find that it is not that restrictive but easy to use - FAT based file systems will simply never be able to operate as fast as it can since it doesn't need to search for data of handle clusters.

Regards

Mark
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on December 01, 2010, 01:15:51 AM
That's quite interesting. I can live with those constraints and I'm happy to have those performance enhancements at my finger tips. Thanks for the informative PDF.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on December 03, 2010, 12:40:37 PM
I'm looking to add two things to this proto board. One is to get a stream of the SPI data into a comma delimited file via HTTP, the other is to display the data on a web page.

To get a 1kb file on the PC it appears that I'm best off using £H20 instead of £H10 and creating a if statement like this under webinterface.c.
Code: [Select]
#ifdef HTTP_DYNAMIC_CONTENT                                              // {5}
        case 'H':

blah blah blah

else if (*ptrBuffer == '2') {
Is that the intended place for me to add such an item, or should I add this somewhere else similar to how I added it somewhere else like with my_first_task.c? 

I seem to recall seeing something that described the characters used in HTML parsing. Something that give a brief description of what these characters are and do.
Code: [Select]
£sO1Does such a document exist? I see there are several designators like that s, and a look up chart would be kind of handy. I've read the dynamic content generation document.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on December 03, 2010, 01:21:04 PM
Hi

The file webInterface.c is a user application file and so additional dynamic generation segments can be aded here (as you have suggested).

The HTML control interface is described here: http://www.utasker.com/forum/index.php?topic=94.0

The actual control characters used are defined in config.h so they can be adjusted if necessary. The escape sequence length defaults to 4 characters but can be increased by defining WEB_ESCAPE_LEN in config.h (some projects prefer to use 5, but make sure that all tags in the HTML have the corresponding lengths).

Regards

Mark
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on December 05, 2010, 11:33:10 PM
I'm having some trouble getting my code to work under webinterface.c. originally I had the SPI comm routine(s) in spi_acc_lpc_AIS226_2.h and #included in my-first-task.c. When I use that same #include in webinterface.c I get complaints from the linker that it's defined twice.
Code: [Select]
Compiling...
webInterface.c
Linking...
webInterface.obj : error LNK2005: _fnSPI_AIS226 already defined in my-first-task.obj
I'm a bit ignorant about exactly how Vissual C++ will compile this part. It appears it will compile anything listed in the solution explorer.

I put spi_acc_lpc_AIS226_2.h next to spi_flash_lpc_stmicro.h in the solution explorer, and I tried to mimic similar programming techniques. I don't know why it keeps trying to define them twice, I might guess I'm doing something wrong with the .h file. It includes prototype(s), #defines, then the functions themselves. I don't know how to modify the compile process to make them show up as a file that is referenced by both my-first-task and the .h file. Are there any suggestions on how to fix it. I can provide additional information if required, but I don't know what pieces of information might be wanted for looking at. Are there any chunks of information I can provide to help diagnose this issue?
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on December 06, 2010, 01:23:58 PM
Hi

It looks as though you have code in your header file and the header file is being included in more that one C-file. You have to avoid the 'code' in the header from being defined more than once or else there will be multiple copies of it and so the linker error.

For example, use a define in the header file like the following around your code (in the header):

#if defined _INCLUDE_THIS_CODE
... code
...
#endif


The header can now be incluided by multiple C-files but the code is not activated unless the calling file defines _INCLUDE_THIS_CODE. Define this only in the (single) file that you want to include it in. Eg.

#defined _INCLUDE_THIS_CODE
    #include "spi_acc_lpc_AIS226_2.h"
#undef _INCLUDE_THIS_CODE // optional


Regards

Mark
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on December 07, 2010, 02:20:43 AM
I believe I see what your saying, but I'm not sure it's quite what I need. I tired a couple more attempts, but no dice yet. I think this will help show the problem. I have been trying several things like using static, vs extern, vs not specified. This is how it is now, and I think this may show the problem.

In my-first-task.c
Code: [Select]
#define _INCLUDE_AIS226
#include "../../hardware/LPC23XX/spi_acc_lpc_AIS226_2.h"  // AIS226 accelerometer
#undef _INCLUDE_AIS226

blah blah blah

y_now = (signed short)  fnSPI_AIS226(OUTY_L, SPI_READ, 0x00)
  + (signed short)((fnSPI_AIS226(OUTY_H, SPI_READ, 0x00) & HI_MASK) << 8);
In webinterface.c
Code: [Select]
#define _INCLUDE_AIS226
#include "../../hardware/LPC23XX/spi_acc_lpc_AIS226_2.h"  // AIS226 accelerometer
#undef _INCLUDE_AIS226

blah blah blah

y_now = (signed short)  fnSPI_AIS226(OUTY_L, SPI_READ, 0x00)
      + (signed short)((fnSPI_AIS226(OUTY_H, SPI_READ, 0x00) & HI_MASK) << 8);
In spi_acc_lpc_AIS226_2.h
Code: [Select]
#if defined _INCLUDE_AIS226 // include AIS chip
unsigned char fnSPI_AIS226(unsigned char cmd, unsigned char rw, unsigned char SPI_data){
unsigned long temp;
int temp2, null;

blah blah

return temp2;
}

#endif // stop including AIS chip
fnSPI_AIS226 is a function that sends 8 bits down the SPI and receives 8 bits from the SPI. Because I'm using it as my comm interface, I'm looking to call it from different c files as a kind of shared function. I tried using the #define and #undef to help limit the scope of when it's seen by the compiler, but it still complains "webInterface.obj : error LNK2005: _fnSPI_AIS226 already defined in my-first-task.obj"

I had expected that it would compile spi_acc_lpc_AIS226_2.h into an object file, as well as my-first-task.c and webinterface.c into their own object files. I expected my c file(s) would simply list a jump command in the object file and it would all come together during linking. But it appears it compiles a bit more literally. I understand that the #include will simply copy the specified file, replacing the include line when it's made into the object file. But I thought it would be a bit less literal than that. I was expecting it would copy just the jump command to the function, not the entire function.

I believe I would normally get around this by modifying my make file to specifically compile the .h file into the .o file, then I would make sure this .o file was a dependent of my-first-task and webinterface. It would then be included while linking and my functions would all pull together in the last compile step.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on December 07, 2010, 01:17:53 PM
Hi

I think that the include of the code is still taking place twice and so the linker will still complain.

Try the following in your header file:

Code: [Select]
#if defined _INCLUDE_AIS226 // include AIS chip
extern unsigned char fnSPI_AIS226(unsigned char cmd, unsigned char rw, unsigned char SPI_data){
unsigned long temp;
int temp2, null;

blah blah

return temp2;
}
#else
    extern unsigned char fnSPI_AIS226(unsigned char cmd, unsigned char rw, unsigned char SPI_data);
#endif // stop including AIS chip

In webinterface.c include as you have done (make sure that the include is not within a function otherwise it will have syntax errors)

In my-first-task.c (don't activate the code in the include):

Code: [Select]
#include "../../hardware/LPC23XX/spi_acc_lpc_AIS226_2.h"  // AIS226 accelerometer
Regards

Mark


Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on December 08, 2010, 01:12:34 AM
It works works spot on that way. I formated the string a bit and now I can process raw data via spread sheet, or other number crunching mechanisms.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on December 08, 2010, 04:43:30 AM
I'm having a bit of a problem when I run it on the target. I have a solid supply, or at least its solid at the board header. With a scope I measured both the 3.3v and 5v, neither appear to drop more than 10% even in short bursts, and both look very solid on the average, not noticeable ripple on the scope. A while back I had thought the problem was caused by slightly exceeding the power supply's limits, but it's now on a different supply that should be overly capable. When it fails, it locks up, the heartbeat LED stops blinking, ect. Most of the time it will come out of it by pressing the proto board's rest button, but not always. Sometimes I have to wait for 30 seconds or so and it self resets. Some times it runs for as little as 1 or 2 seconds, and it rarely lasts longer than 15 seconds.

I don't have much for external or extra devices attached to it. I have two SSR's that draw about 1.5ma each (pin spec is 4ma max), the AIS226 chip, then the typical eth and 232 wires. That's about it. I can't help but feel it has to be software related. I found an Older demo firmware titled uTaskerV1.3_Olimex_LPC2378-STK.hex it seems to work fine. Just blinks an LED.

I'm a bit baffled about how to figure out why it's locking up. I have the Olimex ARM-USB-OCD jtag device, so perhaps I can diagnose it with the jtag. Not sure. Any suggestions would be appreciated. I guess for now I'll keep playing with it in the simulator, but it would be nice to get real raw data.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on December 28, 2010, 12:24:50 PM
I've been working with the simulator, and I'm currently trying to get data in and out of my-first-task.c such that I can modify parameters in my-first-task.c via web browser. I think one of the better ways to do this is by passing messages from my case in webinterface.c. In my-first-task.c I have this section of code.

QUEUE_HANDLE PortIDInternal = ptrTaskTable->TaskID;
unsigned char ucInputMessage[MEDIUM_MESSAGE];

while (fnRead( PortIDInternal, ucInputMessage, HEADER_LENGTH)) {

On the first pass of that section, PortIDInternal is = 0, ucInputMessage has a bunch of junk in it, and HEADER_LENGTH = 4. In driver.c, when it tries to return from fnRead, it crashes with this message
Code: [Select]
Unhandled exception at 0x00000000 in uTaskerV1-4.exe: 0xC0000005: Access violation reading location 0x00000000.

I'm a bit baffled about what the problem could be. The return statement doesn't make a lot of sense to me. I expect that because it shouldn't have a message to read, it should return 0. Perhaps I'm doing something invalid with the HEADER_LENGTH?
"unhandled exception"
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on December 28, 2010, 03:00:11 PM
Hi

If PortIDInternal  is 0 it sounds as though there is no queue allocated to the task - this will result in an exception due to a null pointer as in your case.
Check the following entry in the task table:

{ "x marks my first task!!", fnMyFirstTask, NO_QUE,(DELAY_LIMIT)(5 * SEC), (DELAY_LIMIT)(2 * SEC),  UTASKER_STOP},

This is the simplest task without a queue.

To add a queue to the task add a queue length such as

{ "x marks my first task!!", fnMyFirstTask, SMALL_QUEUE,(DELAY_LIMIT)(5 * SEC), (DELAY_LIMIT)(2 * SEC),  UTASKER_STOP},

Regards

Mark

P.S. Sending a message to a task without a queue will not result in an error but the message will not be sent anywhere. This can also be seen from the return value to the queue write which will be 0.


Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on December 31, 2010, 11:25:19 PM
Spot on again. Thanks. I've got another one though.

I browse to http://10.10.10.3/5MulTable.htm?J1=60.254&J2=68.954 which causes fnHandleWeb to run my newly created case 'J'. Which twice calls fnWrite(INTERNAL_ROUTE, ucMessage, HEADER_LENGTH + ucLength+2); // pass the message to the destination task

Both times it runs, INTERNAL_ROUTE is 0x00 and HEADER_LENGTH + ucLength+2 is 0x000d. ucMessage looks like this the first time through.

(http://i324.photobucket.com/albums/k352/kb1gtt/handleweb1.png)

then the the second time through

(http://i324.photobucket.com/albums/k352/kb1gtt/handleweb2.png)

Then in my-frist-task.c I hit this line twice as expected.

while (fnRead( PortIDInternal, ucInputMessage, HEADER_LENGTH)) {
   ucLength = fnRead( PortIDInternal, ucInputMessage, ucInputMessage[MSG_CONTENT_LENGTH]);

When stopped on the ucLength line, ucInputMessage looks like this on the first pass,

(http://i324.photobucket.com/albums/k352/kb1gtt/mytask1.png)

then like this on the second pass.

(http://i324.photobucket.com/albums/k352/kb1gtt/mytask2.png)

It appears like the second pass is rolling a bit. I expect 'E' in ucInputMessage[3] not ucInputMessage[0], so it appears for some reason the second time through it rolled down by 3 places. Perhaps I have to clean up some variable or memory between passes, I don't know at this point. Is this something that might jump out? Hmmm, could HEADER_LENGTH + ucLength+2 be wrong, I tried my best to eye ball that, but I don't really know if it's completely right. It seems like on the second pass in my-first-task, it only writes 5 characters as well. I'm not seeing why the second pass isn't giving me the message I expecting.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on January 01, 2011, 12:24:42 PM
It appears I have fixed this. I changed case 'J' like this
Code: [Select]
ucMessage[ MSG_CONTENT_LENGTH ] = ucLength+2;
fnWrite(INTERNAL_ROUTE, ucMessage, HEADER_LENGTH + ucLength + 2); // pass the message to the destination task
Then my-first-task like this
Code: [Select]
while (fnRead( PortIDInternal, ucInputMessage, EADER_LENGTH)) {
ucLength = fnRead( PortIDInternal, ucInputMessage, cInputMessage[MSG_CONTENT_LENGTH]);
I'm not exactly sure why I need +2, instead of +1. I think it's because the example didn't need to copy the '/0', where I'm looking for that. With out it, I would read old junk data from prior usage.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on January 09, 2011, 10:53:19 PM
I'm have good success in creating a web page that allows me to configure embedded parameters via HTTP page. However I'm also trying to get a stream of binary data out of it. Right now myfirsttask runs about every .2 seconds producing new data on each pass. I'm looking to stream this data to a blah.csv file on my PC. In webinterface.c I can access the variables used by myfirsttask, which includes an instantaneous snap shot of the stream data at that point. However that data is only good for that instance. I need webinterface.c to wait until new data is ready, then send the data as its produced.

If the stream data is old and has already been sent, I currently return from webinterface.c with a length of 0. Then on the next pass if new data is available, I send it out via http. This seems to have nearly worked, except I'm wasting CPU cycles by polling with webinterface.c, and after I get two chunks of streamed data, txlength overflows and things go bad.

I've tried setting task E to suspended then in myfirsttask, I set it back to stop. I expected this to prevent the code in webinterface.c from running, however it keeps running. Which didn't work as I expected. So I wonder, am I using this correctly? Is there a way I can pause the http code until a new chunk of data is ready in myfirsttask? Perhaps I should be using passing messages but I couldn't figure out how to pass those from myfristtask to the function in webinterface.c.

I'm at a bit of a loss right now.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on January 10, 2011, 11:23:05 AM
Hmmm, Is fnInsertString a part of this task?

uTaskerStateChange(TASK_ETHERNET, UTASKER_SUSPENDED);

I seem to recall that this code can run from serial coms as well as Ethernet coms. Perhaps it's not stopping because it's not part of that task. I'm having a bit of trouble figuring out the included scope of TASK_ETHERNET.
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: mark on January 10, 2011, 09:48:18 PM
Hi

Take a look at SUPPORT_DELAY_WEB_SERVING. This can be used to delay responding until data is ready.
I never used it together with dynamic content insertion but I think that it is basically the soluton required in this case.

TCP and web handling are call-back functions from the Ethernet task - I wouldn't try suspending the Etheret task because it may result in lost Ethernet frames and probably won't help with delayed responses.

Regards

Mark
Title: Re: AIS226DS / MOD-SMB380 I2C evaluation on LPC2378-STK
Post by: kb1gtt on January 13, 2011, 11:02:56 AM
Is there a way to use return DELAY_SERVING; from fnInsertString? I seem to have that function working from from fhHandleWeb, but it jumps off in the weeds when I run it from fnInsertString. I found this thread http://www.utasker.com/forum/index.php?topic=94.msg381#msg381 which helps me understand this delay web page thing, but I haven't figured out how to use it several times to get each piece of data.