Author Topic: New Project with own Hardware  (Read 12933 times)

Offline Oellness

  • Newbie
  • *
  • Posts: 7
    • View Profile
New Project with own Hardware
« on: February 04, 2010, 01:46:15 PM »
Hello,

i'm want to start a new project which use my own hardware. So i copied the demo project files and renamed it.
I can run this copied demo project on a AT91SAM7X-EK Board without problems.

Now i want to port the project to my own hardware which is a "modified" AT91SAM7X-EK Board.

My HW has the following peripheral:
- DM9161 PHY connected to the same pins like the AT91SAM7X-EK
- Mono GLCD with 2 KS108 Controller
-- Data Bus at PA19...PA26
-- Enable at PA27
-- R/W at PA28
-- RS at PA29
-- RST at PB28

- 4 LEDs (active LOW) at PA04...PA07
- 6 Buttons at PA14, PB27, PB20...PB23
- 8 GPIO OUTs at PA02, PA03, PA08, PA09, PA15...PA18 to switch Relais
- 1 DS1307
- 1 I2C Multiplexer for Analog Inputs
- 1 PWM OUT at PB29/PWM2
- 5 Analog Inputs at AD3...AD7
- 1 USB

Now i tried to modify the config.h for my project. I change the following:
#if defined _HW_SAM7X
   #define TB_SAM7X
  //#define SAM7X_EVAL                                                   // evaluation board from ATMEL
  //#define OLIMEX_EX256                                                 // low cost evaluation board from Olimex
   #if defined (TB_SAM7X)
      #define TARGET_HW      "TB_SAM7X"
    #elif defined (SAM7X_EVAL)
        #define TARGET_HW       "AT91SAM7X-EK"
    #elif defined (OLIMEX_EX256)
        #define TARGET_HW       "SAM7X-EX256"
    #endif


and disabled MODBUS, Serial Interface, SD-Card support:
//#define USE_MODBUS_SLAVE                                                 // slave capability supported
//#define USE_MODBUS_MASTER                                                // master capabiity supported (either slave or master required)
//#define MODBUS_GATE_WAY_ROUTING                                          // configurable routing from slave gateways (requires master functionality)
//#define MODBUS_GATE_WAY_QUEUE                                            // support queuing of MODBUS transmissions - advisable for gateways
//  #define MODBUS_DELAYED_RESPONSE                           // allow slave parameter interface to delay request responses - for example to prepare latest data from external location
//  #define MAX_QUEUED_REQUEST_LENGTH    8                                 // longest request data length that needs to be saved when requests are delayed

//#define SERIAL_INTERFACE                                                 // enable serial interface driver

//#define SDCARD_SUPPORT                                                   // SD-card interface


I enabled the Mono GLCD with Samsung Controller:
#define SUPPORT_GLCD                                                   // enable the task for interfacing to a graphical LCD
#define _GLCD_SAMSUNG                                            // Samsung controller based display rather than Toshiba


Now in app_hw_sam7x.h i make these changes:

