further implemented bootp protocol
This commit is contained in:
@@ -8,12 +8,28 @@
|
|||||||
#ifndef _BOOTP_H_
|
#ifndef _BOOTP_H_
|
||||||
#define _BOOTP_H_
|
#define _BOOTP_H_
|
||||||
|
|
||||||
/********************************************************************/
|
#define BOOTP_SERVER_PORT 67
|
||||||
|
#define BOOTP_CLIENT_PORT 68
|
||||||
|
|
||||||
|
/* protocol header information */
|
||||||
|
#define BOOTP_HDR_OFFSET (ETH_HDR_LEN + IP_HDR_SIZE + UDP_HDR_SIZE)
|
||||||
|
|
||||||
|
/* timeout in seconds */
|
||||||
|
#define BOOTP_TIMEOUT 2
|
||||||
|
|
||||||
|
/* BOOTP connection status */
|
||||||
|
|
||||||
|
struct bootp_connection
|
||||||
|
{
|
||||||
|
bool open; /* connection established flag */
|
||||||
|
NIF *nif; /* pointer to network interface */
|
||||||
|
IP_ADDR server_ip; /* server IP address */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This data definition is defined for Ethernet only!
|
* This data definition is defined for Ethernet only!
|
||||||
*/
|
*/
|
||||||
typedef struct
|
struct bootp_packet
|
||||||
{
|
{
|
||||||
uint8_t type; /* bootp operation type */
|
uint8_t type; /* bootp operation type */
|
||||||
uint8_t htype; /* hardware type */
|
uint8_t htype; /* hardware type */
|
||||||
@@ -29,9 +45,9 @@ typedef struct
|
|||||||
uint8_t sname[64]; /* server name */
|
uint8_t sname[64]; /* server name */
|
||||||
uint8_t file[128]; /* name of bootfile */
|
uint8_t file[128]; /* name of bootfile */
|
||||||
uint8_t vend[64]; /* vendor specific (see below) */
|
uint8_t vend[64]; /* vendor specific (see below) */
|
||||||
} bootp_frame_hdr;
|
};
|
||||||
|
|
||||||
#define BOOTP_HDR_LEN sizeof(bootp_frame_hdr)
|
#define BOOTP_PACKET_LEN (BOOTP_HDR_OFFSET + sizeof(struct bootp_packet))
|
||||||
|
|
||||||
/* possible values for type field */
|
/* possible values for type field */
|
||||||
#define BOOTP_TYPE_BOOTREQUEST 1
|
#define BOOTP_TYPE_BOOTREQUEST 1
|
||||||
@@ -46,11 +62,6 @@ typedef struct
|
|||||||
/* values for flags - only broadcast flag in use */
|
/* values for flags - only broadcast flag in use */
|
||||||
#define BOOTP_FLAGS_BROADCAST 1
|
#define BOOTP_FLAGS_BROADCAST 1
|
||||||
|
|
||||||
#define BOOTP_TIMEOUT (1) /* Timeout in seconds */
|
|
||||||
|
|
||||||
/* Protocol Header information */
|
|
||||||
#define BOOTP_HDR_OFFSET ETH_HDR_LEN
|
|
||||||
|
|
||||||
extern void bootp_request(NIF *, uint8_t *);
|
extern void bootp_request(NIF *, uint8_t *);
|
||||||
extern void bootp_handler(NIF *, NBUF *);
|
extern void bootp_handler(NIF *, NBUF *);
|
||||||
//extern void bootp_init(BOOTP_INFO *);
|
//extern void bootp_init(BOOTP_INFO *);
|
||||||
|
|||||||
@@ -47,39 +47,23 @@
|
|||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
QNODE node;
|
QNODE node;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
uint16_t offset;
|
uint16_t offset;
|
||||||
uint16_t length;
|
uint16_t length;
|
||||||
} NBUF;
|
} NBUF;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Functions to manipulate the network buffers.
|
* Functions to manipulate the network buffers.
|
||||||
*/
|
*/
|
||||||
int
|
extern int nbuf_init(void);
|
||||||
nbuf_init(void);
|
extern void nbuf_flush(void);
|
||||||
|
extern NBUF *nbuf_alloc (void);
|
||||||
|
extern void nbuf_free(NBUF *);
|
||||||
|
extern NBUF *nbuf_remove(int);
|
||||||
|
extern void nbuf_add(int, NBUF *);
|
||||||
|
extern void nbuf_reset(void);
|
||||||
|
extern void nbuf_debug_dump(void);
|
||||||
|
|
||||||
void
|
|
||||||
nbuf_flush(void);
|
|
||||||
|
|
||||||
NBUF *
|
|
||||||
nbuf_alloc (void);
|
|
||||||
|
|
||||||
void
|
|
||||||
nbuf_free(NBUF *);
|
|
||||||
|
|
||||||
NBUF *
|
|
||||||
nbuf_remove(int);
|
|
||||||
|
|
||||||
void
|
|
||||||
nbuf_add(int, NBUF *);
|
|
||||||
|
|
||||||
void
|
|
||||||
nbuf_reset(void);
|
|
||||||
|
|
||||||
void
|
|
||||||
nbuf_debug_dump(void);
|
|
||||||
|
|
||||||
/********************************************************************/
|
|
||||||
|
|
||||||
#endif /* _NBUF_H_ */
|
#endif /* _NBUF_H_ */
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* File: net.h
|
* File: net.h
|
||||||
* Purpose: Network definitions and prototypes for dBUG.
|
* Purpose: Network definitions and prototypes for BaS.
|
||||||
*
|
*
|
||||||
* Notes:
|
* Notes:
|
||||||
*/
|
*/
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
|
|
||||||
int net_init(void);
|
extern int net_init(void);
|
||||||
|
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* File: net_timer.h
|
* File: net_timer.h
|
||||||
* Purpose: Provide a timer use by the dBUG network as a timeout
|
* Purpose: Provide a timer use by the BaS network as a timeout
|
||||||
* indicator
|
* indicator
|
||||||
*
|
*
|
||||||
* Notes:
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TIMER_H_
|
#ifndef _TIMER_H_
|
||||||
|
|||||||
@@ -8,8 +8,6 @@
|
|||||||
#ifndef _TFTP_H_
|
#ifndef _TFTP_H_
|
||||||
#define _TFTP_H_
|
#define _TFTP_H_
|
||||||
|
|
||||||
/********************************************************************/
|
|
||||||
|
|
||||||
#define TFTP_RRQ (1)
|
#define TFTP_RRQ (1)
|
||||||
#define TFTP_WRQ (2)
|
#define TFTP_WRQ (2)
|
||||||
#define TFTP_DATA (3)
|
#define TFTP_DATA (3)
|
||||||
|
|||||||
@@ -9,9 +9,14 @@
|
|||||||
#include "bootp.h"
|
#include "bootp.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include "bas_printf.h"
|
||||||
|
|
||||||
#define TIMER_NETWORK 0
|
#define TIMER_NETWORK 0
|
||||||
|
|
||||||
|
static struct bootp_connection connection;
|
||||||
|
#define XID 0x1234 /* this is arbitrary */
|
||||||
|
#define MAX_TRIES 5 /* since UDP can fail */
|
||||||
|
|
||||||
void bootp_request(NIF *nif, uint8_t *pa)
|
void bootp_request(NIF *nif, uint8_t *pa)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -19,172 +24,75 @@ void bootp_request(NIF *nif, uint8_t *pa)
|
|||||||
* address "pa"
|
* address "pa"
|
||||||
*/
|
*/
|
||||||
uint8_t *addr;
|
uint8_t *addr;
|
||||||
NBUF *pNbuf;
|
IP_ADDR broadcast = {255, 255, 255, 255};
|
||||||
bootp_frame_hdr *bootpframe;
|
NBUF *nbuf;
|
||||||
|
struct bootp_packet *p;
|
||||||
int i, result;
|
int i, result;
|
||||||
|
|
||||||
pNbuf = nbuf_alloc();
|
nbuf = nbuf_alloc();
|
||||||
if (pNbuf == NULL)
|
if (nbuf == NULL)
|
||||||
{
|
{
|
||||||
#if defined(DEBUG_PRINT)
|
xprintf("%s: couldn't allocate Tx buffer\r\n", __FUNCTION__);
|
||||||
xprintf("%s: arp_request couldn't allocate Tx buffer\r\n", __FUNCTION__);
|
return;
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bootpframe = (bootp_frame_hdr *) &pNbuf->data[BOOTP_HDR_OFFSET];
|
p = (struct bootp_packet *) &nbuf->data[BOOTP_HDR_OFFSET];
|
||||||
|
|
||||||
/* Build the BOOTP request packet */
|
/* Build the BOOTP request packet */
|
||||||
bootpframe->type = BOOTP_TYPE_BOOTREQUEST;
|
p->type = BOOTP_TYPE_BOOTREQUEST;
|
||||||
bootpframe->htype = BOOTP_HTYPE_ETHERNET;
|
p->htype = BOOTP_HTYPE_ETHERNET;
|
||||||
bootpframe->hlen = BOOTP_HLEN_ETHERNET;
|
p->hlen = BOOTP_HLEN_ETHERNET;
|
||||||
bootpframe->hops = 0;
|
p->hops = 0;
|
||||||
bootpframe->xid = 0x1234;
|
p->xid = XID;
|
||||||
bootpframe->secs = 1;
|
p->secs = 1;
|
||||||
bootpframe->flags = BOOTP_FLAGS_BROADCAST;
|
p->flags = BOOTP_FLAGS_BROADCAST;
|
||||||
bootpframe->cl_addr = 0x0;
|
p->cl_addr = 0x0;
|
||||||
bootpframe->yi_addr = 0x0;
|
p->yi_addr = 0x0;
|
||||||
bootpframe->gi_addr = 0x0;
|
p->gi_addr = 0x0;
|
||||||
|
|
||||||
addr = &nif->hwa[0];
|
addr = &nif->hwa[0];
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
bootpframe->ch_addr[i] = addr[i];
|
p->ch_addr[i] = addr[i];
|
||||||
|
|
||||||
pNbuf->length = BOOTP_HDR_LEN;
|
nbuf->length = BOOTP_PACKET_LEN;
|
||||||
|
|
||||||
/* Send the BOOTP request */
|
for (i = 0; i < MAX_TRIES; i++)
|
||||||
result = nif->send(nif, nif->broadcast, nif->hwa, ETH_FRM_IP, pNbuf);
|
{
|
||||||
|
/* Send the BOOTP request */
|
||||||
|
result = udp_send(connection.nif, broadcast, BOOTP_CLIENT_PORT,
|
||||||
|
BOOTP_SERVER_PORT, nbuf);
|
||||||
|
if (result == true)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
nbuf_free(pNbuf);
|
nbuf_free(nbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bootp_handler(NIF *nif, NBUF *pNbuf)
|
void bootp_handler(NIF *nif, NBUF *nbuf)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* ARP protocol handler
|
* BOOTP protocol handler
|
||||||
*/
|
*/
|
||||||
uint8_t *addr;
|
uint8_t *addr;
|
||||||
bootp_frame_hdr *rx_bootpframe, *tx_bootpframe;
|
struct bootp_packet *rx_p;
|
||||||
|
udp_frame_hdr *udpframe;
|
||||||
|
|
||||||
rx_bootpframe = (bootp_frame_hdr *) &pNbuf->data[pNbuf->offset];
|
rx_p = (struct bootp_packet *) &nbuf->data[nbuf->offset];
|
||||||
|
udpframe = (udp_frame_hdr *) &nbuf->data[nbuf->offset - UDP_HDR_SIZE];
|
||||||
|
|
||||||
#ifdef _NOT_USED_
|
/* check packet if it is valid and if it is really intended for us */
|
||||||
/*
|
|
||||||
* Check for an appropriate ARP packet
|
if (rx_p->type == BOOTP_TYPE_BOOTREPLY && rx_p->xid == XID)
|
||||||
*/
|
|
||||||
if ((pNbuf->length < ARP_HDR_LEN) ||
|
|
||||||
(rx_arpframe->ar_hrd != ETHERNET) ||
|
|
||||||
(rx_arpframe->ar_hln != 6) ||
|
|
||||||
(rx_arpframe->ar_pro != ETH_FRM_IP) ||
|
|
||||||
(rx_arpframe->ar_pln != 4))
|
|
||||||
{
|
{
|
||||||
nbuf_free(pNbuf);
|
/* seems to be valid */
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check to see if it was addressed to me - if it was, keep this
|
|
||||||
* ARP entry in the table permanently; if not, mark it so that it
|
|
||||||
* can be displaced later if necessary
|
|
||||||
*/
|
|
||||||
addr = ip_get_myip(nif_get_protocol_info(nif,ETH_FRM_IP));
|
|
||||||
if ((rx_arpframe->ar_tpa[0] == addr[0]) &&
|
|
||||||
(rx_arpframe->ar_tpa[1] == addr[1]) &&
|
|
||||||
(rx_arpframe->ar_tpa[2] == addr[2]) &&
|
|
||||||
(rx_arpframe->ar_tpa[3] == addr[3]) )
|
|
||||||
{
|
|
||||||
longevity = ARP_ENTRY_PERM;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
longevity = ARP_ENTRY_TEMP;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Add ARP info into the table
|
|
||||||
*/
|
|
||||||
arp_merge(arptab,
|
|
||||||
rx_arpframe->ar_pro,
|
|
||||||
rx_arpframe->ar_hln,
|
|
||||||
&rx_arpframe->ar_sha[0],
|
|
||||||
rx_arpframe->ar_pln,
|
|
||||||
&rx_arpframe->ar_spa[0],
|
|
||||||
longevity
|
|
||||||
);
|
|
||||||
|
|
||||||
switch (rx_arpframe->opcode)
|
|
||||||
{
|
{
|
||||||
case ARP_REQUEST:
|
/* not valid */
|
||||||
/*
|
return;
|
||||||
* Check to see if request is directed to me
|
}
|
||||||
*/
|
|
||||||
if ((rx_arpframe->ar_tpa[0] == addr[0]) &&
|
|
||||||
(rx_arpframe->ar_tpa[1] == addr[1]) &&
|
|
||||||
(rx_arpframe->ar_tpa[2] == addr[2]) &&
|
|
||||||
(rx_arpframe->ar_tpa[3] == addr[3]) )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Reuse the current network buffer to assemble an ARP reply
|
|
||||||
*/
|
|
||||||
tx_arpframe = (arp_frame_hdr *)&pNbuf->data[ARP_HDR_OFFSET];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Build new ARP frame from the received data
|
|
||||||
*/
|
|
||||||
tx_arpframe->ar_hrd = ETHERNET;
|
|
||||||
tx_arpframe->ar_pro = ETH_FRM_IP;
|
|
||||||
tx_arpframe->ar_hln = 6;
|
|
||||||
tx_arpframe->ar_pln = 4;
|
|
||||||
tx_arpframe->opcode = ARP_REPLY;
|
|
||||||
tx_arpframe->ar_tha[0] = rx_arpframe->ar_sha[0];
|
|
||||||
tx_arpframe->ar_tha[1] = rx_arpframe->ar_sha[1];
|
|
||||||
tx_arpframe->ar_tha[2] = rx_arpframe->ar_sha[2];
|
|
||||||
tx_arpframe->ar_tha[3] = rx_arpframe->ar_sha[3];
|
|
||||||
tx_arpframe->ar_tha[4] = rx_arpframe->ar_sha[4];
|
|
||||||
tx_arpframe->ar_tha[5] = rx_arpframe->ar_sha[5];
|
|
||||||
tx_arpframe->ar_tpa[0] = rx_arpframe->ar_spa[0];
|
|
||||||
tx_arpframe->ar_tpa[1] = rx_arpframe->ar_spa[1];
|
|
||||||
tx_arpframe->ar_tpa[2] = rx_arpframe->ar_spa[2];
|
|
||||||
tx_arpframe->ar_tpa[3] = rx_arpframe->ar_spa[3];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now copy in the new information
|
|
||||||
*/
|
|
||||||
addr = &nif->hwa[0];
|
|
||||||
tx_arpframe->ar_sha[0] = addr[0];
|
|
||||||
tx_arpframe->ar_sha[1] = addr[1];
|
|
||||||
tx_arpframe->ar_sha[2] = addr[2];
|
|
||||||
tx_arpframe->ar_sha[3] = addr[3];
|
|
||||||
tx_arpframe->ar_sha[4] = addr[4];
|
|
||||||
tx_arpframe->ar_sha[5] = addr[5];
|
|
||||||
|
|
||||||
addr = ip_get_myip(nif_get_protocol_info(nif,ETH_FRM_IP));
|
|
||||||
tx_arpframe->ar_spa[0] = addr[0];
|
|
||||||
tx_arpframe->ar_spa[1] = addr[1];
|
|
||||||
tx_arpframe->ar_spa[2] = addr[2];
|
|
||||||
tx_arpframe->ar_spa[3] = addr[3];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Save the length of my packet in the buffer structure
|
|
||||||
*/
|
|
||||||
pNbuf->length = ARP_HDR_LEN;
|
|
||||||
|
|
||||||
nif->send(nif,
|
|
||||||
&tx_arpframe->ar_tha[0],
|
|
||||||
&tx_arpframe->ar_sha[0],
|
|
||||||
ETH_FRM_ARP,
|
|
||||||
pNbuf);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
nbuf_free(pNbuf);
|
|
||||||
break;
|
|
||||||
case ARP_REPLY:
|
|
||||||
/*
|
|
||||||
* The ARP Reply case is already taken care of
|
|
||||||
*/
|
|
||||||
default:
|
|
||||||
nbuf_free(pNbuf);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif /* _NOT_USED_ */
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* File: net_timer.c
|
* File: net_timer.c
|
||||||
* Purpose: Provide a timer use by the dBUG network as a timeout
|
* Purpose: Provide a timer use by the BaS network as a timeout
|
||||||
* indicator
|
* indicator
|
||||||
*
|
*
|
||||||
* Notes:
|
* Notes:
|
||||||
@@ -19,158 +19,161 @@
|
|||||||
#error unknown machine!
|
#error unknown machine!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static NET_TIMER net_timer[4] = {{0, 0, 0, 0, 0, 0, 0},
|
static NET_TIMER net_timer[4] =
|
||||||
{0, 0, 0, 0, 0, 0, 0},
|
{
|
||||||
{0, 0, 0, 0, 0, 0, 0},
|
{0, 0, 0, 0, 0, 0, 0},
|
||||||
{0, 0, 0, 0, 0, 0, 0}};
|
{0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{0, 0, 0, 0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int timer_default_isr(void *not_used, NET_TIMER *t)
|
int timer_default_isr(void *not_used, NET_TIMER *t)
|
||||||
{
|
{
|
||||||
(void) not_used;
|
(void) not_used;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear the pending event
|
* Clear the pending event
|
||||||
*/
|
*/
|
||||||
MCF_GPT_GMS(t->ch) = 0;
|
MCF_GPT_GMS(t->ch) = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear the reference - the desired seconds have expired
|
* Clear the reference - the desired seconds have expired
|
||||||
*/
|
*/
|
||||||
t->reference = 0;
|
t->reference = 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_irq_enable(uint8_t ch)
|
void timer_irq_enable(uint8_t ch)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Setup the appropriate ICR
|
* Setup the appropriate ICR
|
||||||
*/
|
*/
|
||||||
MCF_INTC_ICR(TIMER_VECTOR(ch) - 64) =
|
MCF_INTC_ICR(TIMER_VECTOR(ch) - 64) =
|
||||||
(uint8_t)(0
|
(uint8_t)(0
|
||||||
| MCF_INTC_ICR_IP(net_timer[ch].pri)
|
| MCF_INTC_ICR_IP(net_timer[ch].pri)
|
||||||
| MCF_INTC_ICR_IL(net_timer[ch].lvl));
|
| MCF_INTC_ICR_IL(net_timer[ch].lvl));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unmask the FEC interrupt in the interrupt controller
|
* Unmask the FEC interrupt in the interrupt controller
|
||||||
*/
|
*/
|
||||||
if (ch == 3)
|
if (ch == 3)
|
||||||
MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK59;
|
MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK59;
|
||||||
else if (ch == 2)
|
else if (ch == 2)
|
||||||
MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK60;
|
MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK60;
|
||||||
else if (ch == 1)
|
else if (ch == 1)
|
||||||
MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK61;
|
MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK61;
|
||||||
else
|
else
|
||||||
MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK62;
|
MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK62;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool timer_set_secs(uint8_t ch, uint32_t secs)
|
bool timer_set_secs(uint8_t ch, uint32_t secs)
|
||||||
{
|
{
|
||||||
uint16_t timeout;
|
uint16_t timeout;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset the timer
|
* Reset the timer
|
||||||
*/
|
*/
|
||||||
MCF_GPT_GMS(ch) = 0;
|
MCF_GPT_GMS(ch) = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the timeout in seconds
|
* Get the timeout in seconds
|
||||||
*/
|
*/
|
||||||
timeout = (uint16_t)(secs * net_timer[ch].cnt);
|
timeout = (uint16_t)(secs * net_timer[ch].cnt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the reference indicating that we have not yet reached the
|
* Set the reference indicating that we have not yet reached the
|
||||||
* desired timeout
|
* desired timeout
|
||||||
*/
|
*/
|
||||||
net_timer[ch].reference = 1;
|
net_timer[ch].reference = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable timer interrupt to the processor
|
* Enable timer interrupt to the processor
|
||||||
*/
|
*/
|
||||||
timer_irq_enable(ch);
|
timer_irq_enable(ch);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable the timer using the pre-calculated values
|
* Enable the timer using the pre-calculated values
|
||||||
*/
|
*/
|
||||||
MCF_GPT_GCIR(ch) = (0
|
MCF_GPT_GCIR(ch) = (0
|
||||||
| MCF_GPT_GCIR_CNT(timeout)
|
| MCF_GPT_GCIR_CNT(timeout)
|
||||||
| MCF_GPT_GCIR_PRE(net_timer[ch].pre)
|
| MCF_GPT_GCIR_PRE(net_timer[ch].pre)
|
||||||
);
|
);
|
||||||
MCF_GPT_GMS(ch) = net_timer[ch].gms;
|
MCF_GPT_GMS(ch) = net_timer[ch].gms;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t timer_get_reference(uint8_t ch)
|
uint32_t timer_get_reference(uint8_t ch)
|
||||||
{
|
{
|
||||||
return (uint32_t) net_timer[ch].reference;
|
return (uint32_t) net_timer[ch].reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool timer_init(uint8_t ch, uint8_t lvl, uint8_t pri)
|
bool timer_init(uint8_t ch, uint8_t lvl, uint8_t pri)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Initialize the timer to expire after one second
|
* Initialize the timer to expire after one second
|
||||||
*
|
*
|
||||||
* This routine should only be called by the project (board) specific
|
* This routine should only be called by the project (board) specific
|
||||||
* initialization code.
|
* initialization code.
|
||||||
*/
|
*/
|
||||||
if (!((ch <= 3) && (lvl <= 7) && (lvl >= 1) && (pri <= 7)))
|
if (!((ch <= 3) && (lvl <= 7) && (lvl >= 1) && (pri <= 7)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset the timer
|
* Reset the timer
|
||||||
*/
|
*/
|
||||||
MCF_GPT_GMS(ch) = 0;
|
MCF_GPT_GMS(ch) = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Save off the channel, and interrupt lvl/pri information
|
* Save off the channel, and interrupt lvl/pri information
|
||||||
*/
|
*/
|
||||||
net_timer[ch].ch = ch;
|
net_timer[ch].ch = ch;
|
||||||
net_timer[ch].lvl = lvl;
|
net_timer[ch].lvl = lvl;
|
||||||
net_timer[ch].pri = pri;
|
net_timer[ch].pri = pri;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register the timer interrupt handler
|
* Register the timer interrupt handler
|
||||||
*/
|
*/
|
||||||
if (!isr_register_handler(ISR_DBUG_ISR,
|
if (!isr_register_handler(ISR_DBUG_ISR,
|
||||||
TIMER_VECTOR(ch),
|
TIMER_VECTOR(ch),
|
||||||
(int (*)(void *,void *)) timer_default_isr,
|
(int (*)(void *,void *)) timer_default_isr,
|
||||||
NULL,
|
NULL,
|
||||||
(void *) &net_timer[ch])
|
(void *) &net_timer[ch])
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate the require CNT value to get a 1 second timeout
|
* Calculate the require CNT value to get a 1 second timeout
|
||||||
*
|
*
|
||||||
* 1 sec = CNT * Clk Period * PRE
|
* 1 sec = CNT * Clk Period * PRE
|
||||||
* CNT = 1 sec / (Clk Period * PRE)
|
* CNT = 1 sec / (Clk Period * PRE)
|
||||||
* CNT = Clk Freq / PRE
|
* CNT = Clk Freq / PRE
|
||||||
*
|
*
|
||||||
* The system clock frequency is defined as SYSTEM_CLOCK and
|
* The system clock frequency is defined as SYSTEM_CLOCK and
|
||||||
* is given in MHz. We need to multiple it by 1000000 to get the
|
* is given in MHz. We need to multiple it by 1000000 to get the
|
||||||
* true value. If we assume PRE to be the maximum of 0xFFFF,
|
* true value. If we assume PRE to be the maximum of 0xFFFF,
|
||||||
* then the CNT value needed to achieve a 1 second timeout is
|
* then the CNT value needed to achieve a 1 second timeout is
|
||||||
* given by:
|
* given by:
|
||||||
*
|
*
|
||||||
* CNT = SYSTEM_CLOCK * (1000000/0xFFFF)
|
* CNT = SYSTEM_CLOCK * (1000000/0xFFFF)
|
||||||
*/
|
*/
|
||||||
net_timer[ch].pre = 0xFFFF;
|
net_timer[ch].pre = 0xFFFF;
|
||||||
net_timer[ch].cnt = (uint16_t) (SYSCLK * (1000000 / 0xFFFF));
|
net_timer[ch].cnt = (uint16_t) (SYSCLK * (1000000 / 0xFFFF));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Save off the appropriate mode select register value
|
* Save off the appropriate mode select register value
|
||||||
*/
|
*/
|
||||||
net_timer[ch].gms = (0
|
net_timer[ch].gms = (0
|
||||||
| MCF_GPT_GMS_TMS_GPIO
|
| MCF_GPT_GMS_TMS_GPIO
|
||||||
| MCF_GPT_GMS_IEN
|
| MCF_GPT_GMS_IEN
|
||||||
| MCF_GPT_GMS_SC
|
| MCF_GPT_GMS_SC
|
||||||
| MCF_GPT_GMS_CE
|
| MCF_GPT_GMS_CE
|
||||||
);
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority,
|
|||||||
{
|
{
|
||||||
xprintf("%s: interrupt source %d not defined\r\n", __FUNCTION__, source);
|
xprintf("%s: interrupt source %d not defined\r\n", __FUNCTION__, source);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
lp = MCF_INTC_ICR_IL(level) | MCF_INTC_ICR_IP(priority);
|
lp = MCF_INTC_ICR_IL(level) | MCF_INTC_ICR_IP(priority);
|
||||||
|
|
||||||
@@ -88,11 +88,11 @@ int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority,
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int vector;
|
int vector;
|
||||||
int type;
|
int type;
|
||||||
int (*handler)(void *, void *);
|
int (*handler)(void *, void *);
|
||||||
void *hdev;
|
void *hdev;
|
||||||
void *harg;
|
void *harg;
|
||||||
} ISRENTRY;
|
} ISRENTRY;
|
||||||
|
|
||||||
ISRENTRY isrtab[UIF_MAX_ISR_ENTRY];
|
ISRENTRY isrtab[UIF_MAX_ISR_ENTRY];
|
||||||
@@ -100,126 +100,126 @@ ISRENTRY isrtab[UIF_MAX_ISR_ENTRY];
|
|||||||
|
|
||||||
void isr_init(void)
|
void isr_init(void)
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
|
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
|
||||||
{
|
{
|
||||||
isrtab[index].vector = 0;
|
isrtab[index].vector = 0;
|
||||||
isrtab[index].type = 0;
|
isrtab[index].type = 0;
|
||||||
isrtab[index].handler = 0;
|
isrtab[index].handler = 0;
|
||||||
isrtab[index].hdev = 0;
|
isrtab[index].hdev = 0;
|
||||||
isrtab[index].harg = 0;
|
isrtab[index].harg = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int isr_register_handler (
|
int isr_register_handler (
|
||||||
int type, int vector,
|
int type, int vector,
|
||||||
int (*handler)(void *, void *), void *hdev, void *harg)
|
int (*handler)(void *, void *), void *hdev, void *harg)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This function places an interrupt handler in the ISR table,
|
* This function places an interrupt handler in the ISR table,
|
||||||
* thereby registering it so that the low-level handler may call it.
|
* thereby registering it so that the low-level handler may call it.
|
||||||
*
|
*
|
||||||
* The two parameters are intended for the first arg to be a
|
* The two parameters are intended for the first arg to be a
|
||||||
* pointer to the device itself, and the second a pointer to a data
|
* pointer to the device itself, and the second a pointer to a data
|
||||||
* structure used by the device driver for that particular device.
|
* structure used by the device driver for that particular device.
|
||||||
*/
|
*/
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
if ((vector == 0) ||
|
if ((vector == 0) ||
|
||||||
((type != ISR_DBUG_ISR) && (type != ISR_USER_ISR)) ||
|
((type != ISR_DBUG_ISR) && (type != ISR_USER_ISR)) ||
|
||||||
(handler == NULL))
|
(handler == NULL))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
|
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
|
||||||
{
|
{
|
||||||
if ((isrtab[index].vector == vector) &&
|
if ((isrtab[index].vector == vector) &&
|
||||||
(isrtab[index].type == type))
|
(isrtab[index].type == type))
|
||||||
{
|
{
|
||||||
/* only one entry of each type per vector */
|
/* only one entry of each type per vector */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isrtab[index].vector == 0)
|
if (isrtab[index].vector == 0)
|
||||||
{
|
{
|
||||||
isrtab[index].vector = vector;
|
isrtab[index].vector = vector;
|
||||||
isrtab[index].type = type;
|
isrtab[index].type = type;
|
||||||
isrtab[index].handler = handler;
|
isrtab[index].handler = handler;
|
||||||
isrtab[index].hdev = hdev;
|
isrtab[index].hdev = hdev;
|
||||||
isrtab[index].harg = harg;
|
isrtab[index].harg = harg;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false; /* no available slots */
|
return false; /* no available slots */
|
||||||
}
|
}
|
||||||
|
|
||||||
void isr_remove_handler(int type, int (*handler)(void *, void *))
|
void isr_remove_handler(int type, int (*handler)(void *, void *))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This routine removes from the ISR table all
|
* This routine removes from the ISR table all
|
||||||
* entries that matches 'type' and 'handler'.
|
* entries that matches 'type' and 'handler'.
|
||||||
*/
|
*/
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
|
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
|
||||||
{
|
{
|
||||||
if ((isrtab[index].handler == handler) &&
|
if ((isrtab[index].handler == handler) &&
|
||||||
(isrtab[index].type == type))
|
(isrtab[index].type == type))
|
||||||
{
|
{
|
||||||
isrtab[index].vector = 0;
|
isrtab[index].vector = 0;
|
||||||
isrtab[index].type = 0;
|
isrtab[index].type = 0;
|
||||||
isrtab[index].handler = 0;
|
isrtab[index].handler = 0;
|
||||||
isrtab[index].hdev = 0;
|
isrtab[index].hdev = 0;
|
||||||
isrtab[index].harg = 0;
|
isrtab[index].harg = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool isr_execute_handler(int vector)
|
bool isr_execute_handler(int vector)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This routine searches the ISR table for an entry that matches
|
* This routine searches the ISR table for an entry that matches
|
||||||
* 'vector'. If one is found, then 'handler' is executed.
|
* 'vector'. If one is found, then 'handler' is executed.
|
||||||
*/
|
*/
|
||||||
int index;
|
int index;
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First locate a dBUG Interrupt Service Routine handler.
|
* First locate a BaS Interrupt Service Routine handler.
|
||||||
*/
|
*/
|
||||||
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
|
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
|
||||||
{
|
{
|
||||||
if ((isrtab[index].vector == vector) &&
|
if ((isrtab[index].vector == vector) &&
|
||||||
(isrtab[index].type == ISR_DBUG_ISR))
|
(isrtab[index].type == ISR_DBUG_ISR))
|
||||||
{
|
{
|
||||||
if (isrtab[index].handler(isrtab[index].hdev,isrtab[index].harg))
|
if (isrtab[index].handler(isrtab[index].hdev,isrtab[index].harg))
|
||||||
{
|
{
|
||||||
retval = true;
|
retval = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to locate a user-registered Interrupt Service Routine handler.
|
* Try to locate a user-registered Interrupt Service Routine handler.
|
||||||
*/
|
*/
|
||||||
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
|
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
|
||||||
{
|
{
|
||||||
if ((isrtab[index].vector == vector) &&
|
if ((isrtab[index].vector == vector) &&
|
||||||
(isrtab[index].type == ISR_USER_ISR))
|
(isrtab[index].type == ISR_USER_ISR))
|
||||||
{
|
{
|
||||||
if (isrtab[index].handler(isrtab[index].hdev,isrtab[index].harg))
|
if (isrtab[index].handler(isrtab[index].hdev,isrtab[index].harg))
|
||||||
{
|
{
|
||||||
retval = true;
|
retval = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user