http://www.ethernut.de/nutwiki/index.php?title=Special:NewPages&feed=atom&hideredirs=1&limit=100&offset=&namespace=0&username=&tagfilter=Nutwiki - New pages [en]2024-03-29T07:08:04ZFrom NutwikiMediaWiki 1.26.2http://www.ethernut.de/nutwiki/index.php/Hardware/Enut1/PortsHardware/Enut1/Ports2017-07-13T16:25:26Z<p>Harald: /* Analog Port */</p>
<hr />
<div><div id="content"><br />
<br />
= Ethernut 1 Ports =<br />
<br />
== Expansion Port ==<br />
<br />
[[File:ethernut13h-expansion-pins.png]]<br /><br />
<br />
{| class="wikitable"<br />
! Pin<br />
! Signal<br />
! Description<br />
|-<br />
| 1<br />
| '''N/C''' Not Connected<br />
| Reserved for alternative supply<br />
|-<br />
| 2<br />
| '''N/C''' Not Connected<br />
| Reserved for alternative supply<br />
|-<br />
| 3<br />
| '''VCC5''' +5V Power Supply<br />
| Output from on-board regulator<br />
|-<br />
| 4<br />
| '''VCC5''' +5V Power Supply<br />
| Output from on-board regulator<br />
|-<br />
| 5<br />
| '''GND''' Digital Ground<br />
| <br />
|-<br />
| 6<br />
| '''GND''' Digital Ground<br />
| <br />
|-<br />
| 7<br />
| '''GND''' Digital Ground<br />
| <br />
|-<br />
| 8<br />
| '''GND''' Digital Ground<br />
| <br />
|-<br />
| 9<br />
| '''MR\''' Hardware Reset Input<br />
| Drive low to reset Ethernut.<br /><br />
Pressing the reset button pulls this line low.<br /><br />
Also driven low during SPI/JTAG programming.<br />
|-<br />
| 10<br />
| '''DC''' Unregulated DC Power Supply<br />
| Can drive external regulators or<br /><br />
as DC input for Ethernut.<br />
|-<br />
| 11<br />
| '''VCC5''' +5V Power Supply<br />
| Output from on-board regulator<br />
|-<br />
| 12<br />
| '''VCC5''' +5V Power Supply<br />
| Output from on-board regulator<br />
|-<br />
| 13<br />
| '''RD\''' External Memory Bus Read Strobe<br />
| <br />
|-<br />
| 14<br />
| '''WR\''' External Memory Bus Write Strobe<br />
| <br />
|-<br />
| 15<br />
| '''D0''' External Data Bus Bit 0<br />
| <br />
|-<br />
| 16<br />
| '''D1''' External Data Bus Bit 1<br />
| <br />
|-<br />
| 17<br />
| '''D2''' External Data Bus Bit 2<br />
| <br />
|-<br />
| 18<br />
| '''D3''' External Data Bus Bit 3<br />
| <br />
|-<br />
| 19<br />
| '''D4''' External Data Bus Bit 4<br />
| <br />
|-<br />
| 20<br />
| '''D5''' External Data Bus Bit 5<br />
| <br />
|-<br />
| 21<br />
| '''D6''' External Data Bus Bit 6<br />
| <br />
|-<br />
| 22<br />
| '''D7''' External Data Bus Bit 7<br />
| <br />
|-<br />
| 23<br />
| '''A0''' External Address Bus Bit 0<br /><br />
'''PA0''' General Purpose I/O Port A Bit 0<br />
| <br />
|-<br />
| 24<br />
| '''A1''' External Address Bus Bit 1<br /><br />
'''PA1''' General Purpose I/O Port A Bit 1<br />
| <br />
|-<br />
| 25<br />
| '''A2''' External Address Bus Bit 2<br /><br />
'''PA2''' General Purpose I/O Port A Bit 2<br />
| <br />
|-<br />
| 26<br />
| '''A3''' External Address Bus Bit 3<br /><br />
'''PA3''' General Purpose I/O Port A Bit 3<br />
| <br />
|-<br />
| 27<br />
| '''A4''' External Address Bus Bit 4<br /><br />
'''PA4''' General Purpose I/O Port A Bit 4<br />
| <br />
|-<br />
| 28<br />
| '''A5''' External Address Bus Bit 5<br /><br />
'''PA5''' General Purpose I/O Port A Bit 5<br />
| <br />
|-<br />
| 29<br />
| '''A6''' External Address Bus Bit 6<br /><br />
'''PA6''' General Purpose I/O Port A Bit 6<br />
| <br />
|-<br />
| 30<br />
| '''A7''' External Address Bus Bit 7<br /><br />
'''PA7''' General Purpose I/O Port A Bit 7<br />
| <br />
|-<br />
| 31<br />
| '''A8''' External Address Bus Bit 8<br /><br />
'''PC0''' General Purpose I/O Port C Bit 0<br />
| <br />
|-<br />
| 32<br />
| '''A9''' External Address Bus Bit 9<br /><br />
'''PC1''' General Purpose I/O Port C Bit 1<br />
| <br />
|-<br />
| 33<br />
| '''A10''' External Address Bus Bit 10<br /><br />
'''PC2''' General Purpose I/O Port C Bit 2<br />
| <br />
|-<br />
| 34<br />
| '''A11''' External Address Bus Bit 11<br /><br />
'''PC3''' General Purpose I/O Port C Bit 3<br />
| <br />
|-<br />
| 35<br />
| '''A12''' External Address Bus Bit 12<br /><br />
'''PC4''' General Purpose I/O Port C Bit 4<br />
| <br />
|-<br />
| 36<br />
| '''A13''' External Address Bus Bit 13<br /><br />
'''PC5''' General Purpose I/O Port C Bit 5<br />
| <br />
|-<br />
| 37<br />
| '''A14''' External Address Bus Bit 14<br /><br />
'''PC6''' General Purpose I/O Port C Bit 6<br />
| <br />
|-<br />
| 38<br />
| '''A15''' External Address Bus Bit 15<br /><br />
'''PC7''' General Purpose I/O Port C Bit 7<br />
| <br />
|-<br />
| 39<br />
| '''PE0''' General Purpose I/O Port E Bit 0<br /><br />
'''RXD0''' UART 0 Receive Input<br /><br />
'''PDI''' Programming Data Input<br />
| UART0 receiver.<br /><br />
Connected to level converter output via R18.<br /><br />
Also used for SPI programming.<br />
|-<br />
| 40<br />
| '''PE1''' General Purpose I/O Port E Bit 1<br /><br />
'''TXD0''' UART 0 Transmit Output<br /><br />
'''PDO''' Programming Data Output<br />
| UART0 transmitter.<br /><br />
Also used for SPI programming.<br />
|-<br />
| 41<br />
| '''PE2''' General Purpose I/O Port E Bit 2<br /><br />
'''XCK0''' USART 0 External Clock<br /><br />
'''AIN0''' Analog Comparator Positive Input<br />
| Available.<br />
|-<br />
| 42<br />
| '''PE3''' General Purpose I/O Port E Bit 3<br /><br />
'''OC3A''' Counter 3 Compare and PWM A<br /><br />
'''AIN1''' Analog Comparator Positive Input<br />
| Available.<br />
|-<br />
| 43<br />
| '''PE4''' General Purpose I/O Port E Bit 4<br /><br />
'''INT4''' External Interrupt 4<br /><br />
'''OC3B''' Counter 3 Compare and PWM B<br />
| Available.<br />
|-<br />
| 44<br />
| '''PE5''' General Purpose I/O Port E Bit 5<br /><br />
'''INT5''' External Interrupt 5<br /><br />
'''OC3C''' Counter 3 Compare and PWM C<br />
| Internally used for Ethernet Controller Interrupt.<br /><br />
Available when removing R12 and mounting R31.<br />
|-<br />
| 45<br />
| '''PE6''' General Purpose I/O Port E Bit 6<br /><br />
'''INT6''' External Interrupt 6<br /><br />
'''T3''' Counter 3 Clock Input<br />
| Available by default.<br /><br />
Alternative Ethernet Interrupt when<br /><br />
removing R12 and mounting R31.<br />
|-<br />
| 46<br />
| '''PE7''' General Purpose I/O Port E Bit 7<br /><br />
'''INT7''' External Interrupt 7<br /><br />
'''ICP3''' Counter 3 Input Capture<br />
| Available.<br />
|-<br />
| 47<br />
| '''PB0''' General Purpose I/O Port B Bit 0<br /><br />
'''-SS''' SPI Slave Select Input<br />
| Available.<br />
|-<br />
| 48<br />
| '''PB1''' General Purpose I/O Port B Bit 1<br /><br />
'''SCK''' SPI Bus Serial Clock<br />
| Available, but used during SPI programming.<br /><br />
If used as Ethernut input, the external output<br /><br />
must be switched to tri-state during SPI<br /><br />
programming (MR\ low),<br />
|-<br />
| 49<br />
| '''PB2''' General Purpose I/O Port B Bit 2<br /><br />
'''MOSI''' SPI Bus Master Output / Slave Input<br />
| Available.<br />
|-<br />
| 50<br />
| '''PB3''' General Purpose I/O Port B Bit 3<br /><br />
'''MISO''' SPI Bus Master Input / Slave Output<br />
| Available.<br />
|-<br />
| 51<br />
| '''PB4''' General Purpose I/O Port B Bit 4<br /><br />
'''OC0''' Counter 0 Compare and PWM<br />
| Available.<br />
|-<br />
| 52<br />
| '''PB5''' General Purpose I/O Port B Bit 5<br /><br />
'''OC1A''' Counter 1 Compare and PWM A<br />
| Available.<br />
|-<br />
| 53<br />
| '''PB6''' General Purpose I/O Port B Bit 6<br /><br />
'''OC1B''' Counter 1 Compare and PWM B<br />
| Available.<br />
|-<br />
| 54<br />
| '''PB7''' General Purpose I/O Port B Bit 7<br /><br />
'''OC1C''' Counter 1 Compare and PWM C<br /><br />
'''OC2''' Counter 2 Compare and PWM<br />
| Available.<br />
|-<br />
| 55<br />
| '''PD0''' General Purpose I/O Port D Bit 0<br /><br />
'''INT0''' External Interrupt 0<br /><br />
'''SCL''' TWI Serial Clock<br />
| Available.<br />
|-<br />
| 56<br />
| '''PD1''' General Purpose I/O Port D Bit 1<br /><br />
'''INT1''' External Interrupt 1<br /><br />
'''SDA''' TWI Serial Data<br />
| Available.<br />
|-<br />
| 57<br />
| '''PD2''' General Purpose I/O Port D Bit 2<br /><br />
'''INT2''' External Interrupt 2<br /><br />
'''RXD1''' UART 1 Receive Input<br />
| Available by default.<br /><br />
Optional CTS input when R33 is mounted.<br />
|-<br />
| 58<br />
| '''PD3''' General Purpose I/O Port D Bit 3<br /><br />
'''INT3''' External Interrupt 3<br /><br />
'''TXD1''' UART 1 Transmit Output<br />
| Available by default.<br /><br />
Optional RTS output when R32 is mounted.<br />
|-<br />
| 59<br />
| '''PD4''' General Purpose I/O Port D Bit 4<br /><br />
'''ICP1''' Counter 1 Input Capture<br />
| Available.<br />
|-<br />
| 60<br />
| '''PD5''' General Purpose I/O Port D Bit 5<br /><br />
'''XCK1''' USART 1 External Clock<br />
| Available.<br />
|-<br />
| 61<br />
| '''PD6''' General Purpose I/O Port D Bit 6<br /><br />
'''T1''' Counter 1 Clock Input<br />
| Available.<br />
|-<br />
| 62<br />
| '''PD7''' General Purpose I/O Port D Bit 7<br /><br />
'''T2''' Counter 2 Clock Input<br />
| Available.<br />
|-<br />
| 63<br />
| '''N/C''' Not Connected<br />
| <br />
|-<br />
| 64<br />
| '''N/C''' if R34 not mounted<br /><br />
'''ALE''' External Address Bus Latch Enable<br />
| <br />
|}<br />
<br />
<br /><br />
<br /><br />
<br />
== Analog Port ==<br />
<br />
{| class="wikitable"<br />
! Pin<br />
! Signal<br />
! Description<br />
|-<br />
| 1<br />
| '''AVCC''' +5V Power Supply<br />
| Connected to digital power supply via R13<br />
|-<br />
| 2<br />
| '''AREF''' Analog reference<br />
| Connected to CPU AREF pin.<br />
|-<br />
| 3<br />
| '''AVCC''' +5V Power Supply<br />
| Connected to digital power supply via R13<br />
|-<br />
| 4<br />
| '''AGND''' Analog ground<br />
| Connected to digital ground via R15.<br />
|-<br />
| 5<br />
| '''PF0''' General Purpose I/O Port F Bit 0<br /><br />
'''ADC0''' Analog/Digital Converter Channel 0<br />
| Available.<br />
|-<br />
| 6<br />
| '''AGND''' Analog ground<br />
| Connected to digital ground via R15.<br />
|-<br />
| 7<br />
| '''PF1''' General Purpose I/O Port F Bit 1<br /><br />
'''ADC1''' Analog/Digital Converter Channel 1<br />
| Available.<br />
|-<br />
| 8<br />
| '''AGND''' Analog ground<br />
| Connected to digital ground via R15.<br />
|-<br />
| 9<br />
| '''PF2''' General Purpose I/O Port F Bit 2<br /><br />
'''ADC2''' Analog/Digital Converter Channel 2<br />
| Available.<br />
|-<br />
| 10<br />
| '''AGND''' Analog ground<br />
| Connected to digital ground via R15.<br />
|-<br />
| 11<br />
| '''PF3''' General Purpose I/O Port F Bit 3<br /><br />
'''ADC3''' Analog/Digital Converter Channel 3<br />
| Available.<br />
|-<br />
| 12<br />
| '''AGND''' Analog ground<br />
| Connected to digital ground via R15.<br />
|-<br />
| 13<br />
| '''PF4''' General Purpose I/O Port F Bit 4<br /><br />
'''ADC4''' Analog/Digital Converter Channel 4<br /><br />
'''TCK''' JTAG<br />
| Available, but used during<br /><br />
JTAG programming/debugging.<br />
|-<br />
| 14<br />
| '''AGND''' Analog ground<br />
| Connected to digital ground via R15.<br />
|-<br />
| 15<br />
| '''PF5''' General Purpose I/O Port F Bit 5<br /><br />
'''ADC5''' Analog/Digital Converter Channel 5<br /><br />
'''TMS''' JTAG<br />
| Available, but used during<br /><br />
JTAG programming/debugging.<br />
|-<br />
| 16<br />
| '''AGND''' Analog ground<br />
| Connected to digital ground via R15.<br />
|-<br />
| 17<br />
| '''PF6''' General Purpose I/O Port F Bit 6<br /><br />
'''ADC6''' Analog/Digital Converter Channel 6<br /><br />
'''TDO''' JTAG<br />
| Available, but used during<br /><br />
JTAG programming/debugging.<br />
|-<br />
| 18<br />
| '''AGND''' Analog ground<br />
| Connected to digital ground via R15.<br />
|-<br />
| 19<br />
| '''PF7''' General Purpose I/O Port F Bit 7<br /><br />
'''ADC7''' Analog/Digital Converter Channel 7<br /><br />
'''TDI''' JTAG<br />
| Available, but used during<br /><br />
JTAG programming/debugging.<br />
|-<br />
| 20<br />
| '''AGND''' Analog ground<br />
| Connected to digital ground via R15.<br />
|}<br />
<br />
<br /><br />
<br /><br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/Enut1/MemmapHardware/Enut1/Memmap2017-07-13T16:24:42Z<p>Harald: Created page with "{| |width="50%"| {| |width="100%"| |} |width="50%"| {| |width="100%"| |} |- | | {| |width="100%"| = Ethernut 1.3 Memory Map = The ATmega128 used on Ethernut 1.3 is a member o..."</p>
<hr />
<div>{|<br />
|width="50%"|<br />
{|<br />
|width="100%"|<br />
|}<br />
|width="50%"|<br />
{|<br />
|width="100%"|<br />
|}<br />
|-<br />
|<br />
|<br />
{|<br />
|width="100%"|<br />
= Ethernut 1.3 Memory Map =<br />
<br />
The ATmega128 used on Ethernut 1.3 is a member of the AVR family of microcontrollers, which are Harvard Architecture Machine, where program code and data are stored separately.<br />
<br />
== Data Memory ==<br />
<br />
{| class="wikitable"<br />
! Address<br />
! Description<br />
|-<br />
| 0x0000 - 0x001F<br />
| CPU Registers (Note 1)<br />
|-<br />
| 0x0020 - 0x005F<br />
| I/O Registers (Note 1)<br />
|-<br />
| 0x0060 - 0x00FF<br />
| Extended I/O Registers (Note 1)<br />
|-<br />
| 0x0100 - 0x10FF<br />
| Fast Internal RAM, no wait states required<br />
|-<br />
| 0x1100 - 0x7FFF<br />
| External RAM, 1 wait state is recommended<br />
|-<br />
| 0x8000 - 0x82FF<br />
| Unused, Available for Custom Extensions<br />
|-<br />
| 0x8300 - 0x831F<br />
| Ethernet Controller Registers (Note 2)<br />
|-<br />
| 0x8320 - 0xFFFF<br />
| Unused, Available for Custom Extensions<br />
|}<br />
<br />
<br /><br />
<br />
'''Note 1''': See ATmega128 datasheet<br /><br />
'''Note 2''': See RTL8019AS datasheet<br />
<br />
== Program Memory ==<br />
<br />
{| class="wikitable"<br />
! Word Address<br />
! Description<br />
|-<br />
| 0x0000 - 0x0045<br />
| Vector Table<br />
|-<br />
| 0x0046 - 0xEFFF<br />
| Initialization, RTOS and Application Sections<br />
|-<br />
| 0xF000 - 0xF7FF<br />
| Bootloader Section, if BOOTSZ = 00b (Note 1)<br />
|-<br />
| 0xF800 - 0xFBFF<br />
| Bootloader Section, if BOOTSZ = 01b (Note 1)<br />
|-<br />
| 0xFC00 - 0xFDFF<br />
| Bootloader Section, if BOOTSZ = 10b (Note 1)<br />
|-<br />
| 0xFE00 - 0xF7FF<br />
| Bootloader Section, if BOOTSZ = 11b (Note 1)<br />
|}<br />
<br />
<br /><br />
<br />
'''Note 1''': Available for applications if not used by bootloader.<br />
<br />
<br /><br />
<br /><br />
|}<br />
|}</div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/Enut1Hardware/Enut12017-07-13T16:21:57Z<p>Harald: /* How to Make Rev-G and Rev-H Compatible to Rev-F */</p>
<hr />
<div><div id="content"><br />
<br />
= Ethernut 1.3 Hardware =<br />
<br />
<br /><br />
<br />
== Important Note ==<br />
<br />
Almost all documents including the schematics show or describe the wrong jumper setting for JP2. Furthermore, for some months boards had been shipped with this wrong setting as well.<br />
<br />
Both jumpers for the RTS/CTS handshake (JP2, near the RS232 connector) need to connect pins 1 with 2 and 3 with 4. You may alternatively remove these two jumpers.<br />
<br />
== PCB Version 1.3 Revision H ==<br />
<br />
Changes since Revision G<br /><br />
<br />
<br />
* LED4 (Ethernet activity) has been inverted to reduce power consumption in RTL8019AS power down mode.<br />
* Board is now protected by a 1A fast acting fuse.<br />
* Rectifier bridge D1, D2, D3 and D4 (S1A) replaced by Schottky barrier rectifier diodes with a forward voltage below 0.5V.<br />
* R9 and C29 added to MR signal to avoid an unintentional board reset in harsh environments.<br />
* 32kHz crystal Y2 replaced by SMD type.<br />
* Capacitors C7 and C8 replaced by SMD types.<br />
* Identification label moved.<br />
* J7 print changed from &quot;ISP&quot; to &quot;SPI&quot;.<br />
<br />
'''N E W !''' A memory map is on [[Hardware/Enut1/Memmap|this page]].<br />
<br />
Available I/O ports are listed [[Hardware/Enut1/Ports|here]].<br />
<br />
== Known Problems with Version 1.3 Rev.-H ==<br />
<br />
The previously used RS-232 level converter had not been available at the time of production and was replaced by the ZT3222LEET. Unfortunately the RS-232 port shows sporadic data corruption on the receiver side. To fix this, an additional capacitor must be added between pin 16 (GND) and 17 (VCC) of IC6.<br />
<br />
== PCB Version 1.3 Revision G ==<br />
<br />
[[File:Ethernut13g-320.png|320x233px|Ethernut 1.3 G]]]]<br />
4-layer board with ATmega128 running at 14.7456 MHz, 10 MBit Realtek Ethernet Controller and 32 kByte external SRAM.<br /><br />
<br /><br />
[[File:enhwm13e.pdf|Ethernut 1.3 Rev-G Hardware Manual]] (Nov. 2005) Jumper setting corrected.<br />
<br />
Changes since Revision F<br /><br />
<br />
<br />
* Additional JTAG connector added.<br />
* No PROG signal required for SPI programming. Jumper JP4 removed.<br />
* Programming LED has been redefined as User LED connected to PE1.<br />
* ALE signal can be routed to expansion port pin 64 when mounting optional resistor R30.<br />
* EEPROM emulation for RTL8019AS added. Uses A13 and A14 , so no additional port pins are required. This modification allows to clear the full duplex flag in the Ethernet controller.<br />
* Optional resistors allow to use Ethernet interrupts on IRQ5 or IRQ6.<br />
* DS1811 has been replaced by MIC2775, which provides low and high active reset signals. Optional resistors allow to route the reset signal to or from the expansion port.<br />
* Rectifier bridge has been replaced by 4 rectifier diodes.<br />
* Glue logic uses pico gates.<br />
<br />
[[File:Enut130g-s1.pdf|Schematic Part 1]]: CPU.<br /><br />
[[File:Enut130g-s2.pdf|Schematic Part 2]]: SRAM and expansion port.<br /><br />
[[File:Enut130g-s3.pdf|Schematic Part 3]]: Ethernet interface.<br /><br />
[[File:Enut130g-s4.pdf|Schematic Part 4]]: Power supply and reset logic.<br />
<br />
== How to Make Rev-G and Rev-H Compatible to Rev-F ==<br />
<br />
Due to the EEPROM emulation, board Rev-G requires Nut/OS 3.9 or later. However, it is possible to disable EEPROM emulation by removing R7 (0 Ohm 1206 on top of the board near the Realtek)<br /><br />
<br /><br />
[[File:13g-to-13f-top.png|320px]]<br /><br />
<br /><br />
and mounting R37 (10 kOhm 1206 on the bottom side)<br /><br />
<br /><br />
[[File:13g-to-13f-bot.png|320px]]<br /><br />
<br /><br />
For a more detailed view, klick on the pictures above. Also refer to part 3 of the schematic.<br />
<br />
== Known Problems with Version 1.3 Revision G ==<br />
<br />
[[../../../img/mod13g-reset.png|[[File:../../../img/mod13g-reset-small.png]]]] The MIC2775 reset controller is very sensitive. A 10k pullup resistor and a 100n capacitor to ground had been added to the MR/ (manual reset) line. They are mounted on the back side of the board at the JTAG connector. Klick on the photo for a larger view.<br />
<br />
== Initial Software ==<br />
<br />
[http://www.egnite.de/ egnite] delivers the boards pre-installed with<br />
<br />
* [[basemon.hex|basemon.hex]]<br /><br />
A simple application, which tests all basic board functions and outputs the results on the [[../../documents/rs232primer.html|RS232 line]]. See the hardware manual for further details. Basemon runs on all Ethernuts and automatically detects the CPU clock and the Ethernet controller.<br />
* [[eboot.hex|eboot.hex]]<br /><br />
The TFTP bootloader for the RTL8019AS Ethernet Controller. [[../../eboot/index.html|More...]]<br />
<br />
In order to get both hex files programmed into the Flash, do not erase the device when uploading the second file.<br />
== Testing Hardware ==<br />
<br />
'''Updated!''' [[testrtl10.zip|testrtl10.zip]]<br /><br />
This test application for the ATmega128 runs without Nut/OS and does not require any external RAM. The following steps are performed:<br />
<br />
# Scan memory addresses 0x1100 to 0x8300 for an RTL8019AS chip.<br />
# Check if registers are writeable.<br />
# Check for correct jumper mode.<br />
# Verify base address 0x8300.<br />
# Detect and perform EEPROM emulation.<br />
# Scan memory address 0x8300 after EEPROM emulation.<br />
# Stop the controller.<br />
# Reset the controller.<br />
# Test the controller's internal memory (pattern, walking bit, address bus).<br />
# Loopback tests 1, 2 and 3.<br />
# Test for Ethernet link.<br />
# Test controller interrupt request line (PE5 and PE6).<br />
<br />
The output on the Ethernut serial port will look like this:<br />
<pre class="coding">101 RTL8019AS Test 1.0<br />
104 Discovered<br />
100 Write OK<br />
100 Config OK<br />
102 EEPROM emulation OK<br />
101 Re-discovered<br />
101 Stopped<br />
101 Reset OK<br />
100 Memory OK<br />
121 Loopback 1 OK<br />
122 Loopback 2 OK<br />
123 Loopback 3 OK<br />
130 IRQ OK<br />
499 NIC OK<br />
100 Ready for ping 192.168.192.254 (MAC 00:06:98:F0:11:23)</pre><br />
When all tests had been passed, the Ethernut board will be ready to answer ARP and ICMP (ping) requests. The archive contains the full source code, you can adapt the hard coded IP and MAC addresses to your environment.<br />
<br /><br />
<br /><br />
<br /><br />
<br /><br />
<br />
== PCB Version 1.3 Revision F ==<br />
<br />
[[../../../img/ethernut1pbig.png|[[File:../../../img/ethernut1l.png|320x236px|Ethernut 1.3 F]]]]<br />
4-layer board with ATmega128 running at 14.7456 MHz, 10 MBit Realtek Ethernet Controller and 32 kByte external SRAM.<br /><br />
<br /><br />
[[../../../pdf/enhwm16.pdf|Ethernut 1.3 Rev-F Hardware Manual]] (2003)<br />
<br />
The original Eagle CAD files are available in the [[../../download/index.html|download area]].<br />
<br />
[[File:../../../img/enut13_blk3d.png|Ethernut 1.3 Block]]<br />
[[../../../pdf/enut13e-s1.pdf|Schematic Part 1]]: CPU.<br /><br />
[[../../../pdf/enut13e-s2.pdf|Schematic Part 2]]: SRAM and expansion port.<br /><br />
[[../../../pdf/enut13e-s3.pdf|Schematic Part 3]]: Ethernet interface.<br /><br />
[[../../../pdf/enut13e-s4.pdf|Schematic Part 4]]: Power supply and reset logic.<br /><br />
<br /><br />
<br /><br />
[[../../jtag/jtagconn.html|JTAG How To]]<br /><br />
Connecting the ATJTAGICE to the Ethernut Board. This requires board Rev D or F.<br />
<br />
== Known Problems with Version 1.3 Rev.-D ==<br />
<br />
Analog input numbering on the silk screen is mirrored.<br />
<br />
SRAM timing may be critical with crystals above 8 MHz. Only one memory failure had been reported so far, but when refering to the datasheets, additional wait states seem to be required. See registers MCUCR in the ATmega 128 datasheet.<br />
<br />
== PCB Version 1.3 Revision C ==<br />
<br />
[[../../../pdf/enut13c-brd.pdf|Board Layout]]<br /><br />
[[../../../pdf/enut13c-schematics.pdf|Schematic]]<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/Enut1/BOMHardware/Enut1/BOM2017-07-13T16:21:18Z<p>Harald: Created page with "{| |width="50%"| {| |width="100%"| |} |width="50%"| {| |width="100%"| |} |- | | {| |width="100%"| = Ethernut 1 Bill of Material = == Version 1.3 Revision G == {| ! Qty ! Val..."</p>
<hr />
<div>{|<br />
|width="50%"|<br />
{|<br />
|width="100%"|<br />
|}<br />
|width="50%"|<br />
{|<br />
|width="100%"|<br />
|}<br />
|-<br />
|<br />
|<br />
{|<br />
|width="100%"|<br />
= Ethernut 1 Bill of Material =<br />
<br />
== Version 1.3 Revision G ==<br />
<br />
{|<br />
! Qty<br />
! Value<br />
! Package<br />
! Parts<br />
|-<br />
| 1<br />
| ATMEGA128-AU<br />
| TQFP64<br />
| IC1<br />
|-<br />
| 1<br />
| RTL8019AS<br />
| QFP100<br />
| IC2<br />
|-<br />
| 1<br />
| 74HC573<br />
| SOIC20<br />
| IC3<br />
|-<br />
| 1<br />
| K6X0808C1D-DF55<br />
| SOP28<br />
| IC4<br />
|-<br />
| 2<br />
| 74HC1G00GW<br />
| SC88A-5<br />
| IC5, IC7<br />
|-<br />
| 1<br />
| SP3222ECT<br />
| SOIC18<br />
| IC6<br />
|-<br />
| 1<br />
| LM1086IS-5.0<br />
| TO263<br />
| IC8<br />
|-<br />
| 1<br />
| MIC2775-46BM5<br />
| SOT23-5<br />
| IC9<br />
|-<br />
| 2<br />
| 2mA red<br />
| 3mm round<br />
| LED1, LED2<br />
|-<br />
| 1<br />
| 2mA yellow<br />
| 3mm round<br />
| LED3<br />
|-<br />
| 1<br />
| 2mA green<br />
| 3mm round<br />
| LED4<br />
|-<br />
| 4<br />
| S1G<br />
| SMA<br />
| D1, D2, D3, D4<br />
|-<br />
| 1<br />
| 32.768kHz<br />
| TC38H<br />
| Y2<br />
|-<br />
| 1<br />
| 14.7456MHz<br />
| HC18/US<br />
| Y1<br />
|-<br />
| 1<br />
| 20MHz<br />
| HC18/US<br />
| Y3<br />
|-<br />
| 7<br />
| 0R<br />
| 1206<br />
| R7, R12, R13, R14, R15, R18, R22<br />
|-<br />
| 1<br />
| 200R 1%<br />
| 1206<br />
| R6<br />
|-<br />
| 4<br />
| 1k<br />
| 0603<br />
| R1, R2, R3, R4<br />
|-<br />
| 2<br />
| 4k7<br />
| 0603<br />
| R5, R8<br />
|-<br />
| 1<br />
| 10k<br />
| 1206<br />
| R37<br />
|-<br />
| 1<br />
| 27k<br />
| 0603<br />
| R11<br />
|-<br />
| 4<br />
| 22p<br />
| 0603<br />
| C3, C4, C9, C10<br />
|-<br />
| 2<br />
| 10n<br />
| 0603<br />
| C5, C6<br />
|-<br />
| 2<br />
| 10n 1kV<br />
| DEBF33A103N2A<br />
| C7, C8<br />
|-<br />
| 18<br />
| 100n<br />
| 0603<br />
| C1, C2, C11, C12, C13, C14, C15, C16, C17, C18, C21, C22, C23, C24, C25, C26, C27, C28<br />
|-<br />
| 1<br />
| 10u 16V<br />
| EEE1CA100SR<br />
| C20<br />
|-<br />
| 1<br />
| 100u 25V<br />
| EEE1EA101XP<br />
| C19<br />
|-<br />
| 1<br />
| FB2022<br />
| DIP16<br />
| TR1<br />
|-<br />
| 1<br />
| RJ45<br />
| JP-S1-8P8C-S<br />
| J1<br />
|-<br />
| 1<br />
| DSUB9<br />
| female angled<br />
| J3<br />
|-<br />
| 1<br />
| BARREL<br />
| TDC-002-3-2.0MM<br />
| J2<br />
|-<br />
| 1<br />
| PINHEAD<br />
| 2x5 0.1&quot; boxed<br />
| J7, J8<br />
|-<br />
| 3<br />
| PINHEAD<br />
| 2x2 0.1&quot;<br />
| JP1, JP2, JP3<br />
|-<br />
| 1<br />
| PINHEAD<br />
| 2x10 0.1&quot;<br />
| J6<br />
|-<br />
| 1<br />
| PINHEAD<br />
| 2x32 0.1&quot;<br />
| J5<br />
|-<br />
| 1<br />
| SWITCH<br />
| Schurter LSH<br />
| S1<br />
|}<br />
<br />
<br /><br />
<br /><br />
|}<br />
|}</div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/Web_IFHardware/EIR/Web IF2017-07-13T09:11:12Z<p>Harald: Created page with "<div id="content"> = EIR Web Interface = There is currently no user interface hardware, such as LCD or push buttons. You'll probably have some great ideas to implement this...."</p>
<hr />
<div><div id="content"><br />
<br />
= EIR Web Interface =<br />
<br />
There is currently no user interface hardware, such as LCD or push buttons. You'll probably have some great ideas to implement this. Until then, try the web interface.<br />
<br />
If you never configured any IP network, most of the stuff below will be Greek to you. In this case do not miss to query additional information from [http://en.wikipedia.org Wikipedia].<br />
<br />
== Connecting the EIR Webserver ==<br />
<br />
When started, the EIR will try to obtain its network configuration from a local DHCP server. If none is available, some hardcoded values will be used. Most likely, these will not fit to your local network. Even if DHCP is available, it is often difficult to find out the actual IP address of the EIR.<br />
<br />
If not yet done, install the latest [[../../download/index.html|Nut/OS distribution]]. This package includes a tiny utility named ''Nut/OS Discoverer''. Start it and select ''Scan'' from the ''Action'' menu. It will then discover all Nut/OS nodes in your local network.<br />
<br />
[[File:../../../img/eir-nutdisc01.png]]<br />
If you double click the EIR entry, a settings dialog will appear, which allows you to change the EIR's network configuration.<br />
<br />
When properly configured, connect any webbrowser to ''http://a.b.c.d'' replacing a.b.c.d with the actual IP address of the EIR.<br />
<br />
[[File:../../../img/eir-nutdisc02.png]]<br />
=== MAC ===<br />
<br />
Make sure that the given Ethernet MAC address is unique in your local network. Conflicts are rare, but just in case you are running more than one radio with default configuration.<br />
<br />
=== Host Name ===<br />
<br />
Feel free to choose any name, as long as it fits in 15 characters.<br />
<br />
=== Fixed Address ===<br />
<br />
This is useful, if no DHCP service is provided. Enter a unique IP address here. To enable DHCP, set this to 0.0.0.0.<br />
<br />
=== Mask ===<br />
<br />
This should have the same value than the one used on your PC.<br />
<br />
=== Gateway ===<br />
<br />
Enter the IP address of your router. Otherwise the EIR won't know how to reach the Internet.<br />
<br />
== Info Page ==<br />
<br />
[[../../../img/eir-webif01.png|[[File:../../../img/eir-webif01_md.png]]]]<br />
<br />
This is the default page. It displays some basic information about the internal status, the connected radio station and the data stream.<br />
<br />
== Favorites Page ==<br />
<br />
[[../../../img/eir-webif02.png|[[File:../../../img/eir-webif02_md.png]]]]<br />
<br />
This page displays all currently stored favorite stations.<br />
<br />
== Add/Edit Favorite Page ==<br />
<br />
[[../../../img/eir-webif02a.png|[[File:../../../img/eir-webif02a_md.png]]]]<br />
<br />
This page is displayed when the user clicks on ''add new favorite'' in the ''favorites page''. It allows to add stations, which are not available on the ''discover lists''.<br />
<br />
A similar page is displayed when the user clicks ''edit'' in the ''favorites page''.<br />
<br />
== Discover Page ==<br />
<br />
[[../../../img/eir-webif03.png|[[File:../../../img/eir-webif03_md.png]]]]<br />
<br />
When this page is selected, the EIR will retrieve a specific list of radio stations from the Shoutcast server. This may take a few seconds. If nothing appears after a while, check the DNS entry on the ''Basic Settings Page''.<br />
<br />
== Basic Settings Page ==<br />
<br />
[[../../../img/eir-webif04.png|[[File:../../../img/eir-webif04_md.png]]]]<br />
<br />
Like the Nut/OS Discoverer, this page allows to configure the EIR's network settings. However, it contains two more items, which are quite important for our radio.<br />
<br />
'''Note:''' Clicking ''Erase'' and confirming the following warning message will delete all settings, except the Ethernet MAC address.<br />
<br />
=== Proxy ===<br />
<br />
For security or bandwidth saving reasons your local network may not allow direct Internet access. Instead, all HTTP traffic must be routed via a proxy.<br />
<br />
=== DNS ===<br />
<br />
If you are not using DHCP or if your DHCP server doesn't provide any DNS info, you should enter a DNS IP here.<br />
<br />
Without a valid DNS entry, you will not be able to retrieve a station list on the ''discover page''. Furthermore, the radio will not be able to connect to some stations, which use host names instead of IP addresses.<br />
<br />
== Debug Output ==<br />
<br />
The EIR prints additional information on the serial RS-232 port. This comes quite handy in case of hardware and software problems.<br />
<br />
The settings are 115200,8,n,1. A so called [[../../documents/rs232primer.html|null modem cable]] is required to connect this interface to your PC.<br />
<br />
<pre class="coding">ICY 200 OK<br />
Content-Type: audio/mpeg<br />
icy-br:128<br />
icy-name:WDR5, Copyright: Westdeutscher Rundfunk 2008<br />
icy-pub:1<br />
icy-url:http://www.wdr.de<br />
icy-metaint:8192<br />
Server: Limecast 2.0.0<br />
<br />
Connected: 33476123 bytes free<br />
## Try 0x22008974<br />
Buffering<br />
....<br />
Meta=&quot;StreamTitle='';&quot;<br />
...............................................................................................<br />
..........................................................................................Savin<br />
g favorites<br />
......Playback started</pre><br />
== Pitfalls ==<br />
<br />
=== No browser connection ===<br />
<br />
Check the yellow LED in the EIR's RJ45 connector. If its not lit, something is wrong with your Ethernet cable.<br />
<br />
Try ping a.b.c.d on the command line. Replace a.b.c.d with the IP address of the EIR. If there is no response, check your network configuration.<br />
<br />
Check your browser configuration for any proxy setting and disable it, or at least for the IP address of the EIR.<br />
<br />
=== No music ===<br />
<br />
When connected to any radio station, the green LED in the EIR's RJ45 connector should blink rapidly. If not, try another station from the favorites page.<br />
<br />
=== No output at the serial port ===<br />
<br />
Make sure that<br />
<br />
# you are using a null modem cable, pins 2 and 3 crossed.<br />
# you correctly configured the terminal emulator (115.2kBaud, 8 data bits, no parity, 1 stop bit).<br />
# you disabled all handshakes.<br />
<br />
<br />
-----<br />
<br />
Return to the [[index.html|EIR project page]].<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/Vorbis_RecHardware/EIR/Vorbis Rec2017-07-13T09:10:30Z<p>Harald: Created page with "<div id="content"> = EIR Ogg Vorbis Recorder = By default, the VS1053 audio codec on the EIR board offers PCM recording only. However, VLSI Solution offers an Ogg Vorbis enc..."</p>
<hr />
<div><div id="content"><br />
<br />
= EIR Ogg Vorbis Recorder =<br />
<br />
By default, the VS1053 audio codec on the EIR board offers PCM recording only. However, VLSI Solution offers an Ogg Vorbis encoder plug-in. We will use this here to record an audio source connected to the EIR audio input, encode the data to Ogg Vorbis and store the result on a memory cards.<br />
<br />
The code presented on this page assumes, that you are familiar with Nut/OS. If not, you may look to the examples at our [http://www.ethernut.de/nutwiki/Nut/OS_Examples Nutwiki].<br />
<br />
== Using Memory Cards ==<br />
<br />
The document [[mmc.html|EIR Memory Card Support]] explains how configure Nut/OS and the EIR board for using the card socket. The main requirements are<br />
<br />
* Nut/OS 5.0.5 or later<br />
* Shortening SSC TK and RK signals on connector K1 (pins 17 with pin 20)<br />
<br />
== Loading Plug-Ins ==<br />
<br />
The following routine can be used to load a plug-in into the VS1053 chip:<br />
<br />
<pre class="coding">int LoadPlugInImage(int dh, int ph)<br />
{<br />
int got;<br />
uint_fast16_t i;<br />
uint8_t buf[5];<br />
int rec_type;<br />
VS_WRAM_DATA vswd;<br />
<br />
got = _read(ph, buf, 3);<br />
if (got != 3) {<br />
puts(&quot;Read error&quot;);<br />
return -1;<br />
}<br />
if (buf[0] != 'P' || buf[1] != '&amp;' || buf[2] != 'H') {<br />
puts(&quot;Not a plug-in?&quot;);<br />
return -1;<br />
}<br />
/* Prepare plug-in upload. */<br />
putchar('(');<br />
if (_ioctl(dh, AUDIO_WRITE_CMEM, NULL)) {<br />
puts(&quot;ioctl-err&quot;);<br />
}<br />
for (;;) {<br />
got = _read(ph, buf, 5);<br />
if (got != 5) {<br />
break;<br />
}<br />
rec_type = buf[0];<br />
<br />
vswd.vswd_size = buf[1];<br />
vswd.vswd_size &lt;&lt;= 8;<br />
vswd.vswd_size |= buf[2];<br />
vswd.vswd_addr = buf[3];<br />
vswd.vswd_addr &lt;&lt;= 8;<br />
vswd.vswd_addr |= buf[4];<br />
if (rec_type == VSIMG_RECTYP_I) {<br />
vswd.vswd_addr += 0x8000;<br />
}<br />
else if (rec_type == VSIMG_RECTYP_Y) {<br />
vswd.vswd_addr += 0x4000;<br />
}<br />
else if (rec_type == VSIMG_RECTYP_E) {<br />
vswd.vswd_data = NULL;<br />
putchar(')');<br />
if (_ioctl(dh, AUDIO_WRITE_CMEM, &amp;vswd)) {<br />
puts(&quot;ioctl-err&quot;);<br />
}<br />
return 0;<br />
}<br />
vswd.vswd_data = (uint16_t *) malloc(vswd.vswd_size);<br />
vswd.vswd_size &gt;&gt;= 1;<br />
for (i = 0; i &lt; vswd.vswd_size; i++) {<br />
got = _read(ph, buf, 2);<br />
if (got != 2) {<br />
break;<br />
}<br />
vswd.vswd_data[i] = buf[0];<br />
vswd.vswd_data[i] &lt;&lt;= 8;<br />
vswd.vswd_data[i] |= buf[1];<br />
}<br />
putchar('.');<br />
if (_ioctl(dh, AUDIO_WRITE_CMEM, &amp;vswd)) {<br />
puts(&quot;ioctl-err&quot;);<br />
}<br />
free(vswd.vswd_data);<br />
}<br />
return -1;<br />
}</pre><br />
This function expects 2 arguments<br />
<br />
* dh Handle of the previously opened audio device<br />
* ph Handle of a previously opened file that contains the plug-in<br />
<br />
This code snippet shows how to open the audio device:<br />
<br />
<pre class="coding">int fh;<br />
<br />
printf(&quot;Open audio device...&quot;);<br />
dh = _open(&quot;audio0&quot;, _O_RDWR | _O_BINARY);<br />
if (dh == -1) {<br />
printf(&quot;Error %d\n&quot;, errno);<br />
} else {<br />
puts(&quot;OK&quot;);<br />
}</pre><br />
Note, that the audio device needs to be registered first.<br />
<br />
<pre class="coding">printf(&quot;Register audio device...&quot;);<br />
if (NutRegisterSpiDevice(&amp;devSpiVsCodec0, &amp;spiBus0At91, 1)) {<br />
puts(&quot;failed&quot;);<br />
} else {<br />
puts(&quot;OK&quot;);<br />
}</pre><br />
The next code snippet shows how to open a plug-in file located on the memory card.<br />
<br />
<pre class="coding">int fh;<br />
<br />
fh = _open(&quot;PHAT0:/venc44k2q05.img&quot;, _O_RDWR | _O_BINARY);<br />
if (fh == -1) {<br />
printf(&quot;Error %d\n&quot;, errno);<br />
} else {<br />
LoadPlugInImage(dh, fh);<br />
_close(fh);<br />
puts(&quot;OK&quot;);<br />
}</pre><br />
Recording is simply done by reading from the audio device and writing to a file.<br />
<br />
<pre class="coding">static uint8_t ogg_buff[512];<br />
<br />
fh = _open(&quot;PHAT0:/myrecording.ogg&quot;, _O_CREAT | _O_TRUNC | _O_WRONLY | _O_BINARY);<br />
if (fh == -1) {<br />
printf(&quot;Error %d, can't open audio file\n&quot;, errno);<br />
} else {<br />
stop_recording = 0;<br />
while (1) {<br />
got = _read(dh, ogg_buff, sizeof(ogg_buff));<br />
if (got &lt;= 0 || stop_recording) {<br />
break;<br />
}<br />
if (_write(fh, ogg_buff, got) != got) {<br />
break;<br />
}<br />
_close(fh);<br />
}<br />
}</pre><br />
<br /><br />
<br /><br />
<br /><br />
<br />
Return to the [[index.html|EIR project page]].<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/TesterHardware/EIR/Tester2017-07-13T09:09:54Z<p>Harald: Created page with "<div id="content"> = EIR Hardware Tester = A first preview version 0.1.1 of the EIR Hardware Tester is available in this archive. It contai..."</p>
<hr />
<div><div id="content"><br />
<br />
= EIR Hardware Tester =<br />
<br />
A first preview version 0.1.1 of the EIR Hardware Tester is available in [[../../../arc/eirhwt-0.1.1.zip|this archive]]. It contains all source code as well as a pre-compiled binary and will test the following hardware:<br />
<br />
* MultiMedia Card Interface<br /><br />
Insert any MMC or SD-Card before running the test.<br />
* Ethernet Controller<br /><br />
The EIR must be connected to an Ethernet network.<br />
* Audio Codec<br /><br />
Very simple test, which will just read two registers.<br />
* Serial Flash<br /><br />
Extensive test, which will destroy the contents. As a result, your radio configuration will get lost.<br />
* SDRAM<br /><br />
Extensive test, which automatically detects the size of the SDRAM chip.<br />
<br />
== Running the Tester ==<br />
<br />
If running a Windows PC, use [[samba.html|SAM-BA]] to upload the binary to the EIR. Alternatively you can use the [[jtag.html|JTAG interface]].<br />
<br />
Attach the RS-232 connector on the EIR with any COM port of your PC, using a [[../../documents/rs232primer.html|null modem cable]]. Start a terminal emulator like<br /><br />
[http://hp.vector.co.jp/authors/VA002416/teraterm.html TeraTerm for Windows],<br /><br />
[http://alioth.debian.org/projects/minicom/ Minicom for Linux] or<br /><br />
[http://homepage.mac.com/dalverson/zterm/ ZTerm for Mac OS X].<br />
<br />
Configure the serial port to 115,200 Baud, 8 data bit, no parity and 1 stop bit. Disable all handshakes. When pressing the reset button, the following output should appear in the terminal emulator window.<br />
<br />
<pre class="coding">EIR Hardware Tester 0.1.1<br />
CPU Clock: 48.0548 MHz<br />
MMC Init...OK<br />
Manufacturer : 1<br />
OEM ID : 0<br />
Product name : 128MB<br />
Product rev. : 1<br />
Serial number: 3550871616<br />
Date Code : 152<br />
Detecting NIC...OK<br />
Reset NIC...OK<br />
Start NIC.....OK<br />
Detect VS10X3...OK<br />
Testing Dataflash................................................................OK<br />
Clear area ................................................................OK<br />
Pattern test................................................................OK<br />
Fill SDRAM ................................................................OK<br />
Test SDRAM ................................................................OK<br />
67108864 bytes SDRAM</pre><br />
Return to the [[index.html|EIR project page]].<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/SPIHardware/EIR/SPI2017-07-13T09:09:21Z<p>Harald: Created page with "<div id="content"> = EIR SPI Support = == AT91 Hardware SPI == The SAM7SE offers a single [http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus SPI], which is hardw..."</p>
<hr />
<div><div id="content"><br />
<br />
= EIR SPI Support =<br />
<br />
== AT91 Hardware SPI ==<br />
<br />
The SAM7SE offers a single [http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus SPI], which is hardwired to the VS1053 audio codec and the AT45DB321 serial flash.<br />
<br />
The [[mmc.html|memory card socket]] is intentionally not connected to the hardware SPI. When playing or recording MP3 files, memory cards may block the SPI bus for quite some time. If this happens, the audio codec may run out of buffer space. During decoding, this will result in annoying gaps and during encoding the audio recording file may become corrupted.<br />
<br />
== Bit banging SPI ==<br />
<br />
Actually, any available three GPIO pins can serve as SPI when using a [http://en.wikipedia.org/wiki/Bit_banging bit banging driver].<br />
<br />
Unfortunately, bit banging is quite slow. This had been expected during the design of the board and the memory card socket was attached to the SSC interface. From the data sheet it looks like it should be possible to use SSC for SPI communication, see next chapter.<br />
<br />
== SPI over AT91 SSC ==<br />
<br />
Although intended early, it turned out, that SSC will not directly work as SPI. No related Nut/OS driver appeared for several years. The problem was, that the receiver, when started once, will not stop after the first byte or word.<br />
<br />
Finally a solution was found by driving the receiver from an external clock and connecting this pin to the transmitter clock. This works, because the transmitter will stop when running out of data. The first SPI bus driver for the SSC interface became available in Nut/OS 5.0.5, which allows to read from or write to [[mmc.html|memory cards]] at full speed. As explained, this requires a minor hardware modification.<br />
<br />
[[eir10c_mmc_spi_mod.png|[[File:eir10c_mmc_spi_mod_480px.png]]]]<br />
Connecting pin 16 with pin 19 at the port A connector allows to drive the SSC receiver with the SSC transmitter clock.<br />
<br />
<br /><br />
<br /><br />
<br /><br />
<br />
Return to the [[index.html|EIR project page]].<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/SAM-BAHardware/EIR/SAM-BA2017-07-13T09:08:46Z<p>Harald: Created page with "<div id="content"> = EIR Firmware Upload Using SAM-BA = When powering up or resetting the EIR, the SAM7SE CPU will typically start running the firmware currently stored in i..."</p>
<hr />
<div><div id="content"><br />
<br />
= EIR Firmware Upload Using SAM-BA =<br />
<br />
When powering up or resetting the EIR, the SAM7SE CPU will typically start running the firmware currently stored in its internal flash memory.<br />
<br />
However, after erasing the chip or when using a new chip from the factory, the CPU will instead run the SAM-BA boot loader, which is permanently stored in the internal ROM. This boot loader allows to transfer new firmware from a PC to the flash memory via USB or RS-232.<br />
<br />
This document explains how to use the SAM-BA boot loader with the EIR board.<br />
<br />
== Required Tools ==<br />
<br />
Unfortunately, the tool used on the PC is available for the Windows operating system only.<br />
<br />
<ol><br />
<li>=== SAM-BA ===<br />
<br />
<p>Download AT91-ISP.exe from [http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3883 Atmel's website] and run it.</p></li><br />
<li>=== USB Connection ===<br />
<br />
<p>Use a standard USB cable to connect the EIR board to any free USB port on your PC.</p></li></ol><br />
<br />
== Firmware Upload ==<br />
<br />
Here is a step-by-step instruction about how to burn new firmware into the EIR board:<br />
<br />
<ol><br />
<li>=== Erase old firmware ===<br />
<br />
<p>On the EIR board connect pins 34 and 36 of K3 (Port C) using a 2.54 mm jumper. Press the reset button and remove the jumper. This activates the SAM-BA boot loader.</p></li><br />
<li>=== Start SAM-BA ===<br />
<br />
<p>[[../../../img/eirsamba01.png|[[File:../../../img/eirsamba01_tn.png]]]]</p><br />
<p>Start SAM-BA from the start menu. A small dialog window appears, which allows you to select the communication interface and the target board. Select ''\usb\ARM0\'' for the connection and ''AT91SAM7SE512-EK'' for the board.</p></li><br />
<li>=== Select new firmware ===<br />
<br />
<p>[[../../../img/eirsamba02a.png|[[File:../../../img/eirsamba02a_tn.png]]]]</p><br />
<p>Make sure that the ''Flash'' tab is selected and click on the ''Open Folder'' button to select the file to send. Use the file selection dialog to navigate to the right directory, select the binary file you want to upload and click ''Open''.</p></li><br />
<li>=== Send new firmware ===<br />
<br />
<p>[[../../../img/eirsamba04a.png|[[File:../../../img/eirsamba04a_tn.png]]]]</p><br />
<p>Click on the ''Send File'' button and wait a few seconds until the firmware has been uploaded.</p></li><br />
<li>=== Skip region lock ===<br />
<br />
<p>[[../../../img/eirsamba05a.png|[[File:../../../img/eirsamba05a_tn.png]]]]</p><br />
<p>After the upload has been done, a message box appears, asking for a region lock. Locking the region is not required. Click ''No''.</p></li><br />
<li>=== Optionally compare the result ===<br />
<br />
<p>[[../../../img/eirsamba07a.png|[[File:../../../img/eirsamba07a_tn.png]]]]</p><br />
<p>To make sure that everything worked well you may click the button ''Compare sent file with memory''.</p></li><br />
<li>=== Enable booting from flash ===<br />
<br />
<p>[[../../../img/eirsamba08.png|[[File:../../../img/eirsamba08_tn.png]]]]</p><br />
<p>Finally select the script ''Boot from Flash (GPNVM2)'' and click on ''Execute''.</p></li><br />
<li>=== Start the new firmware ===<br />
<br />
<p>Quit SAM-BA and press the reset button on the EIR board.</p></li></ol><br />
<br />
The whole procedure had been captured in this [[samba-demo.html|[[File:../../../img/demo2.gif|16x16px|swf]] Flash Movie]].<br />
<br />
Return to the [[index.html|EIR project page]].<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/OpenOCD/SDRAMHardware/EIR/OpenOCD/SDRAM2017-07-13T09:07:56Z<p>Harald: Created page with "<div id="content"> = OpenOCD for AT91SAM7SE - Part 5 = This is part 5 of our OpenOCD for AT91SAM7SE tutorial. == Using SDRAM == Compared to other ARM7TDMI..."</p>
<hr />
<div><div id="content"><br />
<br />
= OpenOCD for AT91SAM7SE - Part 5 =<br />
<br />
This is part 5 of our [[openocd.html|OpenOCD for AT91SAM7SE tutorial]].<br />
<br />
== Using SDRAM ==<br />
<br />
Compared to other ARM7TDMI embedded boards, the EIR provides a lot of RAM, 64 MBytes. This makes developing new applications quite convenient. Actually the author often uses the EIR to create and debug new Nut/OS applications for other boards. There is enough room to add all kind of test routines, extended debug output etc. Later, this extra code can be removed to squeeze the code into flash and RAM memory of the final target. Other advantages are, that uploading code into RAM is much faster than flashing and that you can set any number of breakpoints hassle-free.<br />
<br />
=== Memory Bus Initialization ===<br />
<br />
In the previous part we learned, how to access the 32 kBytes of static RAM, using OpenOCD's <code>mww</code> command. This SRAM is built into the AT91SAM7SE microcontroller chip. The large SDRAM, that we want to access now, is located in an external chip. Thus, we need to enable the external memory bus of the microcontroller first. This is done by enabling the related peripheral function of the memory bus pins. Again, we use memory write word commands to set the right I/O registers. You may check the data sheet for more details.<br />
<br />
<pre class="coding"># Initialize external memory bus.<br />
#<br />
proc eir_init_membus {} {<br />
# Enable address bus (A0, A2-A11, A13-A17) at PIO B<br />
mww 0xfffff674 0x0003effd ;# PIOB_BSR<br />
mww 0xfffff604 0x0003effd ;# PIOB_PDR<br />
<br />
# Enable 16 bit data bus at PIO C<br />
mww 0xfffff870 0x0000ffff ;# PIOC_ASR<br />
mww 0xfffff804 0x0000ffff ;# PIOC_PDR<br />
}</pre><br />
After calling this routine, we should be able to access the SDRAM chip, which is required for the next step.<br />
<br />
=== SDRAM Initialization ===<br />
<br />
While SRAM is ready-to-use immediately after power-up, SDRAM requires a special initialization sequence. When booting the AT91SAM7SE from flash, this is typically done in the runtime initialization part of the application. If we want to upload code via JTAG directly into SDRAM, then OpenOCD must take over this part.<br />
<br />
It's not easy, to get SDRAM timing right. A lot of data sheet reading and some calculations had to be done. To explain all the details would require a tutorial on its own. For now, just put the code below into your openocd.cfg. We have added many comments to the code, in case you are interested in the details.<br />
<br />
<pre class="coding"># Initialize the EIR SDRAM.<br />
#<br />
# EIR uses Samsung K4S511632D-UC75 SDRAM:<br />
# Organization: 32M x 16<br />
# 8k rows, 1k columns<br />
# 20ns row precharge time<br />
# 45ns min. and 100us max. row active time<br />
#<br />
# MCK cycle is 20ns when running at 48MHz.<br />
#<br />
proc eir_init_sdram {} {<br />
<br />
# Enable SDRAM control at PIO A<br />
#<br />
mww 0xfffff474 0x3f800000 ;# PIOA_BSR<br />
mww 0xfffff404 0x3f800000 ;# PIOA_PDR<br />
<br />
# Enable SDRAM chip select<br />
#<br />
mww 0xffffff80 0x00000002 ;# EBI_CSA<br />
<br />
# Set SDRAM characteristics in configuration register.<br />
# At 48MHz 1 cycle is about 21ns.<br />
#<br />
# 0x00000003 NC: Number of column bits<br />
# 0x00000002 10 bits, 1k columns<br />
#<br />
# 0x0000000C NR: Number of row bits<br />
# 0x00000008 13 bits, 8k rows<br />
#<br />
# 0x00000010 NB: Number of banks<br />
# 0x00000010 4 banks<br />
#<br />
# 0x00000060 CAS: CAS latency<br />
# 0x00000040 2 cycles<br />
#<br />
# 0x00000780 TWR: Write recovery delay<br />
# 0x00000100 2 cycles<br />
#<br />
# 0x00007800 TRC: Row cycle delay<br />
# 0x00002000 4 cycles<br />
#<br />
# 0x00078000 TRP: Row precharge delay<br />
# 0x00020000 4 cycles<br />
#<br />
# 0x00780000 TRCD: Row to column delay<br />
# 0x00100000 2 cycles<br />
#<br />
# 0x07800000 TRAS: Active to precharge delay<br />
# 0x01800000 3 cycles<br />
#<br />
# 0x78000000 TXSR: Exit self refresh to active delay<br />
# 0x20000000 4 cycles<br />
#<br />
mww 0xffffffb8 0x2192215a ;# SDRAMC_CR<br />
sleep 10<br />
<br />
# Issue 16 bit SDRAM command: NOP<br />
#<br />
mww 0xffffffb0 0x00000011 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
<br />
# Issue 16 bit SDRAM command: Precharge all<br />
#<br />
mww 0xffffffb0 0x00000012 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
<br />
# Issue 8 auto-refresh cycles<br />
#<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
<br />
# Issue 16 bit SDRAM command: Set mode register<br />
#<br />
mww 0xffffffb0 0x00000013 ;# SDRAMC_MR<br />
mww 0x20000014 0xcafedede<br />
<br />
# Set refresh rate count ???<br />
#<br />
mww 0xffffffb4 0x00000013 ;# SDRAMC_TR<br />
<br />
# Issue 16 bit SDRAM command: Normal mode<br />
#<br />
mww 0xffffffb0 0x00000010 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000180<br />
}</pre><br />
This procedure requires, that the main clock is running at 48MHz and that the memory bus had been enabled. This must be taken into account when adding a call to it in our reset handler:<br />
<br />
<pre class="coding"># Initialize the EIR board.<br />
#<br />
proc eir_init {} {<br />
eir_init_clock<br />
eir_init_membus<br />
eir_init_sdram<br />
}</pre><br />
As soon as you have added the two procedures <code>eir_init_membus</code> and <code>eir_init_sdram</code>, then the command <code>reset init</code>, if entered in a OpenOCD Telnet session, should enable OpenOCD to execute code in SDRAM.<br />
<br />
OK, it's not that easy. Many applications will have been created to run in flash memory, which is located at memory address 0. At least a different linker script is needed for code running in SDRAM located at memory address 0x20000000. When using interrupts, the ARM7 CPU expects its exception vectors starting at address 0. So we'd need a new runtime initialization, which remaps the internal SRAM to address 0 and copies the exception vectors from the SDRAM image to this location. However, this tutorial is about setting up OpenOCD only.<br />
<br />
While SDRAM is nice for code development and debugging, the final system will need code running in flash. The next part will show how to use OpenOCD for flashing code into the AT91SAM7SE.<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/OpenOCD/OptimizeHardware/EIR/OpenOCD/Optimize2017-07-13T09:07:26Z<p>Harald: Created page with "<div id="content"> = OpenOCD for AT91SAM7SE - Part 7 = This is part 7 of our OpenOCD for AT91SAM7SE tutorial. == Optimizing OpenOCD Configurations == Reme..."</p>
<hr />
<div><div id="content"><br />
<br />
= OpenOCD for AT91SAM7SE - Part 7 =<br />
<br />
This is part 7 of our [[openocd.html|OpenOCD for AT91SAM7SE tutorial]].<br />
<br />
== Optimizing OpenOCD Configurations ==<br />
<br />
Remember the flashy notes we got from OpenOCD when executing the <code>reset init</code> command?<br />
<br />
<pre class="coding">NOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.<br />
NOTE! Severe performance degradation without working memory enabled.<br />
NOTE! Severe performance degradation without fast memory access enabled. Type 'help fast'.</pre><br />
In this part we will show how to increase the speed of the JTAG communication. Furthermore, we will discuss, how to re-organize our configuration to make it a bit more re-usable.<br />
<br />
=== Work Area ===<br />
<br />
As stated in the previous part, OpenOCD flash drivers may use the JTAG interface to present code and data to the CPU without using any real memory. Code and data is shifted into special JTAG registers located between the core and peripherals, which make the CPU think it got these values from real memory. This is sometimes quite helpful to get a virgin system running small code fragments. But it is also slow, because a large number of low level JTAG command are required. Specifically on low end JTAG adapters like the Turtelizer 2, the USB becomes a real bottleneck.<br />
<br />
Luckily, OpenOCD offers a solution, if we can provide some RAM on the target board. In this case, OpenOCD will not have to mimic each code and data memory access via lengthy register shifting, but can upload code and data into the work area and let the CPU access this area directly, without JTAG intervention. A few kilobytes are sufficient, which makes the internal SRAM of the AT91SAM7SE a good candidate.<br />
<br />
It's quite obvious, that the related configuration is part of the debug target and, as such, needs to be added to the <code>target create</code> command. It turned out later, that this is somewhat inflexible. While the debug target needs to be declared during the configuration stage and can be declared once only, it is sometimes required to setup the work area after certain hardware initializations took place. In addition, it is often required to select different work areas for different tasks. Note, that the work area occupies memory and may clash with other firmware already running on the target.<br />
<br />
OpenOCD allows dynamic configuration of certain debug target parameters via the <code>configure</code> command, which must be prepended by the dotted name of the related debug target. To allow OpenOCD to use the last 8kBytes of internal SRAM as a work area, we define<br />
<br />
<pre class="coding">sam7se512.cpu configure -work-area-phys 0x00206000 -work-area-size 0x4000</pre><br />
You can add this line to openocd.cfg now.<br />
<br />
=== Debug Communication Channel ===<br />
<br />
Even if we have established a work area on the target, filling this with data or code via JTAG shifting is still cumbersome. Some CPUs, including the AT91SAM7SE, provide a UART like JTAG interface named debug communication channel, or just DCC, which is much easier to handle than the JTAG state machine. The following command tells OpenOCD to make use of the DCC:<br />
<br />
<pre class="coding">arm7_9 dcc_downloads enable</pre><br />
Unfortunately, this may not work on targets running at low speed. In our case it will probably not work until we switched the main clock to be fed by the PLL. Do not add this line to openocd.cfg now. We will soon see, where the best place for this configuration is.<br />
<br />
=== Fast Memory Access ===<br />
<br />
Frankly, I have no idea, what the following configuration internally works:<br />
<br />
<pre class="coding">arm7_9 fast_memory_access enable</pre><br />
But it significantly increases the transfer rate between the PC and the target. Again, this may not work at slow CPU clocks and we will soon add it at the right place within openocd.cfg.<br />
<br />
=== Increasing the JTAG Clock ===<br />
<br />
This is not new, we already set the JTAG clock in our current openocd.cfg. However, as soon as we have the CPU running at 48kHz, we should increase the JTAG clock as well. And, we can also all the other optimizations, which are not working reliable at slow clocks. The right place is, you guessed it, the reset-init handler.<br />
<br />
<pre class="coding"># Initialize the EIR board.<br />
#<br />
proc eir_init {} {<br />
eir_init_clock<br />
<br />
# Minimum ICE cycle time is 102ns (9800 kHz)<br />
adapter_khz 9800<br />
arm7_9 dcc_downloads enable<br />
arm7_9 fast_memory_access enable<br />
<br />
eir_init_membus<br />
eir_init_sdram<br />
}</pre><br />
Finally we have now a complete OpenOCD configuration for our EIR board:<br />
<br />
<pre class="coding">interface turtle<br />
ft2232_layout turtelizer2<br />
ft2232_device_desc &quot;Turtelizer JTAG/RS232 Adapter&quot;<br />
<br />
reset_config srst_only<br />
adapter_khz 8<br />
<br />
jtag newtap sam7se512 cpu -irlen 4 -expected-id 0x3f0f0f0f<br />
target create sam7se512.cpu arm7tdmi -chain-position sam7se512.cpu<br />
sam7se512.cpu configure -work-area-phys 0x00206000 -work-area-size 0x4000<br />
<br />
flash bank sam7se512.flash.0 at91sam7 0 0 0 0 sam7se512.cpu 0 0 0 0 0 0 0 18432<br />
flash bank sam7se512.flash.1 at91sam7 0 0 0 0 sam7se512.cpu 1 0 0 0 0 0 0 18432<br />
<br />
sam7se512.cpu configure -event reset-init { eir_init }<br />
<br />
# Initialize the EIR board.<br />
#<br />
proc eir_init {} {<br />
eir_init_clock<br />
<br />
# Minimum ICE cycle time is 102ns (9800 kHz)<br />
adapter_khz 9800<br />
arm7_9 dcc_downloads enable<br />
arm7_9 fast_memory_access enable<br />
<br />
eir_init_membus<br />
eir_init_sdram<br />
}<br />
<br />
# Initialize the EIR clocks.<br />
#<br />
# The board uses an 18.432MHz crystal.<br />
# Let the CPU run at 48MHz.<br />
#<br />
proc eir_init_clock {} {<br />
<br />
# Enable main oscillator.<br />
#<br />
# Start-up time of 6 x 8 slow clocks.<br />
#<br />
mww 0xfffffc20 0x00000601 ;# CKGR_MOR<br />
sleep 2<br />
<br />
# Configure the PLL.<br />
#<br />
# 18.432MHz * (72 + 1) / 14 = 96MHz<br />
#<br />
# Divider 14 (0x0e)<br />
# Start-up time of 28 (0x1c) slow clocks<br />
# Multiplier 72 (0x48)<br />
#<br />
mww 0xfffffc2C 0x00481c0e ;# CKGR_PLLR<br />
sleep 1<br />
<br />
# Select PLL clock and divide it by 2<br />
#<br />
# 96MHz / 2 = 48MHz<br />
#<br />
mww 0xfffffc30 0x00000007 ;# PMC_MCKR<br />
sleep 1<br />
<br />
# 1 wait for read, 2 waits for write<br />
# We have 48 master clocks in 1us<br />
mww 0xffffff60 0x00480100 ;# MC_FMR<br />
}<br />
<br />
# Initialize external memory bus.<br />
#<br />
proc eir_init_membus {} {<br />
# Enable address bus (A0, A2-A11, A13-A17) at PIO B<br />
mww 0xfffff674 0x0003effd ;# PIOB_BSR<br />
mww 0xfffff604 0x0003effd ;# PIOB_PDR<br />
<br />
# Enable 16 bit data bus at PIO C<br />
mww 0xfffff870 0x0000ffff ;# PIOC_ASR<br />
mww 0xfffff804 0x0000ffff ;# PIOC_PDR<br />
}<br />
<br />
# Initialize the EIR SDRAM.<br />
#<br />
# EIR uses Samsung K4S511632D-UC75 SDRAM:<br />
# Organization: 32M x 16<br />
# 8k rows, 1k columns<br />
# 20ns row precharge time<br />
# 45ns min. and 100us max. row active time<br />
#<br />
# MCK cycle is 20ns when running at 48MHz.<br />
#<br />
proc eir_init_sdram {} {<br />
<br />
# Enable SDRAM control at PIO A<br />
#<br />
mww 0xfffff474 0x3f800000 ;# PIOA_BSR<br />
mww 0xfffff404 0x3f800000 ;# PIOA_PDR<br />
<br />
# Enable SDRAM chip select<br />
#<br />
mww 0xffffff80 0x00000002 ;# EBI_CSA<br />
<br />
# Set SDRAM characteristics in configuration register.<br />
# At 48MHz 1 cycle is about 21ns.<br />
#<br />
# 0x00000003 NC: Number of column bits<br />
# 0x00000002 10 bits, 1k columns<br />
#<br />
# 0x0000000C NR: Number of row bits<br />
# 0x00000008 13 bits, 8k rows<br />
#<br />
# 0x00000010 NB: Number of banks<br />
# 0x00000010 4 banks<br />
#<br />
# 0x00000060 CAS: CAS latency<br />
# 0x00000040 2 cycles<br />
#<br />
# 0x00000780 TWR: Write recovery delay<br />
# 0x00000100 2 cycles<br />
#<br />
# 0x00007800 TRC: Row cycle delay<br />
# 0x00002000 4 cycles<br />
#<br />
# 0x00078000 TRP: Row precharge delay<br />
# 0x00020000 4 cycles<br />
#<br />
# 0x00780000 TRCD: Row to column delay<br />
# 0x00100000 2 cycles<br />
#<br />
# 0x07800000 TRAS: Active to precharge delay<br />
# 0x01800000 3 cycles<br />
#<br />
# 0x78000000 TXSR: Exit self refresh to active delay<br />
# 0x20000000 4 cycles<br />
#<br />
mww 0xffffffb8 0x2192215a ;# SDRAMC_CR<br />
sleep 10<br />
<br />
# Issue 16 bit SDRAM command: NOP<br />
#<br />
mww 0xffffffb0 0x00000011 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
<br />
# Issue 16 bit SDRAM command: Precharge all<br />
#<br />
mww 0xffffffb0 0x00000012 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
<br />
# Issue 8 auto-refresh cycles<br />
#<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
<br />
# Issue 16 bit SDRAM command: Set mode register<br />
#<br />
mww 0xffffffb0 0x00000013 ;# SDRAMC_MR<br />
mww 0x20000014 0xcafedede<br />
<br />
# Set refresh rate count ???<br />
#<br />
mww 0xffffffb4 0x00000013 ;# SDRAMC_TR<br />
<br />
# Issue 16 bit SDRAM command: Normal mode<br />
#<br />
mww 0xffffffb0 0x00000010 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000180<br />
}</pre><br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/OpenOCD/NutOsHardware/EIR/OpenOCD/NutOs2017-07-13T09:06:50Z<p>Harald: Created page with "<div id="content"> = OpenOCD for AT91SAM7SE - Part 9 = This is the last part of our OpenOCD for AT91SAM7SE tutorial. == Nut/OS Integration == OpenOCD can..."</p>
<hr />
<div><div id="content"><br />
<br />
= OpenOCD for AT91SAM7SE - Part 9 =<br />
<br />
This is the last part of our [[openocd.html|OpenOCD for AT91SAM7SE tutorial]].<br />
<br />
== Nut/OS Integration ==<br />
<br />
OpenOCD can be easily installed on Linux from the source code package. As this requires several Unix-like tools, which in turn rely on certain capabilities of the underlying OS, building OpenOCD on Windows is quite difficult and will most likely fail many times before you succeed, if ever.<br />
<br />
For general use, I'd recommend Freddie Chopin's binary distribution for Windows, available at [http://www.freddiechopin.info/ www.freddiechopin.info]. If you want to use the EIR with Nut/OS, the Turtelizer support package is probably the better choice. The installation detects an existing Nut/OS installation, and places the OpenOCD executable into nut\tools\win32, which needs to be in your PATH environment anyway. Configuration scripts are stored in nut\tools\turtelizer2, for which Makefiles exist to allow using <code>make burn</code> to build and upload your application binary in one go without hassle.<br />
<br />
=== OpenOCD Command Line ===<br />
<br />
Throughout this tutorial we simply started OpenOCD without any command line options. All required configuration was included in a local file openocd.cfg, either directly or by include external configuration files.<br />
<br />
This will become inconvenient, if you are working on several different project, because each time you need to create a local openocd.cfg and over the time, some of them may become outdated when upgrading OpenOCD or Nut/OS and must be updated manually. If you stick to configurations files supplied by OpenOCD or Nut/OS, this can be avoided. Even if they won't fit, you only need to apply changes at one place to make all your projects work again.<br />
<br />
Without a local configuration file, we need to tell OpenOCD, where to find them. This can be done in the same way as in our local configuration. More precisely, instead of reading commands from a file, you can provide commands on the command line, using the command line option <code>-c</code>. Instead of using openocd.cfg with the follwoing lines<br />
<br />
<pre class="coding">add_script_search_dir [../../nut/tools/turtelizer2]<br />
source [find interface/turtelizer2.cfg]<br />
source [find board/eir.cfg]</pre><br />
we can call OpenOCD with the following options.<br />
<br />
<pre class="coding">openocd -s ../../nut/tools/turtelizer2 -c &quot;source [find interface/turtelizer2.cfg]&quot; -c &quot;source [find board/eir.cfg]&quot;</pre><br />
=== Nut/OS Makeburn ===<br />
<br />
Nut/OS provides several Makefiles, which will automatically launch OpenOCD with the right command line options, when requested to build the <code>burn</code> target. For example, entering<br />
<br />
<pre class="coding">make burn</pre><br />
while in the directory of a sample application, configured for building applications running in external RAM, will build the binary image and finally call OpenOCD with the following options:<br />
<br />
{|<br />
! Option<br />
! Function<br />
|-<br />
| -s ../../nut/tools/turtelizer2<br />
| Specifies the OpenOCD search path, which is located in the Nut/OS source tree.<br />
|-<br />
| -c &quot;source [find interface/turtelizer2.cfg]&quot;<br />
| Loads the JTAG programmer configuration, that had been selected by the programmer selection in the Nut/OS Configurator.<br />
|-<br />
| -c &quot;source [find board/eir.cfg]&quot;<br />
| Loads the board configuration of the EIR.<br />
|-<br />
| -c init<br />
| Switches OpenOCD from configuration stage to run stage.<br />
|-<br />
| -c &quot;reset init&quot;<br />
| Calls the reset init handler to initialize the hardware.<br />
|-<br />
| -c &quot;load_image firmware.bin 0x20000000&quot;<br />
| Transfers the firmware image to the SDRAM on the EIR.<br />
|-<br />
| -c &quot;verify_image webradio.bin 0x20000000&quot;<br />
| Verifies the firmware image with the contents of the SDRAM. This is optionally, but fast enough to allow this extra safety.<br />
|-<br />
| -c &quot;resume 0x20000000&quot;<br />
| Starts the uploaded firmware on the target.<br />
|-<br />
| -c shutdown<br />
| Shuts down OpenOCD, so the command line becomes available again for the next command.<br />
|}<br />
<br />
The result is, that your application starts running on your target with a snap. An even more interesting feature is, that if you configured Nut/OS be build applications that shall run in flash memory, the binaries will be programmed into flash instead. Magic, isn't it? How can this work?<br />
<br />
When requested to build the target <code>burn</code>, the Nut/OS Makefiles will figure out the Makeburn file with the configured extension. For OpenOCD, this is <code>nut/app/Makeburn.arm-oocd</code>. Among other things, this file contains the following fragment:<br />
<br />
<pre class="coding">ifeq ($(PLATFORM), ELEKTOR_IR1)<br />
BURNBOARD = eir<br />
# Initialize clocks and SDRAM.<br />
BURNCMDS += -c &quot;reset init&quot;<br />
ifeq ($(LDNAME), at91sam7se512_xram)<br />
# Load image into external SDRAM.<br />
BURNCMDS += -c &quot;load_image $(ITARG) 0x20000000&quot;<br />
# Verify image in external SDRAM.<br />
BURNCMDS += -c &quot;verify_image $(ITARG) 0x20000000&quot;<br />
# Start image in external SDRAM.<br />
BURNCMDS += -c &quot;resume 0x20000000&quot;<br />
endif<br />
ifeq ($(LDNAME), at91sam7se512_rom)<br />
BURNCMDS += -c &quot;flash write_image erase $(ITARG) 0x100000 bin&quot;<br />
BURNCMDS += -c &quot;verify_image $(ITARG) 0x100000 bin&quot;<br />
BURNCMDS += -c &quot;at91sam7 gpnvm 2 set&quot;<br />
BURNCMDS += -c &quot;reset run&quot;<br />
endif<br />
endif</pre><br />
This part is executed when building for the EIR, in which case PLATFORM is set to ELEKTOR_IR by the Nut/OS Configurator. Now the base name of the linker script is examined. If it has been configured as <code>at91sam7se512_xram</code> BURNCMD will be loaded with the options we listed in the table above. If it's configured as <code>at91sam7se512_rom</code>, then BURNCMD will be loaded with the command line options required to program the binary image into flash memory.<br />
<br />
=== The End? ===<br />
<br />
Not really. I'm sure there are many open questions and even bugs, as this is the first version. Watch out for updates.<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/OpenOCD/JTAGHardware/EIR/OpenOCD/JTAG2017-07-13T09:06:18Z<p>Harald: Created page with "<div id="content"> = OpenOCD for AT91SAM7SE - Part 2 = For the second part of our Tutorial it's assumed, that you have successfully openocd_hardware.html|..."</p>
<hr />
<div><div id="content"><br />
<br />
= OpenOCD for AT91SAM7SE - Part 2 =<br />
<br />
For the second part of our [[openocd.html|Tutorial]] it's assumed, that you have successfully [[openocd_hardware.html|setup your hardware]].<br />
<br />
== Configuring the JTAG Adapter ==<br />
<br />
In order to get OpenOCD up and running, we must configure the JTAG interface. Without this, OpenOCD will start, print a few error messages and stop.<br />
<br />
<pre class="coding">Open On-Chip Debugger 0.6.0-rc1 (2012-08-08-20:04)<br />
Licensed under GNU GPL v2<br />
For bug reports, read<br />
http://openocd.sourceforge.net/doc/doxygen/bugs.html<br />
Runtime Error: embedded:startup.tcl:47: Can't find openocd.cfg<br />
in procedure 'script'<br />
at file &quot;embedded:startup.tcl&quot;, line 47<br />
Error: Debug Adapter has to be specified, see &quot;interface&quot; command<br />
in procedure 'init'</pre><br />
When started without any command line options, OpenOCD expects its configuration in a file named openocd.cfg, located in the current directory. Let's create this file, using a text editor.<br />
<br />
=== Selecting the Interface ===<br />
<br />
The first thing we need to tell OpenOCD in this file is the name of the interface. This depends on the JTAG adapter you are using. For most USB JTAG adapters based on FTDI chips, this will be:<br />
<br />
<pre class="coding">interface ft2232</pre><br />
For the Turtelizer support package, this is slightly different:<br />
<br />
<pre class="coding">interface turtle</pre><br />
You may run into a problem here. Some time ago the OpenOCD development team decided not to provide any official binaries anymore. They offer the source code only, expecting the vendor of the JTAG hardware to build the binaries. All supported interfaces are optionally selected during this build stage and therefore the binary you received from somewhere may not support your specific JTAG hardware.<br />
<br />
Luckily, if the specified interface is not supported, OpenOCD will list all known interfaces<br />
<br />
<pre class="coding">The following debug interfaces are available:<br />
1: parport<br />
2: ft2232<br />
3: ftdi<br />
4: usb_blaster<br />
5: amt_jtagaccel<br />
6: gw16012<br />
7: presto<br />
8: usbprog<br />
9: jlink<br />
10: vsllink<br />
11: rlink<br />
12: ulink<br />
13: arm-jtag-ew<br />
14: stlink</pre><br />
If your's is not included, ask your JTAG hardware vendor for the right binary. Btw., the list above has been retrieved from the binary offered at [http://www.freddiechopin.info/ www.freddiechopin.info]. Freddie's binary distributions for Windows PCs are most complete and highly recommended.<br />
<br />
=== Selecting the Layout ===<br />
<br />
Next, we must specify the interface layout. The reason is, that only the main JTAG signals are at fixed pins of the FTDI chip. Selecting pins for additional I/Os like reset lines or LEDs is left to the manufacturer. Layouts are currently hard coded in the OpenOCD binary and selected with the ft2232_layout configuration. For the Turtelizer 2, add the following line to openocd.cfg.<br />
<br />
<pre class="coding">ft2232_layout turtelizer2</pre><br />
Since OpenOCD version 0.6.0 it is possible to specify the pin layout in the configuration file. But this hadn't been documented yet. Freddie Chopin was so kind to add two new configuration files for Turtelizer 2, which make use of this new feature. One is for Rev-B and the other for Rev-C adapters. By the time we will try to test this new feature.<br />
<br />
=== Selecting the USB Device ===<br />
<br />
Saving our two lines in openocd.cfg (interface and layout) and trying to run OpenOCD will still fail with<br />
<br />
<pre class="coding">Error: neither device description nor serial number specified<br />
Error: please add &quot;ft2232_device_desc &quot; or &quot;ft2232_serial &quot; to your .cfg file<br />
in procedure 'init'</pre><br />
OpenOCD needs to know, which USB device it should connect to. You may either specify the interface description or the devices serial number here. When using Turtelizer 2, add the following line to openocd.cfg:<br />
<br />
<pre class="coding">ft2232_device_desc &quot;Turtelizer JTAG/RS232 Adapter&quot;</pre><br />
Saving this and trying to run OpenOCD again should give you an output similar to:<br />
<br />
<pre class="coding">Info : only one transport option; autoselect 'jtag'<br />
Info : device: 4 &quot;2232C&quot;<br />
Info : deviceID: 67354056<br />
Info : SerialNumber: TLVE8EUJA<br />
Info : Description: Turtelizer JTAG/RS232 Adapter A<br />
Error: An adapter speed is not selected in the init script.<br />
Insert a call to adapter_khz or jtag_rclk to proceed.<br />
in procedure 'init'</pre><br />
OpenOCD still terminates, but we will not test your patience any further. The next step will solve this final issue.<br />
<br />
Just one more hint. If you look to the output above, you will probably notice the serial number. This is a unique ID, which may be used instead of the device descriptor. You will need this if you are attaching more than one Turtelizer to the same PC:<br />
<br />
<pre class="coding">ft2232_serial TLVE8EUJA</pre><br />
=== Selecting the Initial Adapter Speed ===<br />
<br />
Unlike other interfaces like RS-232 or Ethernet, JTAG does not define any standardized speeds. Uploading large binaries to your target board can become quite annoying, so you always want to run at the highest possible speed. This, however, is limited by two factors:<br />
<br />
* Maximum speed of the JTAG adapter<br />
* Maximum speed of the target board<br />
<br />
The latter is the critical part, which requires further evaluation. Most ARM CPUs start running at a special slow clock. This is also true for the EIR, which initially uses the 32kHz oscillator. Usually the bootloader will reconfigure the clocks to let the CPU run at full speed. But when the CPU is controlled via JTAG, the bootloader may not have a chance to execute or may be completely absent. On the other hand, many ARM CPUs cannot handle JTAG clock frequencies much higher than the CPU clock.<br />
<br />
The good news first: There is a mechanism called adaptive clocking, where the CPU returns the JTAG clock on a separate pin. This signal is used by the JTAG adapter to synchronize its output clock. OpenOCD supports this mode, when the following is given in the configuration file:<br />
<br />
<pre class="coding">jtag_rclk 3000</pre><br />
It will set the JTAG clock speed to 3MHz and automatically adjust it to lower speeds, if required.<br />
<br />
Now some bad news. First of all, Turtelizer doesn't support this feature. Simply because the FT2232D used in this adapter doesn't support it. There are other adapters based on the later FT2232H, which do support adaptive clocking. But still, they are not able to synchronize down to the full range. It is still required to &quot;manually&quot; adjust the clock. Well, and the final show stopper is the AT91SAM7SE CPU, which neither supports adaptive clocking.<br />
<br />
We will solve this by starting at a low frequency of 8kHz. Later we will use OpenOCD to bring up the PLL, run the CPU at full speed and increase the Turtelizer's JTAG speed to its maximum. Add the following line to openocd.cfg:<br />
<br />
<pre class="coding">adapter_khz 8</pre><br />
For completeness, here is the contents of openocd.cfg we got so far:<br />
<br />
<pre class="coding">interface ft2232<br />
ft2232_layout turtelizer2<br />
ft2232_device_desc &quot;Turtelizer JTAG/RS232 Adapter&quot;<br />
adapter_khz 8</pre><br />
If using the Turtelizer 2 support package, replace the first line with<br />
<br />
<pre class="coding">interface turtle</pre><br />
Starting OpenOCD should now result in the following output and this time OpenOCD will no longer terminated with an error.<br />
<br />
<pre class="coding">Open On-Chip Debugger 0.6.0-rc1 (2012-08-08-20:04)<br />
Licensed under GNU GPL v2<br />
For bug reports, read<br />
http://openocd.sourceforge.net/doc/doxygen/bugs.html<br />
Info : only one transport option; autoselect 'jtag'<br />
8 kHz<br />
Info : device: 4 &quot;2232C&quot;<br />
Info : deviceID: 67354056<br />
Info : SerialNumber: TLVE8EUJA<br />
Info : Description: Turtelizer JTAG/RS232 Adapter A<br />
Info : clock speed 8 kHz<br />
Warn : There are no enabled taps. AUTO PROBING MIGHT NOT WORK!!<br />
Warn : AUTO auto0.tap - use &quot;jtag newtap auto0 tap -expected-id 0x3f0f0f0f ...&quot;<br />
Warn : AUTO auto0.tap - use &quot;... -irlen 4&quot;<br />
Warn : gdb services need one or more targets defined</pre><br />
Of course, your output will slightly vary. But in general you can see, that OpenOCD automatically switches to auto probing and even suggest to add <code>jtag newtap</code> to our configuration file. You will here more about this in the third part.<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/OpenOCD/HardwareHardware/EIR/OpenOCD/Hardware2017-07-13T09:05:50Z<p>Harald: Created page with "<div id="content"> = OpenOCD for AT91SAM7SE - Part 1 = This is the first part of our OpenOCD for AT91SAM7SE tutorial. == Hardware Setup == There's not muc..."</p>
<hr />
<div><div id="content"><br />
<br />
= OpenOCD for AT91SAM7SE - Part 1 =<br />
<br />
This is the first part of our [[openocd.html|OpenOCD for AT91SAM7SE tutorial]].<br />
<br />
== Hardware Setup ==<br />
<br />
There's not much to explain here. Connect your JTAG adapter to the target board and your PC, then power up your target board.<br />
<br />
[[EIR-JTAG-TURT.png|[[File:480px-EIR-JTAG-TURT.png|Connecting the JTAG adapter]]]]<br />
When using the Turtelizer 2 with the Elektor Internet Radio, you will also need a special JTAG connector adapter.<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/OpenOCD/FlashingHardware/EIR/OpenOCD/Flashing2017-07-13T09:05:22Z<p>Harald: Created page with "<div id="content"> = OpenOCD for AT91SAM7SE - Part 6 = This is part 6 of our OpenOCD for AT91SAM7SE tutorial. == Flashing the Target == Almost all tiny to..."</p>
<hr />
<div><div id="content"><br />
<br />
= OpenOCD for AT91SAM7SE - Part 6 =<br />
<br />
This is part 6 of our [[openocd.html|OpenOCD for AT91SAM7SE tutorial]].<br />
<br />
== Flashing the Target ==<br />
<br />
Almost all tiny to medium sized microcontrollers today offer flash memory, either for an initial boot loader or to contain the complete application code. JTAG doesn't provide any native support for flash memory programming. Instead, JTAG is used to access hardware registers. Some of them, which are part of the CPU's JTAG interface, may even be used to mimic code and data values, making the CPU running code without any real memory available. This feature can be used to run code fragments, which act as drivers for the flash controller.<br />
<br />
=== OpenOCD Drivers ===<br />
<br />
A few standards had been established for external flash programming, but internal flash programming, like the one on the AT91SAM7 series, is typically incompatible among chip vendors. OpenOCD contains a number of hard coded flash drivers, including one named at91sam7, which works fine for the internal flash of the AT91SAM7SE CPU and even allows to program the GPNVM bits.<br />
<br />
Flash memory is typically divided into so called flash banks. Note, that a single chip may contain one or more banks. While the AT91SAM7SE256 contains a single bank only, the AT91SAM7SE512 got two of them. This is important to know, at least when your firmware image grows above 256kBytes. Each flash bank must be declared separately in the configuration file with the <code>flash bank</code> command. Its general form is<br />
<br />
<pre class="coding">flash bank &lt;name&gt; &lt;driver&gt; &lt;base&gt; &lt;size&gt; &lt;chip_width&gt; &lt;bus_width&gt; &lt;target&gt; &lt;driver_options&gt;</pre><br />
A lot of parameters, though, most of them are relevant for external flash only and ignored by drivers for internal flash. For our CPU we declare the two banks as follows.<br />
<br />
<pre class="coding">flash bank sam7se512.flash.0 at91sam7 0 0 0 0 sam7se512.cpu 0 0 0 0 0 0 0 18432<br />
flash bank sam7se512.flash.1 at91sam7 0 0 0 0 sam7se512.cpu 1 0 0 0 0 0 0 18432</pre><br />
After adding the two lines to openocd.cfg and restarting OpenOCD, you should be able to retrieve the flash memory information by entering the following commands in a Telnet session.<br />
<br />
<pre class="coding">flash info 0<br />
flash info 1</pre><br />
You probably noticed, that these commands take time. Actually flashing the chip will take a lot more time, an unacceptable long time. We will try to solve this issue in our next part.<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/OpenOCD/CPUHardware/EIR/OpenOCD/CPU2017-07-13T09:04:50Z<p>Harald: Created page with "<div id="content"> = OpenOCD for AT91SAM7SE - Part 3 = This is part 3 of our OpenOCD for AT91SAM7SE tutorial. == Configuring the CPU == === Declaring a TA..."</p>
<hr />
<div><div id="content"><br />
<br />
= OpenOCD for AT91SAM7SE - Part 3 =<br />
<br />
This is part 3 of our [[openocd.html|OpenOCD for AT91SAM7SE tutorial]].<br />
<br />
== Configuring the CPU ==<br />
<br />
=== Declaring a TAP ===<br />
<br />
In the last part OpenOCD suggested to add a <code>jtag newtap</code> command to the configuration. Its general form is<br />
<br />
<pre class="coding">jtag newtap &lt;chipname&gt; &lt;tapname&gt; &lt;options&gt;</pre><br />
We just need to fill out the parameters given in angle brackets. They have the following meanings.<br />
<br />
{|<br />
! Parameter<br />
! Description<br />
|-<br />
| chipname<br />
| A board may contain several chips with JTAG interfaces. You must specify unique chip names to identify each of them.<br />
|-<br />
| tapname<br />
| A chip may contain several test access points (TAPs). You must specify a unique TAP names to identify each of them.<br />
|-<br />
| options<br />
| At least, we must specify the length of the JTAG instruction register of the TAP, using the option <code>-irlen</code>. It is also a good idea to let OpenOCD know the expected JTAG ID-Code using the option <code>-expected-id</code>.<br />
|}<br />
<br />
Remember the output we got at the end of the last part:<br />
<br />
<pre class="coding">Warn : There are no enabled taps. AUTO PROBING MIGHT NOT WORK!!<br />
Warn : AUTO auto0.tap - use &quot;jtag newtap auto0 tap -expected-id 0x3f0f0f0f ...&quot;<br />
Warn : AUTO auto0.tap - use &quot;... -irlen 4&quot;</pre><br />
In most cases the autoprobe feature works quite well and OpenOCD suggests to use<br />
<br />
<pre class="coding">jtag newtap auto tap -irlen 4 -expected-id 0x3f0f0f0f</pre><br />
For the AT91SAM7SE512 let's replace the chip name <code>auto</code> with <code>sam7se512</code> and the TAP name <code>tap</code> with <code>cpu</code>. This gives the following line, which you should add to your existing openocd.cfg. Btw. you can stop the running OpenOCD executable with Ctrl-C.<br />
<br />
<pre class="coding">jtag newtap sam7se512 cpu -irlen 4 -expected-id 0x3f0f0f0f</pre><br />
We may later refer to this specific TAP by its dotted name <code>sam7se512.cpu</code>.<br />
<br />
Starting OpenOCD with this modified configuration should produce the following output<br />
<br />
<pre class="coding">Open On-Chip Debugger 0.6.0-rc1 (2012-08-08-20:04)<br />
Licensed under GNU GPL v2<br />
For bug reports, read<br />
http://openocd.sourceforge.net/doc/doxygen/bugs.html<br />
Info : only one transport option; autoselect 'jtag'<br />
8 kHz<br />
Info : device: 4 &quot;2232C&quot;<br />
Info : deviceID: 67354056<br />
Info : SerialNumber: TLVE8EUJA<br />
Info : Description: Turtelizer JTAG/RS232 Adapter A<br />
Info : clock speed 8 kHz<br />
Info : JTAG tap: sam7se512.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)<br />
Warn : gdb services need one or more targets defined</pre><br />
We still have one warning, which will be handled next.<br />
<br />
=== Declaring a Debug Target ===<br />
<br />
Some of you may simply want to use OpenOCD to flash a target board, but in the first place it has been created for debugging. So far we have configured the JTAG interface only, nothing is known about CPU internals.<br />
<br />
While OpenOCD is mainly used with ARM CPUs, it supports a few other targets, more or less well. Controlling different targets via JTAG is complicated. For example, targets may be switched to different modes or states, may or may not have an MMU and even a simple reset may result in a number of side effects, which are not always trivial to handle. Even if it would have been limited to ARM cores, there are quite many variants with totally different features.<br />
<br />
As a result, most of OpenOCD's knowledge about target CPUs has been hard coded and you select the right routines by simply telling OpenOCD, which kind of chip it is connected to at a given TAP, using the configuration command <code>target create</code>. Its general form is<br />
<br />
<pre class="coding">target create &lt;targetname&gt; &lt;type&gt; &lt;options&gt;</pre><br />
The meaning of the parameters is given in the following table.<br />
<br />
{|<br />
! Parameter<br />
! Description<br />
|-<br />
| targetname<br />
| The name that will be used to access this target. By convention the same dotted name as for the TAP is used here.<br />
|-<br />
| type<br />
| This is the important option, which let's OpenOCD know the type of chip to control. For the AT91SAM7SE we specify <code>arm7tdmi</code>.<br />
|-<br />
| options<br />
| Several options are available to further specify the chip variant and to provide additional information about the target. At least one option is mandantory, the <code>-chain-position</code>, which tells OpenOCD the name of the TAP this target is attached at.<br />
|}<br />
<br />
For the AT91SAM7SE512 we should use<br />
<br />
<pre class="coding">target create sam7se512.cpu arm7tdmi -chain-position sam7se512.cpu</pre><br />
After adding this line to the openocd.cfg (don't forget to save it), OpenOCD should start running without any more errors or warnings.<br />
<br />
<pre class="coding">Open On-Chip Debugger 0.6.0-rc1 (2012-08-08-20:04)<br />
Licensed under GNU GPL v2<br />
For bug reports, read<br />
http://openocd.sourceforge.net/doc/doxygen/bugs.html<br />
Info : only one transport option; autoselect 'jtag'<br />
8 kHz<br />
sam7se512.cpu<br />
Info : device: 4 &quot;2232C&quot;<br />
Info : deviceID: 67354056<br />
Info : SerialNumber: TLVE8EUJA<br />
Info : Description: Turtelizer JTAG/RS232 Adapter A<br />
Info : clock speed 8 kHz<br />
Info : JTAG tap: sam7se512.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)<br />
Info : Embedded ICE version 1<br />
Info : sam7se512.cpu: hardware has 2 breakpoint/watchpoint units</pre><br />
At this point, the complete contents of your openocd.cfg should be<br />
<br />
<pre class="coding">interface ft2232<br />
ft2232_layout turtelizer2<br />
ft2232_device_desc &quot;Turtelizer JTAG/RS232 Adapter&quot;<br />
adapter_khz 8<br />
jtag newtap sam7se512 cpu -irlen 4 -expected-id 0x3f0f0f0f<br />
target create sam7se512.cpu arm7tdmi -chain-position sam7se512.cpu</pre><br />
Again, replacing the first line with <code>interface turtle</code> when using the Turtelizer support package.<br />
<br />
Are you bored? Don't worry, hard times are ahead. In the next part you will learn how to configure the PLL of the EIR board. Dig out the AT91SAM7SE data sheet now.<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/OpenOCD/ConventHardware/EIR/OpenOCD/Convent2017-07-13T09:04:28Z<p>Harald: Created page with "<div id="content"> = OpenOCD for AT91SAM7SE - Part 8 = This is part 8 of our OpenOCD for AT91SAM7SE tutorial. == OpenOCD Script Conventions == So far we h..."</p>
<hr />
<div><div id="content"><br />
<br />
= OpenOCD for AT91SAM7SE - Part 8 =<br />
<br />
This is part 8 of our [[openocd.html|OpenOCD for AT91SAM7SE tutorial]].<br />
<br />
== OpenOCD Script Conventions ==<br />
<br />
So far we have stored our complete configuration in a local file named openocd.cfg, which is loaded by OpenOCD automatically, if it exists.<br />
<br />
In this part we will split this configuration into several files to make it a bit more re-usable. OpenOCD allows to include external configuration files into our local configuration. So we may re-write openocd.cfg to something like<br />
<br />
<pre class="coding">add_script_search_dir [/usr/share/openocd/scripts]<br />
source [find interface/turtelizer2.cfg]<br />
source [find board/eir.cfg]</pre><br />
where <code>board/eir.cfg</code> further includes the CPU configuration by using<br />
<br />
<pre class="coding">source [find target/at91sam7se512.cfg]</pre><br />
Actually OpenOCD provides a number of prepared configuration scripts, which you may use for your specific configuration. We will also discuss the conventions used in these scripts.<br />
<br />
=== Separating Adapter Configurations ===<br />
<br />
Obviously, it will make a lot of sense to move adapter specific configurations into a separate configuration file. It allows to use the same target board with different JTAG adapters. However, the devil is in the details. Let's take a look to the reset configuration as an example. We defined<br />
<br />
<pre class="coding">reset_config srst_only</pre><br />
which is perfect when using Turtelizer 2 Rev-B with the EIR board, because neither of them provides the TAP reset signal nTRST. However, Turtelizer 2 Rev-C does provide it, and the same is true for Ethernut 5. The following table shows, that the reset configuration can't be clearly assigned to the adapter or the board, because it depends on both.<br />
<br />
{|<br />
! <br />
! Turtelizer 2.0B<br />
! Turtelizer 2.0C<br />
|-<br />
| EIR<br />
| srst_only<br />
| srst_only<br />
|-<br />
| Ethernut 5<br />
| srst_only<br />
| trst_and_srst<br />
|}<br />
<br />
The OpenOCD manual states, that <code>reset_config</code> belongs to the board configuration. That doesn't make much sense either, because in most cases this is CPU specific. In very rare cases the board may not route the nTRST signal to the JTAG connector, although it's available on the CPU. Fact is, that in the official OpenOCD distribution <code>reset_config</code> is provided in about 75 board configurations, but also, against the stated rule, in nearly 50 CPU configurations. This includes the configuration for the AT91SAM7SE, which is even wrongly specified, as far as I can say:<br />
<br />
<pre class="coding">reset_config srst_only srst_pulls_trst ;# This is incorrect, do not use!</pre><br />
As explained, nTRST doesn't matter for the AT91SAM7SE and we can painlessly fulfill the rule, assigning it to the board configuration. So, the following lines are left for our adapter configuration:<br />
<br />
<pre class="coding">interface ft2232<br />
ft2232_layout turtelizer2<br />
ft2232_device_desc &quot;Turtelizer JTAG/RS232 Adapter&quot;<br />
ft2232_vid_pid 0x0403 0xbdc8</pre><br />
Again, you may have to replace <code>interface ft2232</code> by <code>interface turtle</code> when using the Turtelizer support package.<br />
<br />
Also note, that the last line, specifying VID and PID, is not really required. When using more than one Turtelizer concurrently on the same PC, you must create a separate configuration file for each of them and additionally declare the unique serial number of the individual adapter in each file.<br />
<br />
<pre class="coding">ft2232_serial &lt;serial number&gt;</pre><br />
=== Separating CPU and Board Configurations ===<br />
<br />
Without question, separating CPU and board specific configuration has the advantage, that we can re-use CPU configurations for other boards which are based on the same CPU. Again, some configuration items may not be clearly assignable to either the CPU or the board.<br />
<br />
Definitely, the reset-init event handler and all the procedures called from within this handler belong to the board configuration. Other board may use<br />
<br />
* different crystals (eir_init_clock)<br />
* different or no SDRAM (eir_init_sdram)<br />
* the memory bus pins for GPIO (eir_init_membus)<br />
<br />
As discussed above, we will also assign the reset configuration to the board. Here is the resulting file:<br />
<br />
<pre class="coding">reset_config srst_only<br />
adapter_khz 8<br />
<br />
sam7se512.cpu configure -event reset-init { eir_init }<br />
<br />
# Initialize the EIR board.<br />
#<br />
proc eir_init {} {<br />
eir_init_clock<br />
<br />
# Minimum ICE cycle time is 102ns (9800 kHz)<br />
adapter_khz 9800<br />
arm7_9 dcc_downloads enable<br />
arm7_9 fast_memory_access enable<br />
<br />
eir_init_membus<br />
eir_init_sdram<br />
}<br />
<br />
# Initialize the EIR clocks.<br />
#<br />
# The board uses an 18.432MHz crystal.<br />
# Let the CPU run at 48MHz.<br />
#<br />
proc eir_init_clock {} {<br />
<br />
# Enable main oscillator.<br />
#<br />
# Start-up time of 6 x 8 slow clocks.<br />
#<br />
mww 0xfffffc20 0x00000601 ;# CKGR_MOR<br />
sleep 2<br />
<br />
# Configure the PLL.<br />
#<br />
# 18.432MHz * (72 + 1) / 14 = 96MHz<br />
#<br />
# Divider 14 (0x0e)<br />
# Start-up time of 28 (0x1c) slow clocks<br />
# Multiplier 72 (0x48)<br />
#<br />
mww 0xfffffc2C 0x00481c0e ;# CKGR_PLLR<br />
sleep 1<br />
<br />
# Select PLL clock and divide it by 2<br />
#<br />
# 96MHz / 2 = 48MHz<br />
#<br />
mww 0xfffffc30 0x00000007 ;# PMC_MCKR<br />
sleep 1<br />
<br />
# 1 wait for read, 2 waits for write<br />
# We have 48 master clocks in 1us<br />
mww 0xffffff60 0x00480100 ;# MC_FMR<br />
}<br />
<br />
# Initialize external memory bus.<br />
#<br />
proc eir_init_membus {} {<br />
# Enable address bus (A0, A2-A11, A13-A17) at PIO B<br />
mww 0xfffff674 0x0003effd ;# PIOB_BSR<br />
mww 0xfffff604 0x0003effd ;# PIOB_PDR<br />
<br />
# Enable 16 bit data bus at PIO C<br />
mww 0xfffff870 0x0000ffff ;# PIOC_ASR<br />
mww 0xfffff804 0x0000ffff ;# PIOC_PDR<br />
}<br />
<br />
# Initialize the EIR SDRAM.<br />
#<br />
# EIR uses Samsung K4S511632D-UC75 SDRAM:<br />
# Organization: 32M x 16<br />
# 8k rows, 1k columns<br />
# 20ns row precharge time<br />
# 45ns min. and 100us max. row active time<br />
#<br />
# MCK cycle is 20ns when running at 48MHz.<br />
#<br />
proc eir_init_sdram {} {<br />
<br />
# Enable SDRAM control at PIO A<br />
#<br />
mww 0xfffff474 0x3f800000 ;# PIOA_BSR<br />
mww 0xfffff404 0x3f800000 ;# PIOA_PDR<br />
<br />
# Enable SDRAM chip select<br />
#<br />
mww 0xffffff80 0x00000002 ;# EBI_CSA<br />
<br />
# Set SDRAM characteristics in configuration register.<br />
# At 48MHz 1 cycle is about 21ns.<br />
#<br />
# 0x00000003 NC: Number of column bits<br />
# 0x00000002 10 bits, 1k columns<br />
#<br />
# 0x0000000C NR: Number of row bits<br />
# 0x00000008 13 bits, 8k rows<br />
#<br />
# 0x00000010 NB: Number of banks<br />
# 0x00000010 4 banks<br />
#<br />
# 0x00000060 CAS: CAS latency<br />
# 0x00000040 2 cycles<br />
#<br />
# 0x00000780 TWR: Write recovery delay<br />
# 0x00000100 2 cycles<br />
#<br />
# 0x00007800 TRC: Row cycle delay<br />
# 0x00002000 4 cycles<br />
#<br />
# 0x00078000 TRP: Row precharge delay<br />
# 0x00020000 4 cycles<br />
#<br />
# 0x00780000 TRCD: Row to column delay<br />
# 0x00100000 2 cycles<br />
#<br />
# 0x07800000 TRAS: Active to precharge delay<br />
# 0x01800000 3 cycles<br />
#<br />
# 0x78000000 TXSR: Exit self refresh to active delay<br />
# 0x20000000 4 cycles<br />
#<br />
mww 0xffffffb8 0x2192215a ;# SDRAMC_CR<br />
sleep 10<br />
<br />
# Issue 16 bit SDRAM command: NOP<br />
#<br />
mww 0xffffffb0 0x00000011 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
<br />
# Issue 16 bit SDRAM command: Precharge all<br />
#<br />
mww 0xffffffb0 0x00000012 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
<br />
# Issue 8 auto-refresh cycles<br />
#<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
<br />
# Issue 16 bit SDRAM command: Set mode register<br />
#<br />
mww 0xffffffb0 0x00000013 ;# SDRAMC_MR<br />
mww 0x20000014 0xcafedede<br />
<br />
# Set refresh rate count ???<br />
#<br />
mww 0xffffffb4 0x00000013 ;# SDRAMC_TR<br />
<br />
# Issue 16 bit SDRAM command: Normal mode<br />
#<br />
mww 0xffffffb0 0x00000010 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000180<br />
}</pre><br />
Configuration of the TAP, the debug target and the internal flash memory are definitely CPU related.<br />
<br />
Defining a work area is a problem, though. By using internal RAM, we may assign it to the CPU. However, it depends on the firmware that is running on the board, how much RAM we have available and whether we should assign the lower or the upper part.<br />
<br />
While a work area is not mandatory, it is essential for user experience, because it significantly improves the JTAG data transfer. The suggestion is to define it in the CPU configuration. If it interferes with running firmware, it may be overridden in a user configuration file.<br />
<br />
This will give us the following CPU configuration for the AT91SAM7SE512:<br />
<br />
<pre class="coding">jtag newtap sam7se512 cpu -irlen 4 -expected-id 0x3f0f0f0f<br />
target create sam7se512.cpu arm7tdmi -chain-position sam7se512.cpu<br />
sam7se512.cpu configure -work-area-phys 0x00206000 -work-area-size 0x4000<br />
<br />
flash bank sam7se512.flash.0 at91sam7 0 0 0 0 sam7se512.cpu 0 0 0 0 0 0 0 18432<br />
flash bank sam7se512.flash.1 at91sam7 0 0 0 0 sam7se512.cpu 1 0 0 0 0 0 0 18432</pre><br />
=== Defining Tcl Variables ===<br />
<br />
In part 4 of the tutorial it had been pointed out, that using a script language in configuration files allows us to define procedures for event based configurations. Another, more obvious advantage is to be able to define variables. They are not really required, so far we didn't use any.<br />
<br />
However, variables will make code easier maintainable. For example, at many places we are referring to the chip name <code>sam7se512</code>. Putting this name into a variable, which is used throughout the configuration instead of the literal name, would make changing it much easier. You may now ask: Why would someone want to do this? Indeed, there are several reasons.<br />
<br />
The most likely reason to modify the chip name is a board, which contains two AT91SAM7SE512 chips. If we put<br />
<br />
<pre class="coding">if { [info exists CHIPNAME] } {<br />
set _CHIPNAME $CHIPNAME<br />
} else {<br />
set _CHIPNAME sam7se512<br />
}</pre><br />
into our board configuration file, then the variable _CHIPNAME will be <code>sam7se512</code> by default. Using _CHIPNAME instead of <code>sam7se512</code> in the remaining configuration will allow us, to use the same CPU configuration file for both CPUs.<br />
<br />
<pre class="coding">set CHIPNAME sam7se512.0<br />
source [find target/at91sam7se512.cfg]<br />
set CHIPNAME sam7se512.1<br />
source [find target/at91sam7se512.cfg]</pre><br />
Side note: Those of you, who are even less familiar with Tcl than I am, may get confused now. Let me explain. CHIPNAME and _CHIPNAME are different variable names. If you want to refer to the contents of a variable, you add a dollar sign in front. For example, $CHIPNAME will be replaced by the contents of the variable CHIPNAME.<br />
<br />
Almost all existing scripts use a kind of standard set of variables. Several variables are also explained in the OpenOCD manual. Thus, it is a good idea to follow this convention, even if we didn't need any of them to get our local configuration up and running.<br />
<br />
Here we present our final CPU configuration file. You should name it <code>at91sam7se512.cfg</code> and store it in subdirectory <code>target</code> of the OpenOCD installation directory, when running Windows, or <code>/usr/share/openocd/scripts</code> on most Linux PCs. Most probably this file already exists and you should make a backup copy first. Anyway, if you compare the existing file with the one we developed during our tutorial, you won't find many differences. And if you find any, you will be able now to decide, which one is better.<br />
<br />
<pre class="coding"># ATMEL sam7se512<br />
# Example: the &quot;Elektor Internet Radio&quot; - EIR<br />
# http://www.ethernut.de/en/hardware/eir/index.html<br />
<br />
if { [info exists CHIPNAME] } {<br />
set _CHIPNAME $CHIPNAME<br />
} else {<br />
set _CHIPNAME sam7se512<br />
}<br />
<br />
if { [info exists ENDIAN] } {<br />
set _ENDIAN $ENDIAN<br />
} else {<br />
set _ENDIAN little<br />
}<br />
<br />
if { [info exists CPUTAPID] } {<br />
set _CPUTAPID $CPUTAPID<br />
} else {<br />
set _CPUTAPID 0x3f0f0f0f<br />
}<br />
<br />
# JTAG Test Access Point<br />
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID<br />
<br />
# JTAG Debug Target<br />
set _TARGETNAME $_CHIPNAME.cpu<br />
target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME -variant arm7tdmi<br />
<br />
# OpenOCD Work Area<br />
$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0<br />
<br />
# Flash Memory Banks<br />
set _FLASHNAME $_CHIPNAME.flash<br />
flash bank $_FLASHNAME.0 at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432<br />
flash bank $_FLASHNAME.1 at91sam7 0 0 0 0 $_TARGETNAME 1 0 0 0 0 0 0 18432</pre><br />
And here we have the final board configuration file for the Elektor Internet Radio. This one should be named <code>eir.cfg</code> and stored in subdirectory <code>boards</code>. Again, keep any exiting file as a backup.<br />
<br />
<pre class="coding"># Elector Internet Radio Board<br />
# http://www.ethernut.de/en/hardware/eir/<br />
<br />
source [find target/at91sam7se512.cfg]<br />
<br />
# Target events<br />
#<br />
$_TARGETNAME configure -event reset-init { eir_init }<br />
<br />
adapter_khz 200<br />
<br />
# Initialize the EIR board.<br />
#<br />
proc eir_init {} {<br />
eir_init_reset<br />
eir_init_clock<br />
<br />
# Minimum ICE cycle time is 102ns (9800 kHz)<br />
adapter_khz 5000<br />
arm7_9 dcc_downloads enable ;# Enable faster DCC downloads<br />
arm7_9 fast_memory_access enable<br />
#jtag_khz 9800<br />
<br />
eir_init_sdram<br />
# flash probe 0<br />
}<br />
<br />
<br />
# Initialize the EIR reset logic.<br />
#<br />
proc eir_init_reset {} {<br />
<br />
# Disable watchdog<br />
mww 0xfffffd44 0x00008000 ;# WDT_MR<br />
<br />
# Enable user reset<br />
mww 0xfffffd08 0xa5000001 ;# RSTC_MR<br />
}<br />
<br />
<br />
# Initialize the EIR clocks.<br />
#<br />
# The board uses an 18.432MHz crystal.<br />
# Let the CPU run at 48MHz.<br />
#<br />
proc eir_init_clock {} {<br />
<br />
# Enable main oscillator.<br />
#<br />
# Start-up time of 6 x 8 slow clocks.<br />
#<br />
mww 0xfffffc20 0x00000601 ;# CKGR_MOR<br />
sleep 2<br />
<br />
# Configure the PLL.<br />
#<br />
# 18.432MHz * (72 + 1) / 14 = 96MHz<br />
#<br />
# Divider 14 (0x0e)<br />
# Start-up time of 28 (0x1c) slow clocks<br />
# Multiplier 72 (0x48)<br />
#<br />
mww 0xfffffc2C 0x00481c0e ;# CKGR_PLLR<br />
sleep 1<br />
<br />
# Select PLL clock and divide it by 2<br />
#<br />
# 96MHz / 2 = 48MHz<br />
#<br />
mww 0xfffffc30 0x00000007 ;# PMC_MCKR<br />
sleep 1<br />
<br />
# 1 wait for read, 2 waits for write<br />
# We have 48 master clocks in 1us<br />
mww 0xffffff60 0x00480100 ;# MC_FMR<br />
}<br />
<br />
<br />
# Initialize the EIR SDRAM.<br />
#<br />
# EIR uses Samsung K4S511632D-UC75 SDRAM:<br />
# Organization: 32M x 16<br />
# 8k rows, 1k columns<br />
# 20ns row precharge time<br />
# 45ns min. and 100us max. row active time<br />
#<br />
# MCK cycle is 20ns when running at 48MHz.<br />
#<br />
proc eir_init_sdram {} {<br />
<br />
# Enable address and data bus<br />
#<br />
eir_init_membus<br />
<br />
# Enable SDRAM control at PIO A<br />
#<br />
mww 0xfffff474 0x3f800000 ;# PIOA_BSR<br />
mww 0xfffff404 0x3f800000 ;# PIOA_PDR<br />
<br />
# Enable SDRAM chip select<br />
#<br />
mww 0xffffff80 0x00000002 ;# EBI_CSA<br />
<br />
# Set SDRAM characteristics in configuration register.<br />
# At 48MHz 1 cycle is about 21ns.<br />
#<br />
# 0x00000003 NC: Number of column bits<br />
# 0x00000002 10 bits, 1k columns<br />
#<br />
# 0x0000000C NR: Number of row bits<br />
# 0x00000008 13 bits, 8k rows<br />
#<br />
# 0x00000010 NB: Number of banks<br />
# 0x00000010 4 banks<br />
#<br />
# 0x00000060 CAS: CAS latency<br />
# 0x00000040 2 cycles<br />
#<br />
# 0x00000780 TWR: Write recovery delay<br />
# 0x00000100 2 cycles<br />
#<br />
# 0x00007800 TRC: Row cycle delay<br />
# 0x00002000 4 cycles<br />
#<br />
# 0x00078000 TRP: Row precharge delay<br />
# 0x00020000 4 cycles<br />
#<br />
# 0x00780000 TRCD: Row to column delay<br />
# 0x00100000 2 cycles<br />
#<br />
# 0x07800000 TRAS: Active to precharge delay<br />
# 0x01800000 3 cycles<br />
#<br />
# 0x78000000 TXSR: Exit self refresh to active delay<br />
# 0x20000000 4 cycles<br />
#<br />
mww 0xffffffb8 0x2192215a ;# SDRAMC_CR<br />
sleep 10<br />
<br />
# Issue 16 bit SDRAM command: NOP<br />
#<br />
mww 0xffffffb0 0x00000011 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
<br />
# Issue 16 bit SDRAM command: Precharge all<br />
#<br />
mww 0xffffffb0 0x00000012 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
<br />
# Issue 8 auto-refresh cycles<br />
#<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
mww 0xffffffb0 0x00000014 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000000<br />
<br />
# Issue 16 bit SDRAM command: Set mode register<br />
#<br />
mww 0xffffffb0 0x00000013 ;# SDRAMC_MR<br />
mww 0x20000014 0xcafedede<br />
<br />
# Set refresh rate count ???<br />
#<br />
mww 0xffffffb4 0x00000013 ;# SDRAMC_TR<br />
<br />
# Issue 16 bit SDRAM command: Normal mode<br />
#<br />
mww 0xffffffb0 0x00000010 ;# SDRAMC_MR<br />
mww 0x20000000 0x00000180<br />
}</pre><br />
Last not least our final configuration for the Turtelizer 2, to be placed in <code>interface/turtelizer2.cfg</code>.<br />
<br />
<pre class="coding">#<br />
# egnite Turtelizer 2<br />
#<br />
# http://www.ethernut.de/en/hardware/turtelizer/index.html<br />
#<br />
<br />
# Replace with<br />
#interface turtle<br />
# when using the Turtelizer support package<br />
interface ft2232<br />
<br />
ft2232_device_desc &quot;Turtelizer JTAG/RS232 Adapter&quot;<br />
ft2232_layout turtelizer2<br />
ft2232_vid_pid 0x0403 0xbdc8</pre><br />
The last part will give you a few usage examples. Although it focuses on Nut/OS applications, you may find it generally useful.<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/OpenOCDHardware/EIR/OpenOCD2017-07-13T09:03:40Z<p>Harald: Created page with "<div id="content"> = Configuring OpenOCD for the AT91SAM7SE = The following tutorial will explain, how to use [http://openocd.sourceforge.net/ OpenOCD] with an AT91SAM7SE bo..."</p>
<hr />
<div><div id="content"><br />
<br />
= Configuring OpenOCD for the AT91SAM7SE =<br />
<br />
The following tutorial will explain, how to use [http://openocd.sourceforge.net/ OpenOCD] with an AT91SAM7SE board. But instead of presenting a ready-to-run configuration, we will start from ground up, developing all configuration items step by step.<br />
<br />
Note, that this tutorial is about configuration only. We will not explain how to build OpenOCD binaries or how to use OpenOCD for debugging.<br />
<br />
== Requirements ==<br />
<br />
To follow this tutorial, some hardware and software is required:<br />
<br />
* A PC running Windows or Linux.<br /><br />
It may work for OS X too, but unfortunately we haven't tried this lately. For the tutorial we are using Windows, but it won't actually matter.<br />
* The OpenOCD software, already installed on your PC.<br /><br />
In this tutorial we are using version 0.6.0-rc1, but version 0.5.0 should work as well.<br />
* Any USB JTAG adapter based on an FTDI chip.<br /><br />
We will use the Turtelizer 2 as an example.<br />
* Any target board with JTAG interface, which is based on the AT91SAM7SE.<br /><br />
As an example we are using the Elektor Internet Radio.<br />
<br />
== Overview ==<br />
<br />
* [[Hardware/EIR/OpenOCD/Hardware|Part 1: Hardware Setup]]<br />
* [[Hardware/EIR/OpenOCD/JTAG|Part 2: Configuring the JTAG adapter]]<br />
* [[Hardware/EIR/OpenOCD/CPU|Part 3: Configuring the CPU]]<br />
* [[Hardware/EIR/OpenOCD/Clocks|Part 4: Configuring the Clocks]]<br />
* [[Hardware/EIR/OpenOCD/SDRAM|Part 5: Using SDRAM]]<br />
* [[Hardware/EIR/OpenOCD/Flashing|Part 6: Flashing the Target]]<br />
* [[Hardware/EIR/OpenOCD/Optimize|Part 7: Optimizing OpenOCD Configurations]]<br />
* [[Hardware/EIR/OpenOCD/Convent|Part 8: OpenOCD Script Conventions]]<br />
* [[Hardware/EIR/OpenOCD/NutOs|Part 9: Nut/OS Integration]]<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/OpenOCD/ClocksHardware/EIR/OpenOCD/Clocks2017-07-13T09:00:52Z<p>Harald: Created page with "<div id="content"> = OpenOCD for AT91SAM7SE - Part 4 = This is part 4 of our OpenOCD for AT91SAM7SE tutorial. == Configuring the Clocks == === Using Tcl =..."</p>
<hr />
<div><div id="content"><br />
<br />
= OpenOCD for AT91SAM7SE - Part 4 =<br />
<br />
This is part 4 of our [[openocd.html|OpenOCD for AT91SAM7SE tutorial]].<br />
<br />
== Configuring the Clocks ==<br />
<br />
=== Using Tcl ===<br />
<br />
Although OpenOCD configuration files may look like ordinary text files, they are not. Instead they are executables, or more precisely, Tcl scripts. OpenOCD includes a tiny Tcl interpreter named Jim Tcl. Using script languages instead of dumb configuration lines can make configurations smarter.<br />
<br />
And actually we need this now. So far, OpenOCD reads our configuration file and immediately executes the commands line by line. To setup the PLL in order to get our CPU running at full speed, we want to access certain I/O registers. Naturally, we won't be able to do that until we have created and configured the TAP and the debug target via <code>jtag newtap</code> and <code>target create</code>, resp. No problem, as long as we keep the commands in our configuration file in the right order.<br />
<br />
But what, if we press the reset button? The CPU will return to its slow clock and OpenOCD would have to re-read and re-execute the configuration again. That's just a simple example. Typically there are other events than reset, which we need to handle when debugging a target board.<br />
<br />
OpenOCD provides a clever solution, which may be confusing, if you are not aware of it. The program starts in a so called configuration stage, where all configuration commands are executed immediately while reading them from the configuration file. When done, it switches to the so called run state. Be aware, that some commands are rejected during the configuration stage, while others are rejected in the run state. Of course, many commands may be executed in either state. Furthermore, Tcl commands to be executed during run state must be defined within Tcl procedures.<br />
<br />
I know... some of you do not want to learn a new programming language just to get OpenOCD up and running. I'll promise you, you don't need to learn more than a few simple syntax rules, which are quite similar to other programming languages you are already familiar with. Frankly, I never liked Tcl, but that's between ourselves.<br />
<br />
=== Accessing Memory Addresses ===<br />
<br />
OpenOCD provides a few commands for reading from and writing to memory addresses. Obviously they are accepted in run mode only. As we learned, we have to create a Tcl procedure. But this is true for the configuration file only. As soon as OpenOCD finished reading that file (or files, as we will see later), it switches automatically into run state. To interactively execute commands in this state, we can use OpenOCD's Telnet interface. If not running already, start OpenOCD in one command line window. Then open another command line and enter<br />
<br />
<pre class="coding">telnet localhost 4444</pre><br />
You will get the OpenOCD command prompt, ready to serve you. The most important command is memory write word, <code>mww</code> followed by the memory address to write to, followed by the data to write. Let's try the internal SRAM of the AT91SAM7SE, which is located at memory address 0x200000:<br />
<br />
<pre class="coding">mww 0x200000 0x12345678</pre><br />
In most cases this will immediately fail, because the CPU is running and occupying the memory bus. To stop the CPU, enter<br />
<br />
<pre class="coding">halt</pre><br />
Now try the memory write command again. You can use the cursor keys on your keyboard to recall previously entered commands. To read from the same address, use the memory display word command, <code>mdw</code> followed by the memory address to read from.<br />
<br />
<pre class="coding">mdw 0x200000</pre><br />
It should display the same value that we wrote into this memory word.<br />
<br />
OK, now get your data sheet and write the right values to the right registers to enable the right PLL to let the CPU run at the right speed. You got all informations required to do that.<br />
<br />
Too hard? What's your problem? You don't know where to start reading? Believe me, there are chips on the market, which will require hours of hard work to get the clocks working. The AT91SAM7SE is one of the most convenient parts. Anyway, I'll give you a helping hand.<br />
<br />
=== Setting up the PLL ===<br />
<br />
Roughly following chapter 29.7 of the AT91SAM7SE data sheet, we will first enable the main oscillator by writing 0x701 into register CKGR_MOR. The startup time is set to 56 slow clock cycles.<br />
<br />
<pre class="coding">mww 0xfffffc20 0x00000701</pre><br />
Next, we set up the PLL divider and multiplier to generate a frequency of 96MHz. We will set the divider to 14 and the multiplier to 72. Based on the 18.432MHz crystal mounted on the EIR, we will get 18.432MHz * (72 + 1) / 14 = 96.11MHz. The startup time should be 28 slow clock cycles. This setting is written into register CKGR_PLLR.<br />
<br />
<pre class="coding">mww 0xfffffc2C 0x00481c0e</pre><br />
Now we select the PLL clock divided by 2 as our master clock in register PMC_MCKR.<br />
<br />
<pre class="coding">mww 0xfffffc30 0x00000007</pre><br />
As soon as this has been done, our CPU is running at 48MHz.<br />
<br />
Finally we set register MC_FMR to 1 wait state for read and 2 wait states for write access to the internal flash memory. This is not really required until we really access that memory area. But we do it here, because it depends on our clock settings.<br />
<br />
<pre class="coding">mww 0xffffff60 0x00480100</pre><br />
Now we want to put this sequence into a Tcl procedure to be placed into our openocd.cfg configuration file. But wait. As explained in the data sheet, we have to wait at certain points until the clock has become stable. When entering commands manually, this is no issue, because the clocks will become stable before we are able to enter the next command. However, executing the same commands within a script may be too fast. One solution would be to use the mem2array command to read examine register contents. But is it worth the effort, just to get the target up and running a few milliseconds earlier? Probably not, so let's add a simple sleep command instead, followed by the number of milliseconds that OpenOCD should wait before executing the next command.<br />
<br />
You may later come back to this piece and it may be hard to find out, what this code is actually doing. We could, for example, use Tcl variables for register names to make the code more readable. I prefer to use good comment lines:<br />
<br />
<pre class="coding"># Initialize the EIR clocks.<br />
#<br />
# The board uses an 18.432MHz crystal.<br />
# Let the CPU run at 48MHz.<br />
#<br />
proc eir_init_clock {} {<br />
<br />
# Enable main oscillator.<br />
#<br />
# Start-up time of 7 x 8 slow clocks.<br />
#<br />
mww 0xfffffc20 0x00000701 ;# CKGR_MOR<br />
sleep 2<br />
<br />
# Configure the PLL.<br />
#<br />
# 18.432MHz * (72 + 1) / 14 = 96MHz<br />
#<br />
# Divider 14 (0x0e)<br />
# Start-up time of 28 (0x1c) slow clocks<br />
# Multiplier 72 (0x48)<br />
#<br />
mww 0xfffffc2C 0x00481c0e ;# CKGR_PLLR<br />
sleep 1<br />
<br />
# Select PLL clock and divide it by 2<br />
#<br />
# 96MHz / 2 = 48MHz<br />
#<br />
mww 0xfffffc30 0x00000007 ;# PMC_MCKR<br />
sleep 1<br />
<br />
# 1 wait for read, 2 waits for write<br />
# We have 48 master clocks in 1us<br />
mww 0xffffff60 0x00480100 ;# MC_FMR<br />
}</pre><br />
Note: People may report their bad experience with OpenOCD, and justifiably so. As you can see, # is used to mark a comment. However, using this on the same line after a command had been working in early releases, but stopped working at a certain version (which I can''t remember right now), making many existing configurations fail, even those included in the official distribution. Adding a semicolon in front of the comment fixes this, but... There had been several other cases of incompatibilities and users tend to avoid updating OpenOCD or using OpenOCD at all. Luckily, this seems to have changed lately, at least upgrading from 0.5.0 to 0.6.0-rc1 was totally painless. In general, OpenOCD is a most reliable tool. I just wanted to explain, why a few developers are talking bad about it and try to avoid it like a plague. If you are one of them, give it one more try, it's worth the effort. Now, back to the topic.<br />
<br />
Add the procedure eir_init_clock to your current openocd.cfg. If you still have the Telnet connection established, you can enter<br />
<br />
<pre class="coding">shutdown</pre><br />
to terminate both, Telnet and OpenOCD.<br />
<br />
You can test the Tcl procedure by simply entering its name in the Telnet session, but this won't make much sense until we have declared a reset event handler. With the current configuration, even resetting the board via OpenOCD won't work. This will be fixed in the next step.<br />
<br />
=== Reset Configuration ===<br />
<br />
JTAG specifies two reset signals, nSRST and nTRST. While the first one is used to reset the hardware (like pressing the reset button), the latter is used to reset the JTAG TAP. In fact, both are optional, because targets may offer alternative ways to reset the system and/or the TAP to a known state. The trouble is, that sometimes these signals are implemented in strange ways. For example, most targets allow JTAG communication while mSRST is held low, others don't. This makes it impossible for the debugger to stop the target before executing the first opcode. Many targets and JTAG adapters, including the AT91SAM7SE and the Turtelizer 2 board revision B, do not require or provide nTRST. As a result, we must add another configuration item to tell OpenOCD, what kind of reset mechanism is available. For the AT91SAM7SE we declare<br />
<br />
<pre class="coding">reset_config srst_only</pre><br />
This will make the reset command available and we can finally implement the related handler.<br />
<br />
=== Creating a Reset Handler ===<br />
<br />
Sooner or later we will have to do more than just setting up clocks. Let's define a reset handler procedure, which in turn calls our <code>eir_init_clock</code> procedure we defined above.<br />
<br />
<pre class="coding"># Initialize the EIR board.<br />
#<br />
proc eir_init {} {<br />
eir_init_clock<br />
}</pre><br />
This routine will be registered as the reset-init handler of our target.<br />
<br />
<pre class="coding">sam7se512.cpu configure -event reset-init { eir_init }</pre><br />
You may add the procedures <code>eir_init_clock</code> and <code>eir_init</code> as well as the <code>configure</code> command to your openocd.cfg file in any order. It doesn't matter. Try to run OpenOCD with this new configuration, establish a Telnet session and enter<br />
<br />
<pre class="coding">reset init</pre><br />
Your output should be similar to<br />
<br />
<pre class="coding">JTAG tap: sam7se512.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)<br />
target state: halted<br />
target halted in ARM state due to debug-request, current mode: Supervisor<br />
cpsr: 0x600000d3 pc: 0x00000000<br />
NOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.<br />
NOTE! Severe performance degradation without working memory enabled.<br />
NOTE! Severe performance degradation without fast memory access enabled. Type 'help fast'.</pre><br />
OpenOCD detected, that our current configuration may lead to slow downloads and prints some flashy notes. Let's ignore them for the time being.<br />
<br />
Before moving to the next part, you may want to verify your current contents of openocd.cfg.<br />
<br />
<pre class="coding">interface turtle<br />
ft2232_layout turtelizer2<br />
ft2232_device_desc &quot;Turtelizer JTAG/RS232 Adapter&quot;<br />
adapter_khz 8<br />
jtag newtap sam7se512 cpu -irlen 4 -expected-id 0x3f0f0f0f<br />
target create sam7se512.cpu arm7tdmi -chain-position sam7se512.cpu<br />
reset_config srst_only<br />
<br />
sam7se512.cpu configure -event reset-init { eir_init }<br />
<br />
# Initialize the EIR board.<br />
#<br />
proc eir_init {} {<br />
eir_init_clock<br />
}<br />
<br />
# Initialize the EIR clocks.<br />
#<br />
# The board uses an 18.432MHz crystal.<br />
# Let the CPU run at 48MHz.<br />
#<br />
proc eir_init_clock {} {<br />
<br />
# Enable main oscillator.<br />
#<br />
# Start-up time of 6 x 8 slow clocks.<br />
#<br />
mww 0xfffffc20 0x00000601 ;# CKGR_MOR<br />
sleep 2<br />
<br />
# Configure the PLL.<br />
#<br />
# 18.432MHz * (72 + 1) / 14 = 96MHz<br />
#<br />
# Divider 14 (0x0e)<br />
# Start-up time of 28 (0x1c) slow clocks<br />
# Multiplier 72 (0x48)<br />
#<br />
mww 0xfffffc2C 0x00481c0e ;# CKGR_PLLR<br />
sleep 1<br />
<br />
# Select PLL clock and divide it by 2<br />
#<br />
# 96MHz / 2 = 48MHz<br />
#<br />
mww 0xfffffc30 0x00000007 ;# PMC_MCKR<br />
sleep 1<br />
<br />
# 1 wait for read, 2 waits for write<br />
# We have 48 master clocks in 1us<br />
mww 0xffffff60 0x00480100 ;# MC_FMR<br />
}</pre><br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/No_RadioHardware/EIR/No Radio2017-07-13T08:59:58Z<p>Harald: Created page with "<div id="content"> = No Radio = Nut/OS comes with a number of application samples, many of them will work on the EIR. The following tools a..."</p>
<hr />
<div><div id="content"><br />
<br />
= No Radio =<br />
<br />
Nut/OS comes with a number of [[../../documents/nutapps.html|application samples]], many of them will work on the EIR.<br />
<br />
The following tools are required:<br />
<br />
* Nut/OS Distribution<br /><br />
Download version 4.5.3 or later from the download area.<br />
* GNU ARM Toolchain<br /><br />
See below for platform specific distributions.<br />
* Text Editor<br /><br />
Anything from simple Notepad or vi to an advanced environment like Eclipse will do.<br />
<br />
== Developing on Windows ==<br />
<br />
Download and install YAGARTO.<br />
<br />
== Developing on Linux ==<br />
<br />
See this page for installing source packages.<br />
<br />
== Developing on Mac OS X ==<br />
<br />
See this page for installing source packages.<br />
<br />
Alternatively try GNU ARM.<br />
<br />
== Configuring Nut/OS ==<br />
<br />
Choose eir10c.conf.<br />
<br />
== Trying the Samples ==<br />
<br />
=== FTP Server ===<br />
<br />
=== HTTP Server ===<br />
<br />
<br /><br />
<br /><br />
<br />
Return to the [[index.html|EIR project page]].<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/MMCHardware/EIR/MMC2017-07-13T08:59:29Z<p>Harald: Created page with "<div id="content"> = EIR Memory Card Support = == Hardware == As explained on this page, the MMC socket is not connected to the hardware SPI. The following tab..."</p>
<hr />
<div><div id="content"><br />
<br />
= EIR Memory Card Support =<br />
<br />
== Hardware ==<br />
<br />
As explained on [[spi.html|this page]], the MMC socket is not connected to the hardware SPI. The following table shows the signals and pins:<br />
<br />
{|<br />
! GPIO<br />
! Periph. A<br />
! Periph. B<br />
! MMC Pin<br />
! SD-Card Mode<br />
! SDIO Mode<br />
! SPI Mode<br />
! EIR Conn.<br />
|-<br />
| PA15<br />
| TF<br />
| A15<br />
| 1<br />
| Unused<br />
| CD/DAT3<br />
| CS<br />
| K1-16<br />
|-<br />
| PA16<br />
| TK<br />
| A16/BA0<br />
| 5<br />
| CLK<br />
| CLK<br />
| SCK<br />
| K1-17<br />
|-<br />
| PA17<br />
| TD<br />
| A17/BA1<br />
| 2<br />
| CMD<br />
| CMD<br />
| MOSI<br />
| K1-18<br />
|-<br />
| PA18<br />
| RD<br />
| NBS3/CFIOW<br />
| 7<br />
| DATA<br />
| DAT0<br />
| MISO<br />
| K1-19<br />
|-<br />
| PA19<br />
| RK<br />
| NCS4/CFCS0<br />
| 8<br />
| IRQ<br />
| DAT1<br />
| Unused<br />
| K1-20<br />
|-<br />
| PA20<br />
| RF<br />
| NCS2/CFCS1<br />
| 9<br />
| RW<br />
| DAT2<br />
| Unused<br />
| K1-21<br />
|}<br />
<br />
Two additional GPIO pins are connected to the card detection and write protect switches of the memory card socket:<br />
<br />
{|<br />
! GPIO<br />
! Periph. A<br />
! Periph. B<br />
! Card Socket<br />
! EIR Conn.<br />
|-<br />
| PC18<br />
| A20<br />
| NANDWE<br />
| Card detect<br />
| K3-19<br />
|-<br />
| PC19<br />
| A21/NANDALE<br />
| <br />
| Write protect<br />
| K3-20<br />
|}<br />
<br />
== SPI Bit Banging Driver ==<br />
<br />
This driver is available since Nut/OS 4.8 in the following source code files:<br />
<br />
{|<br />
| nut/dev/sbi_mmc.c<br />
| Low level memory card routines with SPI read and write functions as well as card and write protect detection. They are used by the block driver routines in nut/dev/mmcard.c.<br />
|-<br />
| nut/dev/sbi0mmc0.c<br />
| Settings for &quot;MMC0&quot; (devSbi0MmCard0), which drives first card socket connected to the first SPI. The actual code is generated by including the source from nut/dev/sbi_mmc.c.<br />
|-<br />
| nut/dev/sbi0mmc1.c<br />
| Settings for &quot;MMC1&quot; (devSbi0MmCard1), which drives second card socket connected to the first SPI. The actual code is generated by including the source from nut/dev/sbi_mmc.c.<br />
|-<br />
| nut/dev/sbi1mmc0.c<br />
| Settings for &quot;MMC2&quot; (devSbi1MmCard0), which drives first card socket connected to a secondary SPI. The actual code is generated by including the source from nut/dev/sbi_mmc.c.<br />
|-<br />
| nut/dev/sbi1mmc1.c<br />
| Settings for &quot;MMC3&quot; (devSbi1MmCard1), which drives second card socket connected to a secondary SPI. The actual code is generated by including the source from nut/dev/sbi_mmc.c.<br />
|-<br />
| nut/include/dev/sbi_mmc.h<br />
| Header file, which needs to be included by the application, either directly or via dev/board.h.<br />
|}<br />
<br />
This portable driver can be configured with the Nut/OS Configurator. Typically this is done when loading the EIR configuration file eir10c.conf.<br />
<br />
[[eir10_mmc_bitbang_conf.png|[[File:eir10_mmc_bitbang_conf_460px.png]]]]<br />
As expected, the performance of the bit banging driver is lousy. The following figures had been attained from a no-name micro-SD card.<br />
<br />
<pre class="coding">Writing 64 byte blocks for 10s...9 kBytes/s<br />
Writing 128 byte blocks for 10s...9 kBytes/s<br />
Writing 256 byte blocks for 10s...10 kBytes/s<br />
Writing 512 byte blocks for 10s...16 kBytes/s<br />
Reading 64 byte blocks...24 kBytes/s<br />
Reading 128 byte blocks...24 kBytes/s<br />
Reading 256 byte blocks...28 kBytes/s<br />
Reading 512 byte blocks...28 kBytes/s</pre><br />
== SPI Bus Based Driver ==<br />
<br />
In opposite to the bit banging driver explained above, the newer [[../../documents/ntn-6_spi.html|SPI bus based drivers]] allow to concurrently access several devices on the same SPI bus. Actually this had been possibly with the old driver model as well, but the application needs to take care that accesses do not overlap. In the new driver model, the bus controller driver is separated from the device driver and serializes their access.<br />
<br />
The required drivers for the EIR are available since Nut/OS 5.0 in the following source code files:<br />
<br />
{|<br />
| nut/arch/arm/dev/atmel/spibus_at91ssc.c<br />
| General SPI over SSC bus controller routines.<br />
|-<br />
| nut/arch/arm/dev/atmel/spibus0at91ssc.c<br />
| SPI over SSC bus controller routines, that are specific for the first bus.<br />
|-<br />
| nut/include/dev/spibus_ssc.h<br />
| Header file, which needs to be included by the application, either directly or via dev/board.h.<br />
|-<br />
| nut/dev/spi_mmc.c<br />
| General memory card routines, which based on an SPI bus driver.<br />
|-<br />
| nut/dev/spi_mmc_gpio.c<br />
| Memory card support routines, mainly GPIO functions for hardware initialization, card detect and write protect. It also includes the device structure, which makes use of nut/dev/spi_mmc.c to implement the driver.<br />
|-<br />
| nut/include/dev/spi_mmc_gpio.h<br />
| Header file, which needs to be included by the application, either directly or via dev/board.h.<br />
|}<br />
<br />
No special configuration required for the bus controller driver, because it has been specifically designed for the AT91SAM7SE CPU that is mounted on the EIR board. All memory card specific configuration items are either included in the eir10c.conf file or used with default values. However, earlier versions of the configuration file do not include the settings for the card detect and write protect switches. You may add them manually.<br />
<br />
[[eir10_mmc_socket_conf.png|[[File:eir10_mmc_socket_conf_480px.png]]]]<br />
The performance gain compared to the bit banging driver is quite impressive. The following figures had been attained from the same micro-SD card as above.<br />
<br />
<pre class="coding">Writing 64 byte blocks for 10s...28 kBytes/s<br />
Writing 128 byte blocks for 10s...26 kBytes/s<br />
Writing 256 byte blocks for 10s...30 kBytes/s<br />
Writing 512 byte blocks for 10s...37 kBytes/s<br />
Writing 1024 byte blocks for 10s...256 kBytes/s<br />
Writing 2048 byte blocks for 10s...359 kBytes/s<br />
Writing 4096 byte blocks for 10s...436 kBytes/s<br />
Reading 64 byte blocks...114 kBytes/s<br />
Reading 128 byte blocks...161 kBytes/s<br />
Reading 256 byte blocks...198 kBytes/s<br />
Reading 512 byte blocks...229 kBytes/s<br />
Reading 1024 byte blocks...242 kBytes/s<br />
Reading 2048 byte blocks...242 kBytes/s<br />
Reading 4096 byte blocks...242 kBytes/s</pre><br />
== Application Code ==<br />
<br />
An application that wants to use an MMC driver, must register it first. For the bit banging driver this is done by simply calling<br />
<br />
<pre class="coding">#include &lt;dev/sbi_mmc.h&gt;<br />
<br />
NutRegisterDevice(&amp;devSbi0MmCard0, 0, 0);</pre><br />
When using the new SSC based driver, the registration requires a different call and different header files to attach the MMC driver to the SPI bus:<br />
<br />
<pre class="coding">#include &lt;dev/spibus_ssc.h&gt;<br />
#include &lt;dev/spi_mmc_gpio.h&gt;<br />
<br />
NutRegisterSpiDevice(&amp;devSpiMmcGpio, &amp;spiBus0Ssc, 0);</pre><br />
All these registration functions initialize the hardware and return 0 on success or -1 in case of an error. The following part is identical for all MMC drivers.<br />
<br />
Typically, applications will use the FAT file system to access the data on the card. In fact, Nut/OS currently doesn't support any other. The Nut/OS PHAT filesystem driver supports FAT12, FAT16 and FAT32 including long filename support. Also this driver needs to be registered:<br />
<br />
<pre class="coding">NutRegisterDevice(&amp;devPhat0, 0, 0);</pre><br />
Now the application is ready to mount the file system on the memory card by using a C standard function:<br />
<br />
<pre class="coding">#include &lt;io.h&gt;<br />
#include &lt;fcntl.h&gt;<br />
<br />
int volid;<br />
<br />
volid = _open(&quot;MMC0:1/PHAT0&quot;, _O_RDWR | _O_BINARY);</pre><br />
The path is composed of following parts: Name of the memory card driver, followed by a colon, followed by the number of the partition, followed by a slash and finally followed by the name of the file system driver.<br />
<br />
The function returns a file handle (volume identifier) or -1 if the mounting failed. Depending on the format of the memory card, this call may take several seconds, or even a few minutes with the bit banging driver.<br />
<br />
When successfully mounted, the application code can use all supported C standard functions to create, delete, read or write files.<br />
<br />
Before removing the card or switching off the power supply, the application should close all open files and unmount the file system with<br />
<br />
<pre class="coding">_close(volid);</pre><br />
This is mandatory, if data had been written. Otherwise the file system may become corrupted. There is currently no support in Nut/OS to repair corrupted FAT filesystems.<br />
<br />
== Known Problems ==<br />
<br />
'''''While MultiMedia and SD-Cards seem to work, I'm not able to mount SDHC cards.'''''<br />
<br />
Support for SDHC cards had been added since Nut/OS 5.0.5.<br />
<br />
'''''When trying to mount cards formatted with FAT12 or FAT16, the related open call never returns.'''''<br />
<br />
This bug has been fixed in Nut/OS 5.0.5.<br />
<br />
'''''The bit banging driver works on the EIR board, but the SPI/SSC bus controller doesn't.'''''<br />
<br />
When using the bus controller driver, it is required to short pins 17 and 20 at port A connector K1, as explained on [[spi.html|this page]].<br />
<br />
'''''The bit banging driver fails to read blocks larger than 512 bytes.'''''<br />
<br />
There is currently no fix available.<br />
<br />
<br /><br />
<br /><br />
<br /><br />
<br />
Return to the [[index.html|EIR project page]].<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/JTAGHardware/EIR/JTAG2017-07-13T08:59:02Z<p>Harald: Created page with "<div id="content"> = EIR JTAG = To our knowledge the best low cost solution so far is to use [http://openocd.sourceforge.net/ OpenOCD] with any FT2232 based adapter hardware..."</p>
<hr />
<div><div id="content"><br />
<br />
= EIR JTAG =<br />
<br />
To our knowledge the best low cost solution so far is to use [http://openocd.sourceforge.net/ OpenOCD] with any FT2232 based adapter hardware. OpenOCD will work on many platforms and several adapters from different vendors are available, which are using the FTDI chip. Some products are listed at the end of this page.<br />
<br />
We are using the [[../turtelizer/index.html|Turtelizer 2]]. However, its JTAG connector follows the AVR 10-pin layout. A special adapter is required to connect it to the 20-pin standard connector that is used on the EIR board.<br />
<br />
== Installing OpenOCD on Windows ==<br />
<br />
'''Warning:''' You must have the USB driver available before attaching your JTAG adapter to a USB port.<br />
<br />
OpenOCD binaries for Windows (including USB drivers) are available on [http://www.freddiechopin.info/ Freddie Chopin's homepage].<br />
<br />
A special version for the Turtelizer 2 can be found on our [[../../download/index.html|download page]].<br />
<br />
Connect one end of the USB cable to the PC USB port and the other to the USB connector on the JTAG adapter. Windows will automatically detect the new Turtelizer hardware. Concurrently the first screen of the ''Found New Hardware Wizard'' appears. Follow the instruction. Make sure that the option ''Specify a location'' is selected and deselect all others. Officially supported drivers are located in the subdirectory ''driver'' within the OpenOCD installation directory. You should also consult the documentation which is available for your specific adapter.<br />
<br />
The following screenshots show the Turtelizer 2 driver installation.<br />
<br />
[[../../../img/ftdi01.png|[[File:../../../img/ftdi01-tn.png|80x23px|FTDI USB Driver Installation Step 1]]]][[../../../img/ftdi02.png|[[File:../../../img/ftdi02-tn.png|100x77px|FTDI USB Driver Installation Step 2]]]][[../../../img/ftdi03.png|[[File:../../../img/ftdi03-tn.png|100x77px|FTDI USB Driver Installation Step 3]]]][[../../../img/ftdi04.png|[[File:../../../img/ftdi04-tn.png|100x77px|FTDI USB Driver Installation Step 4]]]][[../../../img/ftdi05.png|[[File:../../../img/ftdi05-tn.png|90x45px|FTDI USB Driver Installation Step 5]]]][[../../../img/ftdi06.png|[[File:../../../img/ftdi06-tn.png|100x77px|FTDI USB Driver Installation Step 6]]]][[../../../img/ftdi07.png|[[File:../../../img/ftdi07-tn.png|100x77px|FTDI USB Driver Installation Step 7]]]]<br /><br />
[[../../../img/ftdi08.png|[[File:../../../img/ftdi08-tn.png|80x23px|FTDI USB Driver Installation Step 8]]]][[../../../img/ftdi09.png|[[File:../../../img/ftdi09-tn.png|100x77px|FTDI USB Driver Installation Step 9]]]][[../../../img/ftdi10.png|[[File:../../../img/ftdi10-tn.png|100x77px|FTDI USB Driver Installation Step 10]]]][[../../../img/ftdi11.png|[[File:../../../img/ftdi11-tn.png|100x77px|FTDI USB Driver Installation Step 11]]]][[../../../img/ftdi12.png|[[File:../../../img/ftdi12-tn.png|90x45px|FTDI USB Driver Installation Step 12]]]][[../../../img/ftdi13.png|[[File:../../../img/ftdi13-tn.png|100x77px|FTDI USB Driver Installation Step 13]]]][[../../../img/ftdi14.png|[[File:../../../img/ftdi14-tn.png|100x77px|FTDI USB Driver Installation Step 14]]]]<br />
<br />
== Installing OpenOCD on Linux ==<br />
<br />
<br />
<br />
The OpenOCD source code can be retrieved from the SVN repository at [http://developer.berlios.de/svn/?group_id=4148 developer.berlios.de/svn].<br />
<br />
<pre class="coding">$ svn co -r 423 svn://svn.berlios.de/openocd/trunk openocd-r423</pre><br />
The included README file contains a detailed description. A few essential tools are required to create the binaries. The following commands may be used on Debian to make sure that all tools are available:<br />
<pre class="coding">$ sudo apt-get install build-essential<br />
$ sudo apt-get install automake<br />
$ sudo apt-get install autoconf</pre><br />
If not already installed, we further need the FTDI support library. There are two variants, we chose the one supplied by FTDI:<br />
<pre class="coding">$ wget http://www.ftdichip.com/Drivers/D2XX/Linux/libftd2xx0.4.13.tar.gz<br />
$ tar -zxf libftd2xx0.4.13.tar.gz<br />
$ sudo cp *.h /usr/local/include/<br />
$ sudo cp libftd2xx.so.0.4.13 /usr/local/lib/<br />
$ cd /usr/local/lib/<br />
$ sudo ln -s libftd2xx.so.0.4.13 libftd2xx.so<br />
$ sudo ln -s libftd2xx.so.0.4.13 libftd2xx.so.0<br />
$ cd /usr/lib/<br />
$ ln -s /usr/local/lib/libftd2xx.so.0.4.13 libftd2xx.so.0<br />
/etc/fstab (sudo):<br />
none /proc/bus/usb usbdevfs defaults,mode=0666 0 0<br />
(use usbfs in 2.6 kernels, 'uname -a')<br />
$ sudo mount -a</pre><br />
In the next step we can build OpenOCD, using<br />
<pre class="coding">$ cd openocd-r423/<br />
$ ./bootstrap<br />
$ ./configure --enable-ft2232_ftd2xx<br />
$ make<br />
$ sudo make install</pre><br />
The following entry should appear in /proc/bus/usb/devices after plugging in the Turtelizer 2:<br />
<br />
<pre class="coding">T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 4 Spd=12 MxCh= 0<br />
D: Ver= 2.00 Cls=00(&gt;ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1<br />
P: Vendor=0403 ProdID=bdc8 Rev= 5.00<br />
S: Manufacturer=egnite<br />
S: Product=Turtelizer JTAG/RS232 Adapter<br />
S: SerialNumber=TLQ08BET<br />
C:* #Ifs= 2 Cfg#= 1 Atr=80 MxPwr=100mA<br />
I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)<br />
E: Ad=81(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms<br />
E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms<br />
I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)<br />
E: Ad=83(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms<br />
E: Ad=04(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms</pre><br />
== Installing OpenOCD on Mac OS X ==<br />
<br />
Right now we do not have a binary package for OS X. Thus, we need to build OS X from the source code. If not already done, download Xcode from<br /><br />
[http://developer.apple.com/tools/xcode/ developer.apple.com/tools/xcode/] and install it. Xcode contains all the GNU tools, which are needed to create the OpenOCD binary from the source code.<br />
<br />
[[../../../img/ftdi-d2xx-mount.png|[[File:../../../img/ftdi-d2xx-mountth.png|128x76px|FTDI Disk Image]]]] Download the Mac OS X driver from<br /><br />
[http://www.ftdichip.com/Drivers/D2XX.htm www.ftdichip.com/Drivers/D2XX.htm]<br /><br />
The driver is packed in a disk image file. Double click it to mount the image.<br />
<br />
To install the driver, execute the following commands in a Terminal window:<br />
<br />
<pre class="coding">$ cd /Volumes/PPC\ D2XX/D2XX/<br />
$ sudo mkdir -p /usr/local/lib /usr/local/include<br />
$ sudo cp bin/libftd2xx.0.1.0.dylib /usr/local/lib/<br />
$ sudo ln -sf /usr/local/lib/libftd2xx.0.1.0.dylib /usr/local/lib/libftd2xx.dylib<br />
$ sudo cp bin/ftd2xx.h /usr/local/include/<br />
$ sudo cp Samples/WinTypes.h /usr/local/include/</pre><br />
Retrieve the OpenOCD source code from the SVN repository at [http://developer.berlios.de/svn/?group_id=4148 developer.berlios.de/svn]. For this, open Terminal and enter:<br />
<br />
<pre class="coding">$ svn co -r 423 svn://svn.berlios.de/openocd/trunk openocd-r423</pre><br />
Building and installing OpenOCD for OS X is similar to Linux. In a Terminal window enter:<br />
<br />
<pre class="coding">$ cd openocd-r423/<br />
$ ./bootstrap<br />
$ ./configure --enable-ft2232_ftd2xx<br />
$ make<br />
$ sudo make install</pre><br />
== Flashing the Firmware ==<br />
<br />
In order to familliarize yourself with flashing firmware into the EIR, we will go step by step through the whole process.<br />
<br />
You should create a new empty folder to work with. Everything goes into it, and every command you enter has to be run out of this folder.<br />
<br />
First copy your binary into the folder. In this document we suggest you use the internetradio, which can be downloaded as a sample with the following link:<br /><br />
[[../../../arc/eir-bin_1_1_0.bin|eir-bin_1_1_0.bin]]<br />
<br />
Second download the configfile for OpenOCD. If you're not using the Turtlelizer2 you need to modify it.<br /><br />
[[../../../arc/eirocd.cfg|eirocd.cfg]]<br />
<br />
Now connect the Turtleizer2 with the special adapter and the special adapter to the EIR.<br /><br />
[[../../../img/chain.png|[[File:../../../img/chain_thumb.png|chain setup]]]]<br />
<br />
We start with erasing the old firmware. On the EIR board connect pins 34 and 36 of K3 (Port C) using a 2.54 mm jumper. Press the reset button and remove the jumper. This activates the SAM-BA boot loader.<br /><br />
[[../../../img/jumper.png|[[File:../../../img/jumper_thumb.png|Firmware löschen]]]]<br />
<br />
To get access to our board with OpenOCD, we need to start OpenOCD with the proper config file. OpenOCD usually looks for a file called openocd.cfg, because you might use some of our other products too, we gave it names that resemble the specific product. To load config files with a different name use -f or --file if you like. Now we open our preferred command line interpreter, CLI for short (maybe you call it Dos-Box, Text Terminal, Shell, Console...), and enter:<br />
<br />
<pre class="coding">$ openocd -f eirocd.cfg</pre><br />
Because OpenOCD blocks our last CLI we need to start another one. After, we've sucessfully started OpenOCD, we need to connect through OpenOCD to the board with Telnet using localhost and the port specified in eirocd.cfg.<br /><br />
<br />
<br />
<pre class="coding">$ telnet 127.0.0.1 4444</pre><br />
The CPU is already running, so we need to pause it with ''halt''.<br />
<br />
<pre class="coding">&gt; halt</pre><br />
Now we need to detect flash bank 0. This can be done with ''flash'' probe which has the following syntax:<br />
<br />
<pre class="coding">flash probe &lt;bank&gt;</pre><br />
Because we want to detect bank 0 we do:<br />
<pre class="coding">&gt; flash probe 0</pre><br />
We need to write the binary eir-bin_1_1_0.bin to bank 0 at offset 0. According to the syntax of the command ''flash write_bank''<br />
<br />
<pre class="coding">flash write_bank &lt;bank&gt; &lt;file&gt; &lt;offset&gt;</pre><br />
this should work:<br />
<pre class="coding">&gt; flash write_bank 0 eir-bin_1_1_0.bin 0</pre><br />
The at91sam7 has 2 boot modes, booting from ROM and booting from Flash, so we neet to set the boot mode:<br />
<br />
<pre class="coding">at91sam7 gpnvm &lt;bank&gt; &lt;bit&gt; &lt;set|clear&gt;</pre><br />
{|<br />
| boot mode<br />
| flag<br />
|-<br />
| Flash<br />
| set<br />
|-<br />
| ROM<br />
| clear<br />
|}<br />
<br />
<pre class="coding">&gt; at91sam7 gpnvm 0 2 set</pre><br />
Finally to get the EIR to boot from Flash just reset it.<br />
<br />
== External Links ==<br />
<br />
=== JTAG Adapters ===<br />
<br />
We intentionally do not recommend any specific adapter for the EIR. Before buying one, make sure, that it fully supports your operating system and the AT91SAM7SE512 CPU.<br />
<br />
[http://www.amontec.com/ www.amontec.com]<br /><br />
Amontec is specialized on JTAG adapters, most of them are officially supported by OpenOCD.<br />
<br />
[http://microcontrollershop.com/ microcontrollershop.com]<br /><br />
MicroController Pros Corporation runs an online shop, which offers a large variety of JTAG adapters from different vendors.<br />
<br />
[http://www.olimex.com/ www.olimex.com]<br /><br />
Olimex is well known for its low prices. They offer two different JTAG adapters.<br />
<br />
[http://www.signalyzer.com/ www.signalyzer.com]<br /><br />
Xverve Technologies Inc. offers the Signalyzer Tool.<br />
<br />
[http://www.zylin.com/zy1000.html www.zylin.com]<br /><br />
If you are fed up with software installation und USB driver mess, the ZY1000 is probably for you. It is actually a small Linux system, running OpenOCD internally. You can directly connect to it via TCP/IP, for example, using a common webbrowser. Of course, this luxury has its price.<br />
<br />
Return to the [[index.html|EIR project page]].<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIRHardware/EIR2017-07-13T08:58:28Z<p>Harald: /* ELEKTOR Internet Radio */</p>
<hr />
<div><div id="content"><br />
<br />
= ELEKTOR Internet Radio =<br />
<br />
On April 2008, [http://www.elektor.com/ ELEKTOR magazine] published an article about an Internet Radio based on Nut/OS. In November 2008 it had been presented at the Elektor Live Event in Eindhoven (Youtube video on the right).<br />
<br />
[[File:eir10c-overview.png|320px|EIR 1.0 Rev-C Povray]]<br />
Click on the picture to get a more detailed view.<br />
<br />
== License ==<br />
<br />
The firmware is published under the permissive [http://opensource.org/licenses/BSD-3-Clause BSD License], which allows incorporation into proprietary products.<br />
<br />
The CAD files of this open source hardware design are released under a similar license.<br />
<br />
== Hardware ==<br />
<br />
The hardware is build on a 100mm x 100mm 4-layer PCB and offers a large number of features, including:<br />
<br />
* Atmel AT91SAM7SE512 ARM7 CPU with 512kBytes high speed flash and a wide range of peripheral functions.<br />
* Micron/Samsung 64MBytes external SDRAM.<br />
* Atmel AT45DB321D 4MBytes serial Flash.<br />
* Davicom DM9000E Ethernet Controller.<br />
* VLSI VS1053B Audio Decoder supports MP3, AAC, WMA, Ogg Vorbis, WAV and MIDI.<br />
* Philips PCF8563 Realtime Clock with double layer cap backup.<br />
* Yamaichi MMC/SD-Card Socket.<br />
* Wide range (5-24V) switching power supply.<br />
<br />
You can order fully tested and pre-loaded boards from [http://www.egnite.de/en/egnite-shop.html this online shop] or [http://www.egnite.de/en/ueber-uns/distributoren.html other distributors].<br />
<br />
Right now there is no user interface hardware (LCD, pushbuttons etc.) available. However, all CPU ports are accessible via three 2.54mm pinheaders, which may be used by an expansion board.<br />
<br />
[[File:eir_um_1_0_6.pdf|EIR Hardware Manual]]<br /><br />
Brief overview and schematics of the EIR 1.0 Rev-C Board.<br />
<br />
[[File:eir10c-eagle.zip|Eagle CAD files]]<br /><br />
Free for non-commercial and commercial usage.<br />
<br />
[[Hardware/EIR/Assembly|EIR Assembly Instructions]]<br /><br />
[http://www.egnite.de/en/produkte/elektor-internet-radio/elektor-internet-radio.html egnite] shipped the first boards with SMD parts mounted only. Today the boards are fully mounted.<br />
<br />
[[Hardware/EIR/Tester|EIR Hardware Tester]]<br /><br />
Firmware for testing EIR boards.<br />
<br />
== Webradio Software ==<br />
<br />
Check the [http://sourceforge.net/projects/ewebradio/ project page] at SourceForge for the latest release.<br />
<br />
The Windows installable files at [http://sourceforge.net/projects/ewebradio/files/ Sourceforge]<br /><br />
contain the complete source code as well as a ready-to-run binary.<br />
<br />
If you are working on another platform, then get the source code from the [http://sourceforge.net/scm/?type=svn&group_id=258371 Subversion repository]. To build the firmware from the source code, Nut/OS 4.10 or any later release is required.<br />
<br />
Due to the lack of any user interface hardware, the radio runs an internal web server. [[webif.html|This page]] shows how to monitor and control the Internet Radio with a web browser.<br />
<br />
[[doc/index.html|Webradio Firmware Documentation]]<br /><br />
Source code reference.<br />
<br />
[[Hardware/EIR/SAM-BA|EIR Firmware Upload Using SAM-BA]]<br /><br />
Explains how to upload new firmware to the EIR board. This is the most simple way, but requires a Windows PC.<br />
<br />
[[Hardware/EIR/JTAG|EIR JTAG Interface]]<br /><br />
Describes how to use the EIR with OpenOCD. This is supported on Windows, Linux and Mac OS X and offers an alternate method of uploading new firmware.<br />
<br />
== Development Platform ==<br />
<br />
[[nutwiki/Elektor_Internet_Radio_1.0|EIR Wiki Pages]]<br /><br />
Presents several flash movies for trying out the EIR.<br />
<br />
[[Hardware/EIR/Debugging|EIR Source Code Debugging]]<br /><br />
explains how to setup Eclipse and OpenOCD to allow source code debugging of Nut/OS applications running on the Elektor Internet Radio.<br />
<br />
[[Hardware/EIR/MMC|Memory Card Support]]<br /><br />
How to configure and use the memory card socket.<br />
<br />
[[Hardware/EIR/SPI|SPI Support]]<br /><br />
How SPI is implemented on the EIR board.<br />
<br />
[[Hardware/EIR/Vorbis Rec|Ogg Vorbis Recorder]]<br /><br />
How to use the EIR as an audio recorder.<br />
<br />
[[Hardware/EIR/Expansion|Expansion Port]]<br /><br />
Provides additional hints for attaching external hardware.<br />
<br />
== Known Problems ==<br />
<br />
=== Kit Contents ===<br />
<br />
'''Problem:''' The first kits shipped contain a wrong RS232 connector (K5). A male connector is required, but a female one had been packed.<br /><br />
'''Solutions:'''<br /><br />
'''*''' Replace the female connector with a male type. If you don't have one available, send an email to info at egnite dot de. You'll receive a replacement free of charge.<br /><br />
[[File:rs232fnull_tn.png|False Null Modem Cable]] '''*''' Removing an already mounted connector isn't easy. As an alternative you can make a special cable which will work with the wrong connector. Click on the picture on the right to get the wiring schematic. Note that the cable plugs are shown in front view, with cables soldered on the back side. A so called [http://en.wikipedia.org/wiki/Gender_changer Gender Changer] should work too, when used with a [[../../documents/rs232primer.html|Null Modem Cable]].<br /><br />
'''*''' Another option is to send your board to [http://egnite.de/index.php?id=6&L=2 egnite GmbH]. Your connector will be replaced and your board will be tested and returned immediately, free of charge. Please do not forget to use the shielded bag to pack the EIR board.<br />
<br />
=== CD Contents ===<br />
<br />
'''Problem:''' The CD Version 1.1.1 links to the wrong firmware source file, webradio-1.2.0.zip. This source fails to compile.<br /><br />
'''Solution:''' The CD folder firmware also contains the correct file webradio-1.2.1.zip.<br />
<br />
=== Expansion Port in Elektor Article ===<br />
<br />
In table 1 it is stated, that PA20 at pin 21 of connector K1 is used for MMC DAT2. Actually this signal is additionally used for the Ethernet controller chip select.<br />
<br />
In table 2 it is stated, that PB22 at pin 23 of connector K2 is used for the DataFlash chip select. Actually the chip select is at PA11. PB22 is not used and available for external hardware.<br />
<br />
In table 3 it is stated, that PC23 at pin 24 of connector K3 is used for the Ethernet controller chip select. Actually the chip select is at PA20. PC23 is not used and available for external hardware.<br />
<br />
== External Links ==<br />
<br />
[http://www.elektor.com/ www.elektor.de]<br /><br />
Monthly magazine, not only for hobbyists.<br />
<br />
[http://www.atmel.com/products/at91/ www.atmel.com/products/at91/]<br /><br />
Atmel is the company that manufactures the AT91SAM7SE512. Under Tools &amp; Software you'll find the file AT91-ISP.exe. Use this tool on a Windows PC to upload new firmware to the radio.<br />
<br />
[http://www.vlsi.fi/ www.vlsi.fi]<br /><br />
The website of VLSI Solution Oy, who offers the VS1053 audio codec.<br />
<br />
[http://www.yagarto.de/ www.yagarto.de]<br /><br />
Michael Fischer offers a complete package, which allows you to create your own applications for the radio board. Of course you can also use YAGARTO to compile the radio application source code.<br />
<br />
[http://www.myway.de/ElectronicFreak/EIR.html www.myway.de/ElectronicFreak/EIR.html]<br /><br />
Erfahrungen und Methoden zum Elektor EIR: Christian Schöning created a document about how to use the EIR with Eclipse (German language).<br />
<br />
[http://www.raippa.fi/SOP/Hardware2009/ www.raippa.fi/SOP/Hardware2009/]<br /><br />
EIR pages of the Computer Engineering Laboratory at the university of Oulu.<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/ExpansionHardware/EIR/Expansion2017-07-13T08:57:43Z<p>Harald: Created page with "<div id="content"> = EIR Expansion Port = == Expansion Connector K1 == Pin GPIO Periph.<br /> A Periph.<br /> B Usage 1 PA0 PWM0 A0/NBS0 '''Available for external hardwar..."</p>
<hr />
<div><div id="content"><br />
<br />
= EIR Expansion Port =<br />
<br />
== Expansion Connector K1 ==<br />
<br />
<br />
<br />
Pin<br />
GPIO<br />
Periph.<br /><br />
A<br />
Periph.<br /><br />
B<br />
Usage<br />
1<br />
PA0<br />
PWM0<br />
A0/NBS0<br />
'''Available for external hardware''', can permanently drive up to 16mA.<br />
2<br />
PA1<br />
PWM1<br />
A1/NBS1<br />
3<br />
PA2<br />
PWM2<br />
A2<br />
4<br />
PA3<br />
'''TWD'''<br />
A3<br />
I2C Bus to RTC, '''available for external I2C devices'''<br />
5<br />
PA4<br />
'''TWCK'''<br />
A4<br />
6<br />
PA5<br />
'''RXD0'''<br />
A5<br />
USART0 RS232 Rx/Tx via JP1<br />
7<br />
PA6<br />
'''TXD0'''<br />
A6<br />
8<br />
PA7<br />
'''RTS0'''<br />
A7<br />
USART0 RS232 Hardware Handshake<br />
9<br />
PA8<br />
'''CTS0'''<br />
A8<br />
10<br />
PA9<br />
'''DRXD'''<br />
A9<br />
DBGU RS232 Rx/Tx via JP1<br />
11<br />
PA10<br />
'''DTXD'''<br />
A10<br />
12<br />
PA11<br />
'''NPCS0'''<br />
A11<br />
DataFlash Chip Select<br />
13<br />
PA12<br />
'''MISO'''<br />
A12<br />
SPI Bus to MP3 Decoder and DataFlash, '''available for external SPI devices'''<br />
14<br />
PA13<br />
'''MOSI'''<br />
A13<br />
15<br />
PA14<br />
'''SPCK'''<br />
A14<br />
16<br />
'''PA15'''<br />
TF<br />
A15<br />
MMC Chip Select<br />
17<br />
'''PA16'''<br />
TK<br />
A16/BA0<br />
MMC Clock<br />
18<br />
'''PA17'''<br />
TD<br />
A17/BA1<br />
MMC Command<br />
19<br />
'''PA18'''<br />
RD<br />
NBS3/CFIOW<br />
MMC DAT0<br />
20<br />
PA19<br />
RK<br />
NCS4/CFCS0<br />
MMC DAT1 via R7<br />
21<br />
'''PA20'''<br />
RF<br />
NCS2/CFCS1<br />
MMC DAT2 via R8 and Ethernet Chip Select<br />
22<br />
PA21<br />
RXD1<br />
NCS6/CFCE2<br />
'''Available for external hardware''', e.g. 3rd UART<br />
23<br />
PA22<br />
TXD1<br />
NCS5/CFCE1<br />
24<br />
PA23<br />
SCK1<br />
NWR1/'''NBS1'''/CFIOR<br />
SDRAM DQMH<br />
25<br />
PA24<br />
RTS1<br />
'''SDA10'''<br />
SDRAM A10<br />
26<br />
PA25<br />
CTS1<br />
'''SDCKE'''<br />
SDRAM CKE<br />
27<br />
PA26<br />
DCD1<br />
NCS1/'''SDCS'''<br />
SDRAM Chip Select<br />
28<br />
PA27<br />
DTR1<br />
'''SDWE'''<br />
SDRAM WE<br />
29<br />
PA28<br />
DSR1<br />
'''CAS'''<br />
SDRAM CAS<br />
30<br />
PA29<br />
RI1<br />
'''RAS'''<br />
SDRAM RAS<br />
31<br />
PA30<br />
'''IRQ1'''<br />
D30<br />
MP3 Decoder Interrupt<br />
32<br />
'''PA31'''<br />
NPCS1<br />
D31<br />
MP3 Decoder Command Select<br />
33<br />
Vref<br />
<br />
A/D Converter Reference<br />
34<br />
3.3V<br />
<br />
Regulated 3.3V Power Supply, up to 500mA are '''available for external hardware'''<br />
35<br />
AD4<br />
<br />
Four Analog Inputs, '''available for external hardware'''<br />
36<br />
AD5<br />
<br />
37<br />
AD6<br />
<br />
38<br />
AD7<br />
<br />
39<br />
GND<br />
<br />
Ground<br />
40<br />
GND<br />
<br />
== Expansion Connector K2 ==<br />
<br />
<br />
<br />
Pin<br />
GPIO<br />
Periph.<br /><br />
A<br />
Periph.<br /><br />
B<br />
Note<br />
1<br />
PB0<br />
TIOA0<br />
A0/'''NBS0'''<br />
SDRAM DQML<br />
2<br />
PB1<br />
TIOB0<br />
A1/NBS2<br />
Available, but reserved for External Address Bus Bit 1<br />
3<br />
PB2<br />
SCK0<br />
'''A2'''<br />
External Address Bus, Bits 2..11<br />
4<br />
PB3<br />
NPCS3<br />
'''A3'''<br />
5<br />
PB4<br />
TCLK0<br />
'''A4'''<br />
6<br />
PB5<br />
NPCS3<br />
'''A5'''<br />
7<br />
PB6<br />
PCK0<br />
'''A6'''<br />
8<br />
PB7<br />
PWM3<br />
'''A7'''<br />
9<br />
PB8<br />
ADTRG<br />
'''A8'''<br />
10<br />
PB9<br />
NPCS1<br />
'''A9'''<br />
11<br />
PB10<br />
NPCS2<br />
'''A10'''<br />
12<br />
PB11<br />
PWM0<br />
'''A11'''<br />
13<br />
PB12<br />
PWM1<br />
A12<br />
Available, but reserved for External Address Bus Bit 12<br />
14<br />
PB13<br />
PWM2<br />
'''A13'''<br />
External Address Bus, Bits 13..14<br />
15<br />
PB14<br />
PWM3<br />
'''A14'''<br />
16<br />
PB15<br />
TIOA1<br />
A15<br />
Available, but reserved for External Address Bus Bit 15<br />
17<br />
PB16<br />
TIOB1<br />
A16/'''BA0'''<br />
SDRAM BA0<br />
18<br />
PB17<br />
PCK1<br />
A17/'''BA1'''<br />
SDRAM BA1<br />
19<br />
PB18<br />
PCK2<br />
D16<br />
'''Available for external hardware''', e.g. programmable clock output<br />
20<br />
PB19<br />
'''FIQ'''<br />
D17<br />
RTC Interrupt via R35<br />
21<br />
PB20<br />
'''IRQ0'''<br />
D18<br />
Ethernet Controller Interrupt<br />
22<br />
PB21<br />
PCK1<br />
D19<br />
'''Available for external hardware''', e.g. programmable clock output<br />
23<br />
PB22<br />
NPCS3<br />
D20<br />
'''Available for external hardware''', e.g. SPI chip select<br />
24<br />
'''PB23'''<br />
PWM0<br />
D21<br />
USB Monitor<br />
25<br />
PB24<br />
PWM1<br />
D22<br />
'''Available for external hardware''', e.g. GPIO with timer/counter<br />
26<br />
PB25<br />
PWM2<br />
D23<br />
27<br />
PB26<br />
TIOA2<br />
D24<br />
28<br />
PB27<br />
TIOB2<br />
D25<br />
29<br />
PB28<br />
TCLK1<br />
D26<br />
30<br />
PB29<br />
TCLK2<br />
D27<br />
31<br />
'''PB30'''<br />
NPCS2<br />
D28<br />
MP3 Decoder Data Select<br />
32<br />
'''PB31'''<br />
PCK2<br />
D9<br />
MP3 Decoder Hardware Reset<br />
33<br />
3.3V<br />
<br />
Regulated 3.3V Power Supply, up to 500mA are '''available for external hardware'''<br />
34<br />
3.3V<br />
<br />
35<br />
<br />
Not connected, reserved for future expansions<br />
36<br />
<br />
37<br />
<br />
38<br />
NRST<br />
<br />
Hardware Reset, also '''available to reset external hardware'''<br />
39<br />
GND<br />
<br />
Ground<br />
40<br />
GND<br />
<br />
== Expansion Connector K3 ==<br />
<br />
<br />
<br />
Pin<br />
GPIO<br />
Periph.<br /><br />
A<br />
Periph.<br /><br />
B<br />
Note<br />
1<br />
PC0<br />
'''D0'''<br />
<br />
16-Bit External Data Bus<br />
2<br />
PC1<br />
'''D1'''<br />
<br />
3<br />
PC2<br />
'''D2'''<br />
<br />
4<br />
PC3<br />
'''D3'''<br />
<br />
5<br />
PC4<br />
'''D4'''<br />
<br />
6<br />
PC5<br />
'''D5'''<br />
<br />
7<br />
PC6<br />
'''D6'''<br />
<br />
8<br />
PC7<br />
'''D7'''<br />
<br />
9<br />
PC8<br />
'''D8'''<br />
RTS1<br />
10<br />
PC9<br />
'''D9'''<br />
DTR1<br />
11<br />
PC10<br />
'''D10'''<br />
PCK0<br />
12<br />
PC11<br />
'''D11'''<br />
PCK1<br />
13<br />
PC12<br />
'''D12'''<br />
PCK2<br />
14<br />
PC13<br />
'''D13'''<br />
<br />
15<br />
PC14<br />
'''D14'''<br />
NPCS1<br />
16<br />
PC15<br />
'''D15'''<br />
NCS3/NANDCS<br />
17<br />
PC16<br />
A18<br />
'''NWAIT'''<br />
Open Collector Bus Wait<br />
18<br />
'''PC17'''<br />
A19<br />
NANDOE<br />
Ethernet Controller Hardware Reset<br />
19<br />
'''PC18'''<br />
A20<br />
NANDWE<br />
MultiMedia Card Detect<br />
20<br />
'''PC19'''<br />
A21/NANDALE<br />
<br />
MultiMedia Card Write Protect Sensor<br />
21<br />
PC20<br />
A22/REG/NANDCLE<br />
NCS7<br />
'''Available for external hardware''', e.g. chip select for memory mapped devices<br />
22<br />
PC21<br />
<br />
NWR0/'''NWE'''/CFWE<br />
External Bus Write Strobe<br />
23<br />
PC22<br />
<br />
'''NRD'''/CFOE<br />
External Bus Read Strobe<br />
24<br />
PC23<br />
CFRNW<br />
NCS0<br />
'''Available for external hardware''', e.g. chip select for memory mapped devices<br />
25<br />
<br />
Not connected, can be used to route additional signals to external hardware<br />
26<br />
<br />
27<br />
<br />
28<br />
<br />
29<br />
<br />
30<br />
<br />
31<br />
<br />
32<br />
<br />
33<br />
3.3V<br />
<br />
Regulated 3.3V Power Supply, up to 500mA are '''available for external hardware'''<br />
34<br />
3.3V<br />
<br />
35<br />
JTAGSEL<br />
<br />
Connect with pin 33 to enable boundary scan<br />
36<br />
ERASE<br />
<br />
Connect with pin 34 to erase the firmware<br />
37<br />
Vin<br />
<br />
Unregulated Input Voltage, 5-24V<br />
38<br />
SHDN<br />
<br />
Connect with pin 40 to switch off the radio<br />
39<br />
GND<br />
<br />
Ground<br />
40<br />
GND<br />
<br />
<br />
-----<br />
<br />
Return to the [[index.html|EIR project page]].<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/DebuggingHardware/EIR/Debugging2017-07-13T08:57:12Z<p>Harald: Created page with "<div id="content"> = Elektor Internet Radio Source Code Debugging = This document explains how to setup Eclipse and [http://openocd.sourceforge.net/ OpenOCD] to allow source..."</p>
<hr />
<div><div id="content"><br />
<br />
= Elektor Internet Radio Source Code Debugging =<br />
<br />
This document explains how to setup Eclipse and [http://openocd.sourceforge.net/ OpenOCD] to allow source code debugging of Nut/OS applications running on Elektor Internet Radio. It is assumed, that you are already familiar with creating Nut/OS applications. The [[../../pdf/enswm28e.pdf|Nut/OS Software Manual]] describes the required steps.<br />
<br />
This document has been originally written for Nut/OS 4.9 beta. Additional comments had been included later to cover Nut/OS 4.10.<br />
<br />
Note, that you don't need to use Eclipse to create your own Nut/OS applications. You favorite text editor is just fine to create the source code and building your application can be done on the command line.<br />
<br />
The same is true for debugging. There are a number of alternative tools available, like GDB for the command line purists or Insight, which provides a GUI for GDB. Actually, Eclipse uses GDB too, but provides a nicely integrated user interface for editing, compiling, uploading and debugging Nut/OS applications. While based on Java, it is available on all major platforms.<br />
<br />
One last word before you move on: If you got here, because you assume that either your application or any of the Nut/OS libraries contains a bug, you should carefully think about, whether source code debugging will really help. Multithreaded network applications often fail because of timing problems or racing conditions. Setting breakpoints and inspecting variables will seldom help to find such bugs. What you need is some sort of ''tracing''. In its most simple form, you can use the devDebug device to let your program output additional information on the serial port while running. In almost the same way you can use [http://www.ethernut.de/nutwiki/Sending_syslog_Messages syslog]. A similar situation may occur, when parts of memory are overwritten by bad pointers or buffer overflows. You should consider other debugging methods provided by Nut/OS, which are explained in the chapter ''Error Handling'' of the Nut/OS Software Manual.<br />
<br />
== Requirements ==<br />
<br />
This is a short listing only. For Details please refer to the related manuals.<br />
<br />
=== Required Hardware ===<br />
<br />
* Elektor Internet Radio Board<br />
* Turtelizer 2 JTAG Dongle<br />
* JTAG Connector Adapter<br />
* PC with USB and RS-232 port<br />
* 12V Power Supply<br />
* RS-232 DB9 Null Modem Cable<br />
* USB A/B Cable<br />
<br />
The first 2 items you can build yourself, using the Eagle 4.11 CAD files for [[../../../arc/eir10c.zip|Elektor Internet Radio]] and [[../../../arc/turtle20b.zip|Tutelizer 2.0]]. Readily built and tested devices are available at [http://www.egnite.de/en/egnite-shop.html www.egnite.de/en/egnite-shop.html] and from several [http://www.egnite.de/en/ueber-uns/distributoren.html distributors].<br />
<br />
=== Required Software (Windows) ===<br />
<br />
The following software needs to be installed on the Windows PC:<br />
<br />
* Windows XP or later<br />
* Java Runtime Environment 1.6 or later<br />
* Eclipse Platform Runtime Binary 3.6.2 (Helios)<br />
* Eclipse CDT 7.0.2<br />
* TeraTerm or similar Terminal Emulator<br />
* Nut/OS 4.10<br />
* Turtelizer OpenOCD Package<br />
* Turtelizer FTDI Driver<br />
<br />
You can download the Java Runtime at [http://www.oracle.com/technetwork/java/javase/downloads/ www.oracle.com/technetwork/java/javase/downloads].<br />
<br />
Eclipse is available at [http://download.eclipse.org/eclipse/downloads/ download.eclipse.org/eclipse/downloads] and the CDT can be found at [http://www.eclipse.org/cdt/ www.eclipse.org/cdt]. Remember to install the Platform Runtime Binary. You may try Eclipse IDE for C/C++ Developers, which includes the CDT, but this version is not covered here.<br />
<br />
TeraTerm can be downloaded at [http://ttssh2.sourceforge.jp/ ttssh2.sourceforge.jp].<br />
<br />
The last 3 items are available at our [[../download/|download page]].<br />
<br />
Installation details can be found in the documents that come with the specific product.<br />
<br />
=== Required Software (Ubuntu) ===<br />
<br />
The following software needs to be installed on the Linux PC (tested with Ubuntu 10.10):<br />
<br />
* Java Runtime Environment 1.6 or later<br />
* Eclipse Platform Runtime Binary 3.7 (Helios)<br />
* Eclipse CDT 7.0.2<br />
* minicom or other Terminal Emulator<br />
* gcc-arm-elf<br />
* Nut/OS 4.10<br />
* Turtelizer OpenOCD Package<br />
<br />
You can install the Java Runtime Environment, minicom and openocd with the following command:<br />
<br />
<pre class="coding">apt-get install default-jre minicom openocd</pre><br />
Eclipse is available at [http://download.eclipse.org/eclipse/downloads/ download.eclipse.org/eclipse/downloads] and the CDT can be found at [http://www.eclipse.org/cdt/ www.eclipse.org/cdt] Remember to install the Platform Runtime Binary. You may try Eclipse IDE for C/C++ Developers, which includes the CDT, but this version is not covered here. Also the eclipse package of Ubuntu doesn't work.<br />
<br />
Installation details can be found in the documents that come with the specific product.<br />
<br />
== Configuring Nut/OS ==<br />
<br />
When using the latest YAGARTO distribution, you must be aware of a significant change. While earlier releases used arm-elf-gcc, YAGARTO is now using arm-none-eabi-gcc. While Nut/OS 4.10 should work with this environment out of the box, Nut/OS 4.9 has been prepared to make this switch easy. Open the file ''nut/Makevars.arm-gcc'' with your text editor. Locate the line<br />
<br />
<pre class="coding">#TRGT = arm-none-eabi-</pre><br />
and remove the leading numero sign:<br />
<br />
<pre class="coding">TRGT = arm-none-eabi-</pre><br />
Save your changes.<br />
<br />
In order to include debugging information in the compiled binaries you need to switch from arm-gcc to arm-gccdbg. When done, rebuild Nut/OS and recreate the application directory. The following steps will give detailed instructions.<br />
<br />
The screenshots were taken while running the wxWidgets version of the Nut/OS Configurator. In Nut/OS 4.10, this tool had been replaced by Qt based version. Thus, the images will slightly differ from your screen output.<br />
<br />
[[ccd01.png|[[File:381px-ccd01.png]]]]<br />
When started for the first time, the Nut/OS Configurator will display a file selection dialog. If this is hidden by the splash window, simply click on that window to close it.<br />
<br />
<br /><br />
[[ccd02.png|[[File:381px-ccd02.png]]]]<br />
Select the file eir10c.cfg and click on ''Open''.<br />
<br />
<br /><br />
[[ccd03.png|[[File:389px-ccd03.png]]]]<br />
The Configurators main window will show the ''Nut/OS Components'' in a tree structure on the right side.<br />
<br />
<br /><br />
[[ccd04.png|[[File:389px-ccd04.png]]]]<br />
From the ''Edit'' menu select ''Settings...''.<br />
<br />
<br /><br />
[[ccd05.png|[[File:208px-ccd05.png]]]]<br />
Nothing needs to be changed on the ''Repository'' page of the settings dialog. You may check ''Enable multiple configurations'' if you are concurrently working with different target boards.<br />
<br />
<br /><br />
[[ccd06.png|[[File:215px-ccd06.png]]]]<br />
Select ''arm-gccdbg'' as the platform on the ''Build'' page.<br />
<br />
<br /><br />
[[ccd07.png|[[File:215px-ccd07.png]]]]<br />
On the ''Tools'' page you need to enter the path to all required tools, separated by semicolons. For the EIR board this should point to the Nut/OS win32 tools directory and the YAGARTO bin directory. While all other settings use normal slashes in paths, here we must use backslashes. If you are using Linux and the compiler is in a standard path, you don't need to insert a path here.<br />
<br />
<br /><br />
[[ccd08.png|[[File:215px-ccd08.png]]]]<br />
On the last page titled ''Samples'' you may select ''arm-oocd'' as the programmer of choice, but this is only required for programming the flash memory, not for debugging in RAM.<br />
<br />
<br /><br />
[[ccd09.png|[[File:389px-ccd09.png]]]]<br />
Before building the system, change the ''Linker Script'' in the components tree under ''Tools/GCC Settings'' to ''at91sam7se512_ram''.<br />
<br />
<br /><br />
[[ccd10.png|[[File:389px-ccd10.png]]]]<br />
We are using YAGARTO with Newlib 1.19. Make sure that ''Posix compatible unsetenv'' is checked under ''C runtime (target specific)/Environment''.<br />
<br />
<br /><br />
[[Nut-OS_Configurator-Non-BSD.png|[[File:389px-Nut-OS_Configurator-Non-BSD.png]]]]<br />
Under Linux you may need to disable Non-DSDL Code/RealNetworks RPSL/RCSL.<br />
<br />
<br /><br />
<br />
Nut/OS 4.9.10 contains 2 bugs, which let debugging in RAM fail for AT91SAM7SE targets. The first one is with the linker script at91sam7se512_ram.ld in directory nut\arch\arm\ldscripts. You can use a simple text editor like Notepad to fix this.<br />
<br />
Near the beginning of the file remove the line .<br />
<br />
<pre class="coding">rom(rx) : org = 0x00000000, len = 496k</pre><br />
and change the value 0x00200000 in line<br />
<br />
<pre class="coding">iram(rw) : org = 0x00200000, len = 32k</pre><br />
to 0x00000000, resulting in<br />
<br />
<pre class="coding">iram(rw) : org = 0x00000000, len = 32k</pre><br />
Somewhere in the middle you will find the line<br />
<br />
<pre class="coding">.data : AT (__etext)</pre><br />
which needs to be replaced by<br />
<br />
<pre class="coding">.data :</pre><br />
The second bug is in the file crtat91sam7se512_ram.S in directory nut\arch\arm\init. Again use your favorite text editor to remove the following part:<br />
<br />
<pre class="coding">/*<br />
* Remapping memory, SRAM to 0x00000000<br />
*/<br />
ldr r1, =MC_BASE<br />
mov r0, #01<br />
str r0, [r1, #MC_RCR_OFF]<br />
<br />
/*<br />
* Use 2 cycles for flash access.<br />
*/<br />
ldr r1, =MC_BASE<br />
mov r0, #MC_FWS_2R3W<br />
str r0, [r1, #MC_FMR_OFF]</pre><br />
Then remove all lines starting from<br />
<br />
<pre class="coding">/*<br />
* The watchdog is enabled after processor reset. Disable it.<br />
*/<br />
ldr r1, =WDT_BASE<br />
ldr r0, =WDT_WDDIS<br />
str r0, [r1, #WDT_MR_OFF] :</pre><br />
up to and including<br />
<br />
<pre class="coding"> /*<br />
* Switch to PLL clock.<br />
*/<br />
ldr r0, [r1, #PMC_MCKR_OFF]<br />
orr r0, r0, #PMC_CSS_PLL_CLK<br />
str r0, [r1, #PMC_MCKR_OFF]<br />
wait_pllsel:<br />
ldr r0, [r1, #PMC_SR_OFF]<br />
tst r0, #PMC_MCKRDY<br />
beq wait_pllsel</pre><br />
Finally remove this part:<br />
<br />
<pre class="coding"> /*<br />
* Relocate .data section (Copy from ROM to RAM).<br />
*/<br />
ldr r1, =__etext<br />
ldr r2, =__data_start<br />
ldr r3, =__data_end<br />
<br />
_41:<br />
cmp r2, r3<br />
ldrlo r0, [r1], #4<br />
strlo r0, [r2], #4<br />
blo _41</pre><br />
Save your changes.<br />
<br />
<br /><br />
[[ccd11.png|[[File:389px-ccd11.png]]]]<br />
Now we are ready to build Nut/OS for debugging. Select ''Build Nut/OS'' in the ''Build'' menu.<br />
<br />
<br /><br />
[[ccd12.png|[[File:176px-ccd12.png]]]]<br />
A message box shows the settings for creating the build directory. Verify them and click ''OK'' to build this directory.<br />
<br />
<br /><br />
[[ccd13.png|[[File:183px-ccd13.png]]]]<br />
A second message box shows the settings for building the system. Again verify them and click ''OK''.<br />
<br />
<br /><br />
[[ccd14.png|[[File:381px-ccd14.png]]]]<br />
The build may take a few minutes.<br />
<br />
<br /><br />
[[ccd15.png|[[File:389px-ccd15.png]]]]<br />
When done, make sure that it has been terminated successfully.<br />
<br />
<br /><br />
[[ccd16.png|[[File:389px-ccd16.png]]]]<br />
Nut/OS uses a separate directory for the application code. A template can be created by selecting ''Create Sample Directory'', containing all Nut/OS samples that are included in the distribution. Remember, that we will use the events sample.<br />
<br />
<br /><br />
[[ccd17.png|[[File:214px-ccd17.png]]]]<span></span><br />
When runnign the wxWidget based Configurator, a message box will show the current settings. Click ''OK'', if everything looks as expected.<br />
<br />
<br /><br />
[[ccd18.png|[[File:389px-ccd18.png]]]]<br />
When done, you may exit the Configurator by selecting ''Exit'' in the ''File'' menu.<br />
<br />
<br /><br />
[[ccd19.png|[[File:207px-ccd19.png]]]]<br />
Because we changed at least the linker script, the Configurator asks, whether to save these changes. In order to preserve the original settings, you may simply click No. Alternatively you can select Yes and choose a different filename like eir10c-debug.cfg in the following file selection dialog.<br />
<br />
<br /><br />
<br />
== Configuring Eclipse ==<br />
<br />
It is assumed that you successfully installed Eclipse and the CDT plug-in. For a first demonstration we will use the events sample that is included in the Nut/OS distribution.<br />
<br />
[[scd01.png|[[File:330px-scd01.png]]]]<br />
When started, Eclipse will ask for the Workspace Path. Choose the Nut/OS sample directory, e.g. C:\Ethernut-4.10\nutapp or ~/ethernut-4.9.10/nutapp under Linux.<br />
<br />
<br /><br />
[[scd02.png|[[File:431px-scd02.png]]]]<br />
The welcome page appears. Click on ''Workbench'' in the upper right corner.<br />
<br />
<br /><br />
[[scd03.png|[[File:431px-scd03.png]]]]<br />
The so called Java Perspective appears. We will later change to the C Perspective.<br />
<br />
<br /><br />
[[scd04.png|[[File:431px-scd04.png]]]]<br />
In the ''File'' menu select ''New'' and ''Project...''.<br />
<br />
<br /><br />
[[scd05.png|[[File:278px-scd05.png]]]]<br />
In the ''New Project'' dialog choose ''C Project'' and click on ''Next''.<br />
<br />
<br /><br />
[[scd06.png|[[File:278px-scd06.png]]]]<br />
In the ''C Project'' dialog enter ''events'' for the project name. Then choose ''Empty Project'' and ''-- Other Toolchain --''. Again click on ''Next''.<br />
<br />
<br /><br />
[[scd07.png|[[File:278px-scd07.png]]]]<br />
On the next page click on ''Advanced settings...''.<br />
<br />
<br /><br />
[[scd08.png|[[File:437px-scd08.png]]]]<br />
In the ''Project Properties'' page select ''Settings'' and check ''GNU Elf Parser''. Then click on ''OK''.<br />
<br />
<br /><br />
[[scd09.png|[[File:298px-scd09.png]]]]<br />
Back in the ''C Project'' dialog click ''Finish''.<br />
<br />
<br /><br />
[[scd11.png|[[File:281px-scd11.png]]]]<br />
Click ''Yes'' to open the C/C++ perspective.<br />
<br />
<br /><br />
[[scd12.png|[[File:484px-scd12.png]]]]<br />
We do not need the ''Java'' Perspective, therefore you should close it.<br />
<br />
<br /><br />
[[scd13.png|[[File:441px-scd13.png]]]]<br />
Uncheck ''Build Automatically'' in the ''Project'' menu.<br />
<br />
<br /><br />
[[scd13.1.png|[[File:441px-scd13.1.png]]]]<br />
In the same menu select ''Properties''.<br />
<br />
<br /><br />
[[scd13.2.png|[[File:524px-scd13.2.png]]]]<br />
In the ''Properties'' dialog select ''Environment'' in the tree on the right. Then click ''Add''.<br />
<br />
<br /><br />
[[scd13.3.png|[[File:343px-scd13.3.png]]]]<br />
The variable ''Name'' must be <code>PATH</code>. You need to enter the path to all required tools as the ''Value'', separated by semicolons. The first path should point to the Nut/OS win32 tools directory and the second one to the YAGARTO bin directory.<br />
<br />
<br /><br />
[[scd13.4.png|[[File:524px-scd13.4.png]]]]<br />
Click ''OK'' to store the updated Environment.<br />
<br />
<br /><br />
[[scd14.png|[[File:441px-scd14.png]]]]<br />
Then, in the same menu, select ''Build Project''.<br />
<br />
<br /><br />
[[scd15.png|[[File:434px-scd15.png]]]]<br />
Building this simple application requires a few seconds only.<br />
<br />
<br /><br />
<br />
When done, the newly created files appear in the ''Project Explorer''. The file ''events.elf'' contains the executable binary including all debug information.<br />
<br />
<br /><br />
<br />
== Debugging the Application ==<br />
<br />
[[scd16.png|[[File:451px-scd16.png]]]]<br />
Click on the ''Open Perspective'' button [[File:30px-b02.png]] and select ''Debug''. This will open the ''Debug Perspective''.<br />
<br />
<br /><br />
[[scd17.png|[[File:441px-scd17.png]]]]<br />
Click on the tiny arrow near the bug [[File:26px-b01.png]] in the toolbar to open the related menu. Then select ''Debug Configuration...''.<br />
<br />
<br /><br />
[[scd18.png|[[File:314px-scd18.png]]]]<br />
In the ''Debug Configurations'' dialog select ''GDB Hardware Debugging'' and click on the ''New'' button.<br />
<br />
<br /><br />
[[scd19.png|[[File:384px-scd19.png]]]]<br />
Enter <code>EIR Debugging</code> as the configuration name and <code>events</code> as the project name. Next click on ''Search Project...''.<br />
<br />
<br /><br />
[[scd20.png|[[File:195px-scd20.png]]]]<br />
Select ''events.elf'' and click ''OK''.<br />
<br />
<br /><br />
[[scd22.png|[[File:357px-scd22.png]]]]<br />
Back in the ''Debug Configurations'' dialog click on ''Select other''.<br />
<br />
<br /><br />
[[scd21.png|[[File:240px-scd21.png]]]]<br />
Choose ''Standard GDB Hardware Debugging Launcher'' as the preferred launcher and click ''OK''.<br />
<br />
<br /><br />
[[scd21.1.png|[[File:402px-scd21.1.png]]]]<br />
Back in the ''Debug Configurations'' dialog click on the ''Debugger'' tab and enter <code>arm-none-eabi-gdb</code> in ''GDB Command''. Although we will use remote target debugging, ''Use remote target'' must be unchecked here.<br />
<br />
<br /><br />
[[scd21.2.png|[[File:402px-scd21.2.png]]]]<br />
Now click on the ''Startup'' tab. ''Set breakpoint at'' and ''Resume'' must be checked. Enter <code>NutInit</code> as the breakpoint target.<br />
<br />
Then copy and paste the following commands into the field ''Initialization Commands''.<br />
<br />
<pre class="coding">target remote localhost:3333<br />
monitor jtag_khz 30<br />
monitor reset<br />
monitor sleep 500<br />
monitor poll<br />
monitor soft_reset_halt<br />
monitor gdb_breakpoint_override soft<br />
monitor mww 0xfffff130 0xffffffff<br />
monitor mww 0xfffff124 0xffffffff<br />
monitor mww 0xfffffd44 0x00008000<br />
monitor mww 0xffffff00 0x00000001<br />
monitor mww 0xFFFFFC20 0x00000601<br />
monitor sleep 10<br />
monitor mww 0xFFFFFC2C 0x00481c0e<br />
monitor sleep 10<br />
monitor mww 0xFFFFFC30 0x00000004<br />
monitor sleep 10<br />
monitor mww 0xFFFFFC30 0x00000007<br />
monitor sleep 10<br />
monitor mww 0xfffff474 0x3f800000<br />
monitor mww 0xfffff404 0x3f800000<br />
monitor mww 0xfffff674 0x0003effd<br />
monitor mww 0xfffff604 0x0003effd<br />
monitor mww 0xfffff870 0x0000ffff<br />
monitor mww 0xfffff804 0x0000ffff<br />
monitor mww 0xffffff80 0x00000002<br />
monitor mww 0xffffffb8 0x2192215a<br />
monitor sleep 10<br />
monitor mww 0xffffffb0 0x00000011<br />
monitor mww 0x20000000 0x00000000<br />
monitor mww 0xffffffb0 0x00000012<br />
monitor mww 0x20000000 0x00000000<br />
monitor mww 0xffffffb0 0x00000014<br />
monitor mww 0x20000000 0x00000000<br />
monitor mww 0xffffffb0 0x00000014<br />
monitor mww 0x20000000 0x00000000<br />
monitor mww 0xffffffb0 0x00000014<br />
monitor mww 0x20000000 0x00000000<br />
monitor mww 0xffffffb0 0x00000014<br />
monitor mww 0x20000000 0x00000000<br />
monitor mww 0xffffffb0 0x00000014<br />
monitor mww 0x20000000 0x00000000<br />
monitor mww 0xffffffb0 0x00000014<br />
monitor mww 0x20000000 0x00000000<br />
monitor mww 0xffffffb0 0x00000014<br />
monitor mww 0x20000000 0x00000000<br />
monitor mww 0xffffffb0 0x00000014<br />
monitor mww 0x20000000 0x00000000<br />
monitor mww 0xffffffb0 0x00000013<br />
monitor mww 0x20000014 0xcafedede<br />
monitor mww 0xffffffb4 0x00000013<br />
monitor mww 0xffffffb0 0x00000010<br />
monitor mww 0x20000000 0x00000180<br />
monitor jtag_khz 12000<br />
set mem inaccessible-by-default off</pre><br />
<br /><br />
[[scd22.1.png|[[File:357px-scd22.1.png]]]]<br />
Finally click ''Apply'' to store the settings and ''Close'' to close the dialog.<br />
<br />
<br /><br />
[[scd23.png|[[File:441px-scd23.png]]]]<br />
Once again click on the tiny arrow near the bug to open the menu and select ''Organize Favorites...''.<br />
<br />
<br /><br />
[[scd24.png|[[File:190px-scd24.png]]]]<br />
Click ''Add''.<br />
<br />
<br /><br />
[[scd25.png|[[File:170px-scd25.png]]]]<br />
Check ''EIR Debugging'' and click ''OK''.<br />
<br />
<br /><br />
[[scd26.png|[[File:190px-scd26.png]]]]<br />
In the previous dialog click ''OK'' again.<br />
<br />
<br /><br />
<br />
We will now setup the hardware, using the following steps:<br />
<br />
* Connect the Turtelizer's JTAG port to the JTAG Connector board's 10-pin connector.<br />
* Connect the JTAG port of the EIR to the JTAG Connector board's 20-pin connector.<br />
* Attach the power supply to the EIR and switch it on. The red LED on the EIR should go on.<br />
* Connect the Turtelizer's USB port to the PC using the USB A/B cable.<br />
<br />
[[EIR-JTAG-TURT.png|[[File:480px-EIR-JTAG-TURT.png]]]]<br />
If the Turtelizer is used for the first time, it will be required to install the FTDI driver. For more details please refer to the Turtelizer's documentation.<br />
<br />
<br /><br />
<br />
Next we will start OpenOCD. We could do this within Eclipse, but for the first time it makes sense to start it manually to check the output in case of problems.<br />
<br />
[[scd26.1.png|[[File:438px-scd26.1.png]]]]<br />
Now open a command line and change to directory <code>C:\Ethernut-4.10\nut\tools\turtelizer2</code>. Add the Nut/OS tools directory for Windows to your path, using the following command<br />
<br />
<pre class="coding">set PATH=C:\ethernut-4.10\nut\tools\win32;%PATH%</pre><br />
Yout don't need to set the path under Linux. Then start OpenOCD using<br />
<br />
<pre class="coding">openocd -f board/eir.cfg -f interface/turtelizer2.cfg</pre><br />
<br /><br />
[[scd27.2.png|[[File:250px-scd27.2.png]]]]<br />
The ''events'' sample will create some output on the RS-232. To make it visible, we start a ''terminal emulator''. On Windows PCs we could use ''HyperTerminal'', but ''TeraTerm'' is the preferred one. After ''TeraTerm'' started, select ''Serial port...'' from the ''Setup'' menu.<br />
<br />
<br /><br />
[[scd27.1.png|[[File:213px-scd27.1.png]]]]<br />
Select the COM port to which the Ethernut board is connected. Configure the port to 8 data bits, no parity, 1 stop bit and no flow control and click on ''OK''.<br />
<br />
<br /><br />
[[Bildschirmfoto-Terminal-minicom.png|[[File:300px-Bildschirmfoto-Terminal-minicom.png]]]]<br />
Under Linux you can use the following command on a terminal to start minicom:<br />
<br />
<pre class="coding">minicom -D /dev/ttyUSB0 -b 115200</pre><br />
You need to replace /dev/ttyUSB0 with the correct device.<br />
<br />
<br /><br />
<br />
Let's get back to ''Eclipse''. Remember that we specified a breakpoint at <code>NutInit</code> in the debugger configuration. For some unknown reason the debugger fails, if this is not defined. However, the function NutInit is located in the initialization of Nut/OS, while you will be mostly interested in debugging your application code.<br />
<br />
[[scd26.2.png|[[File:441px-scd26.2.png]]]]<br />
Lets specify a second breakpoint at the beginning of the application code, which is the function main. Click on the tab ''C/C++'' in the upper right corner to change to the C Perspective.<br />
<br />
In the ''Project Explorer'' double click on the events folder to expand it. Then click on the tiny arrow in front of ''events.c'' to expand this part of the tree. Note, that this arrow will appear only when moving the mouse over the ''Project Explorer'' window.<br />
<br />
Now double click on ''main(void)'' to open the source file at this location.<br />
<br />
<br /><br />
[[scd26.3.png|[[File:441px-scd26.3.png]]]]<br />
At the first line click with the right mouse button on blue border to open the context menu. Select ''Toggle Breakpoint''.<br />
<br />
<br /><br />
[[scd27.png|[[File:441px-scd27.png]]]]<br />
Switch back to the debug perspective by clicking on the tab ''Debug'' in the upper right corner. Click on the bug button in the toolbar to start debugging.<br />
<br />
<br /><br />
[[scd28.png|[[File:441px-scd28.png]]]]<br />
The code will be downloaded to the target and started. Then it stops at the first breakpoint at the beginning of NutInit. Press ''F8'' or click the ''Resume'' button [[File:30px-b03.png]].<br />
<br />
<br /><br />
[[scd29.png|[[File:441px-scd29.png]]]]<br />
The target code will run up to the next breakpoint in main. You can now press ''F5'' or click the button [[File:30px-b04.png]] to step execute a single line, ''F6'' or click the button [[File:30px-b05.png]] to step over a function call.<br />
<br />
<br /><br />
[[scd29.2.png|[[File:439px-scd29.2.png]]]]<br />
Now continue pressing ''F6'' until we stepped over the first <code>puts()</code> function call.<br />
<br />
<br /><br />
[[scd29.1.png|[[File:226px-scd29.1.png]]]]<br />
When this statement has been executed, the text <code>Nut/OS Event Queue Demo</code> should appear in the terminal emulator window.<br />
<br />
<br /><br />
[[scd29.4.png|[[File:439px-scd29.4.png]]]]<br />
As you continue stepping through the main loop...<br />
<br />
<br /><br />
[[scd29.3.png|[[File:226px-scd29.3.png]]]]<br />
...additional output appears on the serial port.<br />
<br />
<br /><br />
<br />
You may set additional breakpoints, evaluate variables or memory areas and do many other useful things during debugging. Please refer to the Eclipse documentation for further details.<br />
<br />
Under Linux an Error occures in the output of openocd, when debugging:<br />
<br />
<pre class="coding">Error: address + size wrapped(0xfffffffe, 0x00000004)</pre><br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EIR/AssemblyHardware/EIR/Assembly2017-07-13T08:56:24Z<p>Harald: Created page with "<div id="content"> = Assembly Instructions = {| |width="50%"| [[File:../../../img/eir_leer_thumb.jpg]] |width="50%"| EIR boards are shipped wit..."</p>
<hr />
<div><div id="content"><br />
<br />
= Assembly Instructions =<br />
<br />
{|<br />
|width="50%"| [[../../../img/eir_leer.jpg|[[File:../../../img/eir_leer_thumb.jpg]]]]<br />
|width="50%"| EIR boards are shipped with SMD parts populated, but THT parts packed seperately for DIY soldering.<br />
|-<br />
| [[../../../img/eir_1-2.jpg|[[File:../../../img/eir_1-2_thumb.jpg]]]]<br />
|<br />
1. Ethernet connector<br /><br />
2. Power supply connector<br />
<br />
Because the firmware had been preloaded, you should be able to receive and listen to Internet radio stations.<br />
|-<br />
| [[../../../img/eir_3-4.jpg|[[File:../../../img/eir_3-4_thumb.jpg]]]]<br />
|<br />
In order to be able to erase and the Flash memory and upload new firmware, we need to mount<br />
<br />
3. Expansion port connector K3 (or at least pins 34 and 36)<br /><br />
4. USB Connector<br />
|-<br />
| [[../../../img/eir_5-6.jpg|[[File:../../../img/eir_5-6_thumb.jpg]]]]<br />
|<br />
If things are not working as expected, it would be a good idea to make use of the serial port, where the following parts are needed.<br /><br />
<br />
<br />
5. RS-232 jumper<br /><br />
6. RS-232 connector<br />
|-<br />
| [[../../../img/eir_7.jpg|[[File:../../../img/eir_7_thumb.jpg]]]]<br />
|<br />
In order to use the JTAG interface, mount<br /><br />
<br />
<br />
7. JTAG connector<br />
|-<br />
| [[../../../img/eir_8.jpg|[[File:../../../img/eir_8_thumb.jpg]]]]<br />
|<br />
For RTC backup during power loss, mount<br /><br />
<br />
<br />
8. Double layer capacitor<br />
|-<br />
| [[../../../img/eir_9.jpg|[[File:../../../img/eir_9_thumb.jpg]]]]<br />
|<br />
Finally, if you intend to attach an add-on board, K3 should have been fully populated. Additionally mount<br /><br />
<br />
<br />
9. Expansion port connectors K1 and K2<br />
|-<br />
| [[../../../img/eir.jpg|[[File:../../../img/eir_thumb.jpg]]]]<br />
| Finished!<br />
|}<br />
<br />
<br />
-----<br />
<br />
Return to the [[index.html|EIR project page]].<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/Calypso_PortsHardware/Calypso Ports2017-07-13T08:53:07Z<p>Harald: Created page with "<div id="content"> = SAM7X256-EK Ports = == Expansion Port J16 Row-A == {| ! Pin ! Port ! Peri.A ! Peri.B ! Usage |- | A1 | PA0 | RXD0 | | Serial COM port if S15 closed..."</p>
<hr />
<div><div id="content"><br />
<br />
= SAM7X256-EK Ports =<br />
<br />
== Expansion Port J16 Row-A ==<br />
<br />
{|<br />
! Pin<br />
! Port<br />
! Peri.A<br />
! Peri.B<br />
! Usage<br />
|-<br />
| A1<br />
| PA0<br />
| RXD0<br />
| <br />
| Serial COM port if S15 closed (default).<br />
|-<br />
| A2<br />
| PA1<br />
| TXD0<br />
| <br />
| Serial COM port if S13 closed (default).<br />
|-<br />
| A3<br />
| PA2<br />
| SCK0<br />
| SPI1_NPCS1<br />
| CAN standby/normal mode<br />
|-<br />
| A4<br />
| PA3<br />
| RTS0<br />
| SPI1_NPCS2<br />
| Serial COM port if S14 closed (default).<br />
|-<br />
| A5<br />
| PA4<br />
| CTS0<br />
| SPI1_NPCS3<br />
| Serial COM port if S16 closed (default).<br />
|-<br />
| A6<br />
| PA5<br />
| RXD1<br />
| <br />
| Available<br /><br />
Button UP<br />
|-<br />
| A7<br />
| PA6<br />
| TXD1<br />
| <br />
| Available<br /><br />
Button RIGHT<br />
|-<br />
| A8<br />
| PA7<br />
| SCK1<br />
| SPI0_NPCS1<br />
| Available<br /><br />
Button LEFT<br />
|-<br />
| A9<br />
| PA8<br />
| RTS1<br />
| SPI0_NPCS2<br />
| Available<br /><br />
LCD Control 1<br />
|-<br />
| A10<br />
| PA9<br />
| CTS1<br />
| SPI0_NPCS3<br />
| Available<br /><br />
LCD Control 2<br />
|-<br />
| A11<br />
| PA10<br />
| TWD<br />
| <br />
| SDA at on-board EEPROM (not mounted) if S29 closed (default).<br />
|-<br />
| A12<br />
| PA11<br />
| TWCK<br />
| <br />
| SCL at on-board EEPROM (not mounted) if S28 closed (default).<br />
|-<br />
| A13<br />
| PA12<br />
| SPI0_NPCS0<br />
| <br />
| CS at on-board DataFlash chip if J19 closed (default).<br />
|-<br />
| A14<br />
| PA13<br />
| SPI0_NPCS1<br />
| PCK1<br />
| CS at DataFlash socket<br />
|-<br />
| A15<br />
| PA14<br />
| SPI0_NPCS2<br />
| IRQ1<br />
| Available<br /><br />
NPCS2: AT73C213 CS<br />
|-<br />
| A16<br />
| PA15<br />
| SPI0_NPCS3<br />
| TCLK2<br />
| Available<br /><br />
LCD Control 3<br />
|-<br />
| A17<br />
| PA16<br />
| SPI0_MISO<br />
| <br />
| MISO at DataFlash socket and on-board DataFlash chip<br /><br />
MISO: AT73C213 DOUT<br />
|-<br />
| A18<br />
| PA17<br />
| SPI0_MOSI<br />
| <br />
| MOSI at DataFlash socket and on-board DataFlash chip<br /><br />
MOSI: AT73C213 DIN<br />
|-<br />
| A19<br />
| PA18<br />
| SPI0_SPCK<br />
| <br />
| SPCK at DataFlash socket and on-board DataFlash chip<br /><br />
SPCK: AT73C213 CLK<br />
|-<br />
| A20<br />
| PA19<br />
| CANRX<br />
| <br />
| CAN receiver if S9 closed (default).<br />
|-<br />
| A21<br />
| PA20<br />
| CANTX<br />
| <br />
| CAN transmitter if S8 closed (default).<br />
|-<br />
| A22<br />
| PA21<br />
| TF<br />
| SPI1_NPCS0<br />
| Joystick up contact<br /><br />
TF: AT73C213 LRFS<br />
|-<br />
| A23<br />
| PA22<br />
| TK<br />
| SPI1_SPCK<br />
| Joystick down contact<br /><br />
TK: AT73C213 BCLK<br />
|-<br />
| A24<br />
| PA23<br />
| TD<br />
| SPI1_MOSI<br />
| Joystick left contact<br /><br />
TD: AT73C213 SDIN<br />
|-<br />
| A25<br />
| PA24<br />
| RD<br />
| SPI1_MISO<br />
| Joystick right contact<br /><br />
LCD D0<br />
|-<br />
| A26<br />
| PA25<br />
| RK<br />
| SPI1_NPCS1<br />
| Joystick push contact<br /><br />
LCD D1<br />
|-<br />
| A27<br />
| PA26<br />
| RF<br />
| SPI1_NPCS2<br />
| Available<br /><br />
LCD D2<br />
|-<br />
| A28<br />
| PA27<br />
| DRXD<br />
| PCK3<br />
| Serial debug port if S22 closed (default).<br />
|-<br />
| A29<br />
| PA28<br />
| DTXD<br />
| <br />
| Serial debug port if S21 closed (default).<br />
|-<br />
| A30<br />
| PA29<br />
| FIQ<br />
| SPI1_NPCS3<br />
| Available<br /><br />
LCD D3<br />
|-<br />
| A31<br />
| PA30<br />
| IRQ0<br />
| PCK2<br />
| Available<br /><br />
PCK2: AT73C213 MCLK<br />
|-<br />
| A32<br />
| <br />
| <br />
| <br />
| Not connected<br />
|}<br />
<br />
<br /><br />
<br /><br />
<br />
== Expansion Port J16 Row-B ==<br />
<br />
{|<br />
! Pin<br />
! Port<br />
! Peri.A<br />
! Peri.B<br />
! Usage<br />
|-<br />
| B1<br />
| PB0<br />
| ETXCK/EREFCK<br />
| PCK0<br />
| Ethernet PHY<br />
|-<br />
| B2<br />
| PB1<br />
| ETXEN<br />
| <br />
| Ethernet PHY<br />
|-<br />
| B3<br />
| PB2<br />
| ETX0<br />
| <br />
| Ethernet PHY<br />
|-<br />
| B4<br />
| PB3<br />
| ETX1<br />
| <br />
| Ethernet PHY<br />
|-<br />
| B5<br />
| PB4<br />
| ECRS<br />
| <br />
| Ethernet PHY<br />
|-<br />
| B6<br />
| PB5<br />
| ERX0<br />
| <br />
| Ethernet PHY<br />
|-<br />
| B7<br />
| PB6<br />
| ERX1<br />
| <br />
| Ethernet PHY<br />
|-<br />
| B8<br />
| PB7<br />
| ERXER<br />
| <br />
| Ethernet PHY<br />
|-<br />
| B9<br />
| PB8<br />
| EMDC<br />
| <br />
| Ethernet PHY<br />
|-<br />
| B10<br />
| PB9<br />
| EMDIO<br />
| <br />
| Ethernet PHY<br />
|-<br />
| B11<br />
| PB10<br />
| ETX2<br />
| SPI1_NPCS1<br />
| Ethernet PHY<br />
|-<br />
| B12<br />
| PB11<br />
| ETX3<br />
| SPI1_NPCS2<br />
| Ethernet PHY<br />
|-<br />
| B13<br />
| PB12<br />
| ETXER<br />
| TCLK0<br />
| Ethernet PHY<br />
|-<br />
| B14<br />
| PB13<br />
| ERX2<br />
| SPI0_NPCS1<br />
| Ethernet PHY<br />
|-<br />
| B15<br />
| PB14<br />
| ERX3<br />
| SPI0_NPCS2<br />
| Ethernet PHY<br />
|-<br />
| B16<br />
| PB15<br />
| ERXDV/ECRSDV<br />
| <br />
| Ethernet PHY<br />
|-<br />
| B17<br />
| PB16<br />
| ECOL<br />
| SPI1_NPCS3<br />
| Ethernet PHY<br />
|-<br />
| B18<br />
| PB17<br />
| ERXCK<br />
| SPI0_NPCS3<br />
| Ethernet PHY<br />
|-<br />
| B19<br />
| PB18<br />
| EF100<br />
| ADTRG<br />
| Ethernet PHY power down<br />
|-<br />
| B20<br />
| PB19<br />
| PWM0<br />
| TCLK1<br />
| User LED DS1 if S17 closed (default).<br />
|-<br />
| B21<br />
| PB20<br />
| PWM1<br />
| PCK0<br />
| User LED DS2 if S18 closed (default).<br />
|-<br />
| B22<br />
| PB21<br />
| PWM2<br />
| PCK1<br />
| User LED DS3 if S19 closed (default).<br />
|-<br />
| B23<br />
| PB22<br />
| PWM3<br />
| PCK2<br />
| User LED DS4 if S20 closed (default).<br />
|-<br />
| B24<br />
| PB23<br />
| TIOA0<br />
| DCD1<br />
| Available<br />
|-<br />
| B25<br />
| PB24<br />
| TIOB0<br />
| DSR1<br />
| Available<br />
|-<br />
| B26<br />
| PB25<br />
| TIOA1<br />
| DTR1<br />
| Power LED control if S6 closed (default).<br />
|-<br />
| B27<br />
| PB26<br />
| TIOB1<br />
| RI1<br />
| Ethernet PHY interrupt request<br />
|-<br />
| B28<br />
| PB27<br />
| TIOA2<br />
| PWM0<br />
| Available<br />
|-<br />
| B29<br />
| PB28<br />
| TIOB2<br />
| PWM1<br />
| Available<br />
|-<br />
| B30<br />
| PB29<br />
| PCK1<br />
| PWM2<br />
| Available<br />
|-<br />
| B31<br />
| PB30<br />
| PCK2<br />
| PWM3<br />
| PWM3 analog output if S12 closed (default).<br />
|-<br />
| B32<br />
| <br />
| <br />
| <br />
| Not connected<br />
|}<br />
<br />
<br /><br />
<br /><br />
<br />
== Expansion Port J16 Row-C ==<br />
<br />
{|<br />
! Pin<br />
! Port<br />
! Peri.A<br />
! Peri.B<br />
! Usage<br />
|-<br />
| C1<br />
| <br />
| <br />
| <br />
| +5V supply if S3 closed (open by default)<br />
|-<br />
| C2<br />
| <br />
| <br />
| <br />
| Digital ground<br /><br />
Calypso GND<br />
|-<br />
| C3<br />
| PA0<br />
| '''RXD0'''<br />
| <br />
| Serial COM port if S15 closed (default).<br />
|-<br />
| C4<br />
| PA1<br />
| '''TXD0'''<br />
| <br />
| Serial COM port if S13 closed (default).<br />
|-<br />
| C5<br />
| PA2<br />
| '''SCK0'''<br />
| SPI1_NPCS1<br />
| CAN standby/normal mode<br />
|-<br />
| C6<br />
| PA3<br />
| '''RTS0'''<br />
| SPI1_NPCS2<br />
| Serial COM port if S14 closed (default).<br />
|-<br />
| C7<br />
| PA4<br />
| '''CTS0'''<br />
| SPI1_NPCS3<br />
| Serial COM port if S16 closed (default).<br />
|-<br />
| C8<br />
| PA16<br />
| '''SPI0_MISO'''<br />
| <br />
| MISO at DataFlash socket and on-board DataFlash chip<br /><br />
MISO: AT73C213 DOUT<br />
|-<br />
| C9<br />
| PA17<br />
| '''SPI0_MOSI'''<br />
| <br />
| MOSI at DataFlash socket and on-board DataFlash chip<br /><br />
MOSI: AT73C213 DIN<br /><br />
MOSI: LCD<br />
|-<br />
| C10<br />
| PA18<br />
| '''SPI0_SPCK'''<br />
| <br />
| SPCK at DataFlash socket and on-board DataFlash chip<br /><br />
SPCK: AT73C213 CLK<br /><br />
SPCK: LCD<br />
|-<br />
| C11<br />
| PA12<br />
| '''SPI0_NPCS0'''<br />
| <br />
| CS at on-board DataFlash chip if J19 closed (default).<br />
|-<br />
| C12<br />
| PA13<br />
| '''SPI0_NPCS1'''<br />
| PCK1<br />
| CS at DataFlash socket<br />
|-<br />
| C13<br />
| PA10<br />
| '''TWD'''<br />
| <br />
| SDA at on-board EEPROM (not mounted) if S29 closed (default).<br /><br />
TWD: AIC23B SDIN<br />
|-<br />
| C14<br />
| PA11<br />
| '''TWCK'''<br />
| <br />
| SCL at on-board EEPROM (not mounted) if S28 closed (default).<br /><br />
TWCK: AIC23B SCLK<br />
|-<br />
| C15<br />
| PA21<br />
| '''TF'''<br />
| SPI1_NPCS0<br />
| Joystick up contact<br /><br />
TF: AT73C213 LRFS<br /><br />
TF: AIC23B LRCIN<br />
|-<br />
| C16<br />
| PA22<br />
| '''TK'''<br />
| SPI1_SPCK<br />
| Joystick down contact<br /><br />
TK: AT73C213 BCLK<br /><br />
TK: AIC23B BCLK<br />
|-<br />
| C17<br />
| PA23<br />
| '''TD'''<br />
| SPI1_MOSI<br />
| Joystick left contact<br /><br />
TD: AT73C213 SDIN<br /><br />
TD: AIC23B DIN<br />
|-<br />
| C18<br />
| PA24<br />
| '''RD'''<br />
| SPI1_MISO<br />
| Joystick right contact<br /><br />
LCD D0<br /><br />
RD: AIC23B DOUT<br />
|-<br />
| C19<br />
| PA25<br />
| '''RK'''<br />
| SPI1_NPCS1<br />
| Joystick push contact<br /><br />
LCD D1<br />
|-<br />
| C20<br />
| PA26<br />
| '''RF'''<br />
| SPI1_NPCS2<br />
| Available<br /><br />
LCD D2<br /><br />
RF: AIC23B LRCOUT<br />
|-<br />
| C21<br />
| PB23<br />
| '''TIOA0'''<br />
| DCD1<br />
| Available<br /><br />
PB23: LCD RS<br />
|-<br />
| C22<br />
| PB24<br />
| '''TIOB0'''<br />
| DSR1<br />
| Available<br /><br />
PB24: LCD CS<br />
|-<br />
| C23<br />
| PB29<br />
| '''PCK1'''<br />
| PWM2<br />
| Available<br /><br />
PB29: Button UP<br />
|-<br />
| C24<br />
| PA30<br />
| '''IRQ0'''<br />
| PCK2<br />
| Available<br /><br />
PCK2: AT73C213 MCLK<br /><br />
PCK2: AIC23B XTI/MCLK<br />
|-<br />
| C25<br />
| PB27<br />
| TIOA2<br />
| '''PWM0'''<br />
| Available<br /><br />
PB27: Button DOWN<br />
|-<br />
| C26<br />
| PB28<br />
| TIOB2<br />
| '''PWM1'''<br />
| Available<br /><br />
PB28: Button MENU<br />
|-<br />
| C27<br />
| <br />
| <br />
| <br />
| Reserved, not connected<br />
|-<br />
| C28<br />
| <br />
| <br />
| <br />
| Analog ground<br />
|-<br />
| C29<br />
| '''AD6'''<br />
| <br />
| <br />
| <br />
|-<br />
| C30<br />
| '''AD7'''<br />
| <br />
| <br />
| <br />
|-<br />
| C31<br />
| <br />
| <br />
| <br />
| +3.3V supply<br /><br />
Calypso Supply<br />
|-<br />
| C32<br />
| <br />
| <br />
| <br />
| Digital ground<br /><br />
Calypso GND<br />
|}<br />
<br />
<br /><br />
<br /><br />
<br />
= SAM9260-EK Ports =<br />
<br />
== Expansion Port PIO A J23 ==<br />
<br />
{|<br />
! Pin<br />
! Port<br />
! Peri.A<br />
! Peri.B<br />
! Usage<br />
|-<br />
| 1<br />
| PA1<br />
| SPI0_MOSI<br />
| MCCDB<br />
| Card Reader CMD<br />
|-<br />
| 2<br />
| PA0<br />
| SPI0_MISO<br />
| MCDB0<br />
| Card Reader DAT0<br />
|-<br />
| 3<br />
| PA3<br />
| SPI0_NPCS0<br />
| MCDB3<br />
| Card Reader DAT3<br />
|-<br />
| 4<br />
| PA2<br />
| SPI0_SPCK<br />
| <br />
| On-board DataFlash SCK<br />
|-<br />
| 5<br />
| PA5<br />
| CTS2<br />
| MCDB1<br />
| Card Reader DAT1<br />
|-<br />
| 6<br />
| PA4<br />
| RTS2<br />
| MCDB2<br />
| Card Reader DAT2<br />
|-<br />
| 7<br />
| PA7<br />
| MCCDA<br />
| <br />
| Ethernet PHY<br />
|-<br />
| 8<br />
| PA6<br />
| MCDA0<br />
| <br />
| User LED<br />
|-<br />
| 9<br />
| PA9<br />
| MCDA1<br />
| <br />
| Power LED<br />
|-<br />
| 10<br />
| PA8<br />
| MCCK<br />
| <br />
| Card Reader CLK<br />
|-<br />
| 11<br />
| PA11<br />
| MCDA3<br />
| EXT3<br />
| Ethernet PHY<br />
|-<br />
| 12<br />
| PA10<br />
| MCDA2<br />
| EXT2<br />
| Ethernet PHY<br />
|-<br />
| 13<br />
| PA13<br />
| ETX1<br />
| <br />
| Ethernet PHY<br />
|-<br />
| 14<br />
| PA12<br />
| ETX0<br />
| <br />
| Ethernet PHY<br />
|-<br />
| 15<br />
| PA15<br />
| ERX1<br />
| <br />
| Ethernet PHY<br />
|-<br />
| 16<br />
| PA14<br />
| ERX0<br />
| <br />
| Ethernet PHY<br />
|-<br />
| 17<br />
| PA17<br />
| ERXDV<br />
| <br />
| Ethernet PHY<br />
|-<br />
| 18<br />
| PA16<br />
| ETXEN<br />
| <br />
| Ethernet PHY<br />
|-<br />
| 19<br />
| PA19<br />
| ETXCK<br />
| <br />
| Ethernet PHY<br />
|-<br />
| 20<br />
| PA18<br />
| ERXER<br />
| <br />
| Ethernet PHY<br />
|-<br />
| 21<br />
| PA21<br />
| EMDIO<br />
| <br />
| Ethernet PHY<br />
|-<br />
| 22<br />
| PA20<br />
| EMDC<br />
| <br />
| Ethernet PHY<br />
|-<br />
| 23<br />
| PA23<br />
| TWD<br />
| ETX2<br />
| On-board EEPROM SDA<br />
|-<br />
| 24<br />
| PA22<br />
| ADTRG<br />
| ETXER<br />
| Ethernet PHY<br />
|-<br />
| 25<br />
| PA25<br />
| TCLK0<br />
| ERX2<br />
| Ethernet PHY<br />
|-<br />
| 26<br />
| PA24<br />
| TWCK<br />
| ETX3<br />
| On-board EEPROM SCL<br />
|-<br />
| 27<br />
| PA27<br />
| TIOA1<br />
| ERXCK<br />
| Ethernet PHY<br />
|-<br />
| 28<br />
| PA26<br />
| TIOA0<br />
| ERX3<br />
| Ethernet PHY<br />
|-<br />
| 29<br />
| PA29<br />
| SCK1<br />
| ECOL<br />
| Ethernet PHY<br />
|-<br />
| 30<br />
| PA28<br />
| TIOA2<br />
| ECRS<br />
| Ethernet PHY<br />
|-<br />
| 31<br />
| PA31<br />
| SCK0<br />
| TCD4<br />
| Push button BP4<br /><br />
Port available on BGA only<br />
|-<br />
| 32<br />
| PA30<br />
| SCK2<br />
| RXD4<br />
| Push button BP3<br /><br />
Port available on BGA only<br />
|-<br />
| 33<br />
| <br />
| <br />
| <br />
| Digital ground<br />
|-<br />
| 34<br />
| <br />
| <br />
| <br />
| Digital ground<br />
|-<br />
| 35<br />
| <br />
| <br />
| <br />
| +3.3V supply<br />
|-<br />
| 36<br />
| <br />
| <br />
| <br />
| +3.3V supply<br />
|-<br />
| 37<br />
| <br />
| <br />
| <br />
| Not connected<br />
|-<br />
| 38<br />
| <br />
| <br />
| <br />
| Not connected<br />
|-<br />
| 39<br />
| <br />
| <br />
| <br />
| Not connected<br />
|-<br />
| 40<br />
| <br />
| <br />
| <br />
| Not connected<br />
|}<br />
<br />
<br /><br />
<br /><br />
<br />
== Expansion Port PIO B J26 ==<br />
<br />
{|<br />
! Pin<br />
! Port<br />
! Peri.A<br />
! Peri.B<br />
! Usage<br />
|-<br />
| 1<br />
| PB1<br />
| SPI1_MOSI<br />
| TIOB3<br />
| AT73C213 DIN<br /><br />
MOSI: LCD MOSI<br />
|-<br />
| 2<br />
| PB0<br />
| SPI1_MISO<br />
| TIOA3<br />
| AT73C213 DOUT<br />
|-<br />
| 3<br />
| PB3<br />
| SPI1_NPCS0<br />
| TIOA5<br />
| AT73C213 CS<br />
|-<br />
| 4<br />
| PB2<br />
| SPI1_SPCK<br />
| TIOA4<br />
| AT73C213 CLK<br /><br />
SPCK: LCD SPCK<br />
|-<br />
| 5<br />
| PB5<br />
| RXD0<br />
| <br />
| Serial port 0<br />
|-<br />
| 6<br />
| PB4<br />
| TXD0<br />
| <br />
| Serial port 0<br />
|-<br />
| 7<br />
| PB7<br />
| RXD1<br />
| TCLK2<br />
| Serial port 1<br />
|-<br />
| 8<br />
| PB6<br />
| TXD1<br />
| TCLK1<br />
| Serial port 1<br />
|-<br />
| 9<br />
| PB9<br />
| RXD2<br />
| <br />
| Available<br /><br />
Button UP<br /><br />
Button MENU<br />
|-<br />
| 10<br />
| PB8<br />
| TXD2<br />
| <br />
| Available<br /><br />
Button right<br /><br />
Button DOWN<br />
|-<br />
| 11<br />
| PB11<br />
| RXD3<br />
| ISI_D9<br />
| Available<br /><br />
Button left<br /><br />
LCD CS<br />
|-<br />
| 12<br />
| PB10<br />
| TXD3<br />
| ISI_D8<br />
| Available<br /><br />
LCD Control 1<br /><br />
Button UP<br />
|-<br />
| 13<br />
| PB13<br />
| RXD5<br />
| ISI_D11<br />
| BGA only<br /><br />
AIC23B TWCK<br />
|-<br />
| 14<br />
| PB12<br />
| TXD5<br />
| ISI_D10<br />
| BGA only<br /><br />
AIC23B TWD<br />
|-<br />
| 15<br />
| PB15<br />
| DTXD<br />
| <br />
| Serial debug port<br />
|-<br />
| 16<br />
| PB14<br />
| DRXD<br />
| <br />
| Serial debug port<br />
|-<br />
| 17<br />
| PB17<br />
| TF0<br />
| TCLK4<br />
| AT73C213 LRFS<br /><br />
TF0: AIC23B LRFS<br />
|-<br />
| 18<br />
| PB16<br />
| TK0<br />
| TCLK3<br />
| AT73C213 BCLK<br /><br />
TK0: AIC23B BCLK<br />
|-<br />
| 19<br />
| PB19<br />
| RD0<br />
| TIOB5<br />
| Available<br /><br />
LCD Control 2<br /><br />
RD0: AIC23B RD<br />
|-<br />
| 20<br />
| PB18<br />
| TD0<br />
| TIOB4<br />
| AT73C213 SDIN<br /><br />
TD0: AIC23B Data<br />
|-<br />
| 21<br />
| PB21<br />
| RF0<br />
| ISI_D1<br />
| Available<br /><br />
LCD D0<br /><br />
RF0: AIC23B RF<br />
|-<br />
| 22<br />
| PB20<br />
| RK0<br />
| ISI_D0<br />
| Available<br /><br />
LCD Control 3<br /><br />
LCD RS<br />
|-<br />
| 23<br />
| PB23<br />
| DCD0<br />
| ISI_D3<br />
| Serial port 0<br />
|-<br />
| 24<br />
| PB22<br />
| DSR0<br />
| ISI_D2<br />
| Serial port 0<br />
|-<br />
| 25<br />
| PB25<br />
| RI0<br />
| ISI_D5<br />
| Serial port 0<br />
|-<br />
| 26<br />
| PB24<br />
| DTR0<br />
| ISI_D4<br />
| Serial port 0<br />
|-<br />
| 27<br />
| PB27<br />
| CTS0<br />
| ISI_D7<br />
| Serial port 0<br />
|-<br />
| 28<br />
| PB26<br />
| RTS0<br />
| ISI_D6<br />
| Serial port 0<br />
|-<br />
| 29<br />
| PB29<br />
| CTS1<br />
| ISI_VSYNC<br />
| Serial port 1<br />
|-<br />
| 30<br />
| PB28<br />
| RTS1<br />
| ISI_PCK<br />
| Serial port 1<br /><br />
LCD D1<br />
|-<br />
| 31<br />
| PB31<br />
| PCK1<br />
| ISI_MCK<br />
| Available<br /><br />
LCD D3<br /><br />
PCK1: AIC23B MCLK<br />
|-<br />
| 32<br />
| PB30<br />
| PCK0<br />
| ISI_HSYNC<br />
| Available<br /><br />
LCD D2<br />
|-<br />
| 33<br />
| <br />
| <br />
| <br />
| Digital ground<br />
|-<br />
| 34<br />
| <br />
| <br />
| <br />
| Digital ground<br />
|-<br />
| 35<br />
| <br />
| <br />
| <br />
| +3.3V supply<br />
|-<br />
| 36<br />
| <br />
| <br />
| <br />
| +3.3V supply<br />
|-<br />
| 37<br />
| <br />
| <br />
| <br />
| Not connected<br />
|-<br />
| 38<br />
| <br />
| <br />
| <br />
| Not connected<br />
|-<br />
| 39<br />
| <br />
| <br />
| <br />
| Not connected<br />
|-<br />
| 40<br />
| <br />
| <br />
| <br />
| Not connected<br />
|}<br />
<br />
<br /><br />
<br /><br />
<br />
== Expansion Port PIO C And ADC J24 ==<br />
<br />
{|<br />
! Pin<br />
! Port<br />
! Peri.A<br />
! Peri.B<br />
! Usage<br />
|-<br />
| 1<br />
| PC1<br />
| <br />
| PCK0<br />
| AT73C213 MCLK<br />
|-<br />
| 2<br />
| PC0<br />
| <br />
| SCK3<br />
| Available<br />
|-<br />
| 3<br />
| PC3<br />
| <br />
| SPI1_NPCS3<br />
| Available<br />
|-<br />
| 4<br />
| PC2<br />
| <br />
| PCK1<br />
| Available<br />
|-<br />
| 5<br />
| PC5<br />
| A24<br />
| SPI1_NPCS1<br />
| USBCNX<br />
|-<br />
| 6<br />
| PC4<br />
| A23<br />
| SPI1_NPCS2<br />
| Available<br />
|-<br />
| 7<br />
| PC7<br />
| TIOB1<br />
| CFCE2<br />
| Available<br />
|-<br />
| 8<br />
| PC6<br />
| TIOB2<br />
| CFCE1<br />
| Available<br />
|-<br />
| 9<br />
| PC9<br />
| NCS5/CFCS1<br />
| TIOB0<br />
| Available<br />
|-<br />
| 10<br />
| PC8<br />
| NCS4/CFCS0<br />
| RTS3<br />
| Available<br />
|-<br />
| 11<br />
| PC11<br />
| NCS2<br />
| SPI0_NPCS1<br />
| On-board DataFlash CS<br />
|-<br />
| 12<br />
| PC10<br />
| A25/CFRNW<br />
| CTS3<br />
| Available<br />
|-<br />
| 13<br />
| PC13<br />
| FIQ<br />
| NCS6<br />
| NAND Flash RDYBSY<br />
|-<br />
| 14<br />
| PC12<br />
| IRQ0<br />
| NCS7<br />
| BGA only<br />
|-<br />
| 15<br />
| PC15<br />
| NWAIT<br />
| IRQ1<br />
| Available<br />
|-<br />
| 16<br />
| PC14<br />
| NCS3/NANDCS<br />
| IRQ2<br />
| NAND Flash CS<br />
|-<br />
| 17<br />
| PC17<br />
| D17<br />
| SPI0_NPCS3<br />
| SDRAM<br />
|-<br />
| 18<br />
| PC16<br />
| D16<br />
| SPI0_NPCS2<br />
| SDRAM<br />
|-<br />
| 19<br />
| PC19<br />
| D19<br />
| SPI1_NPCS2<br />
| SDRAM<br />
|-<br />
| 20<br />
| PC18<br />
| D18<br />
| SPI1_NPCS1<br />
| SDRAM<br />
|-<br />
| 21<br />
| PC21<br />
| D21<br />
| EF100<br />
| SDRAM<br />
|-<br />
| 22<br />
| PC20<br />
| D20<br />
| SPI1_NPCS3<br />
| SDRAM<br />
|-<br />
| 23<br />
| PC23<br />
| D23<br />
| <br />
| SDRAM<br />
|-<br />
| 24<br />
| PC22<br />
| D22<br />
| TCLK5<br />
| SDRAM<br />
|-<br />
| 25<br />
| PC25<br />
| D25<br />
| <br />
| SDRAM<br />
|-<br />
| 26<br />
| PC24<br />
| D24<br />
| <br />
| SDRAM<br />
|-<br />
| 27<br />
| PC27<br />
| D27<br />
| <br />
| SDRAM<br />
|-<br />
| 28<br />
| PC26<br />
| D26<br />
| <br />
| SDRAM<br />
|-<br />
| 29<br />
| PC29<br />
| D29<br />
| <br />
| SDRAM<br />
|-<br />
| 30<br />
| PC28<br />
| D28<br />
| <br />
| SDRAM<br />
|-<br />
| 31<br />
| PC31<br />
| D31<br />
| <br />
| SDRAM<br />
|-<br />
| 32<br />
| PC30<br />
| D30<br />
| <br />
| SDRAM<br />
|-<br />
| 33<br />
| <br />
| <br />
| <br />
| Digital ground<br />
|-<br />
| 34<br />
| <br />
| <br />
| <br />
| Digital ground<br />
|-<br />
| 35<br />
| <br />
| <br />
| <br />
| +3.3V supply<br />
|-<br />
| 36<br />
| <br />
| <br />
| <br />
| +3.3V supply<br />
|-<br />
| 37<br />
| <br />
| <br />
| <br />
| +3.3V analog supply<br />
|-<br />
| 38<br />
| <br />
| <br />
| <br />
| Analog reference voltage<br />
|-<br />
| 39<br />
| <br />
| <br />
| <br />
| Analog ground<br />
|-<br />
| 40<br />
| <br />
| <br />
| <br />
| Analog ground<br />
|}<br />
<br />
<br /><br />
<br /><br />
<br />
= Calypso Ports =<br />
<br />
Part<br />
Signal<br />
J16C AT91SAM7X256-EK<br />
J26 AT91SAM9260-EK<br />
Usage<br />
DAC<br />
BCLK<br />
16<br />
PA22 (TK)<br />
18<br />
PB16 (TK0)<br />
DAC data clock<br />
DIN<br />
17<br />
PA23 (TD)<br />
20<br />
PB18 (TD0)<br />
DAC data input<br />
LRCIN<br />
15<br />
PA21 (TF)<br />
17<br />
PB17 (TF0)<br />
DAC Sync<br />
DOUT<br />
18<br />
PA24 (RD)<br />
19<br />
PB19 (RD0)<br />
DAC data output<br />
LRCOUT<br />
20<br />
PA26 (RF)<br />
21<br />
PB21 (RF0)<br />
DAC Sync<br />
MCLK<br />
24<br />
PA30 (PCK2)<br />
32<br />
PB31 (PCK1)<br />
DAC main clock<br />
TWD<br />
13<br />
PA10 (TWD)<br />
14<br />
PB12 (BB TWD)<br />
SPI/TWI data input<br />
TWCK<br />
14<br />
PA11 (TWCK)<br />
13<br />
PB13 (BB TWCK)<br />
SPI/TWI clock input<br />
LCD<br />
MOSI<br />
9<br />
PA17 (SPI0_MOSI)<br />
1<br />
PB1 (SPI1_MOSI)<br />
SPI data input<br />
SPCK<br />
10<br />
PA18 (SPI0_SPCK)<br />
4<br />
PB2 (SPI1_SPCK)<br />
SPI clock input<br />
RS<br />
21<br />
PB23<br />
22<br />
PB20<br />
Register select input<br />
CS<br />
22<br />
PB24<br />
11<br />
PB11<br />
Chip select<br />
Buttons<br />
DOWN<br />
25<br />
PB27<br />
10<br />
PB8<br />
Down<br />
MENU<br />
26<br />
PB28<br />
9<br />
PB9<br />
Menu<br />
UP<br />
23<br />
PB29<br />
12<br />
PB10<br />
Up<br />
Supply<br />
+3.3V<br />
31<br />
<br />
35<br /><br />
36<br />
<br />
Power Supply<br />
GND<br />
2<br /><br />
32<br />
<br />
33<br /><br />
34<br />
<br />
Digital ground<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/BoxedHardware/Boxed2017-07-13T08:52:04Z<p>Harald: Created page with " <div id="content"> = Ethernut Boxed = * Picture 1: Front with Ethernut Logo. * Picture 2: Back side. * Picture 3: Top removed for Ethernut 1.3 access. * Picture 4: Front re..."</p>
<hr />
<div><br />
<div id="content"><br />
<br />
= Ethernut Boxed =<br />
<br />
* Picture 1: Front with Ethernut Logo.<br />
* Picture 2: Back side.<br />
* Picture 3: Top removed for Ethernut 1.3 access.<br />
* Picture 4: Front removed for Ethernut 2.1 access.<br />
<br />
<br /><br />
[[File:../../../img/nutbox-front.jpg|Ethernut Box - Front View]]<br /><br />
[[File:../../../img/nutbox-back.jpg|Ethernut Box - Back View]]<br /><br />
[[File:../../../img/nutbox-13.jpg|Ethernut Box - Board 1.3]]<br /><br />
[[File:../../../img/nutbox-21.jpg|Ethernut Box - Board 2.1]]<br /><br />
<br />
<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/HardwareHardware2017-07-13T08:51:03Z<p>Harald: /* Supported Hardware */</p>
<hr />
<div><div id="content"><br />
<br />
= Supported Hardware =<br />
<br />
<div id="overview"><br />
<br />
<div class="lboxof3"><br />
<br />
== [[Hardware/Ethernuts|Reference Designs]] ==<br />
<br />
[[File:ethernut_1_2_3_5.png]]<br />
<br />
Four Ethernut reference designs are available, based on 8-bit AVR as well as 32-bit ARM7 and ARM9. All schematics and the CAD data are published as Open Source Hardware and may be freely used for private or commercial purposes. [[Hardware/Ethernuts|More...]]<br />
<br />
<br />
</div><br />
<div class="mboxof3"><br />
<br />
== Compatible Boards ==<br />
<br />
[[File:xport_195x200.png]]<br />
<br />
Nut/OS is readily available for a number of boards from different manufacturers and hobbyists. [[Hardware/Boards|More...]]<br />
<br />
<br />
</div><br />
<div class="rboxof3"><br />
<br />
== Add-Ons ==<br />
<br />
[[File:stapelbig_150x200.png]]<br />
<br />
Extend the capabilities of your embedded system by adding extension boards. [[Hardware/Add Ons|More...]]<br />
<br />
<br />
</div><br />
<br />
</div><br />
<div style="clear:both"><br />
<br />
<br />
<br />
</div><br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/ExpansionHardware/Expansion2017-07-13T08:50:22Z<p>Harald: Created page with "<div id="content"> = Ethernut Expansion Port = All Ethernut hardware reference designs share the same expansion port, a 64-pin header with two rows and 0.05&quot; (2.54 mm)..."</p>
<hr />
<div><div id="content"><br />
<br />
= Ethernut Expansion Port =<br />
<br />
All Ethernut hardware reference designs share the same expansion port, a 64-pin header with two rows and 0.05&quot; (2.54 mm) grid.<br />
<br />
[[File:../../img/ethernut13h-expansion-pins.png]]<br /><br />
[[File:../../img/ethernut21c-expansion-pins.png]]<br /><br />
[[File:../../img/ethernut31d-expansion-pins.png]]<br /><br />
[[File:../../img/ethernut50f-expansion-pins.png]]<br /><br />
<br />
The connector layout had been originally specified for the 8-bit AVR on Ethernut 1 and 2. To maintain some compatibility, the port pins on ARM-based Ethernut 3 and 5 are not sorted in a specific order, but follow the AVR functions. This allows to develop add-on boards with, for example, I2C or SPI interfaces to be located at the same pins.<br />
<br />
'''Important note: While all pins on Ethernut 1 are 5V CMOS compatible, and all pins on Ethernut 2 are at least 5V tolerant, some pins on Ethernut 3 and all pins on Ethernut 5 are 3.3V only. Applying voltages above 3.3V to these pins may destroy the board.'''<br />
<br />
{|<br />
! Pin<br />
! Ethernut 5 (ARM9)<br />
! Ethernut 3 (ARM7)<br />
! Ethernut 1/2 (AVR)<br />
|-<br />
| 1<br />
| '''VCC3''' +3V Power Supply<br />
| '''VCC3''' +3V Power Supply<br />
| '''VCC3''' +3V Power Supply<br />
|-<br />
| 2<br />
| '''VCC3''' +3V Power Supply<br />
| '''VCC3''' +3V Power Supply<br />
| '''VCC3''' +3V Power Supply<br />
|-<br />
| 3<br />
| '''VCC5''' +5V Power Supply<br />
| '''N/C''' Not Connected<br />
| '''VCC5''' +5V Power Supply<br />
|-<br />
| 4<br />
| '''VCC5''' +5V Power Supply<br />
| '''N/C''' Not Connected<br />
| '''VCC5''' +5V Power Supply<br />
|-<br />
| 5<br />
| '''GND''' Digital Ground<br />
| '''GND''' Digital Ground<br />
| '''GND''' Digital Ground<br />
|-<br />
| 6<br />
| '''GND''' Digital Ground<br />
| '''GND''' Digital Ground<br />
| '''GND''' Digital Ground<br />
|-<br />
| 7<br />
| '''GND''' Digital Ground<br />
| '''GND''' Digital Ground<br />
| '''GND''' Digital Ground<br />
|-<br />
| 8<br />
| '''GND''' Digital Ground<br />
| '''GND''' Digital Ground<br />
| '''GND''' Digital Ground<br />
|-<br />
| Pin<br />
| Ethernut 5 (ARM9)<br />
| Ethernut 3 (ARM7)<br />
| Ethernut 1/2 (AVR)<br />
|-<br />
| 9<br />
| '''NMR''' Hardware Reset I/O<br />
| '''NMR''' Hardware Reset Input<br />
| '''MR\''' Hardware Reset Input<br />
|-<br />
| 10<br />
| '''DC''' Unreg. Auxiliary Power Supply<br />
| '''DC''' Unreg. DC Power Supply<br />
| '''DC''' Unregulated DC Power Supply<br />
|-<br />
| 11<br />
| '''VCC5''' +5V Power Supply<br />
| '''N/C''' Not Connected<br />
| '''VCC5''' +5V Power Supply<br />
|-<br />
| 12<br />
| '''VCC5''' +5V Power Supply<br />
| '''N/C''' Not Connected<br />
| '''VCC5''' +5V Power Supply<br />
|-<br />
| 13<br />
| '''NRD''' Read Strobe<br /><br />
'''CFOE''' CompactFlash Output Enable<br />
| '''NCRD''' Configurable Read Strobe<br />
| '''RD\''' External Memory Bus Read Strobe<br />
|-<br />
| 14<br />
| '''NWR0''' Write Strobe<br /><br />
'''NWE''' Write Enable<br />
| '''NCWR''' Configurable Write Strobe<br />
| '''WR\''' External Memory Bus Write Strobe<br />
|-<br />
| Pin<br />
| Ethernut 5 (ARM9)<br />
| Ethernut 3 (ARM7)<br />
| Ethernut 1/2 (AVR)<br />
|-<br />
| 15<br />
| '''D0''' External Data Bus Bit 0<br />
| '''CDR0''' Configurable Data Bus Bit 0<br />
| '''D0''' External Data Bus Bit 0<br />
|-<br />
| 16<br />
| '''D1''' External Data Bus Bit 1<br />
| '''CDR1''' Configurable Data Bus Bit 1<br />
| '''D1''' External Data Bus Bit 1<br />
|-<br />
| 17<br />
| '''D2''' External Data Bus Bit 2<br />
| '''CDR2''' Configurable Data Bus Bit 2<br />
| '''D2''' External Data Bus Bit 2<br />
|-<br />
| 18<br />
| '''D3''' External Data Bus Bit 3<br />
| '''CDR3''' Configurable Data Bus Bit 3<br />
| '''D3''' External Data Bus Bit 3<br />
|-<br />
| 19<br />
| '''D4''' External Data Bus Bit 4<br />
| '''CDR4''' Configurable Data Bus Bit 4<br />
| '''D4''' External Data Bus Bit 4<br />
|-<br />
| 20<br />
| '''D5''' External Data Bus Bit 5<br />
| '''CDR5''' Configurable Data Bus Bit 5<br />
| '''D5''' External Data Bus Bit 5<br />
|-<br />
| 21<br />
| '''D6''' External Data Bus Bit 6<br />
| '''CDR6''' Configurable Data Bus Bit 6<br />
| '''D6''' External Data Bus Bit 6<br />
|-<br />
| 22<br />
| '''D7''' External Data Bus Bit 7<br />
| '''CDR7''' Configurable Data Bus Bit 7<br />
| '''D7''' External Data Bus Bit 7<br />
|-<br />
| Pin<br />
| Ethernut 5 (ARM9)<br />
| Ethernut 3 (ARM7)<br />
| Ethernut 1/2 (AVR)<br />
|-<br />
| 23<br />
| '''A0''' External Address Bus Bit 0<br /><br />
'''NBS0''' Byte 0 Select<br />
| '''CAR0''' Configurable Address Bus Bit 0<br />
| '''A0''' External Address Bus Bit 0<br /><br />
'''PA0''' GPIO Port A Bit 0<br />
|-<br />
| 24<br />
| '''A1''' External Address Bus Bit 1<br /><br />
| '''CAR1''' Configurable Address Bus Bit 1<br />
| '''A1''' External Address Bus Bit 1<br /><br />
'''PA1''' GPIO Port A Bit 1<br />
|-<br />
| 25<br />
| '''A2''' External Address Bus Bit 2<br /><br />
| '''CAR2''' Configurable Address Bus Bit 2<br />
| '''A2''' External Address Bus Bit 2<br /><br />
'''PA2''' GPIO Port A Bit 2<br />
|-<br />
| 26<br />
| '''A3''' External Address Bus Bit 3<br /><br />
| '''CAR3''' Configurable Address Bus Bit 3<br />
| '''A3''' External Address Bus Bit 3<br /><br />
'''PA3''' GPIO Port A Bit 3<br />
|-<br />
| 27<br />
| '''A4''' External Address Bus Bit 4<br /><br />
| '''CAR4''' Configurable Address Bus Bit 4<br />
| '''A4''' External Address Bus Bit 4<br /><br />
'''PA4''' GPIO Port A Bit 4<br />
|-<br />
| 28<br />
| '''A5''' External Address Bus Bit 5<br /><br />
| '''CAR5''' Configurable Address Bus Bit 5<br />
| '''A5''' External Address Bus Bit 5<br /><br />
'''PA5''' GPIO Port A Bit 5<br />
|-<br />
| 29<br />
| '''A6''' External Address Bus Bit 6<br /><br />
| '''CAR6''' Configurable Address Bus Bit 6<br />
| '''A6''' External Address Bus Bit 6<br /><br />
'''PA6''' GPIO Port A Bit 6<br />
|-<br />
| 30<br />
| '''A7''' External Address Bus Bit 7<br /><br />
| '''CAR7''' Configurable Address Bus Bit 7<br />
| '''A7''' External Address Bus Bit 7<br /><br />
'''PA7''' GPIO Port A Bit 7<br />
|-<br />
| 31<br />
| '''A8''' External Address Bus Bit 8<br /><br />
| '''CAR8''' Configurable Address Bus Bit 8<br />
| '''A8''' External Address Bus Bit 8<br /><br />
'''PC0''' GPIO Port C Bit 0<br />
|-<br />
| 32<br />
| '''A9''' External Address Bus Bit 9<br /><br />
| '''CAR9''' Configurable Address Bus Bit 9<br />
| '''A9''' External Address Bus Bit 9<br /><br />
'''PC1''' GPIO Port C Bit 1<br />
|-<br />
| 33<br />
| '''A10''' External Address Bus Bit 10<br /><br />
| '''CAR10''' Configurable Address Bus Bit 10<br />
| '''A10''' External Address Bus Bit 10<br /><br />
'''PC2''' GPIO Port C Bit 2<br />
|-<br />
| 34<br />
| '''A11''' External Address Bus Bit 11<br /><br />
| '''CAR11''' Configurable Address Bus Bit 11<br />
| '''A11''' External Address Bus Bit 11<br /><br />
'''PC3''' GPIO Port C Bit 3<br />
|-<br />
| 35<br />
| '''A12''' External Address Bus Bit 12<br /><br />
| '''CAR12''' Configurable Address Bus Bit 12<br />
| '''A12''' External Address Bus Bit 12<br /><br />
'''PC4''' GPIO Port C Bit 4<br />
|-<br />
| 36<br />
| '''A13''' External Address Bus Bit 13<br /><br />
| '''CAR13''' Configurable Address Bus Bit 13<br />
| '''A13''' External Address Bus Bit 13<br /><br />
'''PC5''' GPIO Port C Bit 5<br />
|-<br />
| 37<br />
| '''A14''' External Address Bus Bit 14<br /><br />
| '''CAR14''' Configurable Address Bus Bit 14<br />
| '''A14''' External Address Bus Bit 14<br /><br />
'''PC6''' GPIO Port C Bit 6<br />
|-<br />
| 38<br />
| '''A15''' External Address Bus Bit 15<br /><br />
| '''CAR15''' Configurable Address Bus Bit 15<br />
| '''A15''' External Address Bus Bit 15<br /><br />
'''PC7''' GPIO Port C Bit 7<br />
|-<br />
| Pin<br />
| Ethernut 5 (ARM9)<br />
| Ethernut 3 (ARM7)<br />
| Ethernut 1/2 (AVR)<br />
|-<br />
| 39<br />
| '''PC1''' GPIO Port C Bit 1<br /><br />
'''PCK0''' PLL Clock Output 0<br /><br />
'''ADC1''' Analog Input Channel 1<br />
| '''P15''' GPIO Port Bit 15<br /><br />
'''RXD0''' UART 0 Receive Input<br />
| '''PE0''' GPIO Port E Bit 0<br /><br />
'''RXD0''' UART 0 Receive Input<br /><br />
'''PDI''' Programming Data Input<br />
|-<br />
| 40<br />
| '''PC0''' GPIO Port C Bit 0<br /><br />
'''SCK3''' UART 3 External Clock<br /><br />
'''ADC0''' Analog Input Channel 0<br />
| '''P14''' GPIO Port Bit 14<br /><br />
'''TXD0''' UART 0 Transmit Output<br />
| '''PE1''' GPIO Port E Bit 1<br /><br />
'''TXD0''' UART 0 Transmit Output<br /><br />
'''PDO''' Programming Data Output<br />
|-<br />
| 41<br />
| '''PC5''' GPIO Port C Bit 5<br /><br />
'''A24''' External Address Bus Bit 24<br /><br />
'''SPI1_NPCS1''' SPI 1 Peripheral Chip Select 1<br /><br />
| '''P13''' GPIO Port Bit 13<br /><br />
'''SCK0''' USART 0 External Clock<br />
| '''PE2''' GPIO Port E Bit 2<br /><br />
'''XCK0''' USART 0 External Clock<br /><br />
'''AIN0''' Analog Comparator Positive Input<br />
|-<br />
| 42<br />
| '''PC4''' GPIO Port C Bit 4<br /><br />
'''A23''' External Address Bus Bit 23<br /><br />
'''SPI1_NPCS2''' SPI 1 Peripheral Chip Select 2<br />
| '''P8''' GPIO Port Bit 8<br /><br />
'''TIOB2''' Counter Channel 2 I/O Line B<br />
| '''PE3''' GPIO Port E Bit 3<br /><br />
'''OC3A''' Counter 3 Compare and PWM A<br /><br />
'''AIN1''' Analog Comparator Positive Input<br />
|-<br />
| 43<br />
| '''PC7''' GPIO Port C Bit 7<br /><br />
'''TIOB1''' Counter Channel 1 I/O Line B<br /><br />
'''CFCE2''' CompactFlash Chip Enable 2<br />
| '''P9''' GPIO Port Bit 9<br /><br />
'''IRQ0''' External Interrupt Request 1<br />
| '''PE4''' GPIO Port E Bit 4<br /><br />
'''INT4''' External Interrupt 4<br /><br />
'''OC3B''' Counter 3 Compare and PWM B<br />
|-<br />
| 44<br />
| '''PC6''' GPIO Port C Bit 6<br /><br />
'''TIOB2''' Counter Channel 2 I/O Line B<br /><br />
'''CFCE1''' CompactFlash Chip Enable 1<br />
| '''P27''' GPIO Port Bit 27<br /><br />
'''NCS3''' Chip Select Line 3<br />
| '''PE5''' GPIO Port E Bit 5<br /><br />
'''INT5''' External Interrupt 5<br /><br />
'''OC3C''' Counter 3 Compare and PWM C<br />
|-<br />
| 45<br />
| '''PC15''' GPIO Port C Bit 15<br /><br />
'''NWAIT''' Memory Bus Wait<br /><br />
'''IRQ1''' External Interrupt Request 1<br />
| '''P11''' GPIO Port Bit 11<br /><br />
'''IRQ2''' External Interrupt Request 2<br />
| '''PE6''' GPIO Port E Bit 6<br /><br />
'''INT6''' External Interrupt 6<br /><br />
'''T3''' Counter 3 Clock Input<br />
|-<br />
| 46<br />
| '''PC13''' GPIO Port C Bit 13<br /><br />
'''FIQ''' Fast Interrupt Request<br /><br />
'''NCS6''' Chip Select Line 6<br />
| '''P12''' GPIO Port Bit 12<br /><br />
'''FIQ''' Fast Interrupt Request<br />
| '''PE7''' GPIO Port E Bit 7<br /><br />
'''INT7''' External Interrupt 7<br /><br />
'''ICP3''' Counter 3 Input Capture<br />
|-<br />
| 47<br />
| '''PB3''' GPIO Port B Bit 3<br /><br />
'''SPI1_NPCS0''' SPI 1 Peripheral Chip Select 0<br /><br />
'''TIOA5''' Counter Channel 5 I/O Line A<br />
| '''P0''' GPIO Port Bit 0<br /><br />
'''TCLK0''' External Clock Counter Channel 0<br />
| '''PB0''' GPIO Port B Bit 0<br /><br />
'''-SS''' SPI Slave Select Input<br />
|-<br />
| 48<br />
| '''PB2''' GPIO Port B Bit 2<br /><br />
'''SPI1_SPCK''' SPI 1 Serial Clock<br /><br />
'''TIOA4''' Counter Channel 4 I/O Line A<br />
| '''P1''' GPIO Port Bit 1<br /><br />
'''TIOA0''' Counter Channel 0 I/O Line A<br />
| '''PB1''' GPIO Port B Bit 1<br /><br />
'''SCK''' SPI Bus Serial Clock<br />
|-<br />
| 49<br />
| '''PB1''' GPIO Port B Bit 1<br /><br />
'''SPI1_MOSI''' SPI Bus Master Output / Slave Input<br /><br />
'''TIOB3''' Counter Channel 3 I/O Line B<br />
| '''P2''' GPIO Port Bit 2<br /><br />
'''TIOB0''' Counter Channel 0 I/O Line B<br />
| '''PB2''' GPIO Port B Bit 2<br /><br />
'''MOSI''' SPI Bus Master Output / Slave Input<br />
|-<br />
| 50<br />
| '''PB0''' GPIO Port B Bit 0<br /><br />
'''SPI1_MISO''' SPI Bus Master Input / Slave Output<br /><br />
'''TIOA3''' Counter Channel 3 I/O Line A<br />
| '''P3''' GPIO Port Bit 3<br /><br />
'''TCLK1''' External Clock Counter Channel 0<br />
| '''PB3''' GPIO Port B Bit 3<br /><br />
'''MISO''' SPI Bus Master Input / Slave Output<br />
|-<br />
| 51<br />
| '''PB17''' GPIO Port B Bit 17<br /><br />
'''TF0''' SSC Transmit Frame Sync<br /><br />
'''TCLK4''' External Clock Input Counter Channel 4<br />
| '''P4''' GPIO Port Bit 4<br /><br />
'''TIOA1''' Counter Channel 1 I/O Line A<br />
| '''PB4''' GPIO Port B Bit 4<br /><br />
'''OC0''' Counter 0 Compare and PWM<br />
|-<br />
| 52<br />
| '''PB16''' GPIO Port B Bit 16<br /><br />
'''TK0''' SSC Transmit Clock<br /><br />
'''TCLK3''' External Clock Input Counter Channel 3<br />
| '''P5''' GPIO Port Bit 5<br /><br />
'''TIOB1''' Counter Channel 1 I/O Line B<br />
| '''PB5''' GPIO Port B Bit 5<br /><br />
'''OC1A''' Counter 1 Compare and PWM A<br />
|-<br />
| 53<br />
| '''PB19''' GPIO Port B Bit 19<br /><br />
'''RD0''' SSC Receive Data<br /><br />
'''TIOB5''' Counter Channel 5 I/O Line B<br />
| '''P6''' GPIO Port Bit 6<br /><br />
'''TCLK2''' External Clock Counter Channel 0<br />
| '''PB6''' GPIO Port B Bit 6<br /><br />
'''OC1B''' Counter 1 Compare and PWM B<br />
|-<br />
| 54<br />
| '''PB18''' GPIO Port B Bit 18<br /><br />
'''TD0''' SSC Transmit Data<br /><br />
'''TIOB4''' Counter Channel 4 I/O Line B<br />
| '''P7''' GPIO Port Bit 7<br /><br />
'''TIOA2''' Counter Channel 2 I/O Pin A<br />
| '''PB7''' GPIO Port B Bit 7<br /><br />
'''OC1C''' Counter 1 Compare and PWM C<br /><br />
'''OC2''' Counter 2 Compare and PWM<br />
|-<br />
| Pin<br />
| Ethernut 5 (ARM9)<br />
| Ethernut 3 (ARM7)<br />
| Ethernut 1/2 (AVR)<br />
|-<br />
| 55<br />
| '''PA24''' GPIO Port A Bit 24<br /><br />
'''TWCK0''' TWI Serial Clock<br /><br />
'''ETX3''' MII Transmit Data Bit 3<br />
| '''P17''' GPIO Port Bit 17<br />
| '''PD0''' GPIO Port D Bit 0<br /><br />
'''INT0''' External Interrupt 0<br /><br />
'''SCL''' TWI Serial Clock<br />
|-<br />
| 56<br />
| '''PA23''' GPIO Port A Bit 23<br /><br />
'''TWD''' TWI Serial Data<br /><br />
'''ETX2''' MII Transmit Data Bit 2<br />
| '''P16''' GPIO Port Bit 16<br />
| '''PD1''' GPIO Port D Bit 1<br /><br />
'''INT1''' External Interrupt 1<br /><br />
'''SDA''' TWI Serial Data<br />
|-<br />
| 57<br />
| '''PA26''' GPIO Port A Bit 26<br /><br />
'''TIOA0''' Counter Channel 0 I/O Line A<br /><br />
'''TCLK2''' External Clock Input Counter Channel 2<br />
| '''P22''' GPIO Port Bit 22<br /><br />
'''RXD1''' UART 1 Receive Input<br />
| '''PD2''' GPIO Port D Bit 2<br /><br />
'''INT2''' External Interrupt 2<br /><br />
'''RXD1''' UART 1 Receive Input<br />
|-<br />
| 58<br />
| '''PA25''' GPIO Port A Bit 25<br /><br />
'''TCLK0''' External Clock Input Counter Channel 0<br /><br />
'''ERX2''' MII Receive Data Bit 2<br />
| '''P21''' GPIO Port Bit 21<br /><br />
'''TXD1''' UART 1 Transmit Output<br /><br />
'''NTRI''' Three-State Mode Select<br />
| '''PD3''' GPIO Port D Bit 3<br /><br />
'''INT3''' External Interrupt 3<br /><br />
'''TXD1''' UART 1 Transmit Output<br />
|-<br />
| 59<br />
| '''PA28''' GPIO Port A Bit 28<br /><br />
'''TIOA2''' Counter Channel 2 I/O Line A<br /><br />
'''ECRS''' MII Carrier Sense and Data Valid<br />
| '''P23''' GPIO Port Bit 23<br />
| '''PD4''' GPIO Port D Bit 4<br /><br />
'''ICP1''' Counter 1 Input Capture<br />
|-<br />
| 60<br />
| '''PA27''' GPIO Port A Bit 27<br /><br />
'''TIOA1''' Counter Channel 1 I/O Line A<br /><br />
'''ERXCK''' MII Receive Clock<br />
| '''P20''' GPIO Port Bit 20<br /><br />
'''SCK1''' USART 1 External Clock<br />
| '''PD5''' GPIO Port D Bit 5<br /><br />
'''XCK1''' USART 1 External Clock<br />
|-<br />
| 61<br />
| '''PA29''' GPIO Port A Bit 29<br /><br />
'''SCK1''' USART 1 Serial Clock<br /><br />
'''ECOL''' MII Collision Detect<br />
| '''P19''' GPIO Port Bit 19<br />
| '''PD6''' GPIO Port D Bit 6<br /><br />
'''T1''' Counter 1 Clock Input<br />
|-<br />
| 62<br />
| '''PA22''' GPIO Port A Bit 22<br /><br />
'''ADTRG''' ADC Trigger<br /><br />
'''ETXER''' MII Transmit Coding Error<br />
| '''P18''' GPIO Port Bit 18<br />
| '''PD7''' GPIO Port D Bit 7<br /><br />
'''T2''' Counter 2 Clock Input<br />
|-<br />
| 63<br />
| '''N/C''' Not Connected<br />
| '''N/C''' Not Connected<br />
| '''N/C''' Not Connected<br />
|-<br />
| 64<br />
| '''N/C''' Not Connected<br />
| '''N/C''' Not Connected<br />
| '''N/C''' if R34 not mounted<br /><br />
'''ALE''' External Address Bus Latch Enable<br />
|}<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/EthernutsHardware/Ethernuts2017-07-13T08:49:42Z<p>Harald: /* Ethernut 1 */</p>
<hr />
<div><div id="content"><br />
<br />
= Ethernut Reference Boards =<br />
<br />
<div id="overview"><br />
<br />
<div class="lboxof2"><br />
<br />
== Ethernut 1 ==<br />
<br />
[[File:ethernut_1_3_rev_h_pov_267x200.png]]<br />
<br />
The minimalist design of Ethernut 1 had been reduced to four essential components: ATmega128 Flash Microcontroller, 32 kBytes RAM, RTL8019AS 10Mbit Ethernet Controller and Power Supply. [[Hardware/Enut1|More...]]<br />
<br />
<br />
</div><br />
<div class="rboxof2"><br />
<br />
== Ethernut 2 ==<br />
<br />
[[File:ethernut_2_1_rev_b_pov_269x200.png]]<br />
<br />
Ethernut 2 uses the same CPU as its predecessor, but provides 100Mbit Ethernet, 512 kBytes RAM and an RS-485 interface. All parts are available for industrial temperature range. [[Hardware/enut2|More...]]<br />
<br />
<br />
</div><br />
<div style="clear:both"><br />
<br />
<br />
<br />
</div><br />
<div class="lboxof2"><br />
<br />
== Ethernut 3 ==<br />
<br />
[[File:ethernut_3_1_rev_a_pov_269x200.png]]<br />
<br />
This is the first Ethernut board with 32-bit ARM CPU. [[Hardware/enut3|More...]]<br />
<br />
<br />
</div><br />
<div class="rboxof2"><br />
<br />
== Ethernut 5 ==<br />
<br />
[[File:ethernut_5_0_rev_c_pov_282x200.png]]<br />
<br />
This latest board runs Nut/OS as well as Linux. [[Hardware/enut5|More...]]<br />
<br />
<br />
</div><br />
<div style="clear:both"><br />
<br />
<br />
<br />
</div><br />
<br />
</div><br />
<br />
== Trademark ==<br />
<br />
All published reference designs are released as Open Source and may be freely used for private or commercial purposes. However, when used for commercial purposes, be aware that Ethernut is a registered trademark of [http://www.egnite.de egnite GmbH]. Thus, you need to create your own product name.<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/BoardsHardware/Boards2017-07-13T08:49:00Z<p>Harald: Created page with "<div id="content"> = Officially Supported Boards = Officially supported means, that the board configuration is included in the Nut/OS distribution and that compiling and lin..."</p>
<hr />
<div><div id="content"><br />
<br />
= Officially Supported Boards =<br />
<br />
Officially supported means, that the board configuration is included in the Nut/OS distribution and that compiling and linking of the system libraries for the specific board had been verified.<br />
<br />
It does not mean, that binaries had been verified to run on the board. If you have problems, please contact your distributor or try the given support link. If none is available, you may try to contact other developers via the Ethernut mailing list. But note that this service is provided by volunteers. Some companies also offer commercial support for Nut/OS.<br />
<br />
== ARM Boards ==<br />
<br />
{|<br />
!width="25%"| Target Board<br />
!width="25%"| Description<br />
!width="25%"| Vendor<br />
!width="25%"| Nut/OS Support<br />
|-<br />
| '''AT91EB40A'''<br /><br />
[[File:../../img/at91eb40a_200x149.png|200x149px|AT91EB40A]]<br />
| The AT91EB40A Evaluation Board enables real-time code development and evaluation. It supports the AT91R40008. End-of-Life without any replacement was announced in August 2010.<br />
| [http://www.atmel.com/ Atmel]<br />
|<br />
<br />
|-<br />
| '''AT91SAM7SE-EK'''<br /><br />
[[File:../../img/at91sam7se-ek200x117.png|200x117px|AT91SAM7SE-EK]]<br />
| The AT91SAM7SE-EK evaluation board enables the evaluation of and code development for applications running on an AT91SAM7SE device. The board is equipped with an AT91SAM7SE512.<br />
| [http://www.atmel.com/ Atmel]<br />
|<br />
<br />
|-<br />
| '''AT91SAM7X-EK'''<br /><br />
[[File:../../img/sam7x-ek-small.png|164x118px|SAM7X-EK]]<br />
| The AT91SAM7X-EK evaluation kit enables evaluation capabilities and code development of applications running on an AT91SAM7X microcontroller.<br />
| [http://www.atmel.com/ Atmel]<br />
|<br />
<br />
|-<br />
| '''AT91SAM9260-EK'''<br /><br />
[[File:../../img/sam9260-ek-small.png|196x115px|SAM9260-EK]]<br />
| The AT91SAM9260-EK evaluation kit enables the evaluation of and code development for applications running on an AT91SAM9260 device.<br />
| [http://www.atmel.com/ Atmel]<br />
|<br />
<br />
|-<br />
| '''AT91SAM9M10-G45-EK'''<br /><br />
[[File:../../img/sam9m10-g45-ek-200x159.png|200x159px|AT91SAM9M10-G45-EK]]<br />
| The evaluation kit for SAM9M10 and SAM9G45. This kit lets designers quickly evaluate and develop code for applications running on the Atmel SAM9M10 or the Atmel SAM9G45. Only the latter is currently supported by Nut/OS.<br />
| [http://www.atmel.com/ Atmel]<br />
|<br />
<br />
|-<br />
| '''Elektor Internet Radio 1.0'''<br /><br />
[[File:../../img/eir10c-pov_tn.png|164x145px|EIR]]<br />
| The Elektor Internet Radio plays MP3 streams from SHOUTcast radio stations, using the new AT91SAM7SE CPU and 64 MBytes SDRAM.<br />
| [http://www.egnite.de/en/produkte/elektor-internet-radio.html egnite]<br />
| [http://www.egnite.de/en/ueber-uns/adresse-und-anreise.html egnite]<br />
|-<br />
| '''eNet-sam7X'''<br /><br />
[[File:../../img/enet-sam7x.png|180x61px|eNet-sam7X]]<br />
| The eNet-sam7X module was designed by thermotemp as easy drop-in ARM7 module and allows you a money and time saving integration of Ethernet and USB interfaces along with a powerfull SAM7 microcontroller into your project.<br />
| [http://www.embedded-it.de/en/microcontroller/eNet-sam7X.php thermotemp]<br />
| [http://www.embedded-it.de/en/microcontroller/eNet-sam7X.php thermotemp]<br />
|-<br />
| '''Ethernut 3.0'''<br /><br />
[[File:../../img/ethernut30e200x146.png|200x146px|Ethernut 3.0]]<br />
| The first 32 bit version of the Ethernut Open Source Hardware Family is packed with features like 8 MBytes NAND Flash and 256kBytes full speed SRAM, MMC/SD-Card Socket, user programmable logic etc. With the 32-Bit AT91R40008 CPU (ARM7TDMI) running at 73.728MHz, it is mainly targeted at performance intensive processing like real-time coding and decoding applications. A DM9000 controller is used for the 100 MBit Ethernet Interface. [[enut3/enut30e.html|Ethernut 3.0 Rev-E]]<br />
|<br />
<br />
|<br />
<br />
|-<br />
| '''Ethernut 3.1'''<br /><br />
[[File:../../img/ethernut31d-200x149.png|200x149px|Ethernut 3.1]]<br />
| The announcement of Xicor/Intersil to stop production of the combined RTC and EEPROM chip used on Ethernut 3.0 required a redesign, which was published in October 2009.<br />
| [http://www.egnite.de/en/produkte/ethernut-familie/ethernut-31.html egnite]<br />
| [http://www.egnite.de/en/ueber-uns/adresse-und-anreise.html egnite]<br />
|-<br />
| '''Ethernut 5.0'''<br /><br />
[[File:../../img/Ethernut50f_200x147.png|200x147px|Ethernut 5.0]]<br />
| This is the first Ethernut Board based on an ARM9 CPU. Beside Nut/OS it is capable of running Linux.<br />
| [http://www.egnite.de/en/produkte/ethernut-familie/ethernut-50.html egnite]<br />
| [http://www.egnite.de/en/ueber-uns/adresse-und-anreise.html egnite]<br />
|-<br />
| '''GameBoy Advance SP'''<br /><br />
[[File:../../img/xg2link-small.png|128x96px|Gameboy Port]]<br />
| 32-bit handheld video game console with Xport 2.0 devkit. The GameBoy hardware is based on an ARM7 CPU. [[../../en/portarm/gbaxport2.html|Additional hardware]] is required to upload and run a Nut/OS application on the GBA.<br />
| [http://www.charmedlabs.com Charmed Labs]<br />
|<br />
<br />
|-<br />
| '''KickStart Kit for LPC1768'''<br /><br />
[[File:../../img/ksk-lpc17xx-sk.jpg|200x139px|ksk-lpc17xx-sk]]<br />
| LPC1768 evaluation board. Note, that the IAR compiler is currently not supported.<br />
| [http://http://http://www.iar.com/ IAR Systems]<br />
|<br />
<br />
|-<br />
| '''mbed NXP LPC1768'''<br /><br />
[[File:../../img/mbed_nxp_lpc1768.jpg|200x100px|mbed_nxp_lpc1768]]<br />
| The mbed NXP LPC1768 is one of a range of mbed Microcontrollers packaged as a small 40-pin DIP, 0.1-inch pitch form-factor making it convenient for prototyping with solderless breadboard, stripboard, and through-hole PCBs. It includes a built-in USB programming interface that is as simple as using a USB Flash Drive.<br />
| [http://mbed.org// ARM Limited]<br />
|<br />
<br />
|-<br />
| '''Morphoq 1.1 Rev-A'''<br /><br />
[[File:../../img/morphoq_200x124.png|200x124px|Morphoq]]<br />
| Morphoq is a modular monitoring and control device for industrial applications. The main CPU is an AT91SAM7XC512.<br />
| [http://www.egnite.de/en/produkte/elektor-internet-radio.html egnite]<br />
| [http://www.egnite.de/en/produkte/elektor-internet-radio.html egnite]<br />
|-<br />
| '''SAM7-EX256'''<br /><br />
[[File:../../img/olimex-sam7-ex256.jpg|200x152px|OLIMEX-SAM7-EX256]]<br />
| Olimex distributes a nice SAM7X Board with 128x128 TFT, which had been reported to work with Nut/OS. However, only FreeRTOS is officially supported by Olimex.<br />
| [http://www.olimex.com/ Olimex]<br /><br />
[http://www.freertos.org FreeRTOS]<br />
|<br />
<br />
|-<br />
| '''SAMDIP-7X'''<br /><br />
[[File:../../img/samdip-7x.jpg|175x75px|SAMDIP-7X]]<br />
|<br />
taskit GmbH offers the SAMDIP-7X, a small microprocessor board designed to be as simple as possible to use. It contains a low-power, high-performance ARM7TDMI processor core with a large variety of peripherals and needs as less as possible of external components.<br />
The board is mostly compatible to the AT91SAM7X-EK and taskit successfully installed Nut/OS on this target.<br />
| [http://www.taskit.de/ taskit GmbH]<br />
|<br />
<br />
|-<br />
| '''STM32F4DISCOVERY'''<br /><br />
[[File:../../img/stm32f4_discovery.jpg|200x127px|stm32f4_discovery]]<br />
| Based on the STM32F407VGT6, it includes an ST-LINK/V2 embedded debug tool, two ST MEMS, digital accelerometer and digital microphone, one audio DAC with integrated class D speaker driver, LEDs and push buttons and an USB OTG micro-AB connector.<br />
| [http://http://www.st.com/ STMicroelectronics]<br />
|<br />
<br />
|}<br />
<br />
== AVR Boards ==<br />
<br />
{|<br />
!width="25%"| Target Board<br />
!width="25%"| Description<br />
!width="25%"| Vendor<br />
!width="25%"| Nut/OS Support<br />
|-<br />
| '''Arthernet'''<br /><br />
[[File:../../img/arthernet.jpg|193x129px|Arthernet]]<br />
| Arthernet is an ATmega128 based board with Ethernet, USB and CAN interface and additionally provides a memory card socket.<br />
| [http://ispf.de/modules.php?name=News&file=article&sid=5 Arthernet]<br />
|<br />
<br />
|-<br />
| '''Charon 2'''<br /><br />
[[File:../../img/charondb_small.png|143x93px|Charon DB]]<br />
| The Charon Development Kit includes a Charon 2 Module and a Motherboard, which provides the required Ethernet transformer and RJ45 connector for the Charon modules. It additionally includes two RS232 ports, LCD interface, 8 bit dip switch input, 8 bit LED output, JTAG and ISP connector.<br />
| [http://www.hwgroup.cz/products/charon2/ch2dk_en.html HW group]<br />
| [http://www.hwgroup.cz/products/charon2/ch2dk_en.html HW group]<br />
|-<br />
| '''Ethernut 1.1'''<br /><br />
[[File:../../img/ethernut103-200x161.jpg|200x161px|ethernut103]]<br />
| The first Ethernut reference design: Ethernut 1.1 with Atmega103. This board is no longer in production. [http://www.egnite.de/en/produkte/ethernut-familie/ethernut-13.html Ethernut 1.3] can be used as a one-to-one replacement.<br />
| [http://www.egnite.de/ egnite]<br />
| [http://www.egnite.de/ egnite]<br />
|-<br />
| '''Ethernut 1.3'''<br /><br />
[[File:../../img/ethernut13h-200x150.png|200x150px|ethernut13]]<br />
| The minimalist design of Ethernut 1 had been reduced to four essential components: ATmega128 Flash Microcontroller, 32 kBytes RAM, RTL8019AS 10Mbit Ethernet Controller and Power Supply<br />
| [http://www.egnite.de/en/produkte/ethernut-familie/ethernut-13.html egnite]<br />
| [http://www.egnite.de/en/ueber-uns/adresse-und-anreise.html egnite]<br />
|-<br />
| '''Ethernut 2.0'''<br /><br />
[[File:../../img/ethernut2p200px.png|200x146px|ethernut20]]<br />
| 4-layer board with ATmega128 running at 14.7456 MHz, 100 MBit SMSC Ethernet Controller and 512 kByte banked SRAM. [[enut2/index.html|Ethernut 2.0]]<br />
|<br />
<br />
|<br />
<br />
|-<br />
| '''Ethernut 2.1'''<br /><br />
[[File:../../img/ethernut21c-128_200x149.png|200x149px|ethernut21]]<br />
| Ethernut 2.1 is a small (80 x 100 mm) board combining Atmel's ATmega128 RISC microcontroller with SMSC's LAN91C111 Ethernet controller<br />
| [http://www.egnite.de/en/produkte/ethernut-familie/ethernut-21-128.html egnite]<br />
| [http://www.egnite.de/en/ueber-uns/adresse-und-anreise.html egnite]<br />
|-<br />
| '''MMnet01'''<br /><br />
[[File:../../img/mmnet01.jpg|200x198px|MMnet01]]<br />
|<br />
Propox offers several modules and evaluation boards with Nut/OS support.<br />
Minimodule with ATmega128 microcontroller equipped with Ethernet interface 10Mbit, DataFlash memory. Ideal for the production of devices using the Ethernet/Internet.<br />
| [http://www.propox.com Propox]<br />
| [http://www.propox.com Propox]<br />
|-<br />
| '''MMnet02'''<br /><br />
[[File:../../img/mmnet02.jpg|200x149px|MMnet02]]<br />
| Minimodule with ATmega128 microcontroller equipped with Ethernet interface 10Mbit, DataFlash memory, real time clock with battery back-up. Ideal for the production of devices using the Ethernet/Internet.<br />
| [http://www.propox.com Propox]<br />
| [http://www.propox.com Propox]<br />
|-<br />
| '''MMnet03'''<br /><br />
[[File:../../img/mmnet03.jpg|200x169px|MMnet03]]<br />
| Minimodule with ATmega128 microcontroller equipped with Ethernet interface 10Mbit, RS-232 interface, DataFlash memory. Ideal for the production of devices using the Ethernet/Internet.<br />
| [http://www.propox.com Propox]<br />
| [http://www.propox.com Propox]<br />
|-<br />
| '''MMnet04'''<br /><br />
[[File:../../img/mmnet04.jpg|200x166px|MMnet04]]<br />
| Minimodule with ATmega128 microcontroller equipped with Ethernet interface 10Mbit, USB interface, DataFlash memory. Ideal for the production of devices using the Ethernet/Internet.<br />
| [http://www.propox.com Propox]<br />
| [http://www.propox.com Propox]<br />
|-<br />
| '''MMnet101'''<br /><br />
[[File:../../img/mmnet101.jpg|200x190px|MMnet101]]<br />
| Minimodule with ATmega128 microcontroller equipped with Ethernet interface 100Mbit, DataFlash memory. Ideal for the production of devices using the Ethernet/Internet.<br />
| [http://www.propox.com Propox]<br />
| [http://www.propox.com Propox]<br />
|-<br />
| '''MMnet102'''<br /><br />
[[File:../../img/mmnet102.jpg|200x145px|MMnet102]]<br />
| Minimodule with ATmega128 microcontroller equipped with Ethernet interface 100Mbit, DataFlash memory. Ideal for the production of devices using the Ethernet/Internet.<br />
| [http://www.propox.com Propox]<br />
| [http://www.propox.com Propox]<br />
|-<br />
| '''MMnet103'''<br /><br />
[[File:../../img/mmnet103.jpg|164x136px|MMnet103]]<br />
| Minimodule with ATmega128 microcontroller equipped with Ethernet interface 100Mbit, RS-232 interface, DataFlash memory. Ideal for the production of devices using the Ethernet/Internet.<br />
| [http://www.propox.com Propox]<br />
| [http://www.propox.com Propox]<br />
|-<br />
| '''MMnet104'''<br /><br />
[[File:../../img/mmnet104.jpg|200x161px|MMnet104]]<br />
| Minimodule with ATmega128 microcontroller equipped with Ethernet interface 100Mbit, USB interface, DataFlash memory. Ideal for the production of devices using the Ethernet/Internet.<br />
| [http://www.propox.com Propox]<br />
| [http://www.propox.com Propox]<br />
|-<br />
| '''Poor Man's Ethernut'''<br /><br />
[[File:../../img/poorman.png|196x101px|Poor Man's Ethernut]]<br />
| Some people argue, that buying the parts for an Ethernut Board is many times the price of an ISA network card. Too true. So, how about using any cheap ATmega board and add an ISA connector to it?<br /><br />
Jochen Beck contributed all [[../isa/index.html|details]] to build such a real cheap solution.<br />
|<br />
<br />
|<br />
<br />
|-<br />
| '''STK501'''<br /><br />
[[File:../../img/stk501_200px.jpg|200x109px|STK501]]<br />
| The STK501 board is a top module designed to add ATmega103(L) and ATmega128(L) support to the STK500 development board from Atmel Corporation<br />
| [http://www.atmel.com/ Atmel]<br />
|<br />
<br />
|-<br />
| '''XNUT-100'''<br /><br />
[[File:../../img/xnut100.png|77x180px|XNUT]]<br />
| XNUT Boards are packed in DIN-rail enclosures and perfectly suited for process control and industrial automation tasks requiring the integration of serial or CAN devices into an Ethernet or TCP/IP based network.<br />
| [http://www.proconx.com/xnut/ Proconx]<br />
| [http://www.proconx.com/xnut/ Proconx]<br />
|-<br />
| '''XNUT-105'''<br /><br />
[[File:../../img/xnut105.png|77x180px|XNUT]]<br />
| XNUT Boards are packed in DIN-rail enclosures and perfectly suited for process control and industrial automation tasks requiring the integration of serial or CAN devices into an Ethernet or TCP/IP based network.<br />
| [http://www.proconx.com/xnut/ Proconx]<br />
| [http://www.proconx.com/xnut/ Proconx]<br />
|}<br />
<br />
== AVR32 Boards ==<br />
<br />
{|<br />
! Target Board<br />
! Description<br />
! Vendor<br />
! Nut/OS Support<br />
|-<br />
| '''EVK1100'''<br /><br />
[[File:../../img/evk1100.jpg|200x171px|evk1100]]<br />
| The EVK1100 is a evaluation kit and development system for the AVR32 UC3A microcontroller from Atmel Corporation.<br />
| [http://www.atmel.com/ Atmel]<br />
|<br />
<br />
|-<br />
| '''EVK1101'''<br /><br />
[[File:../../img/evk1101.jpg|200x161px|evk1101]]<br />
| The EVK1101 provides a complete development environment for the AT32UC3B micro- controller series from Atmel.<br />
| [http://www.atmel.com/ Atmel]<br />
|<br />
<br />
|-<br />
| '''EVK1104'''<br /><br />
[[File:../../img/at_evk1104.png|200x165px|evk1104]]<br />
| The AVR32 EVK1104 is an evaluation kit for the AT32UC3A3256 which combines Atmel’s state of art AVR32 microcontroller with an unrivalled selection of communication interface like USB device including On-The-Go functionality, SDcard, NAND flash with ECC and stereo 16-bit DAC<br />
| [http://www.atmel.com/ Atmel]<br />
|<br />
<br />
|-<br />
| '''EVK1105'''<br /><br />
[[File:../../img/evk1105_200x159.jpg|200x159px|EVK1105]]<br />
| The EVK1105 is an evaluation kit for the AT32UC3A0512 which demonstrates Atmels state-of-the-art AVR microcontroller in Hi-Fi audio decoding and streaming applications.<br />
| [http://www.atmel.com/ Atmel]<br />
|<br />
<br />
|}<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Hardware/Add_OnsHardware/Add Ons2017-07-13T08:47:11Z<p>Harald: Created page with "<div id="content"> = Ethernut Add-On = <br /> == Medianut 2.0 == {| | '''Updated!'''<br /> Check this page for more information. ..."</p>
<hr />
<div><div id="content"><br />
<br />
= Ethernut Add-On =<br />
<br />
<br /><br />
<br />
== Medianut 2.0 ==<br />
<br />
{|<br />
| '''Updated!'''<br /><br />
Check [[medianut2/index.html|this page]] for more information. <br />
| [[medianut2/index.html|[[File:../../img/Medianut2_Ethernut3_small.png|150x106px|Medianut 2.0]]]]<br />
|}<br />
<br />
<br /><br />
<br /><br />
<br />
== Medianut 1.1 ==<br />
<br />
{|<br />
|width="50%"|<br />
The [[../../pdf/mnhwm11.pdf|Medianut 1]] board can be attached to the Ethernut expansion connector and contains a VS1001K MP3 decoder, a Sony compatible infrared remote control receiver, a simple keyboard and a LCD interface.<br />
<br />
A step by step guide for starting an Internet Radio Application is available [[../documents/webradio.html|here]].<br />
<br />
Due to its 5V-only design and the obsolete decoder chip, egnite stopped production of this board in favor of Medianut 2.<br />
|width="50%"| [[../documents/webradio.html|[[File:../../img/medianut_small.png|128x58px|Medianut 1.1]]]]<br />
|}<br />
<br />
<br /><br />
<br /><br />
<br />
== Housing ==<br />
<br />
{|<br />
|width="50%"| A sample housing can be viewed [[boxed/index.html|here]]. <br />
|width="50%"| [[boxed/index.html|[[File:../../img/nutbox-front-small.jpg|Datanut 1.0]]]]<br />
|}<br />
<br />
<br /><br />
<br /><br />
<br />
== Datanut 1.1 ==<br />
<br />
{|<br />
|width="50%"| The Datanut board never left the prototype phase. It could be attached to the Ethernut expansion connector and provided an IDE and a CompactFlash interface.<br />
|width="50%"| [[File:../../img/datanut-small.png|Datanut 1.0]]<br />
|}<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Firmware/PortingFirmware/Porting2017-07-13T08:44:01Z<p>Harald: Created page with "<div id="content"> = Nut/OS Porting Guide = Nut/OS is not just a kernel, it is a full operating system with peripheral drivers, file systems, network protocols etc. Porting..."</p>
<hr />
<div><div id="content"><br />
<br />
= Nut/OS Porting Guide =<br />
<br />
Nut/OS is not just a kernel, it is a full operating system with peripheral drivers, file systems, network protocols etc. Porting it to a new platform is not trivial.<br />
<br />
Fortunately the kernel is written in ANSI C and quite simple. In fact, only three basic functions need to be implemented for a new platform to get several of the sample applications running.<br />
<br />
* Hardware initialization<br />
* System timer<br />
* Console device<br />
<br />
Hardware initialization is the most essential, but also the most complicated part. That's why we will start with the most easiest, the console device. Next we will implement the system timer and finally settle the initialization part.<br />
<br />
This guide assumes, that you already have a tools available to create binaries from C and assembly source code. You should be able to build a simple application for your target board, like 'Hello world' or a blinking LED.<br />
<br />
Large parts of the following text are still limited. They assume, that your new target CPU is a variant of the ARM architecture. I hope, this page will be still useful, even if your platform is different.<br />
<br />
Further note, that this guide is based on Nut/OS version 5.0.<br />
<br />
== Console Device ==<br />
<br />
This device will become our main user interface. While Nut/OS allows to use many different devices like LCD with keyboard or even network connections as its console, the preferred one is RS-232. If your target board doesn't provide it, I'd highly recommend to upgrade it. Almost all CPUs do have at least one UART and it is usually easier to add the required level shifter and connector, than trying to get an LCD working for fast text output.<br />
<br />
The first thing you need to do is to write minimal C code to initialize the UART and send a simple text message to a terminal emulator running on your PC. But you need to do this without using any external UART library, that may have been included with your board. Your minimal UART code should have four functions:<br />
<br />
* void DebugInit(void);<br />
* void DebugWrite(const char *buffer, int len);<br />
* int DebugRead(char *buffer, int size);<br />
* int main(void);<br />
<br />
Typically, the following parts are needed to implement DebugInit():<br />
<br />
* Select or enable the UART clock<br />
* Calculate and set the baud rate divisor<br />
* Configure the UART, like start, data, stop and parity bits<br />
* Enable peripheral pins<br />
<br />
The datasheet of your CPU should provide all the details. The good news is, that polling mode is just fine. Do not use any interrupts. The most simple console device for Nut/OS is the so called debug device, which intentionally avoids interrupts. This makes the remaining parts, sending and receiving data, much easier. For DebugWrite() we need to<br />
<br />
* check the status register until the transmitter is ready to accept a new character<br />
* write the next character from the buffer into the transmitter data register<br />
* do this for each character in the buffer<br />
<br />
DebugRead() is optional. If you are impatient, you can implement it later. In general, it will contain the following:<br />
<br />
* check the status register until a new character is available in the receiver<br />
* read the new character from the receiver data register and store it in the buffer<br />
* repeat this until the buffer is completely filled<br />
<br />
You main program should then look like<br />
<br />
<pre class="coding">int main(void)<br />
{<br />
char key;<br />
<br />
DebugInit();<br />
<br />
for (;;) {<br />
DebugWrite(&quot;\r\nPress any key &quot;, 16);<br />
DebugRead(&amp;key, 1);<br />
}<br />
}</pre><br />
If this works, we nearly have a first Nut/OS device driver, which will later allow you to use C stdio functions out of the box:<br />
<br />
<pre class="coding">int main(void)<br />
{<br />
int key;<br />
<br />
NutRegisterDevice(&amp;DEV_DEBUG, 0, 0);<br />
<br />
for (;;) {<br />
printf(&quot;\r\nPress any key &quot;);<br />
key = getchar();<br />
}<br />
}</pre><br />
Before actually integrating your code into the Nut/OS source tree, let's take a look to the system timer implementation.<br />
<br />
== System Timer ==<br />
<br />
The system timer is used by the OS for two main purposes. As you probably know, Nut/OS is a multithreading OS. Many threads will wake up in certain time intervals. They use NutSleep() to release CPU control for a specified number of milliseconds. Keeping track of the sleeping threads, Nut/OS uses the system timer to wake them up in time. This is the first purpose of the system timer.<br />
<br />
Most threads will sleep until an external event occurs. However, many of them will set a timeout limit. If no event occurs within a given time, they will be woken up with a timeout error. This is the second purpose the system timer is used for. In fact, it is quite similar to NutSleep(), with the exception, that threads may be woken up not only by the system timer, but also by an external event.<br />
<br />
Before implementing a final system timer for Nut/OS, let's create another minimal application to evaluate timer interrupts on your target board. This time we need three functions:<br />
<br />
* void NutTimerIntr(void *arg);<br />
* void NutRegisterTimer(void (*handler) (void *));<br />
* int main(void);<br />
<br />
NutTimerIntr() is the timer interrupt handler of Nut/OS and part of the kernel. Because we are not yet using Nut/OS, we need to provide it in our minimal test program. The following code will initialize the timer and run in an endless loop, which is interrupted on every millisecond to increment a global variable:<br />
<br />
<pre class="coding">unsigned long nut_ticks;<br />
<br />
void NutTimerIntr(void *arg)<br />
{<br />
nut_ticks++;<br />
}<br />
<br />
void NutRegisterTimer(void (*handler) (void *))<br />
{<br />
/* Initialize the timer hardware to 1 millisecond. */<br />
/* ... */<br />
/* Set the interrupt handler address. */<br />
/* ... */<br />
/* Enable timer interrupts. */<br />
/* ... */<br />
}<br />
<br />
int main(void)<br />
{<br />
NutRegisterTimer(NutTimerIntr);<br />
for (;;) {<br />
}<br />
}</pre><br />
This looks a bit complicated. Actually, it is even more complicated than it looks. The tricky part is, that most platforms require special declarations of interrupt handlers, which are different from the handler given above, NutTimerIntr(). Most likely, the void pointer is not supported, because interrupt calls do not provide parameters.<br />
<br />
The background is, that Nut/OS handles interrupts by a special framework, which allows to pass a single pointer to an interrupt handler. This way, a single interrupt routine is able to serve several similar devices. For example, only a single SPI interrupt handler is required to handle all SPI busses.<br />
<br />
In a first step it makes sense to avoid the internal interrupt framework. Luckily this is possible, because<br />
<br />
* Nut/OS allows to use native interrupt handlers<br />
* The system timer interrupt only needs to increment the system tick counter<br />
* The system tick counter is a public global variable<br />
<br />
The NutTimerIntr() function given above is exactly the same as the one in the Nut/OS kernel. As you can see, it ignores the pointer parameter. Now it should be much easier to implement the timer interrupt, right?<br />
<br />
Again, the datasheet of your CPU should explain all the details. Note, that many recent CPUs offer a dedicated timer to be used by an operating system. If available, use it, because it is usually easier to handle than those general purpose timers.<br />
<br />
Now we have two third of the basic requirements. In the next step we will integrate these into the source tree.<br />
<br />
== System Integration ==<br />
<br />
{|<br />
!width="100%"| Architecture Files<br />
|-<br />
|<br />
<pre>nut/<br />
arch/<br />
&lt;ARCHNAME&gt;<br />
board/<br />
&lt;BOARDNAME&gt;.c<br />
debug/<br />
dev/<br />
&lt;FAMILYNAME&gt;/<br />
dev_debug.c<br />
os_timer.c<br />
init/<br />
crt&lt;LDNAME&gt;.S<br />
ldscript/<br />
&lt;LDNAME&gt;.ld<br />
os/<br />
context.c<br />
nutinit.c</pre><br />
|}<br />
<br />
Where to put our working test code? I assume, that you previously looked into the Nut/OS source tree, where you probably discovered a subdirectory named <code>arch</code>, which is further divided into several subdirectories like <code>avr</code>, <code>arm</code> or <code>unix</code>. If your CPU is already part of one of these existing families, use its subdirectory. If not, you need to create a new one plus several new files and configuration items.<br />
<br />
To make things easy for now, let's assume that you are porting Nut/OS to a new ARM9 CPU. Those ARM7 and ARM9 CPUs, which are currently ported, are quite similar and their code is found in subdirectory <code>arm</code>.<br />
<br />
Let's get down one level deeper, where we find several more subdirectories, on of them is named <code>dev</code>. This looks like the right candidate for our debug device, but in fact it is also the right place for the system timer. By definition, Nut/OS treats the system timer as a device. Well, as you already noticed, we have more subdirectories below, like <code>atmel</code>, <code>gba</code> etc. If your CPU is manufactured by Atmel, then the first one should be the one to use. Unfortunately its name has not been chosen very well, <code>atmel_at91</code> would have been a better name, because that's the CPU family that's actually handled by the drivers in there. It's easy to be wise after the event.<br />
<br />
If the manufacturer or the family of your new target is new to Nut/OS, then create a new subdirectory here. We will later learn, how to tell Nut/OS about this addition. Before you start creating new source files, have a look into subdirectory <code>zero</code> first, which contains two files only:<br />
<br />
* dev_debug.c implements a debug device<br />
* os_timer.c implements a system timer<br />
<br />
Zero is an imaginary CPU only, introduced in Nut/OS Version 5. It doesn't exist in reality and the files do not contain working code. The good news is, that both files are most useful as a template for implementing new platforms. Extensive comments will help, to insert the right code for your target. Copy these files to your new directory and fill in the missing code, using the two test programs that we created above.<br />
<br />
<br /><br />
<br />
{|<br />
!width="100%"| Configuration Files<br />
|-<br />
|<br />
<pre>nut/<br />
conf/<br />
&lt;BOARDNAME&gt;.conf<br />
repository.nut<br />
tools.nut<br />
arch/<br />
arch.nut<br />
&lt;ARCHNAME&gt;.nut</pre><br />
|}<br />
<br />
Beside <code>arch</code>, there is a second subdirectory in the Nut/OS source tree, that is dedicated to hardware specific parts. It's named <code>conf</code> and is used by the Nut/OS Configurator. It also contains a prepared configuration file for an imaginary board (zero_ek.conf) with our imaginary Zero CPU, so you can use it for your new target as well. Simply create a copy, using the name of your target board. Now start the Nut/OS Configurator and select the newly created configuration file. In fact, all further configuration like memory size, tool chain etc. can be done in the Configurator. You can't? Almost all parts of the system are not enabled or refer to the Zero CPU? Your new CPU is not available? Don't panic, this can be fixed easily.<br />
<br />
Beside the board configuration files, subdirectory <code>conf</code> contains a several files with the extension <code>.nut</code>, some of them in subdirectories below <code>conf</code>. All of them, including the board configuration files, are Lua scripts. You can use any text editor to modify them.<br />
<br />
The first one we will touch, is <code>conf/repository.nut</code>. Search for MCU_ZERO, which is part of a Lua array named <code>mcu_names</code>. Simply add the name of your CPU to this list.<br />
<br />
The next one is <code>conf/tools.nut</code>. Search for zero, where you will find a list of linker scripts. We didn't create a linker script yet, because we deferred hardware initialization. Anyway, as we are here right now, add a proper entry for your CPU. Note, that most platforms provide two, some even more entries. That's because different initializations are required, when the final binary should run in Flash memory or RAM, for example.<br />
<br />
<br /><br />
<br />
The rest is straight forward. Check <code>conf/arch/arch.nut</code> and <code>conf/arch/arm.nut</code> for entries of the Zero CPU and create a copy of these parts for your CPU, changing the hardware names accordingly.<br />
<br />
Here is a template for a new CPU entry in <code>conf/arch/arch.nut</code>:<br />
<br />
<pre class="coding">--<br />
-- &lt;MY NEW CPU&gt;<br />
--<br />
{<br />
macro = &quot;MCU_&lt;CPUNAME&gt;&quot;,<br />
brief = &quot;Name&quot;,<br />
description = &quot;Description of this CPU.&quot;,<br />
flavor = &quot;boolean&quot;,<br />
exclusivity = mcu_names, <br />
file = &quot;include/cfg/arch.h&quot;,<br />
requires = { &quot;TOOL_CC_ARM&quot; },<br />
provides = {<br />
&quot;HW_TARGET&quot;,<br />
&quot;HW_MCU_ARM&quot;,<br />
&quot;HW_TIMER_&lt;FAMILYNAME&gt;&quot;,<br />
&quot;HW_UART_&lt;FAMILYNAME&gt;&quot;<br />
},<br />
makedefs = { &quot;MCU=arm9&quot; }<br />
},</pre><br />
And this is a template for the related driver entries in <code>conf/arch/arm.nut</code>:<br />
<br />
<pre class="coding">{<br />
name = &quot;nutarch_ostimer_&lt;FAMILYNAME&gt;&quot;,<br />
brief = &quot;System Timer (&lt;FAMILYNAME&gt;)&quot;,<br />
requires = { &quot;HW_TIMER_&lt;FAMILYNAME&gt;&quot; },<br />
provides = { &quot;NUT_OSTIMER_DEV&quot; },<br />
sources = { &quot;arm/dev/&lt;FAMILYNAME&gt;/os_timer.c&quot; },<br />
},<br />
...<br />
{<br />
name = &quot;nutarch_&lt;FAMILYNAME&gt;_debug&quot;,<br />
brief = &quot;UART Debug Output (&lt;FAMILYNAME&gt;)&quot;,<br />
description = &quot;Polling UART driver for ...&quot;,<br />
requires = { &quot;HW_UART_&lt;FAMILYNAME&gt;&quot; },<br />
provides = { &quot;DEV_UART&quot;, &quot;DEV_FILE&quot;, &quot;DEV_WRITE&quot; },<br />
sources = { &quot;arm/dev/&lt;FAMILYNAME&gt;/dev_debug.c&quot; }<br />
},</pre><br />
After re-opening the board configuration file in the Configurator, you should be able to select your new CPU. Building the system will fail, because the hardware initialization is still missing. This is our last task.<br />
<br />
== Hardware Initialization ==<br />
<br />
Nut/OS does not require any special hardware initialization. However, in most cases you won't be able to build it or get it running without some modifications of the code, that you normally use when writing code without underlying operating system.<br />
<br />
In a previous step we already added the name of a linker script to <code>conf/tools.nut</code>. When building Nut/OS, the compiler expects two files in the <code>arch</code> directory, based on this name.<br />
<br />
* arch/arm/init/crt&lt;NAME&gt;.S<br />
* arch/arm/ldscript/&lt;NAME&gt;.ld<br />
<br />
The first one is an assembly language file and contains the so called C runtime initialization. Every program written in C language needs this, whether it uses and underlying OS or not. As you have done a few samples, one should already exist. Sometimes it is provided with the tools, sometimes it is part of the C library.<br />
<br />
The purpose of the initialization code is to initially setup the hardware, like enabling clocks, configure chip selects, initializing SDRAM etc. Then the .bss segment that contains uninitialized global variables is cleared to zero. If the program starts from read-only memory, like flash, the contents of initialized variables is copied from this read-only memory to RAM. Finally a jump to main() is done.<br />
<br />
One significant difference between a standard initialization and one, that fits with Nut/OS, is, that the jump to main() is replaced by a jump to NutInit(). Even without further knowledge of assembly language, you should be able to modify the initialization code accordingly.<br />
<br />
The second file, the linker script, contains some black magic for most of us. Generally speaking, this file tells the linker, where to place different parts (segments) of the code. For example, code segments and constant variables may be placed in flash memory, but normal variables must be placed in RAM. Jump vectors are typically placed at the bottom or top of address range, and also the stack is often placed at a specific memory location. All this can be defined in the linker script. Like with the runtime initialization, you probably already used a linker script when building target binaries for your board.<br />
<br />
The script refers to specific segment names. Some of them are defined by the compiler, some are user definable. Most of the latter are specified in the runtime initialization. On the other hand it is possible to define new symbols in the linker script as well, which are then referred to by the code. For example, in order to clear uninitialized global variables, the runtime initialization needs to know, where this segment (.bss) is located. Thus, the runtime initialization code and the linker script have strong ties. Beside these, the Nut/OS kernel may also refers to memory locations, which are typically provided by the linker script. For most platforms, only <code>__heap_start</code> is required, which specifies the first address of unused RAM. Nut/OS uses this memory area for its heap. If your default linker script doesn't provide it, you must add it at the proper place.<br />
<br />
The explanation above is mainly based of what we have, when using the GCC toolchain for ARM CPUs. Depending on the target platform, other items may be required. You should additionally check <code>arch/arm/os/nutinit.c</code>.<br />
<br />
== Testing ==<br />
<br />
You should now be able to build Nut/OS in the Configurator. After done that, create your first sample directory, selecting <code>Build &gt; Create Sample Directory</code> in the Configurator's main menu. As usual, open a shell (command line) window, change to the new sample directory, make sure that your compiler tools are inlcuded in the PATH variable and run<br />
<br />
<pre class="coding">make clean all</pre><br />
With our minimal patches, at least the following samples should run fine, when uploading the binaries to your target board:<br />
<br />
* caltime<br />
* editconf<br />
* events<br />
* simple<br />
* threads<br />
* timers<br />
* uart<br />
<br />
We prefer to start with <code>events</code>, because it is quite simple and test the two main functions, context switching and timer. Since we do not have any other driver than the one that implements a console, all samples using the Ethernet interface should compile, but will not work yet.<br />
<br />
== What's Next? ==<br />
<br />
As mentioned in the beginning, Nut/OS provides a large number of features, including a full TCP/IP stack, several filesystems and support for several low level devices like I2C or SPI busses.<br />
<br />
I assume, that you will be most interested in TCP/IP. For this, you need to implement a driver for the Ethernet interface. The debug device driver that had been created above, was a polling driver and didn't require any interrupt handling. This is an exception, most other drivers must be able to handle interrupts. Of course, it it always possible to skip the Nut/OS interrupt framework by using native handlers. The disadvantage is, that such drivers are always hardware dependant. You must place the code in <code>nut/arch/&lt;ARCHNAME&gt;/dev</code> and it will not be available for other platforms.<br />
<br />
This is quite common with network drivers, but a few are already done in a hardware independent way. You can find them in the directory <code>nut/dev/</code>. If one of them fits, you need to adapt the interrupt framework to your architecture as well as some GPIO functions. How to do this, will go beyond the scope of this document. Best, try to follow the code that had been done for other platforms. By the time we will hopefully have more guides to help.<br />
<br />
Good luck,<br /><br />
Harald Kipp<br /><br />
Castrop-Rauxel, 24th of October 2011<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Firmware/NutOSFirmware/NutOS2017-07-13T08:43:31Z<p>Harald: Created page with "<div id="content"> = Nut/OS = == Features == Nut/OS is based on an intentionally simple RTOS kernel, which provides a minimum of services to run Nut/Net, the TCP/IP stack...."</p>
<hr />
<div><div id="content"><br />
<br />
= Nut/OS =<br />
<br />
== Features ==<br />
<br />
Nut/OS is based on an intentionally simple RTOS kernel, which provides a minimum of services to run Nut/Net, the TCP/IP stack. It's features include:<br />
<br />
* Coperative multithreading<br />
* Deterministic interrupt response times<br />
* Priority based event handling<br />
* Periodic and one-shot timers<br />
* Dynamic memory management<br />
<br />
Main features of the TCP/IP stack are:<br />
<br />
* Base protocols Ethernet, ARP, IP, ICMP, UDP, TCP and PPP<br />
* User protocols DHCP, DNS, SNTP, SMTP, FTP, SYSLOG, HTTP and others<br />
* Socket API<br />
* Host, net and default routing<br />
<br />
Nut/OS is a modular operating system. Instead of providing a fixed kernel block, all code is packed in libraries. Only those parts are linked to the final binary image, which are directly or indirectly referenced by the application. This guarantees the lowest possible footprint. Ernst Stippl regularly publishes related figures on his web site at [http://www.es-business.com/ethernut/eng/ www.es-business.com/ethernut/].<br />
<br />
Standard C libraries like newlib or avr-libc are supported and allow to write highly portable applications. While direct hardware access and native interrupts are possible in application code, the system offers ready-to-use drivers for a large number of devices, including:<br />
<br />
* Ethernet controllers<br />
* UART devices with RS-232 handshake and RS-485 mode<br />
* SPI, I2C and CAN busses<br />
* MultiMedia and SD cards<br />
* Hardware and software audio codecs<br />
* Analog-to-digital converters<br />
* Serial flash memory<br />
* Realtime clocks<br />
* Infrared remote controls<br />
* Watchdogs and reset controllers<br />
* Character displays<br />
* GPIO and interrupt control<br />
* Modem control<br />
<br />
Note, that not all drivers may be available on all platforms. The following microcontrollers are actively supported:<br />
<br />
* ATmega103, ATmega128, ATmega2561, AT90CAN128<br />
* AT91SAM7S, AT91SAM7SE, AT91SAM7X<br />
* AT91SAM9260, AT91SAM9XE<br />
* Gameboy Advance<br />
<br />
The system is highly configurable and may work on other hardware too. Support for AVR32 is currently under development and a version for the Freescale Coldfire may become available as well. In addition it is possible to run Nut/OS applications on Linux.<br />
<br />
In order to hide hardware specific details from application code, an almost complete C stdio API is available, which provides:<br />
<br />
* C99 integer types and optional floating point I/O<br />
* File system support, including FAT<br />
* Low level functions and streams on devices, TCP sockets and files<br />
<br />
Nut/OS is perrmanently enhanced by an active community. The following features are currently not available, but planned for future releases or currently under development:<br />
<br />
* Graphical user interface<br />
* USB stack<br />
* IPv6<br />
* Encryption<br />
* Wireless LAN<br />
<br />
[[File:../../img/avr_pd.png]]<br />
== Multithreading ==<br />
<br />
During system initialization, the idle thread is created in the background first. The application code is not aware of this. Like any other C program, it contains a [http://www.ethernut.de/nutwiki/Hello_World! main routine]. Internally the main routine is a thread, running concurrently with the idle thread.<br />
<br />
During runtime, the main thread may [http://www.ethernut.de/nutwiki/Multithreading create additional threads] by calling NutThreadCreate.<br />
<br />
[http://www.ethernut.de/nutwiki/Thread_Synchronization_with_Events Thread synchronization] is provided by events. A thread may wait for an event or it may post an event to wake up another thread, which is waiting for this event.<br />
<br />
[[File:../../img/7segment_pd.png]]<br />
== Device Drivers ==<br />
<br />
Simple operating systems like Nut/OS allow application code to directly access the hardware. Device drivers are not required. Nevertheless, Nut/OS provides a large number of device drivers to allow the application to use portable, high level functions to access them. For example, an [http://www.ethernut.de/nutwiki/MMC_MP3_Player MP3 player] can use the standard C runtime function fread to read the audio file from an SD Card and fwrite to send it to the MP3 decoder for playing.<br />
<br />
For special devices, like general purpose I/O (GPIO), SPI or I2C, specific helper routines are available to keep your applications portable among all supported platforms.<br />
<br />
Nut/OS is a modular kernel, where device drivers are included only, when the applications registers them via NutRegisterDevice.<br />
<br />
[[File:../../img/sdcards_pd.png]]<br />
== Filesystems ==<br />
<br />
While file system support is not common for tiny systems, Nut/OS provides several. The most simple is read-only and named [http://www.ethernut.de/nutwiki/Reading_UROM_Files UROM]. Files are stored as C arrays and directly linked to the application code. A special utility is available to convert a complete directory on your PC's harddisk into such arrays.<br />
<br />
The most advanced file system is a FAT12/16/32 compatible one named [http://www.ethernut.de/nutwiki/Writing_PHAT_Files PHAT]. It is preferably used with MultiMedia and SD Cards.<br />
<br />
The most recent Nut/OS beta includes UFLASH, which is optimized for serial flash chips. It requires a few hundred bytes of RAM only and has an excellent wear leveling performance.<br />
<br />
[[File:../../img/network_pd.png]]<br />
== Network ==<br />
<br />
Nut/OS contains a feature rich TCP/IP stack. Although quite similar, the API is not fully BSD-compatible. It uses its own set of functions. The great thing is, however, that established connections can be associated to stdio streams. For network communication, [http://www.ethernut.de/nutwiki/Basic_TCP_Server applications] can use the full set of stdio routines like fprintf, fscanf, fgetc etc.<br />
<br />
Beside basic TCP and UDP sockets, several high level protocols are included as well. The latest version supports [http://www.ethernut.de/nutwiki/Network_Configuration_Using_Stored_Configuration DHCP], [http://www.ethernut.de/nutwiki/Domain_Name_Service DNS], FTP, HTTP, SMTP, SNMP, [http://www.ethernut.de/mediawiki/Simple_Network_Time_Protocol SNTP], [http://www.ethernut.de/nutwiki/Sending_syslog_Messages syslog] and others.<br />
<br />
== Getting Started ==<br />
<br />
[http://www.ethernut.de/nutwiki/Ethernut_1.3_H Using Nut/OS on Ethernut 1.3]<br /><br />
The [[../hardware/enut1/index.html|Ethernut 1.3 reference hardware]] is based on the 8-bit ATmega128.<br />
<br />
[http://www.ethernut.de/nutwiki/Ethernut_2.1_B Using Nut/OS on Ethernut 2.1]<br /><br />
Like Ethernut 1.3, the [[../hardware/enut2/index.html|Ethernut 2.1 reference hardware]] uses an ATmega128 CPU, but offers more memory, fast Ethernet and an RS-485 interface.<br />
<br />
[http://www.ethernut.de/nutwiki/Ethernut_3.0_E Using Nut/OS on Ethernut 3.0]<br /><br />
The [[../hardware/enut3/index.html|Ethernut 3.0 Board]] comes with a fast 32-bit CPU.<br />
<br />
[http://www.ethernut.de/nutwiki/Elektor_Internet_Radio_1.0 Using Nut/OS on the Elektor Internet Radio]<br /><br />
Also equipped with a 32-bit CPU, the [[../hardware/eir/index.html|Elektor Internet Radio]] not only has very large memory areas, but also the world's first Ogg Vorbis hardware encoder chip.<br />
<br />
[http://www.ethernut.de/nutwiki/Nut/OS_Examples Nutwiki]<br /><br />
Large collection of code snippets and tiny examples.<br />
<br />
== Additional Documents ==<br />
<br />
=== Must Have ===<br />
<br />
[[../../pdf/enswm28e.pdf|Nut/OS Software Manual]]<br /><br />
How to install and use Nut/OS.<br />
<br />
[[../../api/index.html|Online API Documentation]]<br />
<br />
[[../../api-beta/index.html|API Documentation of the beta release]]<br />
<br />
=== More documents ===<br />
<br />
'''NEW:''' [[porting.html|Porting Nut/OS]]<br /><br />
... to new platforms.<br />
<br />
[[../documents/ntn-6_spi.html|SPI Bus Support]]<br /><br />
Technical details about SPI drivers.<br />
<br />
[[../documents/arm-exceptions.html|ARM Exception Handling]]<br /><br />
Nut/OS doesn't provide any exception handling by default. This document shows how to implement an exception handler within your application.<br />
<br />
[[../documents/arm-inline-asm.html|ARM GCC Inline Assembler Cookbook]]<br /><br />
The GNU C compiler for ARM RISC processors offers to embed assembly language code into C programs. This cool feature may be used for manually optimizing time critical parts of the software or to use specific processor instruction, which are not available in the C language.<br />
<br />
[[../documents/led.html|LED control]]<br /><br />
A beginner's guide to connecting external hardware.<br />
<br />
[[../documents/ntn-4_floats.html|Floating Point Support]]<br /><br />
The kernel won't need it, but your application may want to read or write floating point numbers.<br />
<br />
[[../hardware/enut2/rs485.html|Using RS485 with Ethernut 2]]<br /><br />
Jumper settings, configuration and sample code.<br />
<br />
[[../documents/at91sam9260.html|Running Nut/OS on the AT91SAM9260]]<br /><br />
A step by step guide. Preliminary.<br />
<br />
[[../documents/at91sam7x256.html|Running Nut/OS on the AT91SAM7X]]<br /><br />
Access your MultiMedia Card on the AT91SAM7X Evaluation Kit via FTP.<br />
<br />
[[../documents/atmega2561.html|Running Nut/OS on the ATmega2561]]<br /><br />
Preliminary support for the ImageCraft Compiler running on Windows.<br />
<br />
[[../documents/watchdog.html|Using the Hardware Watchdog]]<br /><br />
How to implement a timer interrupt handler for Ethernut 3.<br />
<br />
[[../documents/at91-timer-irq.html|AT91 Timer Interrupts]]<br /><br />
How to implement a timer interrupt handler for Ethernut 3.<br />
<br />
[[../documents/phat.html|Using the PHAT File System]]<br /><br />
Making your MMC interface on Ethernut 3 work.<br />
<br />
[[../documents/ntn-3_broadcast.html|Using UDP Broadcasts]]<br /><br />
This paper presents a simple tool to discover all Ethernuts in a local network.<br />
<br />
=== Partly outdated ===<br />
<br />
[[../documents/npl.html|Nut Programmable Logic]]<br /><br />
This tutorial teaches you to modify the CPLD on Ethernut 3.<br />
<br />
[[../documents/webradio.html|MP3 Streaming]]<br /><br />
A step by step guide on how to build a stand-alone Embedded Internet Radio.<br />
<br />
[[../documents/ntn-1_ppp.html|Setting up PPP]]<br /><br />
This paper provides helpful information about how to get started with Ethernut's PPP.<br />
<br />
[[../documents/sam-web-radio.html|SAM Internet Radio]]<br /><br />
Implementing an Internet Radio on the AT91SAM9260 and AT91SAM7X Evaluation Kits.<br />
<br />
[[../documents/ntn-2_events.html|Nut/OS Events]]<br /><br />
This paper explains Nut/OS event handling internals.<br />
<br />
[[require.html|CPU and Memory Requirements]]<br /><br />
<br />
<br />
[[../../pdf/entet100.pdf|Nut/OS Threads, Events and Timers]]<br /><br />
Recommended reading for application programmers.<br />
<br />
[[../../pdf/enmem21e.pdf|Nut/OS Memory Considerations]]<br /><br />
Includes a design proposal for bank switched RAM.<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Firmware/Nut_LuaFirmware/Nut Lua2017-07-13T08:42:51Z<p>Harald: Created page with "<div id="content"> = Lua on Embedded Systems = == Introduction == Lua Logo Quoting the creators: &quot;Lua is a powerful, fast, lig..."</p>
<hr />
<div><div id="content"><br />
<br />
= Lua on Embedded Systems =<br />
<br />
== Introduction ==<br />
<br />
[[File:../../img/lualogo.gif|128x128px|Lua Logo]]<br />
Quoting the creators: &quot;Lua is a powerful, fast, lightweight, embeddable scripting language.&quot; Lightweight means, that it takes about 150-250 kBytes on a PC. This is still a challenge for small embedded systems running Nut/OS, specifically for the 8-bit AVR targets like Ethernut 1 and 2.<br />
<br />
In a first attempt, Laszlo Parrag succeeded in 2008 with implementing a subset, that runs small Lua scripts on an ARM7 based board. The source code of a Lua script had been stored in a local character array of a sample Nut/OS application. After adding a few minor modifications, the Lua libraries had been added to the official Nut/OS distribution, enabled for ARM CPUs only. Not much happened to it since June 2009, when Nut/OS 4.9.2 beta became available. This version is able to run a stand-alone Lua interpreter on most target systems, including 8-bit AVRs. However, due to memory limitations, not all targets are able to offer the full set of Lua standard libraries. The developer can use the Nut/OS Configurator to enable or disable specific parts.<br />
<br />
Visit [http://www.lua.org/ www.lua.org] to find out more about Lua.<br />
<br />
== Lua Configuration ==<br />
<br />
The Nut/OS Configurator had been enhanced with several items to adapt Lua to the specific platform and the needs of the application. Btw. actually the Configurator itself is driven by Lua scripts, and only these scripts had been modified to add these new functions. But that's a different story.<br />
<br />
The following screenshot shows the initial configuration. All Lua default libraries are disabled, parser and dump are not excluded. With these settings Nut/OS can run basic Lua source code.<br />
<br />
[[File:../../img/lua-config01.png|558x458px|Lua Configuration]]<br />
=== Enabling Libraries ===<br />
<br />
Disabling the libraries doesn't mean, that these libraries are not available. The Configurator will still build them, but they will not be loaded automatically by calling luaL_openlibs. Instead, the Nut/OS application can load individual libraries by calling the related initialization function like luaopen_io or luaopen_string.<br />
<br />
=== Enabling Floating Point Support ===<br />
<br />
[[File:../../img/lua-config02.png|267x133px|Nut/OS Floating Point I/O]]<br />
In general Lua numbers are floating point values by default. This requires some more memory space and, more important, significantly slows down execution on embedded systems without floating point hardware. Therefore, number are integer by default in Lua for Nut/OS.<br />
<br />
You probably noticed that the item ''Floating Point Numbers'' is greyed out, which means that you can't enable it without providing a specific requirement. In this case you must enable Nut/OS floating point support for file streams first. This will allow Lua to read and write floats.<br />
<br />
=== Excluding Parser and Dump ===<br />
<br />
The parser allows to directly execute Lua source code. Well, not really directly. In fact the parser translates the source code to Lua binary code first. This step could be done on a desktop computer and only the binaries may be uploaded to the target. As you can imagine, this can save a lot of RAM.<br />
<br />
The Lua dump allows to display Lua binary code and is typically not required by the final firmware. Excluding it saves a few kilobytes.<br />
<br />
Unlike standard libraries, Lua parser and Lua dump will be completely removed, if excluded. There is no way to load them by function calls in the application during runtime.<br />
<br />
=== TCP/IP Support ===<br />
<br />
The highlighted configuration item in the screenshot above doesn't represent a library. Instead it is an option of the I/O library and will be removed from it unless enabled. More on this later.<br />
<br />
== Lua Interpreter ==<br />
<br />
A standalone interpreter had been created as a Nut/OS sample application to demonstrate the capabilities. It will read Lua source code and print out results on the RS-232 port, which is available on most embedded boards.<br />
<br />
The interpreter uses the new EdLine module of the Nut/OS Gorp library. It is not yet documented. For now, have a look to the source code.<br />
<br />
== Lua Implementation ==<br />
<br />
<br />
<br />
=== TCP Connections ===<br />
<br />
There is no socket library available yet. Instead, the standard I/O library had been extended by two additional functions. They allow to write basic TCP servers and clients.<br />
<br />
The Lua code for a client connecting port 80 at IP address 192.0.0.2 may look like this:<br />
<br />
<pre class="coding">c = io.connect(&quot;192.0.0.2:80&quot;, &quot;r+b&quot;)<br />
c:write(&quot;Hello!\r\n&quot;)<br />
c:flush()<br />
r = c:read()<br />
c:close()</pre><br />
The related TCP server may look like this:<br />
<br />
<pre class="coding">c = io.accept(&quot;80&quot;, &quot;r+b&quot;)<br />
r = c:read()<br />
c:write(&quot;Hello to you too!\r\n&quot;)<br />
c:flush()<br />
c:close()</pre><br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Firmware/ApplicationsFirmware/Applications2017-07-13T08:41:57Z<p>Harald: Created page with "<div id="content"> = Developing Nut/OS Applications = Application development is done on a PC running Linux, Windows or Mac OS X. See the Tools page..."</p>
<hr />
<div><div id="content"><br />
<br />
= Developing Nut/OS Applications =<br />
<br />
Application development is done on a PC running Linux, Windows or Mac OS X. See the [[../tools/index.html|Tools]] page for more information.<br />
<br />
Check the [[../../api/index.html|Online API Documentation]] for a complete list of provided functions. Use this along with the API documentation of your runtime library, like [http://sourceware.org/newlib/ Newlib] for ARM and [http://www.nongnu.org/avr-libc/ avr-libc] or the [http://www.imagecraft.com/ ImageCraft runtime library] for AVR targets.<br />
<br />
If you are interested in the latest beta, then try the Beta API documentation. It is available [[../../api-beta/index.html|online]].<br />
<br />
A very good way of learning to write Nut/OS applications is studying the [http://www.ethernut.de/nutwiki/Nut/OS_Examples NutWiki Examples].<br />
<br />
Several [[../documents/nutapps.html|Nut/OS Samples]] are also included in the distribution.<br />
<br />
== Additional Documents ==<br />
<br />
=== New or recently updated ===<br />
<br />
[[nutlua.html|Lua for Nut/OS]]<br /><br />
Presents a Lua interpreter running on tiny embedded systems.<br />
<br />
[[../documents/ntn-6_spi.html|SPI Bus Support]]<br /><br />
Technical details about SPI drivers.<br />
<br />
[[../documents/arm-exceptions.html|ARM Exception Handling]]<br /><br />
Nut/OS doesn't provide any exception handling by default. This document shows how to implement an exception handler within your application.<br />
<br />
[[../documents/arm-inline-asm.html|ARM GCC Inline Assembler Cookbook]]<br /><br />
The GNU C compiler for ARM RISC processors offers to embed assembly language code into C programs. This cool feature may be used for manually optimizing time critical parts of the software or to use specific processor instruction, which are not available in the C language.<br />
<br />
=== More documents ===<br />
<br />
[[../documents/led.html|LED control]]<br /><br />
A beginner's guide to connecting external hardware.<br />
<br />
[[../documents/ntn-4_floats.html|Floating Point Support]]<br /><br />
The kernel won't need it, but your application may want to read or write floating point numbers.<br />
<br />
[[../hardware/enut2/rs485.html|Using RS485 with Ethernut 2]]<br /><br />
Jumper settings, configuration and sample code.<br />
<br />
[[../documents/at91sam9260.html|Running Nut/OS on the AT91SAM9260]]<br /><br />
A step by step guide. Preliminary.<br />
<br />
[[../documents/at91sam7x256.html|Running Nut/OS on the AT91SAM7X]]<br /><br />
Access your MultiMedia Card on the AT91SAM7X Evaluation Kit via FTP.<br />
<br />
[[../documents/atmega2561.html|Running Nut/OS on the ATmega2561]]<br /><br />
Preliminary support for the ImageCraft Compiler running on Windows.<br />
<br />
[[../documents/watchdog.html|Using the Hardware Watchdog]]<br /><br />
How to implement a timer interrupt handler for Ethernut 3.<br />
<br />
[[../documents/at91-timer-irq.html|AT91 Timer Interrupts]]<br /><br />
How to implement a timer interrupt handler for Ethernut 3.<br />
<br />
[[../documents/phat.html|Using the PHAT File System]]<br /><br />
Making your MMC interface on Ethernut 3 work.<br />
<br />
[[../documents/ntn-3_broadcast.html|Using UDP Broadcasts]]<br /><br />
This paper presents a simple tool to discover all Ethernuts in a local network.<br />
<br />
=== Partly outdated ===<br />
<br />
[[npl.html|Nut Programmable Logic]]<br /><br />
This tutorial teaches you to modify the CPLD on Ethernut 3.<br />
<br />
[[webradio.html|MP3 Streaming]]<br /><br />
A step by step guide on how to build a stand-alone Embedded Internet Radio.<br />
<br />
[[ntn-1_ppp.html|Setting up PPP]]<br /><br />
This paper provides helpful information about how to get started with Ethernut's PPP.<br />
<br />
[[sam-web-radio.html|SAM Internet Radio]]<br /><br />
Implementing an Internet Radio on the AT91SAM9260 and AT91SAM7X Evaluation Kits.<br />
<br />
[[ntn-2_events.html|Nut/OS Events]]<br /><br />
This paper explains Nut/OS event handling internals.<br />
<br />
[[require.html|CPU and Memory Requirements]]<br /><br />
<br />
<br />
[[../../pdf/entet100.pdf|Nut/OS Threads, Events and Timers]]<br /><br />
Recommended reading for application programmers.<br />
<br />
[[../../pdf/enmem21e.pdf|Nut/OS Memory Considerations]]<br /><br />
Includes a design proposal for bank switched RAM.<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/FirmwareFirmware2017-07-13T08:41:04Z<p>Harald: /* Ethernut Firmware */</p>
<hr />
<div>= Ethernut Firmware =<br />
<br />
<div class="lboxof2"><br />
<br />
== Nut/OS ==<br />
<br />
Nut/OS is a modular, open source, real time operating system for embedded platforms. It is easily configurable and optimized to run on 8 and 32 bit microcontrollers.<br />
<br />
Due to the modular architecture of the operating system only those components are included, which the application really needs. In general the adaption to the target system is done automatically. For fine tuning a graphical user interface is available under Linux, Windows and OS X.<br />
<br />
Nut/OS multithreading is safe and easy to use. Its cooperative threading guarantees, that a thread yields control at well-defined points only. In most cases access to shared resources does not require any locking. This finally results in small and simple application code and significantly reduces the risk of race conditions and deadlocks.<br />
<br />
Deterministic interrupt latencies provide hard real-time responses within strict deadlines, independent of currently available system resources. [[nutos.html|More...]]<br />
<br />
<br />
</div><br />
<div class="rboxof2"><br />
<br />
== Applications ==<br />
<br />
The application developer can use a comprehensive C library, which complements the runtime library of the compiler. While almost compatible with the Posix standard, the need for learning a large number of new special calls is avoided. Amongst other features, access to files, TCP sockets and some important hardware interfaces is available via stdio streams. [[Documents/Nut Apps|More...]]<br />
<br />
Many basic and a few advanced examples are available in the [[Nut/OS_Examples|NutWiki...]]<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Firmware/Linker_ScriptsFirmware/Linker Scripts2017-07-13T08:40:17Z<p>Harald: Created page with "<div id="content"> = GNU ARM Linker Scripts = No question, creating linker scripts is black magic for many developers. In the early days, when Nut/OS supports a single CPU,..."</p>
<hr />
<div><div id="content"><br />
<br />
= GNU ARM Linker Scripts =<br />
<br />
No question, creating linker scripts is black magic for many developers. In the early days, when Nut/OS supports a single CPU, the ATmega103, linker scripts were nothing to worry about. The Nut/OS build simply uses the one supplied by the runtime library, avr-libc. For later 8-bit AVR devices, this didn't change.<br />
<br />
A new situation came up with the first ARM port for the Gameboy Advanced, which was created without any runtime library. Luckily the Internet offers a collection of ready-made scripts, which btw. were actually based on the same source somehow. Later on, newlib was used and it comes without linker scripts. It turns out, that for ARM based boards all linker scripts must be provided by Nut/OS.<br />
<br />
For many target boards several scripts are offered. Still, the one you need for your specific memory layout may not be available. We will later learn, what's the reason for this growing collection and how problems may be avoided in the future.<br />
<br />
Until another solution is provided, this document shall help to adapt existing linker scripts to your needs.<br />
<br />
== What does a linker script do? ==<br />
<br />
While reading this question, you may first ask yourself: What does a linker actually do? Simple answer: It links object files. Object files are created by a compiler or assembler by translating source code into machine instructions. In almost all cases, these object files are relocatable. That means, that their final location in the address space is not fixed. While it is generally possible to create pure relocatable code by avoiding instructions with absolute addresses, such code will not be optimal. Instead, the compiler will try to create the best code and specially mark all absolute references. The actual addresses are not known until the linker collects and combines all object files to the final binary. It will then fix the references that had been marked by the compiler.<br />
<br />
Of course, there are certain rules, that the linker must follow when processing the object files. Today, almost all embedded systems offer different types of memories, like SRAM, SDRAM, ROM, Flash memory etc., which can be used by the firmware for either program code, constant data and variables, generally speaking. Naturally, variables will be placed in RAM, code and constant data in ROM or Flash.<br />
<br />
When the compiler generates the object files, it keeps code, constants and variables separated in so called segments. The linker is then responsible for placing the segments in the right physical memory. Of course, the linker has no idea about how to do this, unless a linker script is provided.<br />
<br />
== Selecting the right script ==<br />
<br />
Default linker scripts are defined in the board configuration, e.g. for Ethernut 5 the related entry in nut/conf/ethernut50f.conf is<br />
<br />
<pre class="coding">LDSCRIPT = &quot;at91sam9xe512_ram&quot;</pre><br />
You can change this default in the Nut/OS Configurator.<br />
<br />
[[../../img/linker-script-select.png|[[File:../../img/linker-script-select_346.png|Selecting a linker script]]]]<br />
Many ARM-based boards used with Nut/OS have CPUs with internal Flash memory and RAM. Obviously, the linker script will tell the linker to place variables in RAM and the rest in ROM. Quite easy, so why make such a mountain out of a molehill?<br />
<br />
The tricky part is, that some code needs to be placed at fixed memory addresses. For example, the ARM interrupt vectors must start at a fixed physical memory address, typically address zero. Another problem, which we overlooked in the simple description of segments: Variables may be initialized to a constant value and then change during runtime. For this we need a special segment placed in Flash, which will be copied to RAM when the system starts running.<br />
<br />
But there's is a lot more to consider. While the 8-bit AVRs with Harvard architecture were not able run program code from anything but Flash memory, ARM CPUs may freely mix code and data within the same memory device. Why would someone want to do this? There are many reasons. For example, during development it is preferred to run code in RAM. Programming Flash memory is slow and it wears out. Thus, if enough RAM is available, this is the best place for testing and debugging your firmware. Another reason is, that ARM exception vectors are preferably placed in RAM, which allows to dynamically modify them during runtime. Many ARM targets allow to remap memories. While the system starts with ROM code at address zero, RAM memory may be remapped to this address during runtime. Last not least, different types of memory provide different access times. Typically, internal SRAM is faster than external Flash. During startup, some routines may be copied from Flash to RAM, where they can be executed at maximum speed. You may now get an idea, why one or two linker scripts cannot fulfill all requirements.<br />
<br />
Just for the complete picture: Most embedded CPUs come in various incarnations with all kind of memory sizes. At the time of this writing, Nut/OS offers 8 different linker scripts for the AT91SAM7S, and these are just basic setups.<br />
<br />
The conclusion is, that you need to make up your mind, where you want to place the different segments of your firmware. If you are lucky, a ready-to-use linker script already exists. Too often this will not be the case and you need to roll your own.<br />
<br />
== Nut/OS memory segments ==<br />
<br />
By default, the compiler will place executable code in the ''.text'' segment, uninitialized, non-auto variables in the ''.bss'' segment, values for explicitly initialized variables in the ''.data'' segment and constant data in the ''.rodata'' segment. If you look into a linker map file, you may also notice a segment named ''COMMON'', which is actually a ''.bss'' segment of all global variables.<br />
<br />
Beside these, the source code may freely define additional segments. The runtime library defines several, most of them are variations of basic segments listed above.<br />
<br />
Last not least, Nut/OS itself defines a number of additional segments. Most important are the ''.init'' segments, which contain early initialization code that must be executed first. Then there is the segment ''.vectors'' which, you guessed it, contains the exception (interrupt) vector table. Some functions are located in a segment named ''.ramfunc'', either because they will fail when running in external memory or because they are time critical and therefore should not run in slow Flash memory.<br />
<br />
== Learn linker scripting in a few minutes ==<br />
<br />
Nut/OS linker scripts for ARM CPUs are found in subdirectory nut/arch/arm/ldscripts. Among the first directives, they contain a list of available memory areas. Here is one for the AT91SAM7X128:<br />
<br />
<pre class="coding">MEMORY<br />
{<br />
rom(rx): org = 0x00000000, len = 128k<br />
ram(rw): org = 0x00200000, len = 32k<br />
}</pre><br />
The device contains 128kB Flash (r=readable, x=executable) located at address 0x00000000 and 32kB RAM (r=readable, w=writable) located at address 0x00200000. Note, that the names of the memory areas, ''ram'' and ''rom'' in our case, may be freely chosen.<br />
<br />
The following statements will now tell the linker, which segment must be placed in which of these memory areas. More precisely, one or more sections will be defined, which contain one or more segments. And each section will be placed in a specified memory area. Usually, the exception vectors are placed at the start of Flash memory, followed by the initialization code (.init segment), application code (.text segment) and read-only data (.rodata segment).<br />
<br />
<pre class="coding">.text :<br />
{<br />
*(.vectors);<br />
*(.init);<br />
*(.text);<br />
*(.rodata);<br />
__etext = .;<br />
} &gt; rom</pre><br />
It is worth to note the difference between segments and sections. Sections are created by the linker and contain collections of segments created by the compiler. For historical reasons, sections often get the same name as their most prominent segment. While you are free to choose different names, I wouldn't recommend to do so. Tools as well as developers might become confused. Better stick with the conventions.<br />
<br />
If you wonder about ''__etext'': We will soon come back to this.<br />
<br />
Then we have not-explicitly-initialized static and global variables, located in the segments .bss and COMMON, which should go to RAM.<br />
<br />
<pre class="coding">.bss :<br />
{<br />
*(.bss)<br />
*(COMMON)<br />
} &gt; ram</pre><br />
The C program expects the contents of these variables to be initialized to zero. The C runtime initialization contains code to do this during startup.<br />
<br />
Finally we have explicitly initialized variables, which require special handling. When the system starts, the contents of the RAM is undetermined. Again, the C runtime initialization will initialize these variables, but unlike the .bss and COMMON segments, we cannot simply clear this memory area, but must fill it with defined values. So, what we have to do is, to define an area in Flash, which will be copied to RAM by the startup code.<br />
<br />
<pre class="coding">.data : AT (__etext)<br />
{<br />
*(.data)<br />
} &gt; ram</pre><br />
''AT (__etext)'' does all the magic. While all references of the .data segment will use addresses in RAM, the contents will be placed in Flash, starting at ''__etext''.<br />
<br />
We referred to C runtime initialization at least two times. First, it will clear the .bss and COMMON segment. Second, it will transfer the .data segment to RAM. For this, the initialization code must know, at which addresses these segments were placed by the linker. Fortunately, symbols that are declared in the linker script (like __etext) are visible to the initialization code. Of course, a few more will be required than just the start address of the .data segment.<br />
<br />
Although newer ARM architectures allow to write runtime initialization in C, the majority is still written in assembly language. Many C programmers are afraid of assembly language and try to avoid it, for no reason, really. The next chapter will proof this.<br />
<br />
== Learn ARM assembly language in a few minutes ==<br />
<br />
Runtime initialization routines are for simple tasks, which can be done with simple code. Assembly code gurus are not required.<br />
<br />
As you probably know, the ARM CPU has a number of registers, almost all of them are 32 bit wide on the ARM CPU. Registers like r0, r1, r2 and so on are general purpose registers, others like sp (stack pointer), lr (link register) or pc (program counter) server special purposes. That's trivial, right?<br />
<br />
Registers may be loaded with immediate values or may load or store their contents from or to memory locations. Or, register contents may be moved to other registers. Instead of just moving, contents may be added, subtracted or modified by all kind of binary operations. Still trivial.<br />
<br />
Let's become more specific. The following code will load all ones into register r0. The equal sign specifies a constant value.<br />
<br />
<pre class="coding">ldr r0, =0xFFFFFFFF</pre><br />
Actually, the ARM processor is not able to load 32-bit immediate values. But this is nothing we have to worry about, because the assembler will place the value into memory and instead create an instruction, which fetches the value from that memory location. The resulting code will be something like<br />
<br />
<pre class="coding">ldr r0, [pc, #20]<br />
... more code ...<br />
.word 0xFFFFFFFF</pre><br />
In this very special case, however, it will even optimize it further, because<br />
<br />
<pre class="coding">mvn r0, #0</pre><br />
will give the same result. It means: Move zero negated into register r0. The CPU can do this without using an additional memory location for the value. Isn't that great? We created perfectly working assembly instructions we were not even aware of. Seriously, what I want to show is, that a few simple instructions will do the job. There is no need to know all available variants to figure out which one fits best.<br />
<br />
Now let's do something useful. To disable the watchdog of AT91SAM9XE CPU, we need to set bit 15 in the watchdog timer mode register (address 0xFFFFFD44).<br />
<br />
<pre class="coding">ldr r0, =0x8000<br />
ldr r1, =0xFFFFFD44<br />
str r0, [r1]</pre><br />
The new item is the ''str'' command, which stores the contents of a register in a memory location pointed to by a second register. This may look weird first, but here the same problem with 32-bit values appears. The CPU cannot handle the 32-bit address as an immediate value and therefore needs a secondary storage for it. In this case an additional register (r1) will be used.<br />
<br />
Although working, after a few days we won't have any clue what the sequence above is used for. The GNU assembler allows us to preprocess assembly source code in the same way as C programs. This allows to use C style comments, which are removed by the preprocessor. But, even better, we can use C header files containing register definitions, which already exist in Nut/OS.<br />
<br />
<pre class="coding">#include &lt;arch/arm.h&gt;<br />
<br />
ldr r0, =WDT_WDDIS<br />
ldr r1, =WDT_MR<br />
str r0, [r1]</pre><br />
While 32 bit immediate values cannot be used, smaller offsets are no problem. Often we deal with a specific group of registers, which base address may be loaded into one register. So we can use immediate offsets to access a specific register within this group.<br />
<br />
<pre class="coding">ldr r1, =WDT_BASE<br />
ldr r0, =WDT_WDDIS<br />
str r0, [r1, #WDT_MR_OFF]</pre><br />
If the last line looks strange, you should become familiar with it. It instructs the CPU to store the contents of register r0 into the memory location contained in register r1 plus a fixed offset WDT_MR_OFF.<br />
<br />
You want to do something more useful like clearing the .bss segment? No problem.<br />
<br />
<pre class="coding"> ldr r0, =0<br />
ldr r1, =__bss_start<br />
ldr r2, =__bss_end<br />
clrnxt: cmp r1, r2<br />
strne r0, [r1], #4<br />
bne clrnxt</pre><br />
Nothing new in the first three lines, at least not instruction-wise. The fourth line compares the contents of registers r1 and r2 and sets or clears specific bits in the CPU status register. The next statement is a variation of our ''str'' instruction we already used above. The contents of register r0 will be stored in memory location pointed to by register r1. The trailing part ''#4'' is a really nice feature. It will automatically increment the pointer register r1 by 4 (bytes) after the value had been stored. So it will then point to the next 32-bit memory location. The other modification is ''strne'' instead of ''str''. It is still an str instruction, but it is executed only, if the ''equal flag'' in the status register is not set. In other words, if the cmp instruction figures out, that r1 and r2 are not equal, then the str instruction is executed. Otherwise this instruction is skipped.<br />
<br />
The last instruction is new, but contains a known part. The branch instruction ''b'' is similar to goto in C, it will jump to the specified label. If ''ne'' is appended, it will work in the same way as with ''str''. The branch is executed only, if the last compare was done with unequal values.<br />
<br />
The full picture is, that we created a loop, which clears all 32-bit memory locations starting at __bss_start up to but not including __bss_end. If you are wondering, where __bss_start and __bss_end are defined, you are perfectly right. We have to add them to the linker script.<br />
<br />
<pre class="coding">.bss :<br />
{<br />
__bss_start = .;<br />
*(.bss)<br />
*(COMMON)<br />
__bss_end = .;<br />
} &gt; ram</pre><br />
Are you puzzled? We have more. The following code snippet moves the contents of the .data segment from Flash to RAM:<br />
<br />
<pre class="coding"> ldr r1, =__etext<br />
ldr r2, =__data_start<br />
ldr r3, =__data_end<br />
1: cmp r2, r3<br />
ldrlo r0, [r1], #4<br />
strlo r0, [r2], #4<br />
blo 1b</pre><br />
The first three lines load registers in a familiar way. Register r1 is used as a pointer into Flash memory, r2 as a pointer into RAM. Register r3 contains the loop end value. Instead of the ''ne'' (if not equal) modifier, we use ''lo'' (if lower) this time. Just for not to become boring, the result is the same.<br />
<br />
The only really new feature is the branch instruction, more precisely the label. The GNU assembler allows to use numeric labels. Unlike labels in C, they may be re-used in the same source file as often as you like. When referencing a numeric label, you append either ''b'' (backward) or ''f'' (forward) to refer to the previous or next label with the specified numeric value.<br />
<br />
I leave it to you as an exercise to figure out, how to define the symbols __etext, __data_start and __data_end in the linker script.<br />
<br />
OK, I agree, we just scratched the surface. One cannot learn ARM assembly in a few minutes, but you got a head start.<br />
<br />
For C programmers I have a valuable hint. If you need a more complicated initialization routine and can't get it working in assembly language, why not program it in C? Actually it might be even possible to call your C routine from existing initialization code written in assembly language. But be aware of traps. In early stages there may be no stack available and variables may not be initialized or located in memory areas, which are not yet available. Additional things may be needed to stop the compiler from optimizing out essential parts like delay loops. Under such circumstances, writing C routines will become a nightmare. Anyway, write it, compile it, preferably with optimization switched off, and then look into the compiler listing. Nut/OS default compile options instructs the compiler to include assembly instructions in the listing. You can use them as a template for your first assembly routine. Its definitely worth the effort.<br />
<br />
== Loading and running code in RAM ==<br />
<br />
As mentioned previously, during debugging, it is preferred to directly load the binary image into and start execution in RAM. Typically, the image will be uploaded to the target via JTAG. Another possibility is to use a boot loader, which may load the application binary from serial or NAND Flash, over an RS-232 or network interface, from SD-Card etc. In all these cases the linker will simply place all segments in the same memory device.<br />
<br />
This is (a simplified) linker script for the Elektor Internet Radio (EIR):<br />
<br />
<pre class="coding">MEMORY<br />
{<br />
xram : org = 0x20000000, len = 256M<br />
}<br />
<br />
SECTIONS<br />
{<br />
.text:<br />
{<br />
*(.vectors);<br />
*(.init);<br />
*(.text);<br />
*(.rodata);<br />
*(.data);<br />
__bss_start = .;<br />
*(.bss)<br />
*(COMMON)<br />
__bss_end = .;<br />
} &gt; xram<br />
}</pre><br />
The full script is available in nut/arch/arm/ldscripts/at91sam7se512_xram.ld.<br />
<br />
There is no need to initialize variables in the startup code, because their values will be directly loaded into the right place. Note, that it is still necessary to clear the .bss and COMMON segments.<br />
<br />
When loading the code into internal SRAM, the loader (JTAG or boot loader) can be quite simple. All required hardware initialization may be done in the application code. Actually, I recommended to do it the other way round, keeping the application's startup code simple and let the loader to all the hardware initialization. How to do this with JTAG uploading for Ethernut 5 is explained [[../hardware/enut5/openocd.html|on this page]]. The advantage is, that you can interactively try various settings by using the [http://openocd.sourceforge.net/ OpenOCD] TELNET interface, without time consuming edit-compile-link-upload-cycles. The advantage with letting boot loaders do the work is, that they are typically long living, reliable parts that do not require much updating. If you ever had to modify an old firmware application, which built fine with the toolchain available at that time, but refuses to cooperate with the latest tools, you know what I'm talking about. In these cases it is good to know, that the old boot loader will at least make sure, that the hardware is properly initialized.<br />
<br />
Typical applications will not fit in the internal 32k SRAM of the EIR. The linker script sample given above is made for code running in external SDRAM. In this case the JTAG tool or the boot loader must first enable the external bus interface and initialize the SDRAM chips, which in turn may require to initialize the CPU clocks as well. Anyway, our linker script and startup code remains the same.<br />
<br />
For performance reasons you may want to run some routines in internal RAM, which provides 32-bit access without waitstates. When uploading binaries in ''elf'' or ''hex'' format, this is no big deal. Following the current Nut/OS conventions, you declare such functions as<br />
<br />
<pre class="coding">RAMFUNC void MyFastCode(int xlen);</pre><br />
The compiler will put this function in a new segment named .ramfunc and we extend the linker script by a new section .fast, which will be loaded into internal RAM.<br />
<br />
<pre class="coding">MEMORY<br />
{<br />
iram : org = 0x00200000, len = 32k<br />
xram : org = 0x20000000, len = 256M<br />
}<br />
<br />
SECTIONS<br />
{<br />
.text:<br />
{<br />
*(.vectors);<br />
*(.init);<br />
*(.text);<br />
*(.rodata);<br />
*(.data);<br />
__bss_start = .;<br />
*(.bss)<br />
*(COMMON)<br />
__bss_end = .;<br />
} &gt; xram<br />
<br />
.fast:<br />
{<br />
*(.ramfunc);<br />
} &gt; iram<br />
}</pre><br />
Things are not always going into the right direction, though. When calling the default make procedure to build your application, you will notice, that it takes much longer than usual. having a look into the application's build directory, you will further notice, that the application's ''.bin'' file has become large, extremely large.<br />
<br />
The cause is, that binary files do not allow gaps. While hex and elf formats contain address information, bin files are simple raw images. In our case, the gap between internal RAM and external SDRAM (about 500MB) will be filled with zeroes. To solve this, you may either exclude the ''.bin'' file from the build or place the .ramfunc segment in SDRAM and move it to the internal RAM in the startup code, as this is typically done with code running in Flash, demonstrated in the next chapter.<br />
<br />
== Running code in Flash ==<br />
<br />
When debugging and testing in RAM give you the impression, that your application is running stable, you may want to burn it into Flash memory, so it will start automatically when powering up the board. For this you need a different linker script and a new startup code as well.<br />
<br />
Here is a simplified script for the eNet-sam7X module:<br />
<br />
<pre class="coding">MEMORY<br />
{<br />
rom(rx) : org = 0x00000000, len = 512k<br />
ram(rw) : org = 0x00200000, len = 128k<br />
}<br />
<br />
SECTIONS<br />
{<br />
.text:<br />
{<br />
*(.vectors);<br />
*(.init);<br />
*(.text);<br />
*(.rodata);<br />
__etext = .;<br />
} &gt; rom<br />
<br />
.data : AT (__etext)<br />
{<br />
__data_start = .;<br />
*(.data)<br />
*(.ramfunc)<br />
__data_end = .;<br />
} &gt; ram<br />
<br />
.bss :<br />
{<br />
__bss_start = .;<br />
*(.bss)<br />
*(COMMON)<br />
__bss_end = .;<br />
} &gt; ram<br />
}</pre><br />
The full script is available in nut/arch/arm/ldscripts/at91sam7x512_rom.ld.<br />
<br />
If you were able to follow the previous chapters, you won't find many new items here. But notethe .ramfunc segment, which is included together with the .data segment in the .data section. This whole section will have to be copied from Flash to RAM by the runtime initialization, which uses the symbols __etext, __data_start and __data_end. Furthermore, the startup code will now have to deal with a virgin CPU, no loader was involved. That means, that CPU clocks, watchdog timer, reset controller and possibly other essential hardware functions must be properly configured in the startup code.<br />
<br />
== Loading or running code elsewhere ==<br />
<br />
You are probably able to think about other combinations of memory usage. But do they make sense? Of course, they do. Let's have a look to Ethernut 3, which has been designed for time critical applications in mind.<br />
<br />
On this board we have slow, 16-bit NOR Flash and a large internal SRAM with 32-bit access and no wait states, running applications at about 74 MIPS on a low power ARM7TDMI. During development, a bootloader running in Flash memory will load the application via TFTP into internal RAM. This is quite convenient and many developers miss it when moving to a different target without TFTP boot loader. All hardware initialization is done in the boot loader and the binary images are linked for execution and variable storage in RAM. Naturally, the related linker script and the startup code are quite simple.<br />
<br />
For the final system, the same binary image can be used. This time, the image will be placed in NOR Flash, somewhere above the boot loader code. When started, the boot loader will first check this area and, if a valid image is found, it will move it to RAM ans start it, instead of initiating the TFTP transfer.<br />
<br />
In both cases, the boot loader may be interrupted via RS-232, where it offers a simple dialog to change essential system settings like the IP address etc. When shipping your application to the final customer, this is not always what you want. The alternative is, to overwrite the boot loader with your application, so that it will be started immediately on power up.<br />
<br />
No question, this requires a different linker script and startup code, because no boot loader will take care about early hardware initialization anymore. Your application can still run at full speed in internal RAM. Nut/OS offers a special script/code combination, where the application code moves itself from Flash to RAM during runtime initialization.<br />
<br />
Although 256kB RAM is a lot for Nut/OS, large application may not fit. For example, the UROM file system for HTML contents is wasting valuable resources when located in RAM. Thus, it makes sense to use a different linker script, which places the .rodata segment in Flash.<br />
<br />
But even the executable code may grow further, making the 4MB of Flash memory attractive for functions, which need not to run that fast. For this we may create a new ''.slow'' segment, which is excluded from the loop that moves the application to RAM.<br />
<br />
Luckily, all these requirements and much more can be achieved with a specialized linker script and its related runtime initialization.<br />
<br />
== What should be offered in the future? ==<br />
<br />
The number of supported targets is constantly growing. If we want to cover all kind of memory layouts, the number of linker scripts will grow multiple times. Right now, the Configurator will offer all scripts to the user, even if they don't make sense for his platform. This can be limited by some smart Lua scripts.<br />
<br />
However, the real problem is maintenance. From time to time new features are added to Nut/OS, which may require a change in almost all linker scripts. Similar problems sometimes appear, when upgrading the compiler or the runtime library. If the maintainer is not familiar with the specific platform, he may introduce unforeseen problems. Beside that, the sheer number of linker scripts makes changes in this area a time consuming and error-prone business.<br />
<br />
When looking into the scripts, you will notice, that most of the code is just copied from other scripts, including outdated comments, bad style and other odds. With big (virtual) letters above all: Never touch a running systems. No wonder, that Nut/OS developers shy away from modifications in this area.<br />
<br />
One proposal to solve this, might be the C preprocessor. Instead of selecting a ready-to-use linker script, one may be created based on the user's configuration. The final linker script can be defined as a make target, and make will then initiate the preprocessor to create it, based on some templates and configuration files.<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Ethernet_Boot_Loaders_for_AVREthernet Boot Loaders for AVR2017-07-13T08:37:31Z<p>Harald: Created page with "The Ethernet boot loaders for the AVR based Ethernut boards fit into the upper section of the program memory and use DHCP and TFPT over Ethernet to download an application cod..."</p>
<hr />
<div>The Ethernet boot loaders for the AVR based Ethernut boards fit into the upper section of the program memory and use DHCP and TFPT over Ethernet to download an application code into the ATmega128 flash ROM. They are intended as a replacement for the ISP programming dongle and update a 14 MHz ATmega128 in about 4 seconds or less.<br />
<br />
The boot loader will be stored in upper program memory, while the application starts at address zero. By modifying the AVR's internal fuses, it is possible to start the boot loader on system reset, which may then upload a new application binary at address zero and run it by jumping at this location.<br />
<br />
There are two versions of the boot loader. One is called eboot and works with Ethernut 1 or any other board with a RTL8019AS controller. The second one is called appload and supports the LAN91C111 controller, which is used on the Ethernut 2 board.<br />
<br />
== Important Warnings ==<br />
<br />
'''1.''' According to the datasheet, the ATmega128 flash memory has an endurance of 10,000 write/erase cycles. Using a boot loader may wear out the flash memory. Fatal programming errors may reset your CPU, reloading the bad code over and over again and finally destroying your flash ROM.<br />
<br />
'''2.''' Playing around with the fuse bits may disable your CPU. Do not change any of these bits unless you know what you do. There is some confusion about the terms programmed, unprogrammed, set, cleared, enabled or disabled. We will use terms given in the datasheet, programmed to 0 and unprogrammed to 1.<br />
<br />
'''3.''' The boot loader uses the TFTP protocol, which is known to be insecure. When attached to a public network, do not enable TFTP write access on your computer without further access restrictions. For the boot loader you can limit TFTP read access to a single directory only.<br />
<br />
Are these warnings scaring you? That's fine. So you are aware of the risks and will take precautions to avoid damage.<br />
<br />
== Ethernut 1 Boot Loader ==<br />
<br />
A precompiled binary of the eboot boot loader is available on the [[../hardware/enut1/index.html|Ethernut 1 hardware page]]. To transfer the binary to the target board, several tools are available for [[../tools/in-system-programming.html|in-system programming]]. The following command can be used with AVRDUDE and any STK500v2 compatible programming adapter like the SP Duo.<br />
<br />
<div class="coding"><br />
<br />
<pre>avrdude -p m128 -P com2 -c stk500v2 -V -U flash:w:eboot.hex</pre><br />
<br />
</div><br />
This will also completely erase the flash memory. If the boot loader should be added to an application, which has been already programmed into flash memory, then add the option -D.<br />
If you plan to integrate the boot loader into your final Ethernut based product, you may need to modify the source code and build a new binary. Unfortunately the source code include in Nut/OS 4.8 will not work with the latest avr-gcc compiler, because the stack pointer will no longer be initialized when entering the main routine.<br />
<br />
A new version 2 of the boot loader is available, which offers several enhancements and corrections.<br />
<br />
* Works again with the latest compilers.<br />
* Optionally uses network settings stored in EEPROM.<br />
* Optionally uses TFTP settings stored in EEPROM.<br />
<br />
[[../../arc/eboot20-src.zip|eboot20-src.zip]]<br /><br />
This archive contains the enhanced version of the eboot boot loader.<br /><br />
[[../../arc/eboot20-bin.zip|eboot20-bin.zip]]<br /><br />
Precompiled binaries (bin and hex) of the above, located at word address 0xF000.<br />
<br />
You can disable or enable a few options by editing the DEFS entries in the Makedefs file.<br />
<br />
<ul><br />
<li>DEFS += -DEE_CONFNET=64<br /><br />
Specifies the EEPROM address of the network configuration. 64 is the default, which is also used by Nut/OS applications unless you modified the settings in the Configurator. If this line is commented out, then the bootloader will try to get all information from the DHCP server. Additional information about Nut/OS network settings are available in the [[../../pdf/enswm28e.pdf|Nut/OS Software Manual]].</li><br />
<li>DEFS += -DEE_CONFBOOT=256<br /><br />
Specifies the EEPROM start address of the TFTP configuration. Make sure, that this area is not used by you application code. The required size mainly depends on the CONFBOOT structure, defined in config.h.<br />
<div class="coding"><br />
<br />
<pre>struct _CONFBOOT {<br />
u_char cb_size;<br />
u_char cb_flags;<br />
u_long cb_tftp_ip;<br />
u_char cb_image[128];<br />
};</pre><br />
<br />
</div><br />
If you do not need 128 bytes for the name of the boot image file, you can reduce the size of cb_image. A sample application, which will create a valid entry for the boot loader, is given below. If this line is commented out, then the bootloader expects this information from the DHCP server.</li><br />
<li>DEFS += -DNUTDEBUG<br /><br />
Enables debug output on UART0 using 115200 baud on an ATmega running at 14.745 MHz. This will be helpful, if you modifications are not working as expected. The following routines are available:<br />
<div class="coding"><br />
<br />
<pre>DEBUG(char *); /* Prints out a string. */<br />
DEBUGUSHORT(unsigned short); /* Prints out a short value in hex format. */<br />
DEBUGULONG(unsigned long); /* Prints out a long value in hex format. */</pre><br />
<br />
</div></li></ul><br />
<br />
== Ethernut 2 Boot Loader ==<br />
<br />
You can download a precompiled binary of the appload boot loader from the [[../hardware/enut2/index.html|Ethernut 2 hardware page]]. It is quite similar to the eboot boot loader for Ethernut 1.<br />
<br />
The source code is included in the Nut/OS distribution. Like the Ethernut 1 boot loader, this one may fail when compiled with the latest avr-gcc versions. Make sure that the following lines are available in the file start.S:<br />
<br />
<div class="coding"><br />
<br />
<pre>ldi r18, lo8(RAMEND)<br />
out _SFR_IO_ADDR(SPL), r18<br />
ldi r18, hi8(RAMEND)<br />
out _SFR_IO_ADDR(SPH), r18</pre><br />
<br />
</div><br />
If they are commented out by leading semicolons, simply remove them.<br />
== Creating Bootable Applications ==<br />
<br />
Without a boot loader, your application code is compiled and linked into Intel or Motorola hex files, which are then uploaded via [[../tools/in-system-programming.html|in-system programming]] to the target board. These hex files (file extension hex) contain address information and therefore allow to upload code to any location.<br />
<br />
In contrary, the AVR boot loaders need pure binary images (file extension bin), which are always stored at the beginning of the flash memory area. Usually the command 'make clean all' will produce both, Intel hex and pure binaries. Otherwise you may try 'make appname.bin' or directly use avr-objcopy<br />
<br />
<div class="coding"><br />
<br />
<pre>avr-objcopy -O binary appname.elf appname.bin</pre><br />
<br />
</div><br />
The ImageCraft compiler doesn't provide anything to create raw binary files for the boot loader. Fortunately a simple tool named robi can be integrated into the ICCAVR IDE to take over this task.<br />
<br />
[[../../arc/robi.zip|Download robi]], unpack the archive and move robi.exe to a directory of your choice, preferably your ICCAVR bin directory or any directory included in your PATH environment variable.<br />
<br />
[[File:../../img/tftpiccmain.gif]]<br />
<br />
Start the ImageCraft IDE, load the appliocation's project and select Project Options from the main menu to open the compiler options dialog. Select the compiler tab and enter the command shown to be executed after a successful build.<br />
<br />
[[File:../../img/tftpiccrobi.gif]]<br />
<br />
Each time you build your project, the following output will additionally appear in the IDE status window.<br />
<br />
[[File:../../img/tftpiccbuild.gif]]<br />
<br />
The robi utility converts the hex file containing the application code to a raw image and stores it in the base directory of TFTPD.<br />
<br />
== Ethernut Setup ==<br />
<br />
First you need to upload the boot loader hex file to the Ethernut board using an ISP adapter. Unfortunately a few old programming tools are able to upload a hex file to the upper half of the flash ROM. Make sure, that the upload has been successful by reading back the flash contents. Depending on the size of the boot loader binary, its code should start at byte addresses 0x1E000 or 0x1F000, which is equivalent to word address 0xF000 or 0xF800 resp.<br />
<br />
After uploading the boot loader, you need to modify the ATmega128 fuses. The following three fuse bits of the ATmega128 fuse high byte need to be set to the specified values.<br />
<br />
{|<br />
|width="33%"| '''Bit'''<br />
|width="33%"| '''Fuse'''<br />
|width="33%"| '''Description'''<br />
|-<br />
| 2<br />
| BOOTSZ1<br />
| Program to 0 to select the bootloader size of 4 or 8 kBytes<br />
|-<br />
| 1<br />
| BOOTSZ0<br />
| Unprogram to 1 to select the bootloader size of 4 kBytes or program to 0 to select the bootloader size of 8 kBytes<br />
|-<br />
| 0<br />
| BOOTRST<br />
| Program to 0 to force the CPU to jump to the boot loader upon reset<br />
|}<br />
<br />
On AVR Studio use this selection with a boot loader size of 4 kBytes:<br />
<br />
[[File:../../img/bootfuses.gif]]<br />
<br />
== TFTP Server Setup ==<br />
<br />
When the boot loader starts, it will connect the DHCP server first to load query its network configuration. This may include the IP adress of the TFTP server and the name of the boot image to load from this server. As explained, the latest boot loader are able to read these settings from EEPROM as well.<br />
<br />
While DHCP is a common network service, TFTP may not be available. On Linux, it is part of the OS, but it may not be enabled by default. Please refer to your Linux manual or related online sources. The mini-howtos at [http://www.linux.org/ www.linux.org] will be a good starting point.<br />
<br />
For Windows PCs Philippe Jounin's [http://tftpd32.jounin.net/ TFTPD32] is the recommended solution, which we will now explain in more detail.<br />
<br />
After having installed and started TFTPD32<br />
<br />
[[File:../../img/tftpdstart.gif]]<br />
<br />
click on the button labeled Settings. This will open a new dialog window.<br />
<br />
[[File:../../img/tftpsettings.gif]]<br />
<br />
Select the options shown in the picture above. Your base directory may differ. Click on the browse button to select the subdirectory bin/atmega128 of your Nut/OS installation. Finally click OK and restart TFTPD32.<br />
<br />
Now it is required to configure the DHCP server. Select the DHCP server tab.<br />
<br />
[[File:../../img/tftpdhcptab.gif]]<br />
<br />
If more than one network interface has been installed on your computer, you can select the server interface your Ethernut board is connected to.<br />
<br />
The Ethernet boot loader will request an IP address from the DHCP pool. Enter the IP pool starting address and the number of available addresses in the pool. The sample above will offer IP addresses from 192.168.192.100 upto and including 192.168.192.109.<br />
<br />
The boot file is the name of the raw binary image of the application you want to upload to the Ethernut board. When using WinAVR (AVRGCC), you simply enter make install on the command line. This will automatically compile and link your code and copy the resulting hex file and binary file to the subdirectory bin/atmega128. ICCAVR is not able to create raw binary images. A tool named robi has been created, which will be explained later.<br />
<br />
There's no need to specify a WINS/DNS server address or default router unless your Ethernut application requires direct Internet access. In case it does, you probably know what to enter.<br />
<br />
Make sure that the network mask and the IP pool addresses fit your local network configuration.<br />
<br />
Finally press Save to let TFTPD32 store the values in the Windows registry and select the Tftp Server tab to return to the initial window. Now press the reset switch on your Ethernut board an watch the magic things happening.<br />
<br />
[[File:../../img/tftpreboot.gif]]<br />
<br />
Ethernut will immediately jump to the boot loader, which broadcasts a DHCP request to the network. TFTPD32 will offer the first IP address from the pool and provide additional network information, including the file name of the boot image. In turn, Ethernut will request this file from the TFTP server, burn it into its program flash and finally jump to program memory address 0x0000 to execute the newly loaded application.<br />
<br />
== Creating Upgradeable Applications ==<br />
<br />
While the Ethernet boot loader is very convenient during development, it can be used as well in the field to update the application code.<br />
<br />
[[../../arc/testnetupd.zip|testnetupd.zip]]<br /><br />
This archive contains precompiled binaries for Ethernut 1 and the source code, which can be used to create a binary for Ethernut 2. And, most important, you may use this code to implement it into your application. Of course your requirements may differ. For example, you may keep the BOOTRST fuse unprogrammed and always jump to the boot loader from within your application. Furthermore, your application may use a different ways to initiate the a firmware upgrade. In any case our sample application will provide a helpful starting point.<br />
<br />
When started, the sample code will produce the following output at the serial port:<br />
<br />
<div class="coding"><br />
<br />
<pre>Network Update Test 2.0 running on Nut/OS 4.9.9.0<br />
Opening line editor...OK<br />
<br />
TFTP Server IP: 0.0.0.0<br />
Boot Image : &quot;&quot;<br />
<br />
L - Load boot configuration<br />
E - Enter boot configuration<br />
S - Save boot configuration<br />
D - Delete boot configuration<br />
R - Reset system<br />
J - Jump to boot loader</pre><br />
<br />
</div><br />
and wait for any entry.<br />
<br />
<br />
* Press L<br /><br />
to read the TFTP configuration (the CONFBOOT structure we explained above) from EEPROM. This is done on program start anyway, but may be used to discard any modifications.<br />
* Press E<br /><br />
to enter the IP address of the TFTP server and the name of the image file to boot. Note, that your entry will not be written back to EEPROM unless you ...<br />
* Press S<br /><br />
to save the current TFTP configuration in EEPROM.<br />
* Press D<br /><br />
to delete the TFTP configuration. With an empty configuration, the boot loader will try to get this information from DHCP. If DHCP doesn't offer it, then the boot loader will start the application that is currently stored in flash memory.<br />
* Press R<br /><br />
to reset the Ethernut board. The application will call NutReset, which will enable the watchdog timer hardware and let it time out. This is usually the most reliable way to restart an AVR.<br />
* Press J<br /><br />
to directly jump in to the boot loader code.<br />
<br />
Upgrading the firmware can become tricky, specifically when the boot loading process fails. Imagine a power failure during the TFTP transfer, which leaves the program memory with partly old and partly upgraded areas. Most probably, your application will crash when started. If it uses the hardware watchdog, you may be lucky and the system reset will initiate the boot loader again.<br />
<br />
A more advanced upgrade method may use a CRC to verify, that the loaded boot image is valid. The boot loader may not return to the application, if the CRC check fails. To make this work, not only the code of the boot loader must be changed, you also must create special images, where the CRC is included. An even more advanced method may use encrypted images. Whatever, you should make sure, that an interrupted firmware upgrade will not end up with a dead system.<br />
<br />
If enough additional memory is available, like serial Dataflash or RAM on Ethernut 2, you may not need an Ethernet boot loader at all. Instead you can load a new image from within your application (e.g. web upload) into the Dataflash and then use a much simpler boot loader to move this image from the Dataflash to program flash. You will only do this, if you are sure that the image is complete and valid.<br />
<br />
== To Do List ==<br />
<br />
* The boot loader may update the Nut/OS EEPROM configuration.<br />
* Flash contents should be verified after programming.<br />
* Possibly add PPP support.<br />
* Temporarily store received image in RAM and start programming the flash after upload has been successfully completed.<br />
<br />
== Links ==<br />
<br />
More information about BOOTP and DHCP is available at [http://www.dhcp.org/ www.dhcp.org]</div>Haraldhttp://www.ethernut.de/nutwiki/index.php/DownloadDownload2017-07-13T08:36:33Z<p>Harald: Created page with "<div id="content"> = Nut/OS Downloads = [http://sourceforge.net/projects/ethernut File:http://sflogo.sourceforge.net/sflogo.php?group_id=34079&type=10|80x15px|Get Ethernut..."</p>
<hr />
<div><div id="content"><br />
<br />
= Nut/OS Downloads =<br />
<br />
[http://sourceforge.net/projects/ethernut [[File:http://sflogo.sourceforge.net/sflogo.php?group_id=34079&type=10|80x15px|Get Ethernut Embedded Ethernet at SourceForge.net. Fast, secure and Free Open Source software downloads]]]<br />
== Stable Version 5.1 ==<br />
<br />
[http://sourceforge.net/projects/ethernut/files/ethernut/5.1%20stable/ethernut-5.1.0-1.exe/download ethernut-5.1.0-1.exe]<br /><br />
Executable installation for Windows PCs.<br />
<br />
[http://sourceforge.net/projects/ethernut/files/ethernut/5.1%20stable/ethernut-5.1.0-1.tar.gz/download ethernut-5.1.0-1.tar.gz]<br /><br />
Source code package for Linux and OS X. More details are available [[../documents/debian.html|here]].<br />
<br />
== Latest Beta Version ==<br />
<br />
[http://sourceforge.net/projects/ethernut/files/ethernut/5.2%20beta/ethernut-5.2.4-1.exe/download ethernut-5.2.4.exe]<br /><br />
Executable installation for Windows PCs.<br />
<br />
[http://sourceforge.net/projects/ethernut/files/ethernut/5.2%20beta/ethernut-5.2.4.tar.gz/download ethernut-5.2.4.tar.gz]<br /><br />
Source code package for Linux and OS X. More details are available [[../documents/debian.html|here]].<br />
<br />
== Code Repository ==<br />
<br />
The cutting edge development version is available in an Apache Subversion repository at [http://ethernut.svn.sourceforge.net/viewvc/ethernut/trunk/ ethernut.svn.sourceforge.net].<br />
<br />
If you like to work locally with Git on the Subversion repository, get the bare repository at [http://sourceforge.net/projects/ethernut/files/ethernut-code.git.tar.gz/download ethernut-code.git.tar.gz.]<br /><br />
Unpack the tar file with<br />
<br />
<pre class="coding">tar fxz ethernut-code.git.tar.gz</pre><br />
change to the Ethernut code directory with<br />
<pre class="coding">cd ethernut-code</pre><br />
and checkout the files<br />
<pre class="coding">git checkout -- .</pre><br />
You can stay up to date with<br />
<pre class="coding">git svn rebase</pre><br />
== Previous Releases ==<br />
<br />
Versions, which are no longer maintained, can be downloaded from the [[../../arc/|archive]].<br />
<br />
'''Note! Binary code created from version 5.0.4 beta for Cortex-M may contain code with the following license:'''<br />
<br />
<pre>Copyright (c) 2005-2009 Luminary Micro, Inc. All rights reserved.<br />
Software License Agreement<br />
<br />
Luminary Micro, Inc. (LMI) is supplying this software for use solely and<br />
exclusively on LMI's microcontroller products.<br />
<br />
The software is owned by LMI and/or its suppliers, and is protected under<br />
applicable copyright laws. All rights are reserved. You may not combine<br />
this software with &quot;viral&quot; open-source software in order to form a larger<br />
program. Any use in violation of the foregoing restrictions may subject<br />
the user to criminal sanctions under applicable laws, as well as to civil<br />
liability for the breach of the terms and conditions of this license.</pre><br />
'''We have removed this version.'''<br />
<br />
= Toolchains =<br />
<br />
== AVR 8-Bit Cross Development ==<br />
<br />
=== Debian Packages ===<br />
<br />
[http://packages.debian.org packages.debian.org]<br /><br />
Debian official packages.<br />
<br />
=== Windows Installer ===<br />
<br />
[http://winavr.sourceforge.net WinAVR]<br /><br />
is a complete Win32 installation package, which contains the AVR-GCC compiler and many additional tools.<br />
<br />
== AVR32 Cross Development ==<br />
<br />
[http://www.atmel.com/dyn/Products/tools_card.asp?tool_id=4118 AVR32 GNU Toolchain]<br /><br />
Atmel offers free development environments for PCs running Linux and Windows.<br />
<br />
== ARM Cross Development ==<br />
<br />
=== Debian Packages ===<br />
<br />
[[../../arc/arm-elf-binutils_2.19.1_i386.deb|GNU binary utilities for arm-elf cross development]]<br /><br />
This package is a collection of utilities required for the assembly, linking, symbol dumping, object dumping, object copying and other operations for position independent code on ARM targets using the ELF file format.<br />
<br />
[[../../arc/arm-elf-gcc_4.3.3_i386.deb|GNU C compiler for arm-elf cross development]]<br /><br />
GNU C cross compiler for ARM targets using the ELF file format.<br />
<br />
[[../../arc/arm-elf-gdb_6.8_i386.deb|GNU debugger for arm-elf cross development]]<br /><br />
GNU debugger, configured for remote debugging of ARM targets using the ELF file format.<br />
<br />
[[../../arc/arm-elf-newlib_1.17.0_i386.deb|Standard C library for arm-elf cross development]]<br /><br />
This C library intended for use on ARM targets using the ELF file format. Newlib is a conglomeration of several library parts, all under free software licenses that make them easily usable on embedded products.<br />
<br />
=== Windows and Mac OS X ===<br />
<br />
[http://www.yagarto.de/ YAGARTO]<br /><br />
is the recommended toolchain for 32-bit ARM targets.<br />
<br />
== Ethernut 5 Specific ==<br />
<br />
[[../../arc/en5flasher-20130719.zip|en5flasher-20130719.zip]]<br /><br />
Automagic Flasher for Ethernut 5, described on [[../../en/hardware/enut5/boot.html|this page]]. This release of the Linux kernel 3.8.8 additionally contains the binary images of SAMBoot and U-Boot-2013.01.01.<br />
<br />
[[../../arc/ethernut5-image-20130604.zip|ethernut5-image-20130604.zip]]<br /><br />
Ethernut 5 root file system image for Linux 3.8.8, built with Yocto 1.4.<br />
<br />
[[../../arc/meta-egnite-20130531.tar.bz2|meta-egnite-20130531.tar.bz2]]<br /><br />
[[../../arc/build-ethernut5-3.8-20130531.tar.bz2|build-ethernut5-3.8-20130531.tar.bz2]]<br /><br />
Files needed to build [[../../en/hardware/enut5/yocto.html|Yocto]] for Ethernut 5.<br />
<br />
[[../../arc/en5pwrman-20110610.zip|en5pwrman-20110610.zip]]<br /><br />
Power management firmware for Ethernut 5, mentioned at the end of [[../../en/hardware/enut5/boot.html|this page]].<br />
<br />
=== Previous Releases ===<br />
<br />
[[../../arc/en5flasher-20120308.zip|en5flasher-20120308.zip]]<br /><br />
Automagic Flasher für Ethernut 5, described on [[../../en/hardware/enut5/boot.html|this page]]. This first release of the Linux kernel 3.2.9 additionally contains the binary images of SAMBoot and U-Boot-2011.03.<br />
<br />
[[../../arc/console-image-ethernut5-20120308.zip|console-image-ethernut5-20120308.zip]]<br /><br />
First release of the Ethernut 5 Linux root file system image for kernel 3.2.9. Should be installed in conjunction with en5flasher-20120308.zip.<br />
<br />
[[../../arc/en5flasher-20120305.zip|en5flasher-20120305.zip]]<br /><br />
Automagic Flasher für Ethernut 5, described on [[../../en/hardware/enut5/boot.html|this page]]. This second release for Linux 2.6.37 contains the binary images of SAMBoot, U-Boot-2011.03 and Linux kernel. The latter now supports USB memory sticks and cameras, PPP over UMTS/GPRS, GPS mice and more. The kernel now runs with data cache enabled.<br />
<br />
[[../../arc/console-image-ethernut5-20120305.zip|console-image-ethernut5-20120305.zip]]<br /><br />
Second release of the Ethernut 5 Linux root file system image. Should be installed in conjunction with en5flasher-20120305.zip.<br />
<br />
[[../../arc/egnite-oe-overlay-r2.tar.bz2|egnite-oe-overlay-r2.tar.bz2]]<br /><br />
[[../../arc/egnite-oe-build-2.6.37-r2.tar.bz2|egnite-oe-build-2.6.37-r2.tar.bz2]]<br /><br />
[[../../en/hardware/enut5/angstrom.html|OpenEmbedded overlays]] to build U-Boot, Linux and a root filesystem for Ethernut 5.<br />
<br />
[[../../arc/en5flasher-20110610.zip|en5flasher-20110610.zip]]<br /><br />
Automagic flasher for Ethernut 5, described [[../../en/hardware/enut5/boot.html|this page]].<br />
<br />
[[../../arc/console-image-ethernut5-20110525.zip|console-image-ethernut5-20110525.zip]]<br /><br />
Ethernut 5 Linux root file system image. Use this first version with en5flasher-20110610.zip.<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Documents/Win_InstallDocuments/Win Install2017-07-13T08:35:25Z<p>Harald: </p>
<hr />
<div><div id="content"><br />
<br />
= Installing Nut/OS on Windows =<br />
<br />
This document describes how to install the Nut/OS development environment on Windows.<br />
<br />
Linux/UNIX users should follow [[debian.html|this link]].<br />
<br />
== Requirements ==<br />
<br />
You will need<br />
<br />
* A PC running Windows NT, 2000, 2003 or XP. Other flavors may work as well.<br />
* If you want to build Nut/OS for the AVR target, you need to download WinAVR from the related project page at [http://winavr.sourceforge.net/ SourceForge]. WinAVR is based on the free GNU Compiler Collection for AVR. Here is a [[wininst.html|[[File:../../img/demo2.gif|16x16px|swf]] Shockwave Flash Demo]] of the installation.<br />
* If you intend to use Nut/OS with ARM targets, we recommend the GNU ARM Embedded Toolchain, which is available at [https://developer.arm.com/open-source/gnu-toolchain/gnu-rm ARMdeveloper].<br />
* As an alternative to the GNU Compilers mentioned above, you may consider to use the commercially supported Compilers from [http://www.imagecraft.com/software/ ImageCraft]. However, at the time of this writing, only the AVR compiler had been successfully tested with Nut/OS.<br />
* The executable Nut/OS installation package ethernut-x.y.z.exe (x.y.z to be replaced by the current version number). It is available at our [[../download/index.html|download page]]. Here is a [[nut440.html|[[File:../../img/demo2.gif|16x16px|swf]] Shockwave Flash Demo]] of the installation.<br />
<br />
The tools listed above will enable you to create Nut/OS libraries and final application binaries. A specific software and optional hardware is needed for uploading these binaries to the target board.<br />
<br />
* For the AVR platform, an [[../programmer/index.html|SPI or JTAG Programmer]] is required. The [[../isp/spduo.html|SP Duo]] comes with both interfaces, but doesn't provide debugging like the ATJTAGICE from [http://www.atmel.com/ Atmel].<br />
* Almost all ARM targets offer support for [[../hardware/enut3/jtag.html|JTAG Programming]]. Many of them even come with integrated boot loaders, in which case a standard PC cable (e.g. Ethernet, USB, RS232) is all you need on the hardware side.<br />
<br />
== Compiler Installation ==<br />
<br />
Nothing special is required for Nut/OS. Simply follow the installation instructions for [http://winavr.sourceforge.net/ WinAVR], [http://www.yagarto.de/ YAGARTO] or [http://www.imagecraft.com/software/ ImageCraft].<br />
<br />
== Nut/OS Installation ==<br />
<br />
The Nut/OS package for Windows is a self-extracting executable. Starting it, will present a language selection dialog.<br />
<br />
[[File:../../img/sam7x-inst01.png|Language Selection]]<br /><br />
<br />
Select either English or German. Other languages may be offered, but may not be fully supported. We will use English.<br />
<br />
The next dialog shows a welcome page with the Nut/OS version in the lower left corner.<br />
<br />
[[../../img/nut-inst02.png|[[File:../../img/nut-inst02h.png|487x356px|Welcome Page]]]]<br /><br />
<br />
Click '''Next &gt;'''.<br />
<br />
The following dialog can be used to install a subset of the package. Select '''Full''' and click '''Next &gt;'''.<br />
<br />
[[../../img/nut-inst03.png|[[File:../../img/nut-inst03h.png|487x356px|Component Page]]]]<br /><br />
<br />
Select '''Full''' if not already selected and click '''Next &gt;'''.<br />
<br />
Another dialog allows you to choose a destination folder.<br />
<br />
[[../../img/nut-inst04.png|[[File:../../img/nut-inst04h.png|487x356px|Destination Folder]]]]<br /><br />
<br />
Clicking on '''Install''' will copy the files to the selected folder.<br />
<br />
The following dialog shows the installation progress.<br />
<br />
[[../../img/nut-inst05.png|[[File:../../img/nut-inst05h.png|487x356px|Installation Progress]]]]<br /><br />
<br />
On the last dialog select '''Start Nut/OS Configurator''' and click '''Finish'''.<br />
<br />
[[../../img/nut-inst06.png|[[File:../../img/nut-inst06h.png|487x356px|Installation Completed]]]]<br /><br />
<br />
If everything went well, the installation terminates and the Nut/OS Configurator is started.<br />
<br />
The installation will have created several subdirectories in the destination folder.<br />
<br />
[[File:../../img/nut-inst07.png|Installation Result]]<br />
'''nut'''<br /><br />
Source tree. With the Configurator you will later create sibling directories called build trees (e.g. nutbld-mega256) and application trees (e.g. nutapp-ctrl). This way different Nut/OS configurations for different platforms can be derived from the same source tree and can be used concurrently.<br />
<br />
'''nut/app'''<br /><br />
[[Documents/Nut Apps|Sample applications]], from simple system event or timer tests to FTP and HTTP servers.<br />
<br />
'''nut/appicc'''<br /><br />
ImageCraft project templates for the sample applications.<br />
<br />
'''nut/arch'''<br /><br />
Architecture specific system code, device drivers, linker scripts, runtime initialization etc.<br />
<br />
'''nut/bin'''<br /><br />
Application binaries will be copied to this directory with 'make install'.<br />
<br />
'''nut/boot'''<br /><br />
Ethernut boot loaders.<br />
<br />
'''nut/c'''<br /><br />
Hardware independant C runtime routines. May be used for platforms without libc, but not used with the compilers listed above, as they provide their own.<br />
<br />
'''nut/conf'''<br /><br />
Nut/OS configuration scripts, used by the Configurator.<br />
<br />
'''nut/cpp'''<br /><br />
C++ support, probably limited.<br />
<br />
'''nut/crt'''<br /><br />
Hardware dependant C runtime routines, mainly I/O and date/time.<br />
<br />
'''nut/dev'''<br /><br />
Device drivers, which are configurable for all platforms. These are just a few. Most drivers are not yet portable and are therefore located in nut/arch.<br />
<br />
'''nut/doc'''<br /><br />
API documentation including copyright statements.<br />
<br />
'''nut/fs'''<br /><br />
Nut/OS file systems.<br />
<br />
'''nut/include'''<br /><br />
Collection of all C header files, which are related to Nut/OS source files. You compiler may provide similar, in which case it is important, that this directory is searched first.<br />
<br />
'''nut/lib'''<br /><br />
Pre-build Nut/OS libraries. You may try these, if your compiler somehow fails to create them.<br />
<br />
'''nut/net'''<br /><br />
Network related code. The TCP/IP stack can be found here.<br />
<br />
'''nut/os'''<br /><br />
Nut/OS kernel code and some useful APIs, which are not really needed by the kernel.<br />
<br />
'''nut/pro'''<br /><br />
High level network code, like DHCP, HTTP etc.<br />
<br />
'''nut/tools'''<br /><br />
Source code and binaries of various tools. Your PATH environment should point to nut\tools\win32 in the first place. For example, make.exe may be also included in your compiler package, but it may not work with the Nut/OS Makefiles, which sometimes use very specific features.<br />
<br />
A few main tools are not located in the tools directory, but in the application folder.<br />
<br />
'''nutconf.exe'''<br /><br />
Nut/OS Configurator. GUI tool to setup Nut/OS for your specific environment.<br />
<br />
'''nutconfigure.exe'''<br /><br />
Command line version of the Nut/OS Configurator. Useful for automatic builds and [[../tools/commandline.html|purists]].<br />
<br />
'''nutdisc.exe'''<br /><br />
This tiny utility is new with Nut/OS release 4.2. It scans local networks for Nut/OS nodes and allows to configure them remotely. Provided, that the application activates this service.<br />
<br />
== What's Next? ==<br />
<br />
You will now be able to build Nut/OS for your specific target hardware and test some of the sample applications. The following links will guide you.<br />
<br />
[[../../pdf/enswm28e.pdf|Nut/OS Software Manual]] (November 2005)<br /><br />
For Ethernut 1 and 2 and other ATmega based boards. Needs to be updated for Ethernut 3.<br />
<br />
[[atmega2561.html|Nut/OS on the ATmega2561]]<br /><br />
Requires the commercial ImageCraft Compiler.<br />
<br />
[[../portarm/gbaxport2.html|Nut/OS on the Gameboy Advance]]<br /><br />
Little bit outdated.<br />
<br />
[[at91sam7x256.html|Nut/OS on the AT91SAM7X256 EK]]<br /><br />
Atmel evaluation board.<br />
<br />
[[at91sam9260.html|Nut/OS on the AT91SAM9260 EK]]<br /><br />
Atmel evaluation board.<br />
<br />
[http://www.yagarto.de YAGARTO Projects]<br /><br />
Michael Fischer tried Nut/OS on the LPC2294 and the STR711.<br />
<br />
<br /><br />
<br /><br />
<br />
Good luck,<br /><br />
Harald Kipp<br /><br />
Castrop-Rauxel, 18th of October 2006<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Documents/Win_EclipseDocuments/Win Eclipse2017-07-13T08:34:38Z<p>Harald: Created page with "<div id="content"> = Using Eclipse with Nut/OS on Linux = == Requirements == This is work in progress and for ARM target boards only. It is assumed that you already instal..."</p>
<hr />
<div><div id="content"><br />
<br />
= Using Eclipse with Nut/OS on Linux =<br />
<br />
== Requirements ==<br />
<br />
This is work in progress and for ARM target boards only.<br />
<br />
It is assumed that you already installed Yagarto with Eclipse IDE and Nut/OS.<br />
<br />
== Creating An Eclipse Project ==<br />
<br />
Select '''Programs-&gt;YAGARTO IDE-&gt;Eclipse Platform 3.2''' from your Windows start menu.<br />
<br />
If started for the first time, the welcome screen will appear.<br />
<br />
[[File:../../img/eclipse-win01.png|Language Selection]]<br /><br />
<br />
Click on '''Workbench'''. If Eclipse didn't start with the welcome screen, then select '''Switch Workspace''' from the file menu.<br />
<br />
This will bring up the Workspace Launcher Dialog.<br />
<br />
[[File:../../img/eclipse-win02.png|Language Selection]]<br /><br />
<br />
You may choose any directory. Eclipse will store all workspace settings in this place.<br />
<br />
Click OK to return to the Eclipse main window, which shows the Resource Perspective.<br />
<br />
We will use Eclipse for the C language and should activate the C/C++ Perspective. Select '''Open Perspective-&gt;Other''' from the Window menu.<br />
<br />
[[File:../../img/eclipse-win03.png|Language Selection]]<br /><br />
<br />
Select the C/C++ Perspective and click OK.<br />
<br />
[[File:../../img/eclipse-win04.png|Language Selection]]<br /><br />
<br />
The Resource Perspective is not needed for C developments. Click on the Resource Tab with the right mouse button and select '''Close''' from the context menu.<br />
<br />
[[File:../../img/eclipse-win05.png|Language Selection]]<br /><br />
<br />
We will now create a new project. Select '''New-&gt;Standard Make C Project''' on the file menu.<br />
<br />
[[File:../../img/eclipse-win06.png|Language Selection]]<br /><br />
<br />
The New Project Dialog appears.<br />
<br />
[[File:../../img/eclipse-win06a.png|Language Selection]]<br /><br />
<br />
Enter the project name '''httpd'''.<br />
<br />
Instead of using the default loaction, we need to set the path to the Nut/OS application sample directory. Otherwise the relative paths used in the Nut/OS Makefiles won't work correctly.<br />
<br />
You can use the '''Browse''' button to navigate to the directory that contains the httpd sources.<br />
<br />
Click on the '''Next''' button to move to the '''C/Make Project Settings''' and then click on the '''Discovery Options''' Tab.<br />
<br />
[[File:../../img/eclipse-win07.png|Language Selection]]<br /><br />
<br />
On this page we need to enter the correct '''Compiler invocation command'''. You can use the '''Browse''' button, navigate to the YAGARTO bin folder and select '''arm-elf-gcc.exe'''.<br />
<br />
Click '''Finish''' to return to the Eclipse main window.<br />
<br />
[[File:../../img/eclipse-win08.png|Language Selection]]<br /><br />
[[File:../../img/eclipse-win09.png|Language Selection]]<br /><br />
[[File:../../img/eclipse-win10.png|Language Selection]]<br /><br />
[[File:../../img/eclipse-win11.png|Language Selection]]<br /><br />
[[File:../../img/eclipse-win12.png|Language Selection]]<br /><br />
[[File:../../img/eclipse-win13.png|Language Selection]]<br /><br />
[[File:../../img/eclipse-win14.png|Language Selection]]<br /><br />
[[File:../../img/eclipse-win15.png|Language Selection]]<br /><br />
<br /><br />
<br /><br />
<br />
Good luck,<br /><br />
Harald Kipp<br /><br />
Castrop-Rauxel, 18th of October 2006<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Documents/WebradioDocuments/Webradio2017-07-13T08:33:59Z<p>Harald: Created page with "<div id="content"> = AVR Internet Radio = <br /> == Introduction == This tutorial presents a step by step guide on how to build an stand-alone Embedded Internet Radio. The..."</p>
<hr />
<div><div id="content"><br />
<br />
= AVR Internet Radio =<br />
<br />
<br /><br />
<br />
== Introduction ==<br />
<br />
This tutorial presents a step by step guide on how to build an stand-alone Embedded Internet Radio. The device will be attached to a local Ethernet and connects MP3 streaming servers. If an Internet gateway (router) is available, you can listen to public radio stations listed at [http://www.shoutcast.com/ www.shoutcast.com], for example.<br />
<br />
Note, that this document refers to [[../../pdf/mnhwm11.pdf|Medianut Board Version 1]] (VS1001). In the meantime a [[../hardware/medianut2/index.html|new board revision 2]] (VS1011) became available.<br />
<br />
<br /><br />
<br />
== Required Hardware ==<br />
<br />
Ethernut board, preferably version 2 or similar hardware. It's possible to run the code on version 1 boards, but because of the lack of sufficient RAM, the bitrates for MP3 streaming are limited.<br />
<br />
Medianut board or similar hardware using a VS1001, VS1002 or VS1011 for MP3 decoding. These chips are manufactured by [http://www.vlsi.fi/ VLSI Solution Oy], Finland,<br />
<br />
The Medianut can be mounted on top of the Ethernut board.<br /><br />
<br /><br />
[[File:../../img/mount-nuts-360.png]]<br /><br />
<br /><br />
[[File:../../img/mount-top-360.png]]<br /><br />
<br /><br />
[[File:../../img/mount-side-360.png]]<br /><br />
<br />
<br />
Assembled and tested boards as well as components may be purchased from [http://www.egnite.de/ egnite GmbH], Germany,<br />
<br />
<br /><br />
<br />
== Required Software ==<br />
<br />
The presented code had been tested on Nut/OS 3.9.2.1pre, but should also work on earlier releases of version 3.<br />
<br />
Follow the instructions presented in the [[../../pdf/enswm28e.pdf|Nut/OS Software Manual]] to create the Nut/OS libraries and a sample application directory for your specific environment.<br />
<br />
<br /><br />
<br />
== Step 1: Connecting an Internet Radio Station ==<br />
<br />
We will utilize an [[rs232primer.html|RS232 port]] for debug messages. Nut/OS provides a rich set of stdio routines such as printf, scanf etc., which are fairly similar to Windows and Linux. However, the initialization is a bit different. There are no predefined devices for stdin, stdout and stderr. Devices used by an application have to be registered first by calling <code>NutRegisterDevice()</code>. We choose <code>devDebug0</code>, which is a very simple UART driver for RS232 output. Due to its simplicity it's possible to produce debug messages even from within interrupt routines.<br />
<br />
After device registration, we are able to open a C stdio stream on this device. The function <code>freopen()</code> will attach the resulting stream to stdout. Thus we can use simple calls like <code>printf()</code>, <code>puts()</code> or <code>putchar()</code>.<br />
<br />
The <code>_ioctl()</code> routine provides device specific control functions like setting the baudrate.<br />
<br />
We place an endless loop at the end of <code>main()</code>. In opposite to programs written for desktop computers, the <code>main()</code> function will not return because there is nothing to return to.<br />
<br />
<div class="coding"><br />
<br />
<pre> #include &lt;dev/debug.h&gt;<br />
#include &lt;stdio.h&gt;<br />
#include &lt;io.h&gt;<br />
<br />
#define DBG_DEVICE devDebug0<br />
#define DBG_DEVNAME &quot;uart0&quot;<br />
#define DBG_BAUDRATE 115200<br />
<br />
int main(void)<br />
{<br />
NutRegisterDevice(&amp;DBG_DEVICE, 0, 0);<br />
<br />
freopen(DBG_DEVNAME, &quot;w&quot;, stdout);<br />
_ioctl(_fileno(stdout), UART_SETSPEED, &amp;baud);<br />
<br />
puts(&quot;Reset me!&quot;);<br />
for(;;);<br />
}</pre><br />
<br />
</div><br />
The need for device registration also applies to the Ethernet device. The Ethernut hardware supports two different LAN controller chips, the LAN91C111 and the RTL8019AS.<br />
<br />
<div class="coding"><br />
<br />
<pre> #ifdef ETHERNUT2<br />
#include &lt;dev/lanc111.h&gt;<br />
#else<br />
#include &lt;dev/nicrtl.h&gt;<br />
#endif<br />
<br />
NutRegisterDevice(&amp;DEV_ETHER, 0x8300, 5);</pre><br />
<br />
</div><br />
<code>ETHERNUT2</code> is typically defined in the file UserConf.mk located in the application directory.<br />
<div class="coding"><br />
<br />
<pre> HWDEF += -DETHERNUT2</pre><br />
<br />
</div><br />
Remember to remove this line when the programs should run on Ethernut 1.3 or earlier board revisions.<br />
TCP/IP over Ethernet interfaces typically require some sort of configuration, like the unique MAC address, local IP address, the network mask, routing information etc. The most comfortable way to define these variables is to make use of a local DHCP server. If there is none available in your local network, then you can install a simple one on your Windows PC. DHCP servers are also available on all Linux systems.<br />
<br />
If you can't or don't want to install a DHCP server, you need to provide the required parameters in your application code defining them as preprocessor macros, for example.<br />
<br />
<div class="coding"><br />
<br />
<pre> #define MY_MAC { 0x00, 0x06, 0x98, 0x10, 0x01, 0x10 }<br />
#define MY_IPADDR &quot;192.168.192.100&quot;<br />
#define MY_IPMASK &quot;255.255.255.0&quot;<br />
#define MY_IPGATE &quot;192.168.192.1&quot;</pre><br />
<br />
</div><br />
<code>MY_MAC</code> specifies the Ethernet address, which must be unique in your local Ethernet.<br />
<br />
<code>MY_IPADDR</code> is the local TCP/IP address of the Ethernut board, which needs to be unique too, but not only in the local network. If you are connecting to the Internet, no other node in the Internet should have the same one. Fortunately, your Internet access provider will assign a unique address to your router and the router translates local IP addresses to this unique address. Special address ranges are reserved for local networks, like 192.168.x.y. So you only have to take care, that the address is not used by another computer in your local Ethernet.<br />
<br />
<code>MY_IPMASK</code> must be equal on all computers in your local network. Note, that if your network uses 255.255.255.0 for example, then the first three parts of the <code>MY_IPADDR</code> must be equal on all computers too, 192.168.192 in our example.<br />
<br />
<code>MY_IPGATE</code> should be set to the IP address of your router. If you don't intend to connect to the Internet, then set this parameter to <code>&quot;0.0.0.0&quot;</code>.<br />
<br />
We use a specific routine to configure the network interface in three trial and error steps. The advantage is, that this code will work with DHCP, hard coded values and, not mentioned yet, previously saved EEPROM values.<br />
<br />
<div class="coding"><br />
<br />
<pre> int ConfigureLan(char *devname)<br />
{<br />
if (NutDhcpIfConfig(devname, 0, 60000)) {<br />
u_char mac[6] = MY_MAC;<br />
if (NutDhcpIfConfig(devname, mac, 60000)) {<br />
u_long ip_addr = inet_addr(MY_IPADDR);<br />
u_long ip_mask = inet_addr(MY_IPMASK);<br />
u_long ip_gate = inet_addr(MY_IPGATE);<br />
if(NutNetIfConfig(devname, mac, ip_addr, ip_mask)) {<br />
return -1;<br />
}<br />
if(ip_gate) {<br />
if(NutIpRouteAdd(0, 0, ip_gate, &amp;DEV_ETHER) == 0) {<br />
return -1;<br />
}<br />
}<br />
}<br />
}<br />
return 0;<br />
}</pre><br />
<br />
</div><br />
The first call to <code>NutDhcpIfConfig()</code> assumes, that a complete configuration is available in the ATmega EEPROM already. This may be the case, if you previously ran the Basemon application and entered these parameters before starting the sample Webserver. If the fuse &quot;Preserve EEPROM Contents&quot; has been enabled in the ATmega128, then the network configuration remains intact when erasing the device during the programming cycle, while uploading a new application.<br />
This first call will fail, if the EEPROM is empty. A second call is done, which provides the MAC address. Again, this will fail, if DHCP is not available in the local network. The final call to <code>NutNetIfConfig()</code> will provide all required parameters, except the default route to our Internet gateway. If this parameter is not zero, a call to <code>NutIpRouteAdd()</code> will pass the IP address of the router.<br />
<br />
After having configured the network interface, we can use it to establish a TCP/IP connection to an MP3 streaming server. Three items are required to specify an MP3 stream.<br />
<br />
* The server's IP address.<br />
* The server's TCP port.<br />
* The server's URL.<br />
<br />
All three can be obtained by visiting [http://www.shoutcast.com/ www.shoutcast.com]. Choose one of the stations offered and download the related playlist entry. Simply klicking on the &quot;Tune In&quot; button may automatically start an application like Winamp or whatever has been registered as an MP3 player plugin with your browser. Try to click the &quot;Tune In&quot; button with the right mouse button to download the shoutcast-playlist.pls file instead. This is a simple text file with a contents like the following:<br />
<div class="coding"><br />
<br />
<pre> [playlist]<br />
numberofentries=2<br />
File1=http://64.236.34.196:80/stream/1020<br />
Title1=(#1 - 90/29131) Smoothjazz.Com<br />
Length1=-1<br />
File2=http://64.236.34.4:80/stream/1020<br />
Title2=(#2 - 124/38816) Smoothjazz.Com<br />
Length2=-1<br />
Version=2</pre><br />
<br />
</div><br />
The <code>File1</code> (alternative <code>File2</code>) entry contains the information we need to create the proper parameters in our radio application.<br />
<div class="coding"><br />
<br />
<pre> #define RADIO_IPADDR &quot;64.236.34.196&quot;<br />
#define RADIO_PORT 80<br />
#define RADIO_URL &quot;/stream/1020&quot;</pre><br />
<br />
</div><br />
Connecting the radio station is simple.<br />
<div class="coding"><br />
<br />
<pre> TCPSOCKET *sock;<br />
u_long ip = inet_addr(RADIO_IPADDR);<br />
<br />
sock = NutTcpCreateSocket();<br />
NutTcpConnect(sock, ip, RADIO_PORT);<br />
stream = _fdopen((int) sock, &quot;r+b&quot;);<br />
<br />
fprintf(stream, &quot;GET %s HTTP/1.0\r\n&quot;, RADIO_URL);<br />
fprintf(stream, &quot;Host: %s\r\n&quot;, inet_ntoa(ip));<br />
fprintf(stream, &quot;User-Agent: Ethernut\r\n&quot;);<br />
fprintf(stream, &quot;Accept: */*\r\n&quot;);<br />
fprintf(stream, &quot;Icy-MetaData: 1\r\n&quot;);<br />
fprintf(stream, &quot;Connection: close\r\n\r\n&quot;);<br />
fflush(stream);<br />
<br />
line = malloc(512);<br />
while(fgets(line, 512, stream)) {<br />
cp = strchr(line, '\r');<br />
if(cp == 0)<br />
continue;<br />
*cp = 0;<br />
if(*line == 0)<br />
break;<br />
printf(&quot;%s\n&quot;, line);<br />
}<br />
free(line);</pre><br />
<br />
</div><br />
This code fragment creates a TCP socket, establishes a connection to a given IP address and port number and opens a stream on the TCP socket. Next, the HTTP request is send to the server and the response is received and printed to stdout until the first empty line.<br />
[[../../arc/mnut01-041111.zip|mnut01-041111.zip]]<br /><br />
Contains complete source code and binaries of step 1. Here's a sample output:<br />
<br />
<div class="coding"><br />
<br />
<pre> Medianut Tutorial Part 1 - Nut/OS 3.9.2.1 pre - AVRGCC<br />
29877 bytes free<br />
<br />
Configure eth0...OK<br />
MAC : 00-06-98-21-02-B0<br />
IP : 192.168.192.202<br />
Mask: 255.255.255.0<br />
Gate: 192.168.192.1<br />
<br />
Connecting 64.236.34.196:80...OK<br />
GET /stream/1040 HTTP/1.0<br />
<br />
ICY 200 OK<br />
icy-notice1: &lt;BR&gt;This stream requires &lt;aef=&quot;http://www.winamp.com/&quot;&gt;Winamp&lt;/a&gt;&lt;BR&gt;<br />
icy-notice2: SHOUTcast Distributed Network Audio Server/SolarisSparc v1.9.4&lt;BR&gt;<br />
icy-name: CLUB 977 The 80s Channel (HIGH BANDWIDTH)<br />
icy-genre: 80s Pop Rock<br />
icy-url: http://www.club977.com<br />
icy-pub: 1<br />
icy-metaint: 8192<br />
icy-br: 128<br />
icy-irc: #shoutcast<br />
icy-icq: 0<br />
icy-aim: N/A<br />
<br />
Reset me!</pre><br />
<br />
</div><br />
No music yet, but in the next step.<br />
<br /><br />
<br />
== Step 2: Playing an MP3 Stream ==<br />
<br />
Following the empty line, which marks the end of the header, the streaming server will send an endless stream of binary data, the MP3 encoded audio data. Reading this data into a buffer is nothing special.<br />
<br />
<div class="coding"><br />
<br />
<pre> int got;<br />
u_char *buf;<br />
<br />
buf = malloc(2048);<br />
got = fread(buf, 1, 2048, stream);</pre><br />
<br />
</div><br />
The problem is to pass this data to the MP3 decoder.<br />
Nut/OS includes a device driver for the VS1001K decoder chip. Actually this is not a common device driver with a NUTDEVICE structure and support for stdio read and write. This wouldn't make much sense, because tiny systems like Ethernut suffer from buffer copying. The following code would result in low performance.<br />
<br />
<div class="coding"><br />
<br />
<pre> /* Bad example */<br />
got = fread(buf, 1, 2048, stream);<br />
fwrite(buf, 1, got, decoder); /* Not available */</pre><br />
<br />
</div><br />
The data needs to be copied at least four times.<br />
* From the Ethernet Controller to the TCP buffer.<br />
* From the TCP buffer to the application buffer.<br />
* From the application buffer to the decoder buffer.<br />
* From the decoder buffer to the decoder chip.<br />
<br />
To reduce CPU utilization the MP3 driver expects the data in a Nut/OS segmented buffer. Our radio application uses the following code to fill this buffer.<br />
<div class="coding"><br />
<br />
<pre> NutSegBufInit(8192);<br />
NutSegBufReset();<br />
<br />
for(;;) {<br />
buf = NutSegBufWriteRequest(&amp;rbytes);<br />
got = fread(buf, 1, rbytes, stream);<br />
NutSegBufWriteCommit(got);<br />
}</pre><br />
<br />
</div><br />
Another advantage of the segmented buffer API is, that it can handle non-continous memory like the banked RAM on Ethernut 2.<br />
<code>NutSegBufInit()</code> initializes the buffer. For the banked memory on Ethernut 2 boards, the parameter is ignored. All memory banks are automatically occupied. For Ethernut 1 boards the specified number of bytes are taken from heap memory to create the buffer.<br />
<br />
<code>NutSegBufReset()</code> clears the buffer.<br />
<br />
<code>NutSegBufWriteRequest()</code> returns the continous buffer space available at the current write position.<br />
<br />
<code>NutSegBufWriteCommit()</code> commits the specified number of bytes written.<br />
<br />
With this scheme, data copying is reduced by 25% and takes place<br />
<br />
* From the Ethernet Controller to the TCP buffer.<br />
* From the TCP buffer to the segmented buffer.<br />
* From the segmented buffer to the decoder chip.<br />
<br />
As stated above, the VS1001 driver doesn't support stdio read and write routines. Instead a number of individual routines are provided to control the decoding process.<br />
<br />
<code>VsPlayerInit()</code> resets the decoder hardware and software and should be the first routine called by our application.<br />
<br />
<code>VsPlayerReset()</code> initializes the decoder and must be called before decoding a new data stream.<br />
<br />
<code>VsGetStatus()</code> can be used to query the current status of the driver.<br />
<br />
<code>VsSetVolume()</code> sets the analog output attenuation of both stereo channels.<br />
<br />
<code>VsPlayerKick()</code> finally starts decoding the data in the segmented buffer.<br />
<br />
It is possible to access the segmented buffer from within interrupt routines and the Nut/OS VS1001 driver makes use of this feature. However, calling <code>NutSegBufReset()</code>, <code>NutSegBufWriteRequest()</code> or <code>NutSegBufWriteCommit()</code> modifies certain multibyte values using non-atomic operations, which needs to be protected from access during interrupts. We could use the Nut/OS <code>NutEnterCritical()</code> and <code>NutExitCritical()</code> calls, but this disables all interrupts, system-wide. This includes interrupts initiated by out Ethernet controller, leading to a degradation of our TCP response time and overall transfer rate. Luckily, the VS1001 driver offers a routine named <code>VsPlayerInterrupts()</code>, which disables/enables decoder interrupts only.<br />
<br />
<div class="coding"><br />
<br />
<pre> u_char ief;<br />
<br />
ief = VsPlayerInterrupts(0);<br />
/* Exclusive call here. */<br />
VsPlayerInterrupts(ief);</pre><br />
<br />
</div><br />
[[../../arc/mnut02-041111.zip|mnut02-041111.zip]]<br /><br />
Contains complete source code and binaries of step 2. A sample output is here:<br />
<br />
<div class="coding"><br />
<br />
<pre> Medianut Tutorial Part 2 - Nut/OS 3.9.2.1 pre - AVRGCC<br />
29743 bytes free<br />
<br />
Configure eth0...OK<br />
MAC : 00-06-98-21-02-B0<br />
IP : 192.168.192.202<br />
Mask: 255.255.255.0<br />
Gate: 192.168.192.1<br />
<br />
Connecting 64.236.34.196:80...OK<br />
GET /stream/1020 HTTP/1.0<br />
<br />
ICY 200 OK<br />
icy-notice1: &lt;BR&gt;This stream requires &lt;a href=&quot;http://www.winamp.com/&quot;&gt;Winamp&lt;/a&gt;&lt;BR&gt;<br />
icy-notice2: SHOUTcast Distributed Network Audio Server/SolarisSparc v1.9.4&lt;BR&gt;<br />
icy-name: Smoothjazz.Com - The worlds best Smooth Jazz - Live From Monterey Bay<br />
icy-genre: smooth jazz<br />
icy-url: http://www.smoothjazz.com<br />
icy-pub: 1<br />
icy-metaint: 8192<br />
icy-br: 32<br />
icy-irc: #shoutcast<br />
icy-icq: 0<br />
icy-aim: N/A<br />
<br />
Read 594 of 16384<br />
Read 512 of 15790<br />
Read 512 of 15278<br />
Read 512 of 14766<br />
Read 512 of 14254<br />
Read 512 of 13742<br />
Read 512 of 13230<br />
Read 512 of 12718<br />
Read 512 of 12206<br />
Read 144 of 11694<br />
4834 buffered</pre><br />
<br />
</div><br />
When connecting a headphone or line input of an amplifier to the Medianut, we should be able to listen to the radio station we connected. Though, we may notice hiccups or the stream may stop shortly after establishing the connection. There's obviously something left to do.<br /><br />
<br />
== Step 3: Refining the Player ==<br />
<br />
The default setup of the Nut/Net TCP stack is optimized for tiny embedded systems with data exchange in both directions at minimal memory usage. We can use <code>NutTcpSetSockOpt()</code> to optimize two of the parameters for MP3 streaming.<br />
<br />
<br />
<br />
<div class="coding"><br />
<br />
<pre> u_short tcpbufsiz = 8760;<br />
<br />
NutTcpSetSockOpt(sock, SO_RCVBUF, &amp;tcpbufsiz, sizeof(tcpbufsiz));</pre><br />
<br />
</div><br />
This increases the buffer, which is initially offered to the server. It means, that the server can send up to 8760 bytes without waiting for any response from us.<br />
<br />
<br />
<div class="coding"><br />
<br />
<pre> u_short mss = 1460;<br />
<br />
NutTcpSetSockOpt(sock, TCP_MAXSEG, &amp;mss, sizeof(mss));</pre><br />
<br />
</div><br />
This is the maximum number of data bytes the server may send in a single TCP segment. By default, the Nut/Net TCP stack uses a maximum segment size of 536, which most probably saves us from packet fragmentation, which is not supported by Nut/Net. Fragmentation occurs, when a packet passes a network with lower MTU (maximum transfer unit) on its way through the Internet from the server to our Ethernut. On Ethernet networks, the MTU is 1500 bytes and the TCP header is 40 bytes, which results in an MSS of 1460 bytes. In the Internet today fragmentation of segments with 1460 bytes is quite seldom.<br />
Another problem appears, when the server or the connection dies. In such a case our MP3 player, the TCP client, may never return from the <code>fread()</code>. Setting a socket read timeout solves this problem. After the specified number of milliseconds <code>fread()</code> will return with zero bytes read.<br />
<br />
<div class="coding"><br />
<br />
<pre> u_long rx_to = 3000;<br />
<br />
NutTcpSetSockOpt(sock, SO_RCVTIMEO, &amp;rx_to, sizeof(rx_to));</pre><br />
<br />
</div><br />
As we found out in the last step, audio output contains hiccups or may even become completely scrambled. The reason is, that the stream contains some additional information, the so called metadata tags. In the previous step we passed this unfiltered to the decoder chip, which is of course quite picky about extra bytes included in the MP3 stream.<br />
<br />
The server sends an information about how many bytes of MP3 data are between the metadata tags in the initial header lines.<br />
<br />
<div class="coding"><br />
<br />
<pre> icy-metaint: 8192</pre><br />
<br />
</div><br />
The hiccups should disappear, when we use this value to strip the metadata tags from the stream.<br />
The metadata tag begins with a single byte, which indicates the total size of the tag when multiplied by 16. Here's an example of the contents of such a metadata tag.<br />
<br />
<div class="coding"><br />
<br />
<pre> StreamTitle='Alphaville, Big in Japan';StreamUrl='http://www.club977.com/ads';</pre><br />
<br />
</div><br />
It contains a number of name/value pairs, separated by semicolons. An equals sign is used to separate the name from its value and each value is surrounded by quotes. The value of <code>StreamTitle</code> typically informs us about the music title currently transmitted. For now we print this to our debug device.<br />
[[../../arc/mnut03-041111.zip|mnut03-041111.zip]]<br /><br />
Contains complete source code and binaries of step 3.<br />
<br />
Quite often we will something like this after starting the player.<br />
<br />
<div class="coding"><br />
<br />
<pre> Connecting 64.236.34.196:80...Error: Connect failed with 10060<br />
Reset me!</pre><br />
<br />
</div><br />
The reason for not connecting to a station, which worked before resetting the Ethernut is, that we didn't close our previous connection to this the server. To do this, we need some kind user interface. Medianut supports three hardware interfaces:<br />
* LCD connector<br />
* 4 button keyboard connector<br />
* Infrared remote control receiver connector<br />
<br />
Future parts of this tutorial will show us how to use these.<br />
<br /><br />
<br />
<br /><br />
[[File:../../img/wireless-radio.png]]<br /><br />
Wireless radio prototype with Ethernut, Datanut and Medianut.<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Documents/WatchdogDocuments/Watchdog2017-07-13T08:33:25Z<p>Harald: Created page with "<div id="content"> = Hardware Watchdog = == About This Document == Previous Nut/OS releases supported the AVR platform only and application programmers could safely use the..."</p>
<hr />
<div><div id="content"><br />
<br />
= Hardware Watchdog =<br />
<br />
== About This Document ==<br />
<br />
Previous Nut/OS releases supported the AVR platform only and application programmers could safely use the watchdog routines offered by the avr-libc runtime. Since the introduction of Ethernut 3 board with an AT91 microcontroller, a portable watchdog API is required to maintain portability of applications.<br />
<br />
Version 4.1.5 will provided a first Watchdog API, currently implemented for the ARM7TDMI only.<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Documents/uHTTP_Lib_UploadsDocuments/uHTTP Lib Uploads2017-07-13T08:32:20Z<p>Harald: Created page with "<div id="content"> = MicroHTTP Library: Uploading Files = The capability to upload files can significantly improve the maintainability of your webserver based application. Y..."</p>
<hr />
<div><div id="content"><br />
<br />
= MicroHTTP Library: Uploading Files =<br />
<br />
The capability to upload files can significantly improve the maintainability of your webserver based application. You may, for example, allow users to upload new firmware versions. Unfortunately, compared to other features of the [[uhttplib.html|MicroHTTP library]], the implementation requires more additional application code.<br />
<br />
== Web Content ==<br />
<br />
The following HTML code presents a form that allows to replace an image displayed on the same page.<br />
<br />
<pre class="coding">&lt;html&gt;<br />
&lt;head&gt;<br />
&lt;title&gt;File Upload&lt;/title&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
&lt;h1&gt;Upload Sample&lt;/h1&gt;<br />
&lt;p&gt;Upload PNG image&lt;/p&gt;<br />
&lt;form action=&quot;upload.cgi&quot; method=&quot;post&quot; enctype=&quot;multipart/form-data&quot;&gt;<br />
&lt;table cellspacing=&quot;10&quot; width=&quot;100%&quot;&gt;<br />
&lt;tr&gt;&lt;td&gt;&lt;input type=&quot;file&quot; size=&quot;64&quot; name=&quot;image&quot;&gt;&lt;/td&gt;&lt;/tr&gt;<br />
&lt;tr&gt;&lt;td&gt;&lt;input type=&quot;submit&quot; name=&quot;upload&quot; value=&quot;Send&quot; onClick=&quot;return confirm('Are you sure?');&quot;&gt;&lt;/td&gt;&lt;/tr&gt;<br />
&lt;/table&gt;<br />
&lt;/form&gt;<br />
&lt;img src=&quot;image.png&quot; /&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</pre><br />
When clicking the ''Send'' button, the browser will query the user for confirmation (see ''onClick'') and, if confirmed, transfer the data with the POST method to the CGI script ''upload.cgi''.<br />
<br />
== Application Code ==<br />
<br />
The application must process the form data with a CGI function, registered under the name ''upload.cgi''. The required code to start the webserver is similar to the one we used when explaining the [[uhttplib_forms.html|common gateway interface]] in general.<br />
<br />
<pre class="coding">StreamInit();<br />
MediaTypeInitDefaults();<br />
HttpRegisterCgiFunction(&quot;upload.cgi&quot;, CgiUpload);<br />
HttpRegisterMediaType(&quot;cgi&quot;, NULL, NULL, HttpCgiFunctionHandler);<br />
StreamClientAccept(HttpdClientHandler, NULL);</pre><br />
The CGI function is kept simple:<br />
<br />
<pre class="coding">#define HTTP_ROOT (http_root ? http_root : HTTP_DEFAULT_ROOT)<br />
extern char *http_root;<br />
<br />
int CgiUpload(HTTPD_SESSION *hs)<br />
{<br />
char *upname;<br />
char *lclname;<br />
<br />
lclname = malloc(strlen(HTTP_ROOT) + sizeof(&quot;image.png&quot;));<br />
strcat(strcpy(lclname, HTTP_ROOT), &quot;image.png&quot;);<br />
upname = UploadFile(hs, lclname);<br />
HttpSendRedirection(hs, 303, &quot;/index.html&quot;, NULL);<br />
<br />
return 0;<br />
}</pre><br />
It calls ''UploadFile'' to do all the work. And this is where things become a bit more complicated. When using a form with an input field of type ''file'', we must also declare the encoding type of the form as ''multipart/form-data''. This enables the browser to send both, the data entered by the user as well as the contents of the given file.<br />
<br />
Multipart form data is, as its name implies, sent in parts, which are separated by a boundary string. The real trouble is, that the browser only informs the server about the overall content length. But the server is completely unaware about the size of each part. As long as text lines are transferred, it's not too hard to detect the next boundary string that marks the end of each part. When, like in our case with images, binary data is transfered, detecting the next boundary without significantly degrading the transfer speed can become tricky.<br />
<br />
I will first present the full code of the upload function before turning into a few details.<br />
<br />
<pre class="coding">#define MAX_UPSIZE 1460<br />
#define MIN(a, b) ((a) &lt; (b) ? (a) : (b))<br />
<br />
char *UploadFile(HTTPD_SESSION *hs, char *path)<br />
{<br />
char *rp = NULL;<br />
char *upname = NULL;<br />
long avail;<br />
char *line;<br />
char *delim;<br />
const char *sub_ptr;<br />
int sub_len;<br />
int fd = -1;<br />
int got = 0;<br />
HTTP_STREAM *stream = hs-&gt;s_stream;<br />
HTTP_REQUEST *req = &amp;hs-&gt;s_req;<br />
<br />
/* Retrieve the boundary string. */<br />
delim = GetMultipartBoundary(req);<br />
if (delim == NULL) {<br />
return NULL;<br />
}<br />
<br />
avail = req-&gt;req_length;<br />
line = malloc(MIN(avail, MAX_UPSIZE) + 1);<br />
if (line == NULL) {<br />
/* No memory. */<br />
free(delim);<br />
return NULL;<br />
}<br />
<br />
/* If we have a delimiter, then process the boundary content. */<br />
while (avail &gt; 0) {<br />
/* Parse the next boundary header. */<br />
if (HttpParseMultipartHeader(hs, delim, &amp;avail)) {<br />
/* Broken connection. */<br />
break;<br />
}<br />
/* Ignore headers without content disposition line. */<br />
if (req-&gt;req_bnd_dispo) {<br />
/* Retrieve the name of the form item. */<br />
sub_ptr = HttpArgValueSub(req-&gt;req_bnd_dispo, &quot;name&quot;, &amp;sub_len);<br />
if (sub_ptr) {<br />
/* The item named 'image' contains the binary data of the file. */<br />
if (strncasecmp(sub_ptr, &quot;image&quot;, sub_len) == 0) {<br />
char *filename = NULL;<br />
int fd = -1;<br />
int eol = 0;<br />
<br />
/* Get the upload file name. */<br />
sub_ptr = HttpArgValueSub(req-&gt;req_bnd_dispo, &quot;filename&quot;, &amp;sub_len);<br />
if (sub_ptr &amp;&amp; sub_len) {<br />
upname = malloc(sub_len + 1);<br />
if (upname) {<br />
memcpy(upname, sub_ptr, sub_len);<br />
upname[sub_len] = 0;<br />
/* Open the local file that the caller has provided. */<br />
#ifdef NUT_OS<br />
fd = _open(path, _O_CREAT | _O_TRUNC | _O_RDWR | _O_BINARY);<br />
#else<br />
fd = _open(path, _O_CREAT | _O_TRUNC | _O_RDWR | _O_BINARY, _S_IREAD | _S_IWRITE);<br />
#endif<br />
if (fd == -1) {<br />
printf(&quot;Error %d opening %s\n&quot;, errno, path);<br />
} else {<br />
printf(&quot;Uploading %s\n&quot;, upname);<br />
}<br />
}<br />
}<br />
/* Recieve the binary data. */<br />
while (avail) {<br />
/* Read until the next boundary line. */<br />
got = StreamReadUntilString(stream, delim, line, MIN(avail, MAX_UPSIZE));<br />
if (got &lt;= 0) {<br />
break;<br />
}<br />
avail -= got;<br />
/* Write data to the local file, if one had been opened. */<br />
if (fd != -1) {<br />
if (eol) {<br />
_write(fd, &quot;\r\n&quot;, 2);<br />
}<br />
if (got &gt;= 2 &amp;&amp; line[got - 2] == '\r' &amp;&amp; line[got - 1] == '\n') {<br />
eol = 1;<br />
got -= 2;<br />
}<br />
_write(fd, line, got);<br />
}<br />
}<br />
if (fd != -1) {<br />
_close(fd);<br />
}<br />
free(filename);<br />
if (got &lt; 0) {<br />
/* Broken connection. */<br />
break;<br />
}<br />
rp = upname;<br />
}<br />
else if (strncasecmp(sub_ptr, &quot;upload&quot;, sub_len) == 0) {<br />
got = StreamReadUntilChars(hs-&gt;s_stream, &quot;\n&quot;, &quot;\r&quot;, line, MIN(avail, MAX_UPSIZE));<br />
if (got &lt;= 0) {<br />
break;<br />
}<br />
}<br />
}<br />
}<br />
}<br />
if (fd != -1) {<br />
_close(fd);<br />
}<br />
free(delim);<br />
free(line);<br />
<br />
return rp;<br />
}</pre><br />
Note, that this function will directly read the data stream that is transmitted by the webbrowser. First, it will call ''GetMultipartBoundary'' to retrieve the boundary string that delimits each mime part. It will then allocate a read buffer, which size is limited to either the total content length or a maximum defined by MAX_UPSIZE, whichever is smaller. This prevents the application to run out of memory on tiny embedded systems.<br />
<br />
After the buffer has been successfully allocated, the CPU will execute a loop until all data from the browser will have been consumed. At its beginning the function ''HttpParseMultipartHeader'' is called to parse the mime header. This routine adds the result to the HTTP_REQUEST structure. Most notably, the mime header ''Content-Disposition'' is stored in a buffer, to which ''req-&gt;req_bnd_dispo'' points to. The application can request specific items from this header by calling the library function<br />
<br />
<pre class="coding">const char *HttpArgValueSub(const char *str, const char *name, int *len);</pre><br />
If an item named ''image'' appears, ''HttpArgValueSub()'' is called to retrieve the filename. To receive the binary data (uploaded image file), the function<br />
<br />
<pre class="coding">int StreamReadUntilString(HTTP_STREAM *sp, const char *delim, char *buf, int siz);</pre><br />
is called, which delivers data up to the next multipart boundary string. If reached, the loop is repeated, looking for the next mime header.<br />
<br />
I mentioned above, that ''GetMultipartBoundary'' is called to determine the boundary string. This routine must be provided by the application code too.<br />
<br />
<pre class="coding">char *GetMultipartBoundary(HTTP_REQUEST *req)<br />
{<br />
char *rp = NULL;<br />
const char *bptr;<br />
int blen;<br />
<br />
/* Make sure this is a multipart post. */<br />
if (CheckForPost(req, 1) == 0) {<br />
/* Retrieve the boundary string. */<br />
bptr = HttpArgValueSub(req-&gt;req_type, &quot;boundary&quot;, &amp;blen);<br />
if (bptr) {<br />
/* Build a delimiter string. */<br />
rp = malloc(blen + 3);<br />
if (rp) {<br />
rp[0] = '-';<br />
rp[1] = '-';<br />
memcpy(rp + 2, bptr, blen);<br />
rp[blen + 2] = '\0';<br />
}<br />
}<br />
}<br />
return rp;<br />
}</pre><br />
Before reading any data, this function calls ''CheckForPost'' to make sure, that POST data is indeed available.<br />
<br />
<pre class="coding">int CheckForPost(HTTP_REQUEST * req, int type)<br />
{<br />
if (req-&gt;req_method != HTTP_METHOD_POST || req-&gt;req_type == NULL) {<br />
/* Bad method, POST expected. */<br />
return -1;<br />
}<br />
if (type == 0 &amp;&amp; strncasecmp(req-&gt;req_type, &quot;application/x-www-form-urlencoded&quot;, 33) == 0) {<br />
return 0;<br />
}<br />
if (strncasecmp(req-&gt;req_type, &quot;multipart/form-data&quot;, 19) == 0) {<br />
return 0;<br />
}<br />
/* Bad content. */<br />
return -1;<br />
}</pre><br />
== Next Step ==<br />
<br />
So far we used CGI functions to deliver content to the webbrowser for immediate display. Another technique is to [[uhttplib_ajax.html|asynchronously send data to Javascript]].<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Documents/uHTTP_Lib_SSIDocuments/uHTTP Lib SSI2017-07-13T08:31:51Z<p>Harald: Created page with "<div id="content"> = MicroHTTP Library: Using Server Side Includes = On this page I will explain how to create dynamic web content with the uhttplib.html|MicroHTTP library..."</p>
<hr />
<div><div id="content"><br />
<br />
= MicroHTTP Library: Using Server Side Includes =<br />
<br />
On this page I will explain how to create dynamic web content with the [[uhttplib.html|MicroHTTP library's]] SSI capabilities.<br />
<br />
== Enabling SSI ==<br />
<br />
To enable SSI, the application must register a handler for it. The easiest way to do this is to enable default SSI support in the Configurator. The application simply needs to call<br />
<br />
<pre class="coding">int MediaTypeInitDefaults(void);</pre><br />
to activate all configured handlers. For SSI, it will register the internal default handler<br />
<br />
<pre class="coding">int HttpSsiHandler(HTTPD_SESSION *hs, const MEDIA_TYPE_ENTRY *mt, const char *ext);</pre><br />
When the browser requests a file with extension ''shtml'', the web server will redirect the request to the SSI handler. The handler parses the file for SSI elements and replaces them according to the SSI syntax rules.<br />
<br />
At the time of this writing, the following SSI elements are recognized by the server:<br />
<br />
* echo<br />
* exec<br />
* include<br />
<br />
Support for ''if-then-else'' is not provided, probably the most missing feature. If implemented once, we would also miss the ''set'' command.<br />
<br />
CGI scripts had been discussed on [[uhttplib_forms.html|the previous page]]. Including external files is straight forward and a simple way to add common parts like menus to all your webpages. Retrieving the value of variables will be explained now.<br />
<br />
== Predefined Variables ==<br />
<br />
The library offers a number of predefined SSI variables, for example the current date and time. The following HTTP snippet displays the local time as well as the Greenwich Mean Time.<br />
<br />
<pre class="coding">&lt;p&gt;Local time &lt;!--#echo var=&quot;DATE_LOCAL&quot; --&gt;&lt;/p&gt;<br />
&lt;p&gt;GMT time &lt;!--#echo var=&quot;DATE_GMT&quot; --&gt;&lt;/p&gt;</pre><br />
To enable these variables, applications must call<br />
<br />
<pre class="coding">int EnvInitDefaults(void);<br />
HTTP_SSI_VARHANDLER HttpRegisterSsiVarHandler(HTTP_SSI_VARHANDLER handler);</pre><br />
The first call adds all predefined variables to the environment and the second call is used to register a handler. MicroHTTP offers a default handler named ''EnvHandler'', which can be registered with<br />
<br />
<pre class="coding">HttpRegisterSsiVarHandler(EnvHandler);</pre><br />
The library supports the following variables:<br />
<br />
* SERVER_PORT<br />
* SERVER_NAME<br />
* SERVER_ADDR<br />
* SCRIPT_NAME<br />
* SCRIPT_FILENAME<br />
* REQUEST_URI<br />
* REQUEST_METHOD<br />
* REMOTE_PORT<br />
* REMOTE_ADDR<br />
* QUERY_STRING_UNESCAPED<br />
* QUERY_STRING<br />
* HTTP_USER_AGENT<br />
* HTTP_REFERER<br />
* HTTP_HOST<br />
* HTTP_COOKIE<br />
* HTTP_CONNECTION<br />
* HTTP_ACCEPT_ENCODING<br />
* DOCUMENT_ROOT<br />
* DOCUMENT_NAME<br />
* DATE_LOCAL<br />
* DATE_GMT<br />
<br />
== User Defined Variables ==<br />
<br />
The following HTML snippet should display the application's name and version:<br />
<br />
<pre class="coding">&lt;p&gt;&lt;!--#echo var=&quot;APPNAME&quot; --&gt; &lt;!--#echo var=&quot;APPVERSION&quot; --&gt;&lt;/p&gt;</pre><br />
The default SSI variable handler, that was used for our predefined variables above, also allows to add user defined variables with<br />
<br />
<pre class="coding">int EnvRegisterVariable(char *name, HTTP_ENVVAR_HANDLER handler, int item);</pre><br />
* ''name'' points to the name of the variable.<br />
* ''handler'' points to the handler for this variable.<br />
* ''item'' is an index starting from 1. It will be passed to the handler.<br />
<br />
Here is the complete initialization part:<br />
<br />
<pre class="coding">#define APPVAR_NAME 1<br />
#define APPVAR_VERSION 2<br />
<br />
StreamInit();<br />
MediaTypeInitDefaults();<br />
EnvRegisterVariable(&quot;APPNAME&quot;, AppVarHandler, APPVAR_NAME);<br />
EnvRegisterVariable(&quot;APPVERSION&quot;, AppVarHandler, APPVAR_VERSION);<br />
HttpRegisterSsiVarHandler(EnvHandler);<br />
StreamClientAccept(HttpdClientHandler, NULL);</pre><br />
We can create a single handler for all our user defined variables:<br />
<br />
<pre class="coding">const char *AppVarHandler(HTTPD_SESSION *hs, int item)<br />
{<br />
static char value[128];<br />
<br />
value[0] = '\0';<br />
switch (item) {<br />
case APPVAR_NAME:<br />
strcpy(value, &quot;SSI Sample&quot;);<br />
break;<br />
case APPVAR_VERSION:<br />
sprintf(value, &quot;%d.%d&quot;, MAJOR_VERSION, MINOR_VERSION);<br />
break;<br />
}<br />
return value;<br />
}</pre><br />
Note, that the application must make sure, that each variable, which is sharing the same handler, must have a unique index.<br />
<br />
== Next Step ==<br />
<br />
CGIs and server side includes are most useful to create a web interface to remotely configure your embedded device. Probably, you do not want to grant access to everyone and need some kind of [[uhttplib_auth.html|authentication]].<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Documents/uHTTP_Lib_FormsDocuments/uHTTP Lib Forms2017-07-13T08:30:37Z<p>Harald: </p>
<hr />
<div><div id="content"><br />
<br />
= MicroHTTP Library: Common Gateway Interface =<br />
<br />
Like its predecessor, the [[uhttplib.html|MicroHTTP library]] supports CGI functions. This still works a in most simple way.<br />
<br />
* The application registers a C function as a CGI script.<br />
* When this CGI script is requested, the webserver calls the registered C function.<br />
* The C function sends the content.<br />
<br />
== HTML Forms With GET Method ==<br />
<br />
CGI is most often used to request user input via HTML forms. The following form lets the user to enter his first and his family name:<br />
<br />
<pre class="coding">&lt;html&gt;<br />
&lt;head&gt;<br />
&lt;title&gt;Form Sample&lt;/title&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
&lt;h1&gt;A Form&lt;/h1&gt;<br />
&lt;form action=&quot;getform.cgi&quot; method=&quot;get&quot;&gt;<br />
&lt;p&gt;First name:&lt;br&gt;&lt;input name=&quot;firstname&quot; type=&quot;text&quot; size=&quot;30&quot; maxlength=&quot;30&quot;&gt;&lt;/p&gt;<br />
&lt;p&gt;Family name:&lt;br&gt;&lt;input name=&quot;familyname&quot; type=&quot;text&quot; size=&quot;30&quot; maxlength=&quot;40&quot;&gt;&lt;/p&gt;<br />
&lt;p&gt;&lt;input type=&quot;submit&quot; value=&quot;Send&quot;&gt;&lt;/p&gt;<br />
&lt;/form&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</pre><br />
When the ''Send'' button is clicked, the browser will request the CGI script ''getform.cgi'' with the GET method. This means, that the values of the input fields are appended as arguments to the requested URL as ''name=value'' pairs. The webserver then passes this URL to the CGI function.<br />
<br />
To simplify CGI function programming, the MicroHTTP library provides a set of useful functions to parse the URL for parameters.<br />
<br />
* HttpArgParseFirst() returns the name of the first argument.<br />
* HttpArgParseNext() returns the name of the next argument.<br />
* HttpArgValue() returns the value of the current argument.<br />
<br />
When using these functions, processing the HTML form given above is quite simple. Here is the complete code:<br />
<br />
<pre class="coding">int CgiGetForm(HTTPD_SESSION *hs)<br />
{<br />
char *arg;<br />
char *val;<br />
char *first = NULL;<br />
char *last = NULL;<br />
<br />
for (arg = HttpArgParseFirst(&amp;hs-&gt;s_req); arg; arg = HttpArgParseNext(&amp;hs-&gt;s_req)) {<br />
val = HttpArgValue(&amp;hs-&gt;s_req);<br />
if (val) {<br />
if (strcmp(arg, &quot;firstname&quot;) == 0) {<br />
first = strdup(val);<br />
}<br />
else if (strcmp(arg, &quot;familyname&quot;) == 0) {<br />
last = strdup(val);<br />
}<br />
}<br />
}<br />
SendResult(hs, first, last);<br />
free(first);<br />
free(last);<br />
<br />
return 0;<br />
}</pre><br />
The original Nut/OS HTTP library called CGI functions with a FILE stream pointer and a pointer to a request structure. MicroHTTP instead passes a single pointer to a ''HTTPD_SESSION'' structure, which, among other things, contains a HTTP_STREAM pointer and a slightly different request structure. Nevertheless, it shouldn't be too hard to port existing CGI functions to the new library.<br />
<br />
Please note, that the parser functions simply return pointers to a static buffer, which will be overridden when parsing the next argument. Therefore, the CGI function must make a local copy (strdup) of each string which will be used afterwards.<br />
<br />
Some of you may already have noticed, that the code is not as complete as it pretends to be. Indeed, the response to the webbrowser is missing. The MicroHTTP webserver expects, that the complete response is sent by the CGI function, including all header lines. This is done in the function ''SendResult'' that is called near the end of the CGI function. To simplify this task, two functions are provided by the library to cover standard responses.<br />
<br />
* void HttpSendHeaderTop() sends initial header lines, HTTP version and the name of the server.<br />
* void HttpSendHeaderBottom() sends final header lines: Content type and length, connection type and content encoding, depending on the configuration of the library.<br />
<br />
Splitting HTTP header line transmission into two functions enables the CGI to send additional lines between both calls. The latter function will also send an empty line to terminate the HTTP header. The CGI may directly append the content thereafter. Here is the source code of the missing function:<br />
<br />
<pre class="coding">int SendResult(HTTPD_SESSION *hs, char *first, char *last)<br />
{<br />
static const char head[] =<br />
&quot;&lt;html&gt;&quot;<br />
&quot;&lt;head&gt;&quot;<br />
&quot;&lt;title&gt;Form Result&lt;/title&gt;&quot;<br />
&quot;&lt;/head&gt;&quot;;<br />
static const char body[] =<br />
&quot;&lt;body&gt;&quot;<br />
&quot;&lt;p&gt;Hello %s %s!&lt;/p&gt;&quot;<br />
&quot;&lt;a href=\&quot;/index.html\&quot;&gt;back&lt;/a&gt;&quot;<br />
&quot;&lt;/body&gt;&quot;<br />
&quot;&lt;html&gt;&quot;;<br />
<br />
HttpSendHeaderTop(hs, 200);<br />
HttpSendHeaderBottom(hs, &quot;text&quot;, &quot;html&quot;, -1);<br />
<br />
s_puts(head, hs-&gt;s_stream);<br />
s_printf(hs-&gt;s_stream, body, first, last);<br />
s_flush(hs-&gt;s_stream);<br />
<br />
return 0;<br />
}</pre><br />
Of course, this code could have been included into the CGI function. We use a separate function here, so we can reuse it when explaining the POST method in the next chapter.<br />
<br />
== HTML Forms With POST Method ==<br />
<br />
The first problem you may encounter with the GET method is its size limitation. MicroHTTP is designed to run on tiny embedded systems with a 32 kilobytes of RAM or less. As it is often required to process all HTTP headers before parsing the URL, which always comes in the first line, there may not be enough memory space for large forms. Furthermore, even webbrowsers, which typically occupy megabytes or gigabytes of memory, do have a tight limit here. After the first release of HTTP routines in Nut/OS with POST method capabilities, application developers missed this feature immediately.<br />
<br />
To instruct the browser to use POST, we simply need to replace a single line in our HTML document.<br />
<br />
<pre class="coding">&lt;form action=&quot;getform.cgi&quot; method=&quot;get&quot;&gt;</pre><br />
must be replaced by<br />
<br />
<pre class="coding">&lt;form action=&quot;postform.cgi&quot; method=&quot;post&quot;&gt;</pre><br />
Actually, the CGI function doesn't require many modifications. The most obvious one is, that it needs to keep track of the content length. Futhermore, ''HttpArgParseFirst()'' is not required, ''HttpArgParseNext()'' is replaced by ''HttpArgReadNext()''. The value is retrieved by the same function as used with the GET method, ''HttpArgValue()''.<br />
<br />
<pre class="coding">static int CgiPostForm(HTTPD_SESSION *hs)<br />
{<br />
char *arg;<br />
char *val;<br />
char *first = NULL;<br />
char *last = NULL;<br />
long avail;<br />
<br />
avail = hs-&gt;s_req.req_length;<br />
while (avail) {<br />
arg = HttpArgReadNext(hs, &amp;avail);<br />
if (arg) {<br />
val = HttpArgValue(&amp;hs-&gt;s_req);<br />
if (val) {<br />
if (strcmp(arg, &quot;firstname&quot;) == 0) {<br />
first = strdup(val);<br />
}<br />
else if (strcmp(arg, &quot;familyname&quot;) == 0) {<br />
last = strdup(val);<br />
}<br />
}<br />
}<br />
}<br />
SendResult(hs, first, last);<br />
free(first);<br />
free(last);<br />
<br />
return 0;<br />
}</pre><br />
For the response we can use the same function ''SendResult()'', that had been used in the previous chapter above.<br />
<br />
== Webserver Code ==<br />
<br />
The webserver is started in the same way as in the [[uhttplib_basic.html|minimal sample]]:<br />
<br />
<pre class="coding">StreamInit();<br />
MediaTypeInitDefaults();<br />
HttpRegisterCgiFunction(&quot;getform.cgi&quot;, CgiGetForm);<br />
HttpRegisterCgiFunction(&quot;postform.cgi&quot;, CgiPostForm);<br />
HttpRegisterMediaType(&quot;cgi&quot;, NULL, NULL, HttpCgiFunctionHandler);<br />
StreamClientAccept(HttpdClientHandler, NULL);</pre><br />
Two additional calls have been added to register the two CGI functions, one is used for the GET and another one of the POST method. In addition, we need to register a CGI media type, using the standard handler ''HttpCgiFunctionHandler'' of the MicroHTTP library. This handler will call any registered CGI function when the browser requests an URL with the extension ''cgi''. Further details about media type handlers will be discussed later.<br />
<br />
== Next Step ==<br />
<br />
We can use CGIs to create all kind of dynamic content. However, in many cases only parts of a web page need to updated. Creating complete HTML pages within CGI functions may be an annoying job and requires to create a new runtime binary each time the web content is changed. [[uhttplib_ssi.html|Server side includes]] provide a smarter solution.<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Documents/uHTTP_Lib_Basic.htmlDocuments/uHTTP Lib Basic.html2017-07-13T08:30:00Z<p>Harald: Created page with "<div id="content"> = MicroHTTP Library: Basic Functions = This page gives you an overview of the application programming interface (API) provided by the uhttplib.html|Micr..."</p>
<hr />
<div><div id="content"><br />
<br />
= MicroHTTP Library: Basic Functions =<br />
<br />
This page gives you an overview of the application programming interface (API) provided by the [[uhttplib.html|MicroHTTP library]].<br />
<br />
== Initialization ==<br />
<br />
While Nut/OS tries to avoid initialization calls as far as possible, other operating systems and TCP/IP stacks may require them. Applications should therefore call<br />
<br />
<pre class="coding">int StreamInit(void);</pre><br />
before using any other function of the library. The Nut/OS version of this function simply returns 0 to indicate, that everything is just fine. And Nut/OS applications will run just fine without this call. However, this may change in later versions and it is highly recommended to include this call in any webserver application, even if you do not intend to run it on another operating system than Nut/OS.<br />
<br />
As explained previously, the old library expected the application to establish the TCP connection. This has been changed in the MicroHTTP library to maintain portability. All this TCP stack related stuff is now handled in<br />
<br />
<pre class="coding">int StreamClientAccept(HTTP_CLIENT_HANDLER handler, const char *params);</pre><br />
The first argument, the handler for incoming HTTP request, can be set to the standard handler ''HttpdClientHandler'' that is provided by the library. The argument ''params'' can be used to pass special arguments to the server routine, like the TCP port number. If a NULL pointer is passed instead, defaults will be used, for example, TCP port 80.<br />
<br />
Note, that this function will only return on fatal errors, e.g. when the system is running out of memory. Once called, it will handle all HTTP requests from connecting clients. There is just one problem: It will send all data with ''Content-Type: text/plain''. Most webbrowsers will then display HTML source code instead of rendered content. Thus, before calling the function above, you should first call<br />
<br />
<pre class="coding">int MediaTypeInitDefaults(void);</pre><br />
This will setup a minimum set of mime types. For Nut/OS, they are configurable with the Configurator. On a PC, where plenty of memory is available, all major media types will be enabled by default. At the time of this writing, these are<br />
<br />
* text/xml<br />
* text/plain<br />
* image/svg+xml<br />
* text/html<br />
* image/png<br />
* application/pdf<br />
* image/jpeg<br />
* application/x-javascript<br />
* application/x-java-archive<br />
* text/html<br />
* image/gif<br />
* text/css<br />
* image/bmp<br />
<br />
As a result, a minimal webserver can be implemented with three lines of code:<br />
<br />
<pre class="coding">StreamInit();<br />
MediaTypeInitDefaults();<br />
StreamClientAccept(HttpdClientHandler, NULL);</pre><br />
This simply webserver will handle all GET requests for files. On Nut/OS, it will use the previously configured file system, which is UROM by default.<br />
<br />
I will later explain how to implement all the fancy stuff like processing HTML forms, receiving file uploads or creating dynamic content. To be able to do this, the application must implement its own handlers, which need to deal with the TCP/IP stream of the established connection. The next chapter will give an introduction.<br />
<br />
== TCP/IP Streams ==<br />
<br />
Standard HTTP is based on TCP/IP streams. The server is listening on a TCP socket, to which the client (webbrowser) connects. As soon as the connection is established, both parties send and receive data via a stream socket.<br />
<br />
Nut/OS allows to attach stream sockets to standard C I/O-streams (FILE streams). This is a nice feature, because you can use C stdio functions like fprintf or fgets to send and receive data to and from the remote host. Actually, the old HTTP library didn't use any network specific API. Instead it expects, that the applications establishes the connection, attaches a FILE stream to the socket connection and passes a stream file pointer to the HTTP library functions.<br />
<br />
While being convenient for the developer, it is less optimal for the target system. For example, reading a header line up to the next carriage-return/linefeed requires to call fgetc() for each character, which in turn calls a number of lower level functions. Quite a lot of overhead. As long as only a few header lines need to be processed by the embedded webserver application on a GET request, this may be acceptable. Performance problems were raised with the implementation of the POST method, specifically when posting large chunks of binary data. File uploading became unacceptable slow.<br />
<br />
To avoid this bottleneck, the new library implements its own input functions.<br />
<br />
<pre class="coding">int StreamReadUntilChars(HTTP_STREAM *sp, const char *delim, const char *ignore, char *buf, int siz);<br />
int StreamReadUntilString(HTTP_STREAM *sp, const char *delim, char *buf, int siz);</pre><br />
The first function reads data from a stream until any of the characters in the string delim appears. It further allows to skip all the characters contained in the string ignore. For example, reading a header line can be done by<br />
<br />
<pre class="coding">got = StreamReadUntilChars(stream, &quot;\n&quot;, &quot;\r&quot;, buffer, avail);</pre><br />
Note that HTTP header lines are terminated by a carriage return follow by a linefeed character. With the call above, all linefeeds are ignored and the read stops at the carriage return, which will be replaced by string terminator. As a result, the buffer will contain the pure header line without any line ending character. The parameter ''avail'' tells the function, how many bytes to read at maximum. With header lines, this will be typically limited to the buffer size. It is somewhat more interesting, when the function is used to retrieve the data of a POST request. The application will have parsed the ''Content-Length'' header of the POST request and therefore knows, how many bytes the body will contain. To keep track of this figure, the function returns the number of bytes consumed, which is typically more than the number of bytes stored in the buffer.<br />
<br />
The second function is similar, but reads from the stream until a specified string appears. This comes quite handy when reading multipart MIME contents, as they appear in file uploads. The following call may be used to read all data until the next boundary string, which had been given by the ''Content-Type'' header.<br />
<br />
<pre class="coding">got = StreamReadUntilString(stream, delim, data, avail);</pre><br />
In the current implementation, the stream parameter of type HTTP_STREAM is no longer a FILE pointer, as it has been in the old library. Therefore, it cannot be used with C stdio functions. For reading, this is no big deal, because the new functions are much more convenient for handling HTTP streams. But it's a pity for writing to the stream, because the C standard functions were just fine and you are probably most familiar with them and don't want to learn, how to use new ones. Luckily, a set of output functions is provided, which is similar to the standard. They just have slightly different names and accept a HTTP_STREAM instead of a FILE stream pointer.<br />
<br />
<pre class="coding">int s_write(const void *buf, size_t size, size_t count, HTTP_STREAM *sp);<br />
int s_puts(const char *str, HTTP_STREAM *sp);<br />
int s_printf(HTTP_STREAM *sp, const char *fmt, ...);<br />
int s_flush(HTTP_STREAM *sp);</pre><br />
One additional function, which is not part of the C stdio, is<br />
<br />
<pre class="coding">int s_vputs(HTTP_STREAM *sp, ...);</pre><br />
This function writes a variable number of strings, which is quite useful with HTTP, where a mixture of constant and variable strings are often sent in one line. For example<br />
<br />
<pre class="coding">time_t now = time(NULL);<br />
s_vputs(stream, &quot;Date: &quot;, Rfc1123TimeString(gmtime(&amp;now)), &quot; GMT\r\n&quot;, NULL);</pre><br />
sends a complete ''Date'' header line. While the same could have been done with<br />
<br />
<pre class="coding">s_printf(stream, &quot;Date: %s GMT\r\n&quot;, Rfc1123TimeString(gmtime(&amp;now)));</pre><br />
the function ''s_vputs()'' is faster and much more simple, because no format string needs to be parsed. In any case, never forget to add a final NULL pointer to the list of arguments. Otherwise ''s_vputs()'' may send a lot of garbage to the server and may even crash your application.<br />
<br />
== Next Step ==<br />
<br />
You should now have the basis for [[uhttplib_forms.html|processing HTML forms]].<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Documents/uHTTP_Lib_AuthDocuments/uHTTP Lib Auth2017-07-13T08:29:30Z<p>Harald: Created page with "<div id="content"> = MicroHTTP Library: Basic Authentication = On this page we will look into basic access authentication, as it is provided by the uhttplib.html|MicroHTTP..."</p>
<hr />
<div><div id="content"><br />
<br />
= MicroHTTP Library: Basic Authentication =<br />
<br />
On this page we will look into basic access authentication, as it is provided by the [[uhttplib.html|MicroHTTP library]].<br />
<br />
Note, that this type of authentication will transmit user names and passwords over the line with Base64 encoding only, which can be easily converted back to human readable text. Additional techniques like TLS must be used to secure the connection.<br />
<br />
== Enabling Access Protection ==<br />
<br />
Applications can protect access to specific paths within their web content by calling<br />
<br />
<pre class="coding">int HttpRegisterAuthBasic(const char *path, const char *login, const char *realm);</pre><br />
If any requested URL starts with the given path, then the server will send back a 401 response, which tells the client, that access to the requested resource requires authentication. The browser will typically display the realm and prompt the user for name and password.<br />
<br />
Let's say, that on our webserver we move all protected files into a subdirectory named ''admin''. Then the following code snippet starts a webserver, where all URLs starting with the word ''admin'' are protected by user name ''root'' and password ''secret''. On the first access, the browser will prompt the user with an ''Admin Login'' dialog.<br />
<br />
<pre class="coding">StreamInit();<br />
MediaTypeInitDefaults();<br />
HttpRegisterAuthBasic(&quot;admin&quot;, &quot;root:secret&quot;, &quot;Admin Login&quot;);<br />
StreamClientAccept(HttpdClientHandler, NULL);</pre><br />
== Next Step ==<br />
<br />
Beside allowing authenticated users to modify the device's configuration remotely, you may further offer the capability to upgrade the firmware via the web interface by [[uhttplib_uploads.html|uploading files]].<br />
<br />
<br />
</div></div>Haraldhttp://www.ethernut.de/nutwiki/index.php/Documents/uHTTP_Lib_AjaxDocuments/uHTTP Lib Ajax2017-07-13T08:28:56Z<p>Harald: Created page with "<div id="content"> = MicroHTTP Library: Using Ajax = With Asynchronous JavaScript, data can be exchanged between the webserver and the webbrowser in the background. On this..."</p>
<hr />
<div><div id="content"><br />
<br />
= MicroHTTP Library: Using Ajax =<br />
<br />
With Asynchronous JavaScript, data can be exchanged between the webserver and the webbrowser in the background. On this page I will explain, how to implement this technique with the [[uhttplib.html|MicroHTTP library]].<br />
<br />
== HTML Document ==<br />
<br />
The following HTML document is kept intentionally simple. It's body contains a ''div'' element named ''time'' and references an external Javascript.<br />
<br />
<pre class="coding">&lt;html&gt;<br />
&lt;head&gt;<br />
&lt;title&gt;AJAX Sample&lt;/title&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
&lt;div id=&quot;time&quot;&gt;&lt;/div&gt;<br />
&lt;script type=&quot;text/javascript&quot; src=&quot;script.js&quot;&gt;&lt;/script&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</pre><br />
== Javascript ==<br />
<br />
The active part on the client's side is the following Javascript:<br />
<br />
<pre class="coding">var req = GetRequestObject();<br />
var wdog = 1;<br />
<br />
window.onload = main();<br />
<br />
function GetRequestObject()<br />
{<br />
if(window.XMLHttpRequest) {<br />
return new XMLHttpRequest();<br />
}<br />
else if (window.ActiveXObject) {<br />
try {<br />
return new ActiveXObject(&quot;Msxml2.XMLHTTP&quot;);<br />
} catch (e) {<br />
try {<br />
return new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;);<br />
} catch (e) {<br />
}<br />
}<br />
} <br />
alert('Ajax not available on this browser');<br />
}<br />
<br />
function RequestData()<br />
{<br />
if (req.readyState == 0) {<br />
wdog++;<br />
req.open('GET', 'clock.cgi', true);<br />
req.onreadystatechange = DisplayTime;<br />
req.send(null);<br />
} else {<br />
req.onreadystatechange = function () { };<br />
req.abort();<br />
setTimeout(&quot;RequestData();&quot;, 100);<br />
}<br />
}<br />
<br />
function Watchdog() {<br />
if (wdog != 0) {<br />
wdog = 0;<br />
} else {<br />
req.onreadystatechange = function () { };<br />
req.abort();<br />
setTimeout(&quot;RequestData();&quot;, 100);<br />
}<br />
setTimeout(&quot;Watchdog();&quot;, 5000);<br />
}<br />
<br />
function DisplayTime()<br />
{<br />
if(req.readyState == 4) {<br />
var response = eval('(' + req.responseText + ')');<br />
document.getElementById('time').innerHTML = response.time;<br />
RequestData();<br />
}<br />
}<br />
<br />
function main() {<br />
RequestData();<br />
Watchdog();<br />
}</pre><br />
When loaded into the brwoser, the script is running in the background and periodically requests ''clock.cgi'' from the webserver. A watchdog function is used to automatically recover from lost connections.<br />
<br />
Initially, Ajax used XML as its data exchange format. However, XML doesn't fit well in small embedded systems, so we will use JSON instead.<br />
<br />
<pre class="coding">req.open('GET', 'clock.cgi', true);</pre><br />
sends a HTTP request the server to execute ''clock.cgi'', which is expected to return the current time in JSON format<br />
<br />
<pre class="coding">{ &quot;time&quot;: &quot;HH:MM:SS&quot; }</pre><br />
which is then evaluated and displayed by<br />
<br />
<pre class="coding">var response = eval('(' + req.responseText + ')');<br />
document.getElementById('time').innerHTML = response.time;</pre><br />
As a result, the browser continuously displays the current time.<br />
<br />
== CGI Function ==<br />
<br />
There is nothing special in the required CGI function:<br />
<br />
<pre class="coding">static int CgiClock(HTTPD_SESSION *hs)<br />
{<br />
time_t now;<br />
const struct _tm *ltm;<br />
<br />
NutSleep(1000);<br />
<br />
HttpSendHeaderTop(hs, 200);<br />
HttpSendHeaderBottom(hs, &quot;text&quot;, &quot;html&quot;, -1);<br />
<br />
time(&amp;now);<br />
ltm = localtime(&amp;now);<br />
s_printf(hs-&gt;s_stream, &quot;{\&quot;time\&quot;: \&quot;%02d:%02d:%02d\&quot;}\r\n&quot;, ltm-&gt;tm_hour, ltm-&gt;tm_min, ltm-&gt;tm_sec);<br />
s_flush(hs-&gt;s_stream);<br />
<br />
return 0;<br />
}</pre><br />
Just one problem may appear on most browser: Due to internal caching, the browser may request the CGI just once and satisfy further request with his cached data. To avoid this, we can insert an additional HTTP header to disable caching. Unfortunately, there is no unique way to achieve this. The following should work for all major webbrowsers.<br />
<br />
<pre class="coding">HttpSendHeaderTop(hs, 200);<br />
s_puts(&quot;Cache-Control: no-cache, must-revalidate\r\n&quot;, hs-&gt;s_stream);<br />
s_puts(&quot;Content-Type: text/html; charset=iso-8859-1\r\n&quot;, hs-&gt;s_stream);<br />
s_puts(&quot;Expires: Mon, 26 Jul 1997 05:00:00 GMT\r\n&quot;, hs-&gt;s_stream);<br />
HttpSendHeaderBottom(hs, &quot;text&quot;, &quot;html&quot;, -1);</pre><br />
For the sake of completeness, here is the code to start the Ajax webserver.<br />
<br />
<pre class="coding">StreamInit();<br />
MediaTypeInitDefaults();<br />
HttpRegisterCgiFunction(&quot;clock.cgi&quot;, CgiClock);<br />
HttpRegisterMediaType(&quot;cgi&quot;, NULL, NULL, HttpCgiFunctionHandler);<br />
StreamClientAccept(HttpdClientHandler, NULL);</pre><br />
Actually there is nothing new in here.<br />
<br />
== That's all for now ==<br />
<br />
The [[uhttplib.html|MicroHTTP library]] offers several other features like redirecting, error handling etc. By the time I will try to add more to this documentation. Since then, you may refer to the uHttp samples and the API documentation that comes with the Nut/OS distribution.<br />
<br />
<br />
</div></div>Harald