I have no SPI Flash so i disabled it and patch the LCD to my port pins:
//  #define SPI_FLASH_AT45DB321
#define DATA_LINES             (PA26 | PA25 | PA24 | PA23 | PA22 | PA21 | PA20 | PA19)
    #define GLCD_RST               PB28                                  // reset
    #define GLCD_RS                PA29                                  // GLCD Register Select
    #define GLCD_RW                PA28                                  // GLCD Read/Write
    #define GLCD_ENA               PA27                                  // GLCD Enable

    #define GLCD_CS0               PA12                                  // LCD Controller 0 Chip Select - 2 controller chips for 128 x 64
    #define GLCD_CS1               PA13                                  // LCD Controller 1 Chip Select

    #define SET_PULL_DOWNS()       
    #define REMOVE_PULL_DOWNS()   

    #define CONFIGURE_GLCD() \
        _CONFIG_DRIVE_PORT_OUTPUT_VALUE(A, ( GLCD_RS | GLCD_RW | GLCD_ENA | GLCD_CS0 | GLCD_CS1), GLCD_RW ); \
      _CONFIG_DRIVE_PORT_OUTPUT_VALUE(B, GLCD_RST, GLCD_RW ); \
        _CONFIG_PORT_INPUT(A, DATA_LINES);

    #define GLCD_DATAASOUTPUT()    _DRIVE_PORT_OUTPUT(A, DATA_LINES)
    #define GLCD_DATAASINPUT()     _FLOAT_PORT(A, DATA_LINES)

    #define GLCD_DATAOUT(data)     _WRITE_PORT_MASK(A, data, DATA_LINES)
    #define GLCD_DATAIN()          _READ_PORT_MASK(A, DATA_LINES)

    #define GLCD_RS_H()            _SETBITS(A, GLCD_RS)
    #define GLCD_RS_L()            _CLEARBITS(A, GLCD_RS)

    #define GLCD_RW_H()            _SETBITS(A, GLCD_RW)
    #define GLCD_RW_L()            _CLEARBITS(A, GLCD_RW)

    #define GLCD_CS0_H()           _SETBITS(A, GLCD_CS0)
    #define GLCD_CS0_L()           _CLEARBITS(A, GLCD_CS0)

    #define GLCD_CS1_H()           _SETBITS(A, GLCD_CS1)
    #define GLCD_CS1_L()           _CLEARBITS(A, GLCD_CS1)

    #define GLCD_DELAY_WRITE()                                       // no write delay since the data is stable for long enough at full speed
    #define GLCD_DELAY_READ()      GLCD_RW_H()                       // one extra operation to ensure set up time of read

    #define GLCD_RST_H()           _SETBITS(B, GLCD_RST)
    #define GLCD_RST_L()           _CLEARBITS(B, GLCD_RST)

    #define GLCD_ENA_H()           _SETBITS(A, GLCD_ENA)
    #define GLCD_ENA_L()           _CLEARBITS(A, GLCD_ENA)

    #define MAX_GLCD_WRITE_BURST   80                                // the maximum number of writes to the GLCD before the task yields

and defined my own HW:
#if defined (TB_SAM7X)
   #define SHIFT_PORT_TO_BYTE      4
    #define FIRST_USER_PORT         PA04
    #define DEMO_LED_1              (PA04 >> SHIFT_PORT_TO_BYTE)
    #define DEMO_LED_2              (PA05 >> SHIFT_PORT_TO_BYTE)
    #define DEMO_LED_3              (PA06 >> SHIFT_PORT_TO_BYTE)
    #define DEMO_LED_4              (PA07 >> SHIFT_PORT_TO_BYTE)
    #define DEMO_USER_PORTS         (PA04 | PA05 | PA06 | PA07)
    #define TEST_OUTPUT_LED         PA05

    #define BLINK_LED               PA04
    #define BLINK_LED_OUTPUT_STATE  PIO_ODSR_A
    #define BLINK_LED_CLR           PIO_CODR_A
    #define BLINK_LED_SET           PIO_SODR_A

    #define PHY_ADD_31              (PB04 | PB05 | PB06 | PB13 | PB14)   // {7}

    // DAVICON DM9161AE on ATMEL eval board
    // remove pullup on TEST input (MII ERXDV) so that device goes to normal mode
    // remove pullup on RMII input (MII ECOL) so that device uses MII mode
    // drive power down mode to '0'
    // drive PHY address to 0x1f (31)                                    // {7}
    #define DRIVE_PHY_OPTION_LINES() PIO_PUDR_B = (PB15 | PB16); PIO_PER_B = (PB18 | PHY_ADD_31); PIO_OER_B = (PB18 | PHY_ADD_31); PIO_CODR_B = PB18; \
                                     PIO_SODR_B = (PHY_ADD_31);          // {7}

    #define PHY_INTERRUPT           PB26
    #define PHY_IDENTIFIER          0x0181b8a0                           // DAVICON DM9161AE identifier
    #define PHY_MASK                0xfffffff0

    // SMTP settings
    #define SENDERS_EMAIL_ADDRESS             "AT91SAM7X-EK@uTasker.com" // fictional Email address of the board being used
    #define EMAIL_SUBJECT                     "AT91SAM7X-EK Test"        // Email subject
    #define EMAIL_CONTENT                     "Hallo!!\r\nThis is an email message from the AT91SAM7X-EK.\r\nI hope that you have received this test and have fun using the uTasker operating system with integrated TCP/IP stack.\r\r\nRegards your AT91SAM7X-EK!!";


