Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
R
RIOT
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
cm-projects
RIOT
Commits
df8c4a5a
Commit
df8c4a5a
authored
11 years ago
by
Oleg Hahm
Browse files
Options
Downloads
Patches
Plain Diff
added board dependent part of the cc2420 for TelosB
parent
21dff812
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
telosb/driver_cc2420.c
+247
-0
247 additions, 0 deletions
telosb/driver_cc2420.c
with
247 additions
and
0 deletions
telosb/driver_cc2420.c
0 → 100644
+
247
−
0
View file @
df8c4a5a
/*
* driver_cc2420.c - Implementation of the board dependent cc2420 functions.
* Copyright (C) 2005, 2006, 2007, 2008 by Thomas Hillebrandt and Heiko Will
* Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
*
* This source code is licensed under the GNU Lesser General Public License,
* Version 2. See the file LICENSE for more details.
*/
#include
<stdio.h>
#include
<board.h>
#include
<cpu.h>
#include
<irq.h>
#include
<hwtimer.h>
#include
<cc2420.h>
#define ENABLE_DEBUG (1)
#include
"debug.h"
#define CC2420_RESETn_PIN 0x40
#define CC2420_VREGEN_PIN 0x20
#define CC2420_FIFOP_PIN 0x01
#define CC2420_GIO0_PIN 0x08
#define CC2420_GIO1_PIN 0x10
#define CC2420_CCA_PIN 0x40
#define CC2420_SFD_PIN 0x02
#define CC2420_FIFOP (P1IN & CC2420_FIFOP_PIN)
/* FIFOP <-> packet interrupt (P1.0) */
#define CC2420_GIO0 (P1IN & CC2420_GIO0_PIN)
/* FIFO <-> GIO0 - RX data available (P1.3) */
#define CC2420_GIO1 (P1IN & CC2420_GIO1_PIN)
/* CCA <-> GIO1 - clear channel (P1.4) */
#define CC2420_SFD (P4IN & CC2420_SFD_PIN)
/* SFD <-> TBL - start frame delimiter (P4.1) */
#define CC2420_CS_LOW (P4OUT &= ~0x04)
/* P4.2 */
#define CC2420_CS_HIGH (P4OUT |= 0x04)
volatile
int
abort_count
;
volatile
int
retry_count
=
0
;
void
cc2420_reset
(
void
)
{
P4OUT
|=
CC2420_VREGEN_PIN
;
P4OUT
&=
~
CC2420_RESETn_PIN
;
hwtimer_wait
(
500
);
P4OUT
|=
CC2420_RESETn_PIN
;
}
void
cc2420_gio0_enable
(
void
)
{
P1IFG
&=
~
CC2420_GIO0_PIN
;
/* Clear IFG for GIO0 */
P1IE
|=
CC2420_GIO0_PIN
;
/* Enable interrupt for GIO0 */
}
void
cc2420_gio0_disable
(
void
)
{
P1IE
&=
~
CC2420_GIO0_PIN
;
/* Disable interrupt for GIO0 */
P1IFG
&=
~
CC2420_GIO0_PIN
;
/* Clear IFG for GIO0 */
}
void
cc2420_gio1_enable
(
void
)
{
P1IFG
&=
~
CC2420_GIO1_PIN
;
/* Clear IFG for GIO1 */
P1IE
|=
CC2420_GIO1_PIN
;
/* Enable interrupt for GIO1 */
}
void
cc2420_gio1_disable
(
void
)
{
P1IE
&=
~
CC2420_GIO1_PIN
;
/* Disable interrupt for GIO1 */
P1IFG
&=
~
CC2420_GIO1_PIN
;
/* Clear IFG for GIO1 */
}
void
cc2420_before_send
(
void
)
{
/* Disable SFD interrupt before sending packet */
/* However this is not used atm */
}
void
cc2420_after_send
(
void
)
{
/* Enable SFD interrupt after sending packet */
/* However this is not used atm */
}
int
cc2420_get_gio0
(
void
)
{
return
CC2420_GIO0
;
}
int
cc2420_get_gio1
(
void
)
{
return
CC2420_GIO1
;
}
int
cc2420_get_sfd
(
void
)
{
return
CC2420_SFD
;
}
void
cc2420_spi_cs
(
void
)
{
CC2420_CS_LOW
;
}
uint8_t
cc2420_txrx
(
uint8_t
data
)
{
/* Ensure TX Buf is empty */
long
c
=
0
;
IFG1
&=
~
UTXIFG0
;
IFG1
&=
~
URXIFG0
;
U0TXBUF
=
data
;
while
(
!
(
IFG1
&
UTXIFG0
))
{
if
(
c
++
==
1000000
)
{
puts
(
"cc2420_txrx alarm()"
);
}
}
/* Wait for Byte received */
c
=
0
;
while
(
!
(
IFG1
&
URXIFG0
))
{
if
(
c
++
==
1000000
)
{
puts
(
"cc2420_txrx alarm()"
);
}
}
return
U0RXBUF
;
}
void
cc2420_spi_select
(
void
)
{
CC2420_CS_LOW
;
}
void
cc2420_spi_unselect
(
void
)
{
CC2420_CS_HIGH
;
}
void
cc2420_init_interrupts
(
void
)
{
unsigned
int
state
=
disableIRQ
();
/* Disable all interrupts */
P1SEL
&=
~
CC2420_FIFOP_PIN
;
/* must be <> 1 to use interrupts */
P1IE
&=
~
CC2420_FIFOP_PIN
;
/* Disable interrupt for GIO0 */
P1IFG
&=
~
CC2420_FIFOP_PIN
;
/* Clear IFG for GIO0 */
restoreIRQ
(
state
);
/* Enable all interrupts */
}
void
cc2420_spi_init
(
void
)
{
/* Switch off async UART */
while
(
!
(
U0TCTL
&
TXEPT
));
/* Wait for empty UxTXBUF register */
IE1
&=
~
(
URXIE0
+
UTXIE0
);
/* Disable USART0 receive&transmit interrupt */
ME1
&=
~
(
UTXE0
+
URXE0
);
/* configure SPI-related pins */
P3SEL
|=
0x0E
;
/* P3.1 - SIMO mode, P3.2 - SOMI mode, P3.3 - SCL mode */
P3DIR
|=
0x0A
;
/* P3.1 and P3.3 as output */
P3DIR
&=
~
(
0x04
);
/* P3.2 as input for SOMI */
P4OUT
|=
0x04
;
/* P4.2 radio CS, hold high */
P4DIR
|=
0x04
;
/* P4.2 radio CS, output */
/* Keep peripheral in reset state */
U0CTL
=
SWRST
;
/* 8-bit SPI Master 3-pin mode, with SMCLK as clock source */
/* CKPL works also, but not CKPH+CKPL or none of them!! */
U0CTL
|=
CHAR
+
SYNC
+
MM
;
U0TCTL
=
CKPH
+
SSEL1
+
SSEL0
+
STC
+
TXEPT
;;
/* Ignore clockrate argument for now, just use clock source/2 */
/* SMCLK = 8 MHz */
U0BR0
=
0x02
;
/* Ensure baud rate >= 2 */
U0BR1
=
0x00
;
U0MCTL
=
0x00
;
/* No modulation */
U0RCTL
=
0x00
;
/* Reset Receive Control Register */
/* Enable SPI mode */
ME1
|=
USPIE0
;
/* Release for operation */
U0CTL
&=
~
SWRST
;
}
/*
* CC1100 receive interrupt
*/
interrupt
(
PORT1_VECTOR
)
__attribute__
((
naked
))
cc2420_isr
(
void
){
__enter_isr
();
/* Check IFG */
if
((
P1IFG
&
CC2420_FIFOP_PIN
)
!=
0
)
{
P1IFG
&=
~
CC2420_FIFOP_PIN
;
if
(
cc2420_get_gio0
())
{
cc2420_rx_irq
();
DEBUG
(
"rx interrupt"
);
}
else
{
cc2420_rxoverflow_irq
();
DEBUG
(
"[CC2420] rxfifo overflow"
);
}
}
else
{
puts
(
"cc2420_isr(): unexpected IFG!"
);
/* Should not occur - only GDO1 and GIO1 interrupts are enabled */
}
__exit_isr
();
}
/**
\brief TimerB CCR1-6 interrupt service routine (taken from OpenWSN)
*/
interrupt
(
TIMERB0_VECTOR
)
__attribute__
((
naked
))
radiotimer_isr
(
void
)
{
uint16_t
tbiv_local
;
/* reading TBIV returns the value of the highest pending interrupt flag */
/* and automatically resets that flag. We therefore copy its value to the */
/* tbiv_local local variable exactly once. If there is more than one */
/* interrupt pending, we will reenter this function after having just left */
/* it. */
tbiv_local
=
TBIV
;
switch
(
tbiv_local
)
{
case
0x0002
:
/* CCR1 fires */
if
(
TBCCTL1
&
CCI
)
{
/* SFD pin is high */
DEBUG
(
"start of a frame
\n
"
);
}
else
{
/* SFD pin is low */
DEBUG
(
"end of a frame
\n
"
);
}
break
;
case
0x0004
:
/* CCR2 fires */
break
;
case
0x0006
:
/* CCR3 fires */
break
;
case
0x0008
:
/* CCR4 fires */
break
;
case
0x000a
:
/* CCR5 fires */
break
;
case
0x000c
:
/* CCR6 fires */
break
;
case
0x000e
:
/* timer overflow */
break
;
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment