Académique Documents
Professionnel Documents
Culture Documents
ELEX SEM-II)
LAB MANUAL
T.E. ELECTRONICS (SEMESTER-II)
Embedded Processors Lab
Subject Code: 304215
Teaching Scheme
Examination Scheme
Practical: 2Hrs/Week
PREFACE
TABLE OF CONTENTS
Sr. No.
1
1.1
Topic
Introduction
SCARM Installation
Page No.
4
Embedded C
Embedded C is a set of language extensions for the C Programming language
by the C Standards committee to address commonality issues that exist between
C extensions for different embedded systems. Historically, embedded C
programming requires nonstandard extensions to the C language in order to
support exotic features such as fixed-point arithmetic, multiple distinct memory
banks, and basic I/O operations.
In 2008, the C Standards Committee extended the C language to address these
issues by providing a common standard for all implementations to adhere to. It
includes a number of features not available in normal C, such as, fixed-point
arithmetic, named address spaces, and basic I/O hardware addressing.
Embedded C uses most of the syntax and semantics of standard C, e.g., main()
function, variable definition, datatype declaration, conditional statements (if,
switch, case), loops (while, for), functions, arrays and strings, structures and
union, bit operations, macros, etc.
Advantages
It is small and reasonably simpler to learn, understand, program and
debug.
Compared to assembly language, C code written is more reliable and
scalable, more portable between different platforms.
C compilers are available for almost all embedded devices in use today,
and there is a large pool of experienced C programmers.
Unlike assembly, C has advantage of processor-independence and is not
specific to any particular microprocessor/microcontroller or any system.
This makes it convenient for a user to develop programs that can run on
most of the systems.
As C combines functionality of assembly language and features of high
level languages, C is treated as a middle-level computer language or
high level assembly language.
It is fairly efficient.
It supports access to I/O and provides ease of management of large
embedded projects.
Java also used in many embedded systems but Java programs require
Java Virtual Machine (JVM), which consume lot of resources. Hence it is
not used for smaller embedded devices.
1.
10
11
12
13
Signal name
3.3V
P1.31/NTRST
P1.28/TDI
P1.30/TMS
17
2
4
6
8
P1.29/TCK
P1.26/RTCK
P1.27/TDO
NRST
GND
GND
10
14
18
20
GND
12
GND
GND
16
GND
GND
GND
J6:
This is 26 pin dual line headers. It brings out I/O and most of the pins of the
LPC21xx micro-controller.
Further, 5V and GND are also made available on these connectors. These
connectors are intended for use to connect external peripherals.
The pin/signal details of J6 are as below:
Pin
1
3
5
7
9
11
13
15
17
19
21
23
25
Signal name
P1.16
2
P1.18
4
P0.28
6
P0.30
8
P0.10
10
P0.12
12
P0.14
14
P0.16
16
P1.18
18
P1.25
20
P1.23
22
P1.21
24
+ 5V
26
6.2 Contents:
The JTAG Cable consists of following parts:
Dongle (a small box with connectors on both ends).
Cable.
The dongle consists of some electronic circuit for interfacing the JTAG port
of target processor to the host computer. The cable is a bunch of wires to
connect the dongle with the JTAG port of target.
6.3 Power Supply Requirements:
The JTAG cable draws power from the target board. Thus it does not require a
separate power source.
6.4 Connecting JTAG Cable:
SJT-S:
There is a DB9 female connector on one end of the dongle. This directly mates
with the PC COM port which has a DB9 male connector (or you can connect
yellow color serial cable, supplied with SJT-S or STK-2148 board, between
DB9 female connector on one end of the dongle and PC COM port which has
a DB9 male connector). The other end of the dongle has DB25 female
connector. There is a DB25 male connector on one end of the cable. These
DB25 female and DB25 male connectors are designed to mate with each other
directly. The other end of the cable has a 20-pin header. This should be
connected to the JTAG connector of the target board.
CAUTION:
The JTAG Cable must not be connected or dis-connected when power is
applied to the target board.
Turn off power to the target board, connect the JTAG Cable and then you may
turn on power to the target board.
Connecting the JTAG Cable with incorrect polarity / orientation may
permanently damage the STK- 2148 board and/or the JTAG Cable. It will also
make the warranty void for both the products.
6.5 Verifying correct cable connection:
When the JTAG Cable is correctly connected to PC as well as the target board,
it serves as a link between the JTAG port of target processor and the PC. This
link is used by SPJ - SCARM software
Tools (e.g. Debugger for ARM microcontrollers).
20
21
22
Connections:
Keep S6.1 switch in ON position.
Keep S13.1 switch in ON position.
Keep S12 switch in ON position.
Procedure:
To Edit / Compile/ Generate Hex file.
To download and run this program.
Output:
You can see the message Welcome to AISSMSCOE on LCD. If required Reset
the board.
Conclusion:
23
LCD.C
/* LCD connections:
P1.25 P1.24 P0.30 P0.22 P0.17 P0.15
RS
EN
D7
D6
4 bit interface is used.
D5
*/
#include <Philips\LPC2148.h>
#include "LCD.h"
void SmallDelay (void)
{
int i;
for(i=0;i<100;i++);
}
void LcdCmd1 (unsigned char cmd)
{
// send command on on data lines (D4 to D7)
if (cmd & 0x01)
IO0SET = (1<<15);
else
IO0CLR = (1<<15);
if (cmd & 0x02)
IO0SET = (1<<17);
else
IO0CLR = (1<<17);
if (cmd & 0x04)
IO0SET = (1<<22);
else
IO0CLR = (1<<22);
if (cmd & 0x08)
IO0SET = (1<<30);
else
IO0CLR = (1<<30);
IO1CLR = 0x03000000
SmallDelay() ;
// CLEAR(0) RS and EN
IO1SET = 0x01000000
// SET(1) EN
SmallDelay() ;
24
D4
// CLEAR(0) EN
SmallDelay() ;
}
void LcdDat1 (unsigned char dat)
{
// send data on on data lines (D4 to D7)
if (dat & 0x01)
IO0SET = (1<<15);
else
IO0CLR = (1<<15);
if (dat & 0x02)
IO0SET = (1<<17);
else
IO0CLR = (1<<17);
if (dat & 0x04)
IO0SET = (1<<22);
else
IO0CLR = (1<<22);
if (dat & 0x08)
IO0SET = (1<<30);
else
IO0CLR = (1<<30);
IO1SET = 0x02000000
// SET(1) RS
// CLEAR(0) EN
// SET(1) EN
// CLEAR(0) EN
SmallDelay() ;
IO1CLR = 0x01000000
SmallDelay() ;
IO1SET = 0x01000000
SmallDelay() ;
IO1CLR = 0x01000000
SmallDelay() ;
}
void Delay250 (void)
{
int k,j ;
j =200 ;
for(k = 0 ; k < 100 ; k ++)
{
25
IO0DIR = 0x40428000 ;
// Configure P0.15(D4),
P0.17(D5), P0.22(D6) and P0.30(D7) as Output
IO0CLR = 0x40428000 ;
// CLEAR(0) P0.15(D4),
P0.17(D5), P0.22(D6) and P0.30(D7)
DelayMs(6) ;
LcdCmd1(0x03) ;
DelayMs(6) ;
LcdCmd1(0x03) ;
Delay250() ;
LcdCmd1(0x03) ;
Delay250() ;
LcdCmd1(0x02) ;
Delay250() ;
LcdCmd(0x28) ;
LcdCmd(0x08) ;
LcdCmd(0x0c) ;
26
27
2.
HELLOLCD.C
#include <Philips\LPC2148.h>
#include "lcd.h"
void main ()
{
LcdInit();
LCD
// Initialize
DisplayRow (1,"
DisplayRow (2,"
WELCOME TO
AISSMS COE
");
");
while(1)
{}
}
3.
LCD.H
#ifndef LCD_H
#define LCD_H
void LcdInit (void);
void DisplayRow (int row, char *str);
#endif /* LCH_H */
28
Procedure:
To Edit / Compile/ Generate Hex file.
To download and run this program.
Output:
You can see the digital values on the LCD. If required reset the board.
Note: Keep S4.1 switch in OFF position, after execution of program.
Conclusion:
29
LCD.C
/* LCD connections:
P1.25 P1.24 P0.30 P0.22 P0.17 P0.15
RS
EN
D7
D6
4 bit interface is used.
D5
*/
#include <Philips\LPC2148.h>
#include "LCD.h"
void SmallDelay (void)
{
int i;
for(i=0;i<100;i++);
}
void LcdCmd1 (unsigned char cmd)
{
// send command on on data lines (D4 to D7)
if (cmd & 0x01)
IO0SET = (1<<15);
else
IO0CLR = (1<<15);
if (cmd & 0x02)
IO0SET = (1<<17);
else
IO0CLR = (1<<17);
if (cmd & 0x04)
IO0SET = (1<<22);
else
IO0CLR = (1<<22);
if (cmd & 0x08)
IO0SET = (1<<30);
else
IO0CLR = (1<<30);
IO1CLR = 0x03000000
SmallDelay() ;
// CLEAR(0) RS and EN
IO1SET = 0x01000000
// SET(1) EN
SmallDelay() ;
30
D4
// CLEAR(0) EN
SmallDelay() ;
}
void LcdDat1 (unsigned char dat)
{
// send data on on data lines (D4 to D7)
if (dat & 0x01)
IO0SET = (1<<15);
else
IO0CLR = (1<<15);
if (dat & 0x02)
IO0SET = (1<<17);
else
IO0CLR = (1<<17);
if (dat & 0x04)
IO0SET = (1<<22);
else
IO0CLR = (1<<22);
if (dat & 0x08)
IO0SET = (1<<30);
else
IO0CLR = (1<<30);
IO1SET = 0x02000000
// SET(1) RS
// CLEAR(0) EN
// SET(1) EN
// CLEAR(0) EN
SmallDelay() ;
IO1CLR = 0x01000000
SmallDelay() ;
IO1SET = 0x01000000
SmallDelay() ;
IO1CLR = 0x01000000
SmallDelay() ;
}
void Delay250 (void)
{
int k,j ;
j =200 ;
for(k = 0 ; k < 100 ; k ++)
{
31
IO0DIR = 0x40428000 ;
// Configure P0.15(D4),
P0.17(D5), P0.22(D6) and P0.30(D7) as Output
IO0CLR = 0x40428000 ;
// CLEAR(0) P0.15(D4),
P0.17(D5), P0.22(D6) and P0.30(D7)
DelayMs(6) ;
LcdCmd1(0x03) ;
DelayMs(6) ;
LcdCmd1(0x03) ;
Delay250() ;
LcdCmd1(0x03) ;
Delay250() ;
LcdCmd1(0x02) ;
Delay250() ;
LcdCmd(0x28) ;
LcdCmd(0x08) ;
LcdCmd(0x0c) ;
32
2.
ADC.C
/*******************************************************************
********************
# Project Code : MA-Exp
#
# TESTADC C file
#
# ------# History
# ------# Date
|Release|Author| Changes
# DD-MM-YYYY |
|
|
# -----------------------------------------------------------------------------------# 08.03.2007 | 0.1 | NSG | Initial Version.
#
|
|
|
#
|
|
|
#
|
|
|
********************************************************************
********************/
#include <Philips\LPC2148.h>
33
//
34
BLOCK DIAGRAM:
CONNECTIONS:
PROCEDURE:
To Edit / Compile/ Generate Hex file.
To download and run this program.
OUTPUT:
CONCLUSION:
35
36
CONNECTIONS:
Keep S5 switch (present in I2C Peripherals region) in ON position.
PROCEDURE:
To Edit / Compile/ Generate Hex file.
To download and run this program.
OUTPUT:
You can see output on SPJTerminal. Therefore Open SPJTerminal. Go to Port ->
Settings. Do proper settings (Baud Rate: 19200, Data Bits: 8, Stop Bits: 1, Echo: Off,
Parity: None, Com Port: Com 1 (if other choose it)). Click on OK. Go to Port ->
Open. If required Reset the STK-2148 board. First data will be written in EEPROM
and then it will be read from EEPROM. The same data (0, 1, 2 and 3) will be
displayed on SPJTerminal. It will transmit the message "Hello world!.
Note: Keep S5 switch in OFF position, after execution of program.
CONCLUSION:
37
<Philips\LPC2138.h>
<Stdio.h>
"I2C.h"
"TIMER.h"
/***************************************************
Contains all EEPROM related functions.
Writing to and reading from the EEPROM fuctions.
All the user data, settings and logged data
will goes into EEPROM.
I2C0 is used for interfacing.
****************************************************
*/
/*
Initialises the I2C protocol and port pins.
*/
void I2C_Init (void)
{
// Power on I2C0 peripheral
PCONP |= 0x00000080;
// Define port pin as SDA and SCL
PINSEL0
|= 0x00000050 ;
I2C0CONCLR = 0x6C;
I2C0CONSET = 0x40;
39
// Start set
// 0x08: ready for device
address
return FALSE;
I2C0DAT
= EEPROM_DEVADDR|0x01;// addr[0]=1 means I2C read
I2C0CONCLR = 0x28;
// clear all except I2EN and AA
if (!I2C_WaitStatus(0x40))
// 0x40: ready for data byte
return FALSE;
I2C0CONCLR = 0x2C;
if (!I2C_WaitStatus(0x58))
return ACK
return FALSE;
= 0x08;
// clear SI flag
= ((u32startAddr & 0x0000FF00)>>8) &0xFF;
#endif
I2C0CONCLR = 0x2C;
if (!I2C_WaitStatus(0x28))
return FALSE;
I2C0DAT
= (u8ptr2arr[u32i])&0x000000FF;
u32startAddr++;
I2C0CONCLR = 0x2C;
if (!I2C_WaitStatus(0x28))
return FALSE;
I2C0CONSET = 0x10;
I2C0CONCLR = 0x2C;
write
I2C0CONCLR = 0x2C;
if (I2C_WaitStatus(0x18))
break;
else
{
I2C0CONCLR = 0x2C;
I2C0CONSET = 0x10;
I2C0CONCLR = 0x2C;
}
}
I2C0CONSET = 0x10;
I2C0CONCLR = 0x2C;
}
return TRUE;
}
41
I2C_H
I2C_H
NULL
NULL
(0)
FALSE
FALSE
(0)
TRUE
TRUE
(1)
/* Settings */
#define
PERIFERAL_OPERATING_FREQUENCY_IN_HZ
12000000
#define
EEPROM_OPERATING_FREQUENCY_IN_HZ 50000
#define EEPROM_DEVADDR
0xA0
#define
EEPROM_24C512
1
// EEPROM IC used
#define
EEPROM_SIZE
0xFFFF
// Size
#define
EEPROM_WAIT_TIME_OUT
5000 // 1msec
//EEPROM_24C02
//EEPROM_24C04
//EEPROM_24C08
//EEPROM_24C16
//EEPROM_24C32
//EEPROM_24C64
//EEPROM_24C128
//EEPROM_24C256
//EEPROM_24C512
size
size
size
size
size
size
size
size
size
0x0000FF
0x0001FF
0x0003FF
0x0007FF
0x000FFF
0x001FFF
0x003FFF
0x007FFF
0x00FFFF
/* Function Definations */
extern
void I2C_Init (void);
extern
unsigned char
I2C_WaitStatus (unsigned char u8status);
extern
unsigned char
I2C_WriteToEEPROM (unsigned int
u32startAddr, unsigned char *u8ptr2arr, unsigned int u32len);
extern
unsigned char
I2C_ReadFromEEPROM (unsigned int
u32startAddr, unsigned char *u8ptr2arr, unsigned int u32len);
#endif //I2C_H
3. TIMER.C
/*******************************************************************
********************
# Project Code : MA-Exp
#
# TIMER C file
#
# ------# History
# ------# Date
|Release|Author| Changes
42
43
4. TIMER.H
/*
Timer.h
*/
#ifndef TIMER_H
#define TIMER_H
/* Prescaler */
#define PERIFERAL_OPERATING_FREQUENCY_IN_HZ 12000000
#define DESIRED_COUNT_FREQ0
1000000
//1MHz
#define PRESCALER0
((PERIFERAL_OPERATING_FREQUENCY_IN_HZ/DESIRED_COUNT_FREQ0)-1)
//#define PRESCALER1
((PERIFERAL_OPERATING_FREQUENCY_IN_HZ/DESIRED_COUNT_FREQ1)-1)
#define
#define
#define
TIMER0_RESET()
TIMER0_ENABLE()
TIMER0_DISABLE()
T0TCR=2
T0TCR=1
T0TCR=0
/* Function declrations */
extern void TIMER_Init (void);
extern void TIMER_WaitForNextTick (void);
#endif /* TIMER_H */
5. MAIN.C
#include
#include
#include
#include
#include
<Philips\LPC2148.h>
<Stdio.h>
"UART0.h"
"I2C.h"
"TIMER.h"
/***************************************************
Main function.
****************************************************
*/
unsigned
unsigned
unsigned
unsigned
44
char
char
char
char
*MAIN_u8buffer1;
MAIN_u8buffer2[20] ;
MAIN_u8temp = 0;
MAIN_u8temp12[2][2]={0,1,2,3};
printf("\n%s",*MAIN_u8buffer2);
printf("\n%x",MAIN_u8buffer2[0]);
printf("\n%x",MAIN_u8buffer2[1]);
printf("\n%x",MAIN_u8buffer2[2]);
printf("\n%x",MAIN_u8buffer2[3]);
while(1);
}
}
45
CONNECTIONS:
Connect the power supply to board i.e.9V & 500MA.
Connect the one terminal i.e. male connector to board at UART0 & other
terminal to our PC.
PROCEDURE:
To Edit / Compile/ Generate Hex file.
To download and run this program.
OUTPUT:
Seven Segment Display starts displaying from 0 to 9 nos.
CONCLUSION:
46
// I2C Clock Duty Cycle (high and low), Bit freq.= 100KHz
I2C1SCLH
= 60;
I2C1SCLL
= 60;
}
/*
Waits until given status occured.
Return:
True on status occured and
False on time out
*/
/***************************************************
Main function.
****************************************************
47
// Start set
I2C1CONCLR = 0x2C;
// clear all except I2EN
I2C1DAT
= I2CEXPANDER_ADDR;// addr[0]=0 means
I2C write
for(i=0;i<300;i++);
I2C1CONCLR = 0x2C;
I2C1DAT
= dis1 ;
for(i=0;i<300;i++);
I2C1CONCLR = 0x2C;
// Data on DIS1
// clear all except I2EN
I2C1DAT
= dis2 ;
for(i=0;i<300;i++);
I2C1CONCLR = 0x2C;
// Data on DIS2
// clear all except I2EN
I2C1CONSET = 0x10;
// generate stop
condition
for(i=0;i<300;i++);
I2C1CONCLR = 0x2C;
}
void SmallDelay()
{
unsigned int i,j ;
for( i = 0 ; i < 3000000 ; i++)
{
j++ ;
j--;
}
}
void main(void)
{
TargetResetInit();
I2C_Init();
while(1)
{
SevenSeg(DISPLAY_0,
SmallDelay();
SevenSeg(DISPLAY_2,
SmallDelay();
SevenSeg(DISPLAY_4,
SmallDelay();
SevenSeg(DISPLAY_6,
SmallDelay();
SevenSeg(DISPLAY_8,
48
DISPLAY_1);
DISPLAY_3);
DISPLAY_5);
DISPLAY_7);
DISPLAY_9);
2. SevenSeg.h
#ifndef SEVENSEG_H
#define SEVENSEG_H
void I2C_Init (void);
#define I2CEXPANDER_ADDR 0x40
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
DISPLAY_0
DISPLAY_1
DISPLAY_2
DISPLAY_3
DISPLAY_4
DISPLAY_5
DISPLAY_6
DISPLAY_7
DISPLAY_8
DISPLAY_9
DISPLAY_A
DISPLAY_B
DISPLAY_C
DISPLAY_D
DISPLAY_E
DISPLAY_F
0xC0
0xf9
0xA4
0xB0
0x99
0x92
0x82
0xf8
0x80
0x90
0xA0
0x83
0xC6
0xA1
0x84
0x8E
#endif /* SEVENSEG_H*/
49
CONNECTIONS:
Connect the power supply to board i.e.9V & 500MA.
Connect the one terminal i.e. male connector to board at UART0 & other
terminal to our PC.
Connect the Board to STWS-DCM_V1.0 with 10-Pin Relimate Connector.
Switch Position
SW3.1 ON
SW3.2 ON
SW5.1 ON
SW5.2 ON
PROCEDURE:
To Edit / Compile/ Generate Hex file.
To download and run this program.
OUTPUT:
DC Motor speed varies continuously.
CONCLUSION:
50
not defined.
bits23:16=> NSEL0 Read-back for the PLL0 Pre-Divider
value. This is the value
currently used by PLL0, and is one less
than the actual divider.
bit24 =>
PLLE0_STAT Read-back for the PLL0 Enable bit.
This bit reflects the state of the
53
Reserved
* */
/*IF OUTPUT OF PLL IS ALREADY CONNECTED TO ADV PERIPHERAL BUS
(APB) THEN DISCONNECT PLL*/
if(LPC_SC->PLL0STAT & (1<<25)) // CHECK PLLC0 BIT IN PLL0CON
{
LPC_SC->PLL0CON
= 1;
LPC_SC->PLL0FEED = 0XAA;
LPC_SC->PLL0FEED = 0X55;
}
/*DISABLE PLL*/
LPC_SC->PLL0CON
= 0;
LPC_SC->PLL0FEED = 0XAA;
LPC_SC->PLL0FEED = 0X55;
/*
* CCLKCFG Description
* bits7:0
CCLKSEL Selects the divide value for creating
the CPU clock (CCLK)
from the PLL0 output.
0
the CPU clock. This setting is
clock.
pllclk is divided by 3 to produce
//By default it is
/*
* PLL0CFG Description
* bits14:0
MSEL0 PLL0 Multiplier value. Supplies the
value "M" in PLL0 frequency
calculations. The value stored here is M
- 1. Supported values for M
are 6 through 512 and those listed in
Table 21.
Note:Not all values of M are needed, and
therefore some are not
supported by hardware.
bit15
Reserved, user software should not write
ones to reserved bits. The
value read from a reserved bit is not
defined.
bits23:16 NSEL0 PLL0 Pre-Divider value. Supplies the
value "N" in PLL0 frequency
calculations. The value stored here is N
- 1. Supported values for N are
1 through 32.
bits 24:31
Reserved
* */
LPC_SC->PLL0CFG
55
|= (PLL0_MVALUE-1) | ((PLL0_NVALUE-1)<<16);
2. PLL.H
/*
* PLL.h
*
* Created on: Sep 3, 2013
*
Author: Amar
*/
#ifndef PLL_H_
#define PLL_H_
/*PLL SETTINGS FOR CCLK =117/100/48MHZ WITH 6MHZ CRYSTAL
*
* 117 => m=39,n=1,clkdiv = 4
* 100 => m=21,n=1,clkdiv = 5
* 48 => m=20,n=1,clkdiv = 10
* 120 => m=20,n=1,clkdiv = 2
* 12 => m=20,n=1,clkdiv = 40
* */
#define FIN
12000000
#define MainOsc
1
#define ENABLEPLL0
1
#define ENCONNECTPLL0 3
#define PLL0_MVALUE
20
#define PLL0_NVALUE
1
#define CCLKDIV
40
//Controller Clock
Divider
#define CCLK
(((2*PLL0_MVALUE*FIN)/PLL0_NVALUE)/CCLKDIV)
/*END PLL SETTINGS*/
void ConfigureClock();
56
3. MAIN.C
/*
====================================================================
===========
Name
: main.c
Description : main definition
====================================================================
===========
*/
#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif
#include
#include
#include
#include
<cr_section_macros.h>
<NXP/crp.h>
<stdio.h>
"PLL.h"
//PWM1 channel 1
is
//P2.1 as GPIO
//P2.1 as High
PWM_Init();
while(1)
{
for(i=0;i<=3000;i++);
// delay for Stability of
Change in Width
if(flag == 0x00)
{
LPC_PWM1->MR1 = LPC_PWM1->MR1+100;
LPC_PWM1->LER = 0x000000FF;
//Reset
PWM1 Match Registers
if(LPC_PWM1->MR1 >= 27000)
{
flag1 = 0xff;
flag = 0xff;
LPC_PWM1->LER = 0x000000FF; //Reset PWM1
Match Registers
}
}
else if(flag1 == 0xff)
{
LPC_PWM1->MR1 = LPC_PWM1->MR1-100;
LPC_PWM1->LER = 0x000000FF;
58
59
CONNECTIONS:
Connect the power supply to board i.e.9V & 500MA.
Connect the one terminal i.e. male connector to board at UART0 & other
terminal to our PC.
Connect the J1 & J2 (LPC1768EtherCan_V1.0) Connect with DB-9 Connector
(Male- Male).
Switch Position
SW3.1 ON
SW3.2 ON
S3.1 ON
S3.2 ON
S3.3 ON
S3.4 ON
PROCEDURE:
To Edit / Compile/ Generate Hex file.
OUTPUT:
On HyperTerminal/SPJ Terminal [Setting=> Baud Rate: 19200, No Parity, No
Echo, 8-Bits Data, 1-StopBit].
1st time Press any Key=>CAN1 Transmit with id and Data, CAN2 Receive with
id and Data,
2nd time Press any key =>CAN2 Transmit with id and Data, CAN1 Receive
with id and Data.
CONCLUSION:
60
<stdio.h>
"LPC17xx.h"
"UART0.h"
"CAN.h"
/*******************************************************************
*******
GLOBAL VARIABLES
********************************************************************
*******/
CAN_TX_CONF CAN_CanTxConf[CAN_MAX_TX_MSG]=
{
CAN_TX_400, 8, CAN_CHANNEL1, 00, (CAN_29BIT | CAN_NO_RTR),
0x400,
CAN_TX_420, 8, CAN_CHANNEL1, 00, (CAN_29BIT | CAN_NO_RTR),
0x420,
CAN_TX_DEAD, 8, CAN_CHANNEL2, 00, (CAN_29BIT | CAN_NO_RTR),
0xDEAD,
CAN_TX_ADDED, 8, CAN_CHANNEL2, 00, (CAN_29BIT | CAN_NO_RTR),
0xADDED
};
CAN_CHANNEL_CONF CAN_CanChannelConf[MAX_CANPORTS]=
{
CAN_CHANNEL1, 0, 0, CAN_BAUD_125K,
CAN_CHANNEL2, 1, 0, CAN_BAUD_125K
};
CAN_RX_CONF CAN_CanRxConf[CAN_MAX_RX_MSG]=
{
CAN_RX_400,
0x400,
CAN_RX_420,
0x420,
CAN_RX_DEAD,
0xDEAD,
CAN_RX_ADDED,
0xADDED
};
CAN_RX_FRAME
unsigned int
unsigned int
unsigned int
CAN_CanRxBuffer[CAN_MAX_RX_MSG];
CAN_u32CANStatus;
CAN_u32CAN1RxCount = 0, CAN_u32CAN2RxCount = 0;
CAN_u32CAN1ErrCount = 0, CAN_ulCAN2ErrCount = 0;
/*******************************************************************
*************************************
*
* Function Name
CAN_SetACCFLookup
* Description :
Set Acceptance Filter Look up Table
* Arguments
none
* returns
function doesn't return
********************************************************************
************************************/
void CAN_SetACCFLookup( void )
{
61
62
#ifdef DEBUG
UART_PrintString("CAN_IsrRx1\n");
#endif
66
*/
for(u8Count=0; u8Count < CAN_MAX_RX_MSG ; u8Count++)
{
if(CAN_CanRxConf[u8Count].u32Id == LPC_CAN1->RID)
{
CAN_CanRxBuffer[u8Count].u8Channel = CAN_CHANNEL1;
CAN_CanRxBuffer[u8Count].u8DLC = (LPC_CAN1->RFS &
0x000F0000)>>16;
*((unsigned
int*)&CAN_CanRxBuffer[u8Count].u8Data[0]) = LPC_CAN1->RDA;
*((unsigned
int*)&CAN_CanRxBuffer[u8Count].u8Data[4]) = LPC_CAN1->RDB;
CAN_CanRxBuffer[u8Count].u8RxFlag = 1;
break;
}
}
CAN_CanRxBuffer[u8Count].u8RxFlag = 1;
LPC_CAN1->CMR = 0x04; // release receive buffer
}
/*******************************************************************
*************************************
*
* Function Name
CAN_IsrRx2
* Description :
CAN Rx2 interrupt handler
*
*
*
* Arguments
none
* returns
function doesn't return
********************************************************************
************************************/
void CAN_IsrRx2(void)
{
unsigned char u8Count;
//
#ifdef DEBUG
//
UART_PrintString("CAN_IsrRx2\n");
//
#endif
LPC_GPIO2->FIOPIN2 = 0x00000002;
*/
for(u8Count=0; u8Count < CAN_MAX_RX_MSG ; u8Count++)
{
if(CAN_CanRxConf[u8Count].u32Id == LPC_CAN2->RID)
{
CAN_CanRxBuffer[u8Count].u8Channel = CAN_CHANNEL1;
CAN_CanRxBuffer[u8Count].u8DLC = (LPC_CAN2->RFS &
0x000F0000)>>16;
*((unsigned
int*)&CAN_CanRxBuffer[u8Count].u8Data[0]) = LPC_CAN2->RDA;
*((unsigned
int*)&CAN_CanRxBuffer[u8Count].u8Data[4]) = LPC_CAN2->RDB;
CAN_CanRxBuffer[u8Count].u8RxFlag = 1;
67
68
(0xE0000000)
(CAN_REG_BASE + 0x00038000)
(CAN_REG_BASE + 0x0003C000)
(CAN_REG_BASE + 0x00040000)
0x001C001D
0x001C000E
70
u8RxHandle;
u8DLC;
u8Channel;
u8RxFlag;
u8Data[12];
CAN_RX_CONF CAN_CanRxConf[CAN_MAX_RX_MSG];
CAN_RX_FRAME CAN_CanRxBuffer[CAN_MAX_RX_MSG];
CAN_CHANNEL_CONF CAN_CanChannelConf[MAX_CANPORTS];
CAN_TX_CONF CAN_CanTxConf[CAN_MAX_TX_MSG];
3. UART0.C
/*
====================================================================
====================================
Name
: UART0.c
Description : This file contains the functions related to UART0
communication
====================================================================
====================================
*/
#include "LPC17xx.h"
#include "PLL.h"
#include "UART0.h"
void InitUart0(void)
{
/*
*****************************************************************
* Inputs : NA
* Output :
NA
71
00
5-bit
01
6-bit
10
7-bit
11
8-bit
character length
character length
character length
bit2
1 stop bit. 0
1
2 stop
Disable parity
1
Enable
Break Control
Disable break
1
Enable
break transmission. Output pin UARTn TXD is forced to logic 0
72
Disable
1
Enable
73
75
76
4. UART0.H
/*
* UART0.h
*
* Created on: Sep 3, 2013
*
Author: Amar
*/
#ifndef UART0_H_
#define UART0_H_
#define
#define
#define
#define
#define
void
char
char
void
LSR_RDR
1
LSR_THRE 0x20
PCUART0
(1<<3)
PCLK_UART0
01
BAUDRATE 19200
InitUart0(void);
UART0putchar(char);
UART0getchar(void);
UART0Puts(char *pcString);
77
5. MAIN.C
#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif
#include
#include
#include
#include
#include
#include
<cr_section_macros.h>
<NXP/crp.h>
<stdio.h>
"PLL.h"
"UART0.h"
"CAN.h"
79
SW6.4 ON
SW7.1 ON
SW7.2 ON
SW7.3 ON
SW7.4 ON
PROCEDURE:
To Edit / Compile/ Generate Hex file.
To download and run this program.
OUTPUT:
On PC, Any Internet Browser -> 192.168.1.150
CONCLUSION:
80
// Default to DP83848C
if (phy_in_use == LAN8720_ID) {
phy_linkstatus_reg = PHY_REG_BMSR;
phy_linkstatus_mask = 0x0004;
}
// Now check the link status
for (loop = 0; loop < 0x10000; loop++) {
value = ReadFromPHY (phy_linkstatus_reg);
if (value & phy_linkstatus_mask) {
// The link is on
break;
}
}
// Now configure for full/half duplex mode
if (value & 0x0004) {
// We are in full duplex is enabled mode
LPC_EMAC->MAC2
|= MAC2_FULL_DUP;
LPC_EMAC->Command |= CR_FULL_DUP;
LPC_EMAC->IPGT
= IPGT_FULL_DUP;
}
else {
// Otherwise we are in half duplex mode
LPC_EMAC->IPGT = IPGT_HALF_DUP;
83
84
85
// discards an
// from RX-fifo
2. ETHMAC.H
#ifndef __ETHMAC_H
#define __ETHMAC_H
#define
address
#define
#define
#define
#define
#define
MYMAC_1
MYMAC_2
MYMAC_3
MYMAC_4
MYMAC_5
MYMAC_6
2
3
4
5
6
/* EMAC
#define
4*1536=
#define
3*1536=
#define
Bytes
#define ETH_MAX_FLEN
*/
87
1536
status definitions. */
(*(unsigned int *)(RX_DESC_BASE
(RX_BUF_BASE + ETH_FRAG_SIZE*i)
(TX_BUF_BASE + ETH_FRAG_SIZE*i)
/* Receive Enable
/* Pass All Receive Frames
/* RX Flow Control
/* TX Flow Control
/* Loop Back Mode
/* Reset TX Logic
/* Reset MAC TX Control
/* Reset RX Logic
/* Reset MAC RX Control
/* Simulation Reset
/* Soft Reset MAC
MAC2_FULL_DUP
0x00000001
MAC2_FRM_LEN_CHK
0x00000002
MAC2_HUGE_FRM_EN
0x00000004
MAC2_DLY_CRC
0x00000008
MAC2_CRC_EN
0x00000010
MAC2_PAD_EN
0x00000020
MAC2_VLAN_PAD_EN
0x00000040
MAC2_ADET_PAD_EN
0x00000080
MAC2_PPREAM_ENF
0x00000100
MAC2_LPREAM_ENF
0x00000200
MAC2_NO_BACKOFF
0x00001000
/* No Backoff Algorithm
MAC2_BACK_PRESSURE
*/
MAC2_EXCESS_DEF
0x00002000
/* Backoff Presurre / No
0x00004000
/* Excess Defer
/* Default value
0x00000100
Register */
TEST_SHCUT_PQUANTA
0x00000001
TEST_TST_PAUSE
0x00000002
/* Test Pause
TEST_TST_BACKP
0x00000004
/* Test
#define
*/
#define
*/
#define
*/
89
0x00000001
0x00000002
/* Suppress Preamble
0x0000001C
0x00008000
#define MCFG_CLK_DIV28
#define MCFG_CLK_DIV36
#define MCFG_CLK_DIV64
/* MII Read
/* MII Scan continuously
0x00050000
0x00050000
MII is Busy
MII Scanning in Progress
MII Read Data not valid
MII Link Failed
0x00000001
/* Enable Receive
0x00000002
/* Enable Transmit
0x00000008
0x00000010
0x00000020
0x00000040
0x00000080
/* Pass RX Filter
0x00000100
/* TX Flow Control
0x00000200
0x00000400
/* Full Duplex
0x00000001
/* Enable Receive
0x00000002
/* Enable Transmit
/* CRC error
/* Length Check Error
/* Length Out of Range
/* Tramsmission Completed
/* Multicast Destination
/* Broadcast Destination
/* Packet Deferred
/* Excessive Packet Deferral
/* Excessive Collision
/* Late Collision Occured
/* Giant Frame
/* Buffer Underrun
/* Total Bytes Transferred
/* Control Frame
/* Pause Frame
/* Backpressure Method
/* VLAN Frame
91
/* Mirror Counter
/* Pause Timer
0x00000020
0x00001000
0x00002000
0x80000000
93
0x80000000
(RINFO_FAIL_FILT | RINFO_CRC_ERR
RINFO_LEN_ERR
| RINFO_ALIGN_ERR |
RINFO_OVERRUN)
/* TX Descriptor Control Word */
#define TCTRL_SIZE
0x000007FF
bytes
*/
#define TCTRL_OVERRIDE
0x04000000
Registers
*/
#define TCTRL_HUGE
0x08000000
*/
#define TCTRL_PAD
0x10000000
bytes
*/
94
0x20000000
0x40000000
0x80000000
95
/* Collision Count
/* Packet Deferred (not an
/* Excessive Deferral
/* Excessive Collision
/* Late Collision Occured
/* Transmit Underrun
/* No new Descriptor
/* Error Occured (OR of all
/* Status Register
/* MII Interrupt Control
/* MII Interrupt Status
0x14
0x15
0x16
0x17
0x18
0x19
0x1A
/* 10Base-T Status/Control
0x1B
0x1D
PHY_FULLD_100M
0x2100
PHY_HALFD_100M
0x2000
PHY_FULLD_10M
0x0100
PHY_HALFD_10M
0x0000
PHY_AUTO_NEG
0x3000
0x0100
0x20005C90
/* PHY Identifier
#define DP83848C_DEF_ADR
address
*/
#define DP83848C_ID
*/
/*************************************************
* CodeRed - PHY definitions for RDB1768 rev 2
* which uses SMSC LAN8720 PHY instead of DP83848C
*************************************************/
#define LAN8720_ID
0x0007C0F0 /* PHY Identifier
*/
void Init_EthMAC(void);
unsigned short ReadFrameBE_EthMAC(void);
void CopyToFrame_EthMAC(void *Source, unsigned int Size);
void CopyFromFrame_EthMAC(void *Dest, unsigned short Size);
void DummyReadFrame_EthMAC(unsigned short Size);
void RequestSend(unsigned short FrameSize);
unsigned int Rdy4Tx(void);
unsigned short StartReadingFrame(void);
void StopReadingFrame(void);
unsigned int CheckIfFrameReceived(void);
#endif
96
// "M1-M2-M3-M4-M5-M6"
// easyWEB-API function
// initalizes the LAN-controller, reset flags, starts timer-ISR
void TCPLowLevelInit(void)
{
LPC_GPIO1->FIODIR = 1 << 25;
// P1.25 defined as
Output (LED)
Start_SysTick10ms();
// Start SysTick timer running (10ms
ticks)
Init_EthMAC();
TransmitControl = 0;
TCPFlags = 0;
TCPStateMachine = CLOSED;
SocketStatus = 0;
}
// easyWEB-API function
// does a passive open (listen on 'MyIP:TCPLocalPort' for an
incoming
// connection)
void TCPPassiveOpen(void)
{
if (TCPStateMachine == CLOSED)
{
TCPFlags &= ~TCP_ACTIVE_OPEN;
passive open!
TCPStateMachine = LISTENING;
SocketStatus = SOCK_ACTIVE;
now active
}
}
// let's do a
// reset, socket
// easyWEB-API function
// does an active open (tries to establish a connection between
// 'MyIP:TCPLocalPort' and 'RemoteIP:TCPRemotePort')
void TCPActiveOpen(void)
97
// reset, socket
// easyWEB-API function
// closes an open connection
void TCPClose(void)
{
switch (TCPStateMachine)
{
case LISTENING :
case SYN_SENT :
{
TCPStateMachine = CLOSED;
TCPFlags = 0;
SocketStatus = 0;
break;
}
case SYN_RECD :
case ESTABLISHED :
{
TCPFlags |= TCP_CLOSE_REQUESTED;
break;
}
}
}
// easyWEB-API function
// releases the receive-buffer and allows easyWEB to store new data
// NOTE: rx-buffer MUST be released periodically, else the other TCP
//
get no ACKs for the data it sent
void TCPReleaseRxBuffer(void)
{
SocketStatus &= ~SOCK_DATA_AVAILABLE;
}
// easyWEB-API function
// transmitts data stored in 'TCP_TX_BUF'
// NOTE: * number of bytes to transmit must have been written to
'TCPTxDataCount'
98
void TCPTransmitTxBuffer(void)
{
if ((TCPStateMachine == ESTABLISHED) || (TCPStateMachine ==
CLOSE_WAIT))
if (SocketStatus & SOCK_TX_BUF_RELEASED)
{
SocketStatus &= ~SOCK_TX_BUF_RELEASED;
// occupy
tx-buffer
TCPUNASeqNr += TCPTxDataCount;
//
advance UNA
TxFrame1Size = ETH_HEADER_SIZE + IP_HEADER_SIZE +
TCP_HEADER_SIZE + TCPTxDataCount;
TransmitControl |= SEND_FRAME1;
LastFrameSent = TCP_DATA_FRAME;
TCPStartRetryTimer();
}
}
// CodeRed - New function to check if received frame
// was a broadcast message
// Reads the length of the received ethernet frame and checks if the
// destination address is a broadcast message or not
unsigned int BroadcastMessage(void)
{
unsigned short FrameDestination[3]; // to hold 48 bit MAC address
RecdFrameLength = StartReadingFrame();
// Read destination address
CopyFromFrame_EthMAC(&FrameDestination,
// Save it for reply
CopyFromFrame_EthMAC(&RecdFrameMAC, 6);
6);
// set a new
// resend last
frame
RetryCounter--;
}
else
{
TCPStopTimer();
TCPHandleTimeout();
}
}
}
else if (TCPTimer > FIN_TIMEOUT)
{
TCPStateMachine = CLOSED;
TCPFlags = 0;
stop retransmission...
SocketStatus &= SOCK_DATA_AVAILABLE;
but data available
}
switch (TCPStateMachine)
{
case CLOSED :
case LISTENING :
{
if (TCPFlags & TCP_ACTIVE_OPEN)
// stack has to
open a connection?
if (TCPFlags & IP_ADDR_RESOLVED)
// IP resolved?
if (!(TransmitControl & SEND_FRAME2)) // buffer free?
{
// CodeRed - change TAR -> TOTC to use LPC1768 clock
100
// clear tx-flag
}
if (TransmitControl & SEND_FRAME1)
{
PrepareTCP_DATA_FRAME();
actual SEQ, ACK....
RequestSend(TxFrame1Size);
if (Rdy4Tx())
accept our frame?
SendFrame1();
else {
TCPStateMachine = CLOSED;
SocketStatus = SOCK_ERR_ETHERNET;
error to user
TCPFlags = 0;
stop timers etc.
}
TransmitControl &= ~SEND_FRAME1;
// build frame w/
// CS8900 ready to
// (see note above)
// indicate an
// clear all flags,
// clear tx-flag
}
}
// easyWEB internal function
// handles an incoming broadcast frame
void ProcessEthBroadcastFrame(void)
{
unsigned short TargetIP[2];
if (ReadFrameBE_EthMAC() == FRAME_ARP)
type, check for ARP
if (ReadFrameBE_EthMAC() == HARDW_ETH10)
frame
if (ReadFrameBE_EthMAC() == FRAME_IP)
protocol
if (ReadFrameBE_EthMAC() == IP_HLEN_PLEN)
PLEN
102
// get frame
// Ethernet
// check
// check HLEN,
103
// get
//
//
//
// get
// get
// is it
for us?
switch
case
case
case
implemented!
}
}
}
break;
}
}
}
(ProtocolType) {
PROT_ICMP : { ProcessICMPFrame(); break; }
PROT_TCP : { ProcessTCPFrame(); break; }
PROT_UDP : break;
// not
// get Message
// ignore ICMP
// check type
// is echo request?
// echo as much as
void ProcessTCPFrame(void)
{
unsigned short TCPSegSourcePort;
source port
unsigned short TCPSegDestPort;
destination port
unsigned long TCPSegSeq;
sequence number
unsigned long TCPSegAck;
acknowledge number
unsigned short TCPCode;
header length
unsigned char TCPHeaderSize;
length
unsigned short NrOfDataBytes;
data
// segment's
// segment's
// segment's
// segment's
// TCP code and
// real TCP header
// real number of
TCPSegSourcePort = ReadFrameBE_EthMAC();
ports
TCPSegDestPort = ReadFrameBE_EthMAC();
if (TCPSegDestPort != TCPLocalPort) return;
segment if port doesn't match
// get
// drop
// get
// get
TCPCode = ReadFrameBE_EthMAC();
control bits, header length...
// get
// header
// packet
105
//
// save
// for
// reset
a bad
{
acknowledgement
TCPSeqNr = TCPSegAck;
PrepareTCP_FRAME(TCP_CODE_RST);
}
else if (TCPCode & TCP_CODE_SYN)
{
106
//
// get
| TAR; //
(LPC_TIM0// one
drop
to current
// drop
// ACK field
// is our ISN
// drop segment
// RST??
// if ACK was
// connection
// reset all flags,
// drop segment
// SYN??
// get opponents
TCPAckNr++;
// inc. by one...
ISN
if (TCPCode & TCP_CODE_ACK)
{
TCPStopTimer();
retransmission, other TCP got our SYN
TCPSeqNr = TCPUNASeqNr;
sequence number
// stop
// advance our
PrepareTCP_FRAME(TCP_CODE_ACK);
// ACK this ISN
TCPStateMachine = ESTABLISHED;
SocketStatus |= SOCK_CONNECTED;
SocketStatus |= SOCK_TX_BUF_RELEASED; // user may send
data now :-)
}
else
{
TCPStopTimer();
PrepareTCP_FRAME(TCP_CODE_SYN | TCP_CODE_ACK);
// our
SYN isn't ACKed yet,
LastFrameSent = TCP_SYN_ACK_FRAME;
// now
continue with sending
TCPStartRetryTimer();
//
SYN_ACK frames
TCPStateMachine = SYN_RECD;
}
}
break;
}
default :
{
if (memcmp(&RemoteIP, &RecdFrameIP, 4)) break; // drop
segment if IP doesn't belong
// to current
session
if (TCPSegSourcePort != TCPRemotePort) break;
segment if port doesn't match
// drop
// drop if
108
// RST??
// close the state
// reset all flags,
// indicate an
// SYN??
// is NOT allowed
// close
// reset all flags,
// fatal error!
// ...and drop the
// drop segment if
if (TCPSegAck == TCPUNASeqNr)
sent ACKed?
{
TCPStopTimer();
retransmission
TCPSeqNr = TCPUNASeqNr;
sequence number
switch (TCPStateMachine)
// change state if
necessary
{
case SYN_RECD :
// ACK of our SYN?
{
TCPStateMachine = ESTABLISHED;
// user may send
data now :-)
SocketStatus |= SOCK_CONNECTED;
break;
}
case FIN_WAIT_1 : { TCPStateMachine = FIN_WAIT_2; break; }
// ACK of our FIN?
case CLOSING :
{ TCPStateMachine = TIME_WAIT; break; }
// ACK of our FIN?
case LAST_ACK :
// ACK of our FIN?
{
TCPStateMachine = CLOSED;
TCPFlags = 0;
// reset all flags,
stop retransmission...
SocketStatus &= SOCK_DATA_AVAILABLE; // clear all flags
but data available
break;
}
case TIME_WAIT :
{
PrepareTCP_FRAME(TCP_CODE_ACK);
// ACK a
retransmission of remote FIN
TCPRestartTimer();
// restart
TIME_WAIT timeout
break;
109
// if true, give
// to user
//
//
// ACK
// FIN??
flag
PrepareTCP_FRAME(TCP_CODE_ACK);
}
}
}
}
// easyWEB internal function
// prepares the TxFrame2-buffer to send an ARP-request
void PrepareARP_REQUEST(void)
{
// Ethernet
memset(&TxFrame2[ETH_DA_OFS], (char)0xFF, 6);
//
we don't know opposites MAC!
memcpy(&TxFrame2[ETH_SA_OFS], &MyMAC, 6);
*(unsigned short *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_ARP);
// ARP
*(unsigned short *)&TxFrame2[ARP_HARDW_OFS] = SWAPB(HARDW_ETH10);
*(unsigned short *)&TxFrame2[ARP_PROT_OFS] = SWAPB(FRAME_IP);
*(unsigned short *)&TxFrame2[ARP_HLEN_PLEN_OFS] =
SWAPB(IP_HLEN_PLEN);
*(unsigned short *)&TxFrame2[ARP_OPCODE_OFS] =
SWAPB(OP_ARP_REQUEST);
memcpy(&TxFrame2[ARP_SENDER_HA_OFS], &MyMAC, 6);
memcpy(&TxFrame2[ARP_SENDER_IP_OFS], &MyIP, 4);
memset(&TxFrame2[ARP_TARGET_HA_OFS], 0x00, 6);
don't know opposites MAC!
// we
//
// if we've a TCP
// ...include TCP
// TCP header
// sum words
// add left-over
return ~Sum;
}
// easyWEB internal function
// starts the timer as a retry-timer (used for retransmissiontimeout)
void TCPStartRetryTimer(void)
{
TCPTimer = 0;
RetryCounter = MAX_RETRYS;
TCPFlags |= TCP_TIMER_RUNNING;
TCPFlags |= TIMER_TYPE_RETRY;
}
// easyWEB internal function
// starts the timer as a 'TIME_WAIT'-timer (used to finish a TCPsession)
void TCPStartTimeWaitTimer(void)
{
TCPTimer = 0;
TCPFlags |= TCP_TIMER_RUNNING;
TCPFlags &= ~TIMER_TYPE_RETRY;
}
// easyWEB internal function
// restarts the timer
void TCPRestartTimer(void)
{
TCPTimer = 0;
}
// easyWEB internal function
// stopps the timer
void TCPStopTimer(void)
{
TCPFlags &= ~TCP_TIMER_RUNNING;
}
// easyWEB internal function
// if a retransmission-timeout occured, check which packet
116
4. TCPIP.H
// Modifications by Code Red Technologies for NXP LPC1776
#ifndef __TCPIP_H
#define __TCPIP_H
// easyWEB-stack definitions
#define MYIP_1
protocol (IP) address
#define MYIP_2
#define MYIP_3
#define MYIP_4
#define
#define
#define
#define
118
SUBMASK_1
SUBMASK_2
SUBMASK_3
SUBMASK_4
192
// our internet
168
1
150
255
255
255
0
// subnet mask
192
// standard gateway
168
// IP is no part of
1
10
#define RETRY_TIMEOUT
8
262ms for an ACK (about 2 sec.)
#define FIN_TIMEOUT
2
wait for an ACK of a FIN
// wait max. 8 x
// max. time to
// before closing
// nr. of
// total nr. of
transmissions = MAX_RETRYS + 1
#define MAX_TCP_TX_DATA_SIZE 512
TCP data size (even!)
#define MAX_TCP_RX_DATA_SIZE 256
TCP data size (even!)
// max. outgoing
// max. incoming
// (increasing the
buffer-size dramatically
// increases the
transfer-speed!)
#define MAX_ETH_TX_DATA_SIZE 60
for ARP, ICMP, TCP (even!)
64
119
layer definitions
IP_VER_IHL_TOS_OFS
Type of Service
IP_TOTAL_LENGTH_OFS
// Time To Live
// Destination MAC
// Source MAC
// Type field (16
// Frame Data
// frame types
ETH_DATA_OFS + 0
// Version, Header
ETH_DATA_OFS + 2
// IP Frame's Total
ETH_DATA_OFS + 4
// Identifying
ETH_DATA_OFS + 6
// Flags and
ETH_DATA_OFS + 8
// Frame's Time to
ETH_DATA_OFS + 10
// IP Frame's
ETH_DATA_OFS + 12
// Source Address
ETH_DATA_OFS + 16
// Destination
ETH_DATA_OFS + 20
20
// w/o options
#define IP_VER_IHL
Length = 5x32 bit
#define IP_TOS_D
#define IP_TOS_T
throughput
#define IP_TOS_R
reliability
0x4500
// IPv4, Header
0x0010
0x0008
0x0004
// TOS high
#define IP_FLAG_DONTFRAG
IP frame
#define IP_FLAG_MOREFRAG
available
#define IP_FRAGOFS_MASK
this fragment belongs
0x4000
// don't fragment
0x2000
// more fragments
0x1FFF
// indicates where
#define PROT_ICMP
Message Protocol
#define PROT_TCP
Control Protocol
#define PROT_UDP
Protocol
// Internet Control
// Transmission
17
// User Datagram
ETH_DATA_OFS + 0
// Hardware address
ETH_DATA_OFS + 2
ETH_DATA_OFS + 4
// Protocol
// byte length of
ETH_DATA_OFS + 6
ETH_DATA_OFS + 8
// Opcode
// Hardw. address
ETH_DATA_OFS + 14
// IP address of
ETH_DATA_OFS + 18
// Hardw. address
ETH_DATA_OFS + 24
// IP address of
// ARP definitions
#define ARP_HARDW_OFS
type
#define ARP_PROT_OFS
#define ARP_HLEN_PLEN_OFS
each hardw. / prot. address
#define ARP_OPCODE_OFS
#define ARP_SENDER_HA_OFS
of sender of this packet
#define ARP_SENDER_IP_OFS
sender
#define ARP_TARGET_HA_OFS
of target of this packet
#define ARP_TARGET_IP_OFS
target
#define ARP_FRAME_SIZE
120
28
// hardware-type
0x0604
// MAC = 6 byte
// operations for
2
IP_DATA_OFS + 0
IP_DATA_OFS + 2
// type of message
// checksum of
IP_DATA_OFS + 4
4
8
// message is an
// message is an
IP_DATA_OFS + 0
IP_DATA_OFS + 2
// Destination Port
IP_DATA_OFS + 4
// Sequence Number
IP_DATA_OFS + 8
// Acknowledge
IP_DATA_OFS + 12
IP_DATA_OFS + 14
IP_DATA_OFS + 16
// Checksum Field
IP_DATA_OFS + 18
// Urgent Pointer
IP_DATA_OFS + 20
20
#define DATA_OFS_MASK
words in the TCP Header
0xF000
// number of 32 bit
#define
#define
#define
#define
#define
#define
0x0001
0x0002
0x0004
0x0008
0x0010
0x0020
TCP_CODE_FIN
TCP_CODE_SYN
TCP_CODE_RST
TCP_CODE_PSH
TCP_CODE_ACK
TCP_CODE_URG
#define TCP_OPT_MSS
0x0204
Length 4 (Max. Segment Size)
#define TCP_OPT_MSS_SIZE
4
121
// Type 2, Option
// states of the
// according to
// type of last
// for
// constants
// Code Red
// ifdef added as due to change to including .h files rather than .c
files.
// The use of ifdef reduces the coding changes that would otherwise
be required,
// depending upon which file is including this one.
//
#ifdef extern
const unsigned short MyIP[] =
//
"MYIP1.MYIP2.MYIP3.MYIP4"
122
//
//
//
//
//
// "M1-M2-M3-M4-M5-
// next seq to
// incremented
// EMAC reported
// 48 bit MAC
// 32 bit IP
// 16 bit IP packet
// bytes to send in
// bytes to send in
0x01
0x02
0x01
// easyWEB shall
0x02
// IP sucessfully
0x04
0x08
0x10
// prototypes
void DoNetworkStuff(void);
// Handlers for incoming frames
void ProcessEthBroadcastFrame(void);
void ProcessEthIAFrame(void);
void ProcessICMPFrame(void);
void ProcessTCPFrame(void);
// fill TX-buffers
void PrepareARP_REQUEST(void);
void PrepareARP_ANSWER(void);
void PrepareICMP_ECHO_REPLY(void);
void PrepareTCP_FRAME(unsigned short TCPCode);
void PrepareTCP_DATA_FRAME(void);
// general help functions
void SendFrame1(void);
void SendFrame2(void);
void TCPStartRetryTimer(void);
void TCPStartTimeWaitTimer(void);
124
// setup timer,
// listen for a
// open connection
// close connection
// indicate to
// initiate
// nr. of bytes
// nr. of bytes to
// TCP ports
// MAC and IP of
125
0x01
// state machine
0x02
0x04
// new data
0x08
0xF0
// bit-mask to
0x00
0x10
// no error
// timeout waiting
0x20
// timeout waiting
0x30
// connection was
0x40
// remote TCP
0x50
// network
// easyWEB-API buffer-pointers
#define TCP_TX_BUF
((unsigned char *)TxFrame1 + ETH_HEADER_SIZE
+ IP_HEADER_SIZE + TCP_HEADER_SIZE)
#define TCP_RX_BUF
((unsigned char *)RxTCPBuffer)
#endif
5. EASYWEB.C
#include
#include
#include
#include
#include
"stdlib.h"
"stdio.h"
"string.h"
<cr_section_macros.h>
<NXP/crp.h>
void HTTPServer(void)
{
if (SocketStatus & SOCK_CONNECTED)
somebody has connected to our TCP
{
if (SocketStatus & SOCK_DATA_AVAILABLE)
TCP sent data
TCPReleaseRxBuffer();
away
if (SocketStatus & SOCK_TX_BUF_RELEASED)
is free for TX
{
if (!(HTTPStatus & HTTP_SEND_PAGE))
counter and pointer to webside
{
1st time
HTTPBytesToSend = sizeof(WebSide) - 1;
ignore trailing zero
PWebSide = (unsigned char *)WebSide;
code
}
// check if
// check if remote
// and throw it
// check if buffer
// init byte// if called the
// get HTML length,
// pointer to HTML-
// bytes to xfer
// xfer buffer
}
else if (HTTPBytesToSend)
// transmit
leftover bytes
{
memcpy(TCP_TX_BUF, PWebSide, HTTPBytesToSend);
TCPTxDataCount = HTTPBytesToSend;
// bytes to xfer
TCPTransmitTxBuffer();
// send last
segment
TCPClose();
// and close
connection
HTTPBytesToSend = 0;
// all data sent
}
HTTPStatus |= HTTP_SEND_PAGE;
executed
}
}
else
HTTPStatus &= ~HTTP_SEND_PAGE;
if not connected
}
// reset help-flag
6. EASYWEB.H
#ifndef __EASYWEB_H
#define __EASYWEB_H
const unsigned char GetResponse[] =
server sends to a client
{
"HTTP/1.0 200 OK\r\n"
1.0, code 200, reason OK
"Content-Type: text/html\r\n"
want to send
"\r\n"
HTTP-header
};
void start(void);
void InitOsc(void);
void InitPorts(void);
void HTTPServer(void);
void InsertDynamicValues(void);
unsigned int GetAD7Val(void);
unsigned int GetTempVal(void);
128
// prototypes
// pointer to
// bytes left to
0x01
#endif
129
// status byte
// help flag