I change also the Timer Test LEds and the Watchdog LED:
#define TIMER_TEST_LED_1            PA06
#define TIMER_TEST_LED_2            PA07

#define CONFIG_TIMER_TEST_LEDS()    PIO_SODR_A = (TIMER_TEST_LED_1 | TIMER_TEST_LED_2); PIO_OER_A = (TIMER_TEST_LED_1 | TIMER_TEST_LED_2); _SIM_PORTS
#define TIMER_TEST_LED_ON()         PIO_CODR_A = (TIMER_TEST_LED_1); _SIM_PORTS
#define TIMER_TEST_LED2_ON()        PIO_CODR_A = (TIMER_TEST_LED_2); _SIM_PORTS
#define TIMER_TEST_LED_OFF()        PIO_SODR_A = (TIMER_TEST_LED_1); _SIM_PORTS
#define TIMER_TEST_LED2_OFF()       PIO_SODR_A = (TIMER_TEST_LED_2); _SIM_PORTS

#ifdef USE_MAINTENANCE
    #define INIT_WATCHDOG_LED()                                          // we let the application configure all LEDs
#else
    #define INIT_WATCHDOG_LED()     _CONFIG_PORT_OUTPUT(A, BLINK_LED)    // {26}
#endif
#if defined SUPPORT_GLCD && defined NOKIA_GLCD_MODE && defined OLIMEX_EX256 // {32}
    #define TOGGLE_WATCHDOG_LED()
#else
    #define TOGGLE_WATCHDOG_LED()   _TOGGLE_PORT(A, BLINK_LED)           // {26} blink the LED, if set as output
#endif


At this time i thought that i can see something on my LCD or see a LED toggle.
But nothing happens....

Have i forgotten something???

Thanks for your help!!

Volker

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: New Project with own Hardware
« Reply #1 on: February 04, 2010, 01:51:09 PM »
Hi Volker

I would first try a minimum configuration (without Ethernet and LCD) and just with the Blink LED. Once this works add the next step, etc.

I would certainly leave the LCD integration until final step since it may cause the board to hang if it is not correct.

Regards

Mark

Offline Oellness

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: New Project with own Hardware
« Reply #2 on: February 05, 2010, 08:40:18 AM »
Good Morning!

I'd got the minimal configuration (only Watchdog) working.
Now i want to insert the GLCD because i need the output at the lcd for my analog inputs, so this must be the next step...
Is the configuration of the port pin ok?
The RST Line is at Pin PB28 so i modified the config define...

#define DATA_LINES             (PA26 | PA25 | PA24 | PA23 | PA22 | PA21 | PA20 | PA19)
    #define GLCD_RST               PB28                                  // reset
    #define GLCD_RS                PA29                                  // GLCD Register Select
    #define GLCD_RW                PA28                                  // GLCD Read/Write
    #define GLCD_ENA               PA27                                  // GLCD Enable

    #define GLCD_CS0               PA12                                  // LCD Controller 0 Chip Select - 2 controller chips for 128 x 64
    #define GLCD_CS1               PA13                                  // LCD Controller 1 Chip Select

    #define SET_PULL_DOWNS()       
    #define REMOVE_PULL_DOWNS()   

    #define CONFIGURE_GLCD() \
        _CONFIG_DRIVE_PORT_OUTPUT_VALUE(A, ( GLCD_RS | GLCD_RW | GLCD_ENA | GLCD_CS0 | GLCD_CS1), GLCD_RW ); \
      _CONFIG_DRIVE_PORT_OUTPUT_VALUE(B, GLCD_RST, GLCD_RW ); \
        _CONFIG_PORT_INPUT(A, DATA_LINES);

    #define GLCD_DATAASOUTPUT()    _DRIVE_PORT_OUTPUT(A, DATA_LINES)
    #define GLCD_DATAASINPUT()     _FLOAT_PORT(A, DATA_LINES)

    #define GLCD_DATAOUT(data)     _WRITE_PORT_MASK(A, data, DATA_LINES)
    #define GLCD_DATAIN()          _READ_PORT_MASK(A, DATA_LINES)

    #define GLCD_RS_H()            _SETBITS(A, GLCD_RS)
    #define GLCD_RS_L()            _CLEARBITS(A, GLCD_RS)

    #define GLCD_RW_H()            _SETBITS(A, GLCD_RW)
    #define GLCD_RW_L()            _CLEARBITS(A, GLCD_RW)

    #define GLCD_CS0_H()           _SETBITS(A, GLCD_CS0)
    #define GLCD_CS0_L()           _CLEARBITS(A, GLCD_CS0)

    #define GLCD_CS1_H()           _SETBITS(A, GLCD_CS1)
    #define GLCD_CS1_L()           _CLEARBITS(A, GLCD_CS1)

    #define GLCD_DELAY_WRITE()                                       // no write delay since the data is stable for long enough at full speed
    #define GLCD_DELAY_READ()      GLCD_RW_H()                       // one extra operation to ensure set up time of read

    #define GLCD_RST_H()           _SETBITS(B, GLCD_RST)
    #define GLCD_RST_L()           _CLEARBITS(B, GLCD_RST)

    #define GLCD_ENA_H()           _SETBITS(A, GLCD_ENA)
    #define GLCD_ENA_L()           _CLEARBITS(A, GLCD_ENA)

    #define MAX_GLCD_WRITE_BURST   80                                // the maximum number of writes to the GLCD before the task yields


Should i see the same pictures and text like i see at the simulator ?

Thanks!
Volker

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: New Project with own Hardware
« Reply #3 on: February 05, 2010, 01:03:27 PM »
Hi Volker

If the simulator is showing the pictures correctly it means that the project is configured correctly for the LCD (you are using a Samsung compatible type according to the configuration). The simulator checks the data lines when reads and writes are performed and uses the data contents as input to the simulation, which then drives the LCD display in the appropriate manner (assuming Samsung compatibility).

What the simulator can't do is verify that all control lines are connected properly. Therefore if the target is not responding as expected (check that the blink LED is always operating to show that the processor has not crashed for some reason) it may be because not all control signals are correct. It could also be that something is not physically connected correctly. Also there is usually a contrast control on the LCD which needs to be set correctly - if this is not set it may be that the LCD is displaying something but that this is not visible because the contrast setting is too low.

Therefore it is often necessary to carefully check each signal - best is with a logic analyser so that read and write accesses and their timing can be verified.


One inconsistency that I see in the set up is:
       _CONFIG_DRIVE_PORT_OUTPUT_VALUE(A, ( GLCD_RS | GLCD_RW | GLCD_ENA | GLCD_CS0 | GLCD_CS1), GLCD_RW ); \
      _CONFIG_DRIVE_PORT_OUTPUT_VALUE(B, GLCD_RST, GLCD_RW ); \


Here the GLCD_RW is being set to '1' in the first line.
In the second line the GLCD_RST is being configured as an output and its value is being set to '0'. The GLCD_RW is being used, which is not on port B so may be affecting a different pin on port B. I don't think that this will cause the LCD to fail though.

Check also in the simulator that the port pins that you have configured are displayed as expected - the routine fnInitialisePorts() called from application.c configures some GPIO for demonstration purposes - and can be setting the same ports. Therefore check for collisions between settings and modify accordingly.

Finally note that LCDs may not always be 100% compatible even if certain types of controller chips are used. Always compare with the data sheet of the display to be sure that there are no additional requirements.

Regards

Mark



Offline Oellness

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: New Project with own Hardware
« Reply #4 on: February 06, 2010, 11:35:40 AM »
Hi,

on a Scope i see that the Signals from the Data Bus is not a good signal. It seems that the capacity on the lines are to high for the µC speed. it looks like a sawtooth with a period of 1 µs.
Is there a method to run the LCD with a lower speed?

Regards
Volker

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: New Project with own Hardware
« Reply #5 on: February 06, 2010, 11:57:52 AM »
Hi Volker

If possible, step through the code and watch each port change to verify that each pin is really doing what you expect.

I wouldn't necessarily assume that it is too fast by watching data lines; these are bidirectional and so are set as inputs after they have been used as outputs (usually reading the busy state of the display). If nothing drives the bus the signal will usually quite slowly move to the idle level and this may look like a saw-tooth.

However, when the LCD is read, the R/W will be set accordingly and the display will drive the bus too - if the display doesn't drive the bus you will need to find out why; when stepping with a debugger at this point you can check whether the LCD is really driving (being read) by either monitoring that the data lines move quickly to a new state or else by connecting a resistor (say 1k) from the data line with 0V and then with +V; if the LCD is driving the data line will stay stable, if not it will change between the two voltages.

Small adjustments in timing can be made by adding wait states in the interface code:

    #define GLCD_DELAY_WRITE()                            // no write delay since the data is stable for long enough at full speed
    #define GLCD_DELAY_READ()      GLCD_RW_H()            // one extra operation to ensure set up time of read


This means that the commands are repeated to introduce extra delays, which should be adequate since the LCDs read/write access times are not that much slower than possible with the processor's bit-banging port interface.


Regards

Mark

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: New Project with own Hardware
« Reply #6 on: February 14, 2010, 05:33:52 PM »
Hi Volker

I don't know whether you have managed to solve your problem in the meantime but I have some news concerning an error that I detected in the SAM7 port macros which may cause problems.

First of all it is important to note that the SAM7X project has probably not been tested together with a graphical LCD, connected via GPIO. It has been simulated but the simulator didn't detect the port macro error.

Today I was working on extending the SAM7X project to include also the SAM7S types. It happens that the board that I have (Olimex SAM7-MT256) has a 2 x 16 LCD on it (connected in 4-bit mode). Since the display is on the board I configured the project to use it but it didn't run first time - the simulator suggested that all settings were correct so I had to debug it.

It turned out that several SAM7 port macros are not correct and this is noticeable when using the parallel LCD interface (character and probably also GLCD).

The corrected macros (in sam7x.h) are here:

#define _WRITE_PORT(ref, value) PIO_OWER_##ref = (0xffffffff); PIO_ODSR_##ref = value; PIO_OWDR_##ref = (0xffffffff)
#define _WRITE_PORT_MASK(ref, value, mask) PIO_OWER_##ref = (mask); PIO_ODSR_##ref = value; PIO_OWDR_##ref = (mask)
#define _TOGGLE_PORT(ref, mask)     PIO_OWER_##ref = (mask); PIO_ODSR_##ref = (PIO_ODSR_##ref ^ (mask)); PIO_OWDR_##ref = (mask)
#define _CONFIG_DRIVE_PORT_OUTPUT_VALUE(ref, pins, value) PMC_PCER = PIO##ref; PIO_PER_##ref = pins; PIO_OWER_##ref = (pins); PIO_ODSR_##ref = (value); PIO_OWDR_##ref = (pins); PIO_OER_##ref = (pins)
#define _DRIVE_PORT_OUTPUT_VALUE(ref, pins, value) PIO_OWER_##ref = (pins); PIO_ODSR_##ref = (pins); PIO_OWDR_##ref = (pins); PIO_OER_##ref = (pins)


The error was in the way that they were working with the PIO_OWER - they were enabling a write mask but not clearing it correctly afterward using PIO_OWDR.

After correcting, the LCD worked correctly and I expect that the GLCD interface will also require the same correction!

Regards

Mark

PS. The SAM7S has now been integrated so I will make a new package shortly (with SAM7X and SAM7S) so that this correction is included.