1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

boards: removed support for redbee-econotag

This commit is contained in:
Hauke Petersen 2015-09-03 16:06:56 +02:00
parent 076e9db374
commit d71f0fa895
18 changed files with 0 additions and 1784 deletions

View File

@ -1,5 +0,0 @@
MODULE =$(BOARD)_base
DIRS = drivers
include $(RIOTBASE)/Makefile.base

View File

@ -1 +0,0 @@
FEATURES_MCU_GROUP = arm7

View File

@ -1,39 +0,0 @@
## the cpu to build for
export CPU = mc1322x
# Target triple for the build. Use arm-none-eabi if you are unsure.
export TARGET_TRIPLE ?= arm-none-eabi
# toolchain config
export PREFIX = $(if $(TARGET_TRIPLE),$(TARGET_TRIPLE)-)
export CC = $(PREFIX)gcc
export AR = $(PREFIX)ar
export CFLAGS += -march=armv4t -mtune=arm7tdmi-s -mlong-calls \
-msoft-float -mthumb-interwork -fno-strict-aliasing -fno-common \
-ffixed-r8 -ffunction-sections -ffreestanding -fno-builtin \
-nodefaultlibs -Wall -Wstrict-prototypes \
-Os -pipe
export CFLAGS_MTHUMB ?= -mthumb
# TODO add -mthumb
export AFLAGS = -Wa,-gstabs $(CFLAGS)
export AS = $(PREFIX)as
export LINK = $(PREFIX)gcc
export SIZE = $(PREFIX)size
export OBJCOPY = $(PREFIX)objcopy
FLASHER = mc1322x-load.pl
TERM = pyterm
LINKFLAGS += -mcpu=arm7tdmi-s -static -lgcc -nostartfiles -Wl,--gc-sections -T$(RIOTBASE)/cpu/$(CPU)/mc1322x.lds
ifeq ($(strip $(PORT)),)
export PORT = /dev/ttyUSB0
endif
export FFLAGS = -t $(PORT) -f $(HEXFILE) -c 'bbmc -l redbee-econotag reset'
export OFLAGS = -O binary --gap-fill=0xff
export TERMFLAGS += -p "$(PORT)"
export INCLUDES += -I$(RIOTCPU)/$(CPU)/include/ -I$(RIOTBOARD)/$(BOARD)/include/
export INCLUDES += -I$(RIOTCPU)/$(CPU)/maca/include
export INCLUDES += -I$(RIOTBOARD)/$(BOARD)/drivers/include
export UNDEF += $(BINDIR)cpu/startup.o

View File

@ -1,11 +0,0 @@
Flashing:
tools/mc1322x-load.pl -f <path/to/binary> -t /dev/<tty-device>
more information: https://github.com/malvira/libmc1322x/wiki/libmc1322x#loading-images-to-ram-with-mc1322x-loadpl
Erase:
cd tools/ftditools/
make
./bbmc -l redbee-econotag erase
more information: https://github.com/malvira/libmc1322x/wiki/bbmc

View File

@ -1,23 +0,0 @@
/*
* board_init.c - redbee-econotag initialization code
* Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
void board_init(void)
{
asm("nop");
}
void bl_init_clks(void)
{
// dummy to compile
}
void bl_init_ports(void)
{
// dummy to compile
}

View File

@ -1,7 +0,0 @@
MODULE =$(BOARD)_base
include $(RIOTBOARD)/$(BOARD)/Makefile.include
INCLUDES += -Iinclude
include $(RIOTBASE)/Makefile.base

View File

@ -1,65 +0,0 @@
/*
* nvm.h - non-volatile memory specific definitions
* Copyright (C) 2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
#ifndef NVM_H_
#define NVM_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum
{
g_nvm_type_no_nvm_c = 0,
g_nvm_type_SST_c,
g_nvm_type_ST_c,
g_nvm_type_ATM_c,
g_nvm_type_Max_c
} nvm_type_t;
typedef enum
{
g_nvm_err_no_error_c = 0,
g_nvm_err_invalid_interface_c,
g_nvm_err_onvalid_nvm_type_c,
g_nvm_err_invalid_pointer_c,
g_nvm_err_write_protect_c,
g_nvm_err_verify_error_c,
g_nvm_err_address_space_overflow_c,
g_nvm_err_blank_check_error_c,
g_nvm_err_restricted_area_c,
g_nvm_err_max_error_c
} nvm_err_t;
typedef enum
{
g_nvm_internal_interface_c = 0,
g_nvm_external_interface_c,
g_nvm_interface_max_c
} nvm_interface_t;
/* ROM code seems to be THUMB */
/* need to be in a THUMB block before calling them */
extern nvm_err_t (*nvm_detect)(nvm_interface_t nvm_interface,nvm_type_t* p_nvm_type);
extern nvm_err_t (*nvm_read)(nvm_interface_t nvm_interface , nvm_type_t nvm_type , void *p_dest, uint32_t address, uint32_t num_bytes);
extern nvm_err_t (*nvm_write)(nvm_interface_t nvm_interface, nvm_type_t nvm_type ,void *p_src, uint32_t address, uint32_t num_bytes);
/* sector bit field selects which sector to erase */
/* SST flash has 32 sectors 4096 bytes each */
/* bit 0 is the first sector, bit 31 is the last */
extern nvm_err_t (*nvm_erase)(nvm_interface_t nvm_interface, nvm_type_t nvm_type ,uint32_t sector_bitfield);
extern void(*nvm_setsvar)(uint32_t zero_for_awesome);
#ifdef __cplusplus
}
#endif
#endif /* NVM_H_ */

View File

@ -1,112 +0,0 @@
/*
* uart.h - UART driver for redbee
* Copyright (C) 2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
#ifndef UART_H_
#define UART_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------*/
/* UART */
#define UART1_BASE (0x80005000)
#define UART2_BASE (0x8000B000)
struct UART_struct {
union {
uint32_t CON;
struct UART_CON {
uint32_t TXE: 1; /*< Tx Enable */
uint32_t RXE: 1; /*< Rx Enable */
uint32_t PEN: 1; /*< Parity Enable */
uint32_t EP: 1; /*< Even Parity (1=Odd, 0=Even) */
uint32_t ST2: 1; /*< Enable 2 Stop Bits */
uint32_t SB: 1; /*< Send Break */
uint32_t CONTX: 1; /*< Continuous Tx (Test Mode) */
uint32_t TXOENB: 1; /*< TXD Outbut Disable */
uint32_t : 2; /*< reserved */
uint32_t XTIM: 1; /*< Times of Oversampling */
uint32_t FCP: 1; /*< Flow Control Polarity */
uint32_t FCE: 1; /*< Flow Control Enable */
uint32_t MTXR: 1; /*< enable/disable TxRDY Interrupts */
uint32_t MRXR: 1; /*< enable/disable RxRDY Interrupts */
uint32_t TST: 1; /*< Test Loop-Back */
uint32_t : 16; /*< reserved */
} CONbits;
};
union {
uint32_t STAT;
struct UART_STAT {
uint32_t SE: 1; /*< Start Bit Error */
uint32_t PE: 1; /*< Parity Bit Error */
uint32_t FE: 1; /*< Frame/Stop Bit Error */
uint32_t TOE: 1; /*< Tx FIFO Overrun Error */
uint32_t ROE: 1; /*< Rx FIFO Overrun Error */
uint32_t RUE: 1; /*< Rx FIFO Underrun Error */
uint32_t RXRDY: 1; /*< Receiver is causing Interrupts */
uint32_t TXRDY: 1; /*< Transmitter is causing Interrupts */
uint32_t : 24;
} USTATbits;
};
union {
uint32_t DATA;
struct UART_DATA {
uint32_t DATA: 8;
uint32_t : 24;
} DATAbits;
};
union {
uint32_t RXCON;
struct UART_URXCON {
uint32_t LVL: 6;
uint32_t : 26;
} RXCONbits;
};
union {
uint32_t TXCON;
struct UART_TXCON {
uint32_t LVL: 6;
uint32_t : 26;
} TXCONbits;
};
union {
uint32_t CTS;
struct UART_CTS {
uint32_t LVL: 5;
uint32_t : 27;
} CTSbits;
};
uint32_t BR; /*< BR is 32bit access only */
};
static volatile struct UART_struct *const UART1 = (void *)(UART1_BASE);
static volatile struct UART_struct *const UART2 = (void *)(UART2_BASE);
void uart_init(volatile struct UART_struct *uart, uint32_t baud);
void uart_set_baudrate(volatile struct UART_struct *uart, uint32_t baud);
void uart_flow_ctl(volatile struct UART_struct *uart, uint8_t on);
#undef UART0_BUFSIZE
#define UART0_BUFSIZE (32)
void uart1_putc(uint8_t c);
uint8_t uart1_getc(void);
void uart2_putc(uint8_t c);
uint8_t uart2_getc(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,23 +0,0 @@
/*
* nvm.c - non-volatile memory implementations
* Copyright (C) 2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
* This file is part of RIOT.
*/
#include "nvm.h"
nvm_err_t (*nvm_detect) (nvm_interface_t nvm_interface, nvm_type_t* p_nvm_type)
= (void*) 0x00006cb9;
nvm_err_t (*nvm_read) (nvm_interface_t nvm_interface, nvm_type_t nvm_type, void *p_dest, uint32_t address, uint32_t num_bytes)
= (void*) 0x00006d69;
nvm_err_t (*nvm_write) (nvm_interface_t nvm_interface, nvm_type_t nvm_type, void *p_src, uint32_t address, uint32_t numb_bytes)
= (void*) 0x00006ec5;
nvm_err_t (*nvm_erase) (nvm_interface_t nvm_interface, nvm_type_t nvm_type, uint32_t sector_bitfield)
= (void*) 0x00006e05;
void (*nvm_setsvar) (uint32_t zero_is_for_winners)
= (void*) 0x00007085;

View File

@ -1,178 +0,0 @@
/*
* redbee_uart.c - UART driver for redbee
* Copyright (C) 2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
#include "mc1322x.h"
#include "uart.h"
#include "gpio.h"
#define MOD_ 9999
#define CLK_ 24000000
#define DIV_ 16 /* uart->CON.XTIM = 0 is 16x oversample (datasheet is incorrect) */
#define BAUTRATE_UART1 115200
#define BAUTRATE_UART2 115200
void uart_set_baudrate(volatile struct UART_struct *uart, uint32_t baudrate)
{
uint64_t inc = 0;
/* calculate inc following equation 13-1 from datasheet */
/* multiply by another 10 to get a fixed point*/
inc = ((uint64_t) baudrate * DIV_ * MOD_ * 10 / CLK_) - 10;
/* add 5 and div by 10 to get a proper rounding */
inc = (inc + 5) / 10;
/* disable UARTx to set baudrate */
uart->CONbits.TXE = 0;
uart->CONbits.RXE = 0;
/* set baudrate */
/* BR register is 32bit access only */
uart->BR = (((uint16_t) inc << 16) | MOD_);
/* reenable UARTx again */
/* uart->CON.XTIM = 0 is 16x oversample (datasheet is incorrect) */
uart->CONbits.XTIM = 0;
uart->CONbits.TXE = 1;
uart->CONbits.RXE = 1;
}
void uart_flow_ctl(volatile struct UART_struct *uart, uint8_t on)
{
if (on) {
/* enable flow control */
if (uart == UART1) {
/* CTS and RTS directions */
GPIO->PAD_DIR_SET.U1CTS = 1;
GPIO->PAD_DIR_RESET.U1RTS = 1;
/* function select to uart */
GPIO->FUNC_SEL.U1CTS = 1;
GPIO->FUNC_SEL.U1RTS = 1;
}
else {
/* UART2 */
/* CTS and RTS directions */
GPIO->PAD_DIR_SET.U2CTS = 1;
GPIO->PAD_DIR_RESET.U2RTS = 1;
/* function select to uart */
GPIO->FUNC_SEL.U2CTS = 1;
GPIO->FUNC_SEL.U2RTS = 1;
}
/* enable flow control */
uart->CONbits.FCE = 1;
}
else {
/* disable flow control */
uart->CONbits.FCE = 0;
if (uart == UART1) {
/* CTS and RTS directions */
GPIO->PAD_DIR_RESET.U1CTS = 1;
GPIO->PAD_DIR_RESET.U1RTS = 1;
/* function select to GPIO */
GPIO->FUNC_SEL.U1CTS = 3;
GPIO->FUNC_SEL.U1RTS = 3;
}
else {
/* CTS and RTS directions */
GPIO->PAD_DIR_RESET.U2CTS = 1;
GPIO->PAD_DIR_RESET.U2RTS = 1;
/* function select to GPIO */
GPIO->FUNC_SEL.U2CTS = 3;
GPIO->FUNC_SEL.U2RTS = 3;
}
}
}
void uart_init(volatile struct UART_struct *uart, uint32_t baudrate)
{
/* enable the uart so we can set the gpio mode */
/* has to be enabled before setting the function with GPIO->FUNC_SEL */
uart->CONbits.TXE = 1;
uart->CONbits.RXE = 1;
if (uart == UART1) {
/* TX and RX direction */
GPIO->PAD_DIR_SET.U1TX = 1;
GPIO->PAD_DIR_RESET.U1RX = 1;
/* set function selection to UART */
GPIO->FUNC_SEL.U1TX = 1;
GPIO->FUNC_SEL.U1RX = 1;
UART1->CONbits.TXE = 1; /*< enable transmit */
UART1->CONbits.RXE = 1; /*< enable receive */
UART1->CONbits.FCE = 1; /*< enable flowcontrol */
UART1->CONbits.MRXR = 1; /*< disable Rx interrupt */
UART1->CTSbits.LVL = 31; /*< drop cts when tx buffer at trigger level */
GPIO->FUNC_SEL.U1CTS = 1; /*< set GPIO 16 to UART1 CTS */
GPIO->FUNC_SEL.U1RTS = 1; /*< set GPIO 17 to UART1 RTS */
ITC->INTENABLEbits.UART1 = 1;
}
else {
/* UART2 */
/* TX and RX direction */
GPIO->PAD_DIR_SET.U2TX = 1;
GPIO->PAD_DIR_RESET.U2RX = 1;
/* set function selection to UART */
GPIO->FUNC_SEL.U2TX = 1;
GPIO->FUNC_SEL.U2RX = 1;
UART2->CONbits.TXE = 1; /*< enable transmit */
UART2->CONbits.RXE = 1; /*< enable receive */
UART2->CONbits.FCE = 1; /*< enable flowcontrol */
UART2->CONbits.MRXR = 1; /*< disable Rx interrupt */
UART2->CTSbits.LVL = 31; /*< drop cts when tx buffer at trigger level */
GPIO->FUNC_SEL.U2CTS = 1; /*< set GPIO 20 to UART2 CTS */
GPIO->FUNC_SEL.U2RTS = 1; /*< set GPIO 21 to UART2 RTS */
ITC->INTENABLEbits.UART2 = 1;
}
uart_set_baudrate(uart, baudrate);
}
int uart0_puts(uint8_t *astring, uint32_t length)
{
uint32_t i = 0;
for (; i < length; i++) {
uart1_putc(astring[i]);
}
return i;
}
void stdio_flush(void)
{
ITC->INTENABLEbits.UART1 = 0;
ITC->INTENABLEbits.UART2 = 0;
while (UART1->RXCON != 0 || UART2->RXCON != 0) {
UART1->DATA;
UART2->DATA;
}
while (UART1->TXCON != 0 || UART2->TXCON != 0) {
/* wait */
}
ITC->INTENABLEbits.UART1 = 1;
ITC->INTENABLEbits.UART2 = 1;
}
void bl_uart_init(void)
{
uart_init(UART1, BAUTRATE_UART1);
}

View File

@ -1,56 +0,0 @@
/*
* uart1.c - UART1 driver for redbee
* Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
* 2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
#include "mc1322x.h"
#include "board_uart0.h"
#include "uart.h"
void uart1_isr(void)
{
if (UART1->USTATbits.RXRDY == 1) {
#ifdef MODULE_UART0
if (uart0_handler_pid != KERNEL_PID_UNDEF) {
uint32_t i = 0;
while (UART1->RXCON != 0) {
uart0_handle_incoming(UART1->DATA);
if (++i >= UART0_BUFSIZE) {
uart0_notify_thread();
i = 0;
}
}
uart0_notify_thread();
}
#endif
}
}
void uart1_putc(uint8_t c)
{
/* while uart fifo is full */
while (UART1->TXCON == 0) {
/* wait */
}
UART1->DATA = c;
}
uint8_t uart1_getc(void)
{
/* while uart fifo is empty */
while (UART1->RXCON == 0) {
/* wait */
}
return UART1->DATA;
}

View File

@ -1,56 +0,0 @@
/*
* uart1.c - UART1 driver for redbee
* Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
* 2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
#include "mc1322x.h"
#include "board_uart0.h"
#include "uart.h"
void uart2_isr(void)
{
if (UART2->USTATbits.RXRDY == 1) {
#ifdef MODULE_UART0
if (uart0_handler_pid != KERNEL_PID_UNDEF) {
uint32_t i = 0;
while (UART2->RXCON != 0) {
uart0_handle_incoming(UART2->DATA);
if (++i >= UART0_BUFSIZE) {
uart0_notify_thread();
i = 0;
}
}
uart0_notify_thread();
}
#endif
}
}
void uart2_putc(uint8_t c)
{
/* while uart fifo is full */
while (UART2->TXCON == 0) {
/* wait */
}
UART2->DATA = c;
}
uint8_t uart2_getc(void)
{
/* while uart fifo is empty */
while (UART2->RXCON == 0) {
/* wait */
}
return UART2->DATA;
}

View File

@ -1,41 +0,0 @@
/*
* Copyright (C) 2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup boards_redbee-econotag Redbee Econotag
* @ingroup boards
* @brief Support for the Redbee Econotag board
* @{
*
* @file
* @brief Basic definitions for the Redbee Econotag board
*
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*/
#ifndef REDBEE_ECONOTAG_BOARD_H_
#define REDBEE_ECONOTAG_BOARD_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define F_CPU (24000000) /**< CPU target speed in Hz */
#define CTUNE 0xb
#define IBIAS 0x1f
#define FTUNE 0x7
#ifdef __cplusplus
}
#endif
#endif
/** @} */

View File

@ -1,24 +0,0 @@
/*
* Copyright (C) 2014 INRIA
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup boards_redbee-econotag
* @{
*
* @file
* @brief Redbee Econotag peripheral configuration
*
* @author Oliver Hahm <oliver.hahm@inria.fr>
*/
#ifndef PERIPH_CONF_H_
#define PERIPH_CONF_H_
/* make Travis happy: #ifdef __cplusplus extern "C" { #endif */
#endif /* PERIPH_CONF_H_ */

View File

@ -1,17 +0,0 @@
INSTALL= /usr/local/bin
################
LDLIBS = -lftdi
TARGETS = bbmc
CFLAGS = -Wall -Wextra #-Werror
all: $(TARGETS)
clean:
-rm -f $(TARGETS)
install: all
cp bbmc $(INSTALL)

View File

@ -1,571 +0,0 @@
/*
* Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors
* to the MC1322x project (http://mc1322x.devl.org)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of libmc1322x: see http://mc1322x.devl.org
* for details.
*
*
*/
/* control reset and VREF2 lines */
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <getopt.h>
#include <ftdi.h>
#define DEBUG 0
#define low(x) (1 << x)
#define high(x) (1 << (x + 8))
#define REDBEE_ECONOTAG_RESET high(2)
#define REDBEE_ECONOTAG_VREF2L high(7)
#define REDBEE_ECONOTAG_VREF2H high(6)
#define REDBEE_ECONOTAG_INTERFACE INTERFACE_A
#define REDBEE_USB_RESET high(2)
#define REDBEE_USB_VREF2L low(5)
#define REDBEE_USB_VREF2H low(6)
#define REDBEE_USB_INTERFACE INTERFACE_B
#define FLEXIBITY_USB_RESET high(2)
#define FLEXIBITY_USB_VREF2L high(7)
#define FLEXIBITY_USB_VREF2H high(6)
#define FLEXIBITY_USB_INTERFACE INTERFACE_A
#define BOARD REDBEE_USB
#define STR(x) #x
#define STR2(x) STR(x)
#define CAT(x,y) x##y
#define CAT2(x, y, z) x##y##z
#define dir(x) ( CAT(x,_RESET) | CAT(x,_VREF2L) | CAT(x,_VREF2H))
#define interface(x) ( CAT(x,_INTERFACE) )
#define reset_release(x) ( CAT(x,_RESET) )
#define reset_set(x) ( 0 )
#define vref2_normal(x) ( CAT(x,_VREF2H) )
#define vref2_erase(x) ( CAT(x,_VREF2L) )
/* fgets input buffer length: for prompts and such */
#define BUF_LEN 32
struct layout {
char *name;
char *desc;
enum ftdi_interface interface;
uint16_t dir;
uint16_t reset_release;
uint16_t reset_set;
uint16_t vref2_normal;
uint16_t vref2_erase;
};
int print_and_prompt(struct ftdi_device_list *devlist);
int bb_mpsee(struct ftdi_context *ftdic, uint16_t dir, uint16_t val);
void reset(struct ftdi_context *ftdic, const struct layout *l);
void erase(struct ftdi_context *ftdic, const struct layout *l);
void usage(void);
#define std_layout(x) \
.interface = interface(x), \
.dir = dir(x), \
.reset_release = reset_release(x), \
.reset_set = reset_set(x), \
.vref2_normal = vref2_normal(x), \
.vref2_erase = vref2_erase(x),
static struct layout layouts[] = {
{
.name = "redbee-econotag",
.desc = "Redbee Econotag",
std_layout(REDBEE_ECONOTAG)
},
{
.name = "redbee-usb",
.desc = "Redbee USB stick",
std_layout(REDBEE_USB)
},
{
.name = "flexibity",
.desc = "Flexibity USB Interface",
std_layout(FLEXIBITY_USB)
},
{ .name = NULL, /* end of table */ },
};
struct command {
char *name;
char *desc;
void (*cmd)(struct ftdi_context *ftdic, const struct layout *l);
};
static const struct command commands[] = {
{
.name = "reset",
.desc = "Toggles reset pin",
.cmd = reset,
},
{
.name = "erase",
.desc = "Sets VREF2 erase mode; toggles reset; waits 2 sec.; sets normal; toggles reset again",
.cmd = erase,
},
{ .name = NULL, /* end of table */ },
};
struct layout *find_layout(char *str)
{
uint32_t i = 0;
while (layouts[i].name != NULL) {
if (strcmp(layouts[i].name, str) == 0) {
return &layouts[i];
}
i++;
}
return NULL;
}
static uint32_t vendid = 0x0403;
uint32_t prodid = 0x6010;
#if __APPLE__
static void restore_ftdi_kext(void)
{
system("sudo kextload /System/Library/Extensions/FTDIUSBSerialDriver.kext");
}
#endif
int main(int argc, char **argv)
{
struct ftdi_context ftdic;
struct ftdi_device_list *devlist;
int dev_index = -1;
int num_devs;
char layout_str[BUF_LEN];
struct layout layout;
struct layout *l = NULL;
int i, ret;
/* overrides for layout parameters */
int interface = -1;
int dir = -1;
int reset_release = -1;
int reset_set = -1;
int vref2_normal = -1;
int vref2_erase = -1;
layout.name = NULL;
while (1) {
int c;
int option_index = 0;
static struct option long_options[] = {
{"layout", required_argument, 0, 'l'},
{"index", required_argument, 0, 'i'},
{"vendor", required_argument, 0, 'v'},
{"product", required_argument, 0, 'p'},
{"dir", required_argument, 0, 0 },
{"reset_release", required_argument, 0, 0 },
{"reset_set", required_argument, 0, 0 },
{"vref2_normal", required_argument, 0, 0 },
{"vref2_erase", required_argument, 0, 0 },
{"interface", required_argument, 0, 0 },
{"help", no_argument, 0, '?'},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "i:l:v:p:",
long_options, &option_index);
if (c == -1) {
break;
}
switch (c) {
/* process long opts */
case 0:
if (strcmp(long_options[option_index].name, "interface") == 0) {
sscanf(optarg, "%11i", &interface);
}
if (strcmp(long_options[option_index].name, "dir") == 0) {
sscanf(optarg, "%11i", &dir);
}
if (strcmp(long_options[option_index].name, "reset_release") == 0) {
sscanf(optarg, "%11i", &reset_release);
}
if (strcmp(long_options[option_index].name, "reset_set") == 0) {
sscanf(optarg, "%11i", &reset_set);
}
if (strcmp(long_options[option_index].name, "vref2_normal") == 0) {
sscanf(optarg, "%11i", &vref2_normal);
}
if (strcmp(long_options[option_index].name, "vref2_erase") == 0) {
sscanf(optarg, "%11i", &vref2_erase);
}
break;
case 'l':
strncpy(layout_str, optarg, BUF_LEN);
break;
case 'i':
dev_index = atoi(optarg);
break;
case 'v':
sscanf(optarg, "%11i", &vendid);
break;
case 'p':
sscanf(optarg, "%11i", &prodid);
break;
default:
usage();
break;
}
}
if (!(l = find_layout(layout_str)) &&
!((interface >= 0) &&
(dir >= 0) &&
(reset_release >= 0) &&
(reset_set >= 0) &&
(vref2_normal >= 0) &&
(vref2_erase >= 0))
) {
printf("*** You must specify a layout or a complete set of overrides\n");
return EXIT_FAILURE;
}
if (l) {
memcpy(&layout, l, sizeof(struct layout));
}
#define override(x) if(x > 0) { layout.x = x; }
override(interface);
override(dir);
override(reset_release);
override(reset_set);
override(vref2_normal);
override(vref2_erase);
if ((num_devs = ftdi_usb_find_all(&ftdic, &devlist, vendid, prodid)) < 0) {
fprintf(stderr, "ftdi_usb_find_all failed: %d (%s)\n",
num_devs,
ftdi_get_error_string(&ftdic));
return EXIT_FAILURE;
}
if (ftdi_init(&ftdic) < 0) {
fprintf(stderr, "ftdi_init failed\n");
return EXIT_FAILURE;
}
if ((ret = ftdi_set_interface(&ftdic, layout.interface)) < 0) {
fprintf(stderr, "couldn't set interface %d, err %d (%s)\n", layout.interface, ret, ftdi_get_error_string(&ftdic));
return EXIT_FAILURE;
}
printf("Found %d devices with vendor id 0x%04x product id 0x%04x\n",
num_devs, vendid, prodid);
if (num_devs == 0) {
return EXIT_SUCCESS;
}
if (num_devs == 1) {
dev_index = 0;
}
while ((dev_index < 0) || (dev_index >= num_devs)) {
dev_index = print_and_prompt(devlist);
}
if (layout.name != NULL) {
printf("Opening device %d interface %d using layout %s\n",
dev_index, layout.interface, layout.name);
}
else {
printf("Opening device %d interface %d without a layout.\n",
dev_index, layout.interface);
}
if ((ret = ftdi_usb_open_desc_index(
&ftdic,
vendid,
prodid,
NULL,
NULL,
dev_index)) < 0) {
#if __APPLE__
if ((ret == -5) && (0 == system("sudo kextunload /System/Library/Extensions/FTDIUSBSerialDriver.kext"))) {
// Try again without the FTDI kext loaded this time
atexit(&restore_ftdi_kext);
ret = ftdi_usb_open_desc_index(
&ftdic,
vendid,
prodid,
NULL,
NULL,
dev_index
);
}
if (ret)
#endif // __APPLE__
{
fprintf(stderr, "couldn't open dev_index %d, err %d (%s)\n", dev_index, ret, ftdi_get_error_string(&ftdic));
return EXIT_FAILURE;
}
}
for (i = 0; commands[i].name != NULL; i++) {
if ((argv[optind] != NULL) &&
(strcmp(commands[i].name, argv[optind]) == 0)) {
break;
}
}
if (commands[i].name != NULL) {
commands[i].cmd(&ftdic, &layout);
}
else {
printf("invalid command\n");
ftdi_list_free(&devlist);
ftdi_deinit(&ftdic);
return EXIT_FAILURE;
}
printf("done.\n");
ftdi_list_free(&devlist);
ftdi_deinit(&ftdic);
return EXIT_SUCCESS;
}
void usage(void)
{
int i;
printf("Usage: bbmc [options|overrides] -l|--layout layout command \n");
printf("Commands:\n");
for (i = 0; commands[i].name != NULL; i++) {
printf(" %s: %s\n", commands[i].name, commands[i].desc);
}
printf("\n");
printf("Required options:\n");
printf(" -l|--layout\t specifiy which board layout to use\n");
printf(" \t layout is not necessary with a full\n");
printf(" \t set of overrides\n");
printf("\nLayout overrides:\n");
printf(" --interface\t\t FTDI interface to use\n");
printf(" --dir\t\t direction (1 is output)\n");
printf(" --reset_release\t reset release command\n");
printf(" --reset_set\t\t reset set command\n");
printf(" --vref2_normal\t vref2 normal\n");
printf(" --vref2_erase\t vref2 erase\n");
printf("\n");
printf("Layouts:\n");
for (i = 0; layouts[i].name != NULL; i++) {
printf("\t%s: %s\n", layouts[i].name, layouts[i].desc);
printf("\n");
printf("\t\tinterface: \t0x%04x\n", layouts[i].interface);
printf("\t\tdir: \t\t0x%04x\n", layouts[i].dir);
printf("\t\treset release: \t0x%04x\n", layouts[i].reset_release);
printf("\t\treset hold: \t0x%04x\n", layouts[i].reset_set);
printf("\t\tvref2 normal: \t0x%04x\n", layouts[i].vref2_normal);
printf("\t\tvref2 erase: \t0x%04x\n", layouts[i].vref2_erase);
printf("\n");
}
printf("\n");
printf("Options:\n");
printf(" -i|--index specifiy which device to use (default 0)\n");
printf(" -v|--vendor set vendor id (default 0x0403)\n");
printf(" -p|--product set vendor id (default 0x6010)\n");
}
int print_and_prompt(struct ftdi_device_list *devlist)
{
int i;
struct ftdi_context ftdic;
struct ftdi_device_list *curdev;
char manufacturer[128], description[128], serial[128];
char input[BUF_LEN];
char *s;
int sel = -1;
printf("\n");
i = 0;
for (curdev = devlist; curdev != NULL; i++) {
printf(" [%d] ", i);
int ret = ftdi_usb_get_strings(&ftdic,
curdev->dev,
manufacturer, 128,
description, 128,
serial, 128);
if (0 > ret) {
fprintf(stderr, "ftdi_usb_get_strings failed: %d (%s)\n",
ret, ftdi_get_error_string(&ftdic));
return EXIT_FAILURE;
}
printf("Manufacturer: %s, Description: %s, Serial %s\n",
manufacturer, description, serial);
curdev = curdev->next;
}
printf("\nUse which device? ");
s = fgets(input, BUF_LEN, stdin);
if (s != NULL) {
size_t last = strlen(input) - 1;
if (input[last] == '\n') {
/* cppcheck: input is accessed later via *s */
/* cppcheck-suppress unreadVariable */
input[last] = '\0';
}
sscanf(s, "%11i", &sel);
}
return sel;
}
void reset(struct ftdi_context *ftdic, const struct layout *l)
{
/* using MPSSE since it give access to high GPIO*/
/* set as inputs for now */
ftdi_set_bitmode(ftdic, 0 , BITMODE_MPSSE);
printf("toggle reset\n");
bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
bb_mpsee(ftdic, l->dir, (l->reset_set | l->vref2_normal));
bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
return;
}
void erase(struct ftdi_context *ftdic, const struct layout *l)
{
printf("setting VREF2 erase\n");
/* using MPSSE since it give access to high GPIO*/
/* set as inputs for now */
ftdi_set_bitmode(ftdic, 0 , BITMODE_MPSSE);
bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_erase));
printf("toggle reset\n");
bb_mpsee(ftdic, l->dir, (l->reset_set | l->vref2_erase));
bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_erase));
printf("waiting for erase\n");
sleep(2);
printf("setting VREF2 normal\n");
bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
reset(ftdic, l);
return;
}
int bb_mpsee(struct ftdi_context *ftdic, uint16_t dir, uint16_t val)
{
uint8_t buf[3];
/* command "set data bits low byte" */
buf[0] = 0x80;
buf[1] = (val & 0xff);
buf[2] = dir & 0xff;
#if DEBUG
fprintf(stderr, "write %x %x %x\n", buf[0], buf[1], buf[2]);
#endif
if ((ret = (ftdi_write_data(ftdic, buf, 3))) < 0) {
perror("ft2232_write error");
fprintf(stderr, "ft2232_write command %x\n", buf[0]);
return EXIT_FAILURE;
}
/* command "set data bits high byte" */
buf[0] = 0x82;
buf[1] = (val >> 8);
buf[2] = dir >> 8;
#if DEBUG
fprintf(stderr, "write %x %x %x\n", buf[0], buf[1], buf[2]);
#endif
if ((ftdi_write_data(ftdic, buf, 3)) < 0) {
perror("ft2232_write error");
fprintf(stderr, "ft2232_write command %x\n", buf[0]);
return EXIT_FAILURE;
}
return 0;
}

View File

@ -1,385 +0,0 @@
/*
* Copyright (c) 2012, Maxim Osipov <maxim.osipov@gmail.com>
* Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors
* to the MC1322x project (http://mc1322x.devl.org)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <stdint.h>
char *filename;
char *second;
char *term = "/dev/ttyUSB0";
int baud = B115200;
int verbose = 0;
char *rts = "rts";
char *command;
int first_delay = 50;
int second_delay = 100;
int do_exit = 0;
int zerolen = 0;
char *args = NULL;
struct stat sbuf;
struct termios options;
char buf[256];
int pfd;
int ffd;
int sfd;
void help(void);
int main(int argc, char **argv)
{
int c = 0;
int r = 0;
int i = 0;
uint32_t s = 0;
opterr = 0;
/* Parse options */
while ((c = getopt(argc, argv, "f:s:zt:vu:r:c:a:b:eh")) != -1) {
switch (c) {
case 'f':
filename = optarg;
break;
case 's':
second = optarg;
break;
case 'z':
zerolen = 1;
break;
case 't':
term = optarg;
break;
case 'v':
verbose = 1;
break;
case 'u':
if (strcmp(optarg, "115200")) {
baud = B115200;
}
else if (strcmp(optarg, "57600")) {
baud = B115200;
}
else if (strcmp(optarg, "19200")) {
baud = B19200;
}
else if (strcmp(optarg, "9600")) {
baud = B9600;
}
else {
printf("Unknown baud rate %s!\n", optarg);
return -1;
}
break;
case 'r':
rts = optarg;
break;
case 'c':
command = optarg;
break;
case 'a':
first_delay = atoi(optarg);
break;
case 'b':
second_delay = atoi(optarg);
break;
case 'e':
do_exit = 1;
break;
case 'h':
case '?':
help();
return 0;
default:
abort();
}
}
/* Get other arguments */
if (optind < argc) {
args = argv[optind];
}
/* Print settings */
if (verbose) {
printf("Primary file (RAM): %s\n", filename);
printf("Secondary file (Flash): %s\n", second);
printf("Zero secondary file: %s\n", zerolen == 1 ? "Yes" : "No");
printf("Port: %s\n", term);
printf("Baud rate: %i\n", baud);
printf("Flow control: %s\n", rts);
printf("Reset command: %s\n", command);
printf("Exit after load: %s\n", do_exit == 1 ? "Yes" : "No");
printf("Delay 1: %i\n", first_delay);
printf("Delay 2: %i\n", second_delay);
}
/* Open and configure serial port */
pfd = open(term, O_RDWR | O_NOCTTY | O_NDELAY);
if (pfd == -1) {
printf("Cannot open serial port %s!\n", term);
return -1;
}
fcntl(pfd, F_SETFL, FNDELAY);
tcgetattr(pfd, &options);
cfsetispeed(&options, baud);
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
if (strcmp(rts, "rts")) {
options.c_cflag &= ~CRTSCTS;
}
else {
options.c_cflag |= CRTSCTS;
}
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag &= ~OPOST;
tcsetattr(pfd, TCSANOW, &options);
/* Reset the board if we can */
printf("Reset the board to enter bootloader (waiting for CONNECT)...\n");
if (command) {
printf("Performing reset: %s\n", command);
system(command);
}
/* Primary bootloader wait loop */
i = 0;
while (1) {
/* Wait for CONNECT */
write(pfd, (const void *)"\0", 1);
sleep(1);
r = read(pfd, &buf[i], sizeof(buf) - 1 - i);
if (r > 0) {
buf[i + r] = '\0';
printf("%s", &buf[i]);
fflush(stdout);
if (strstr(&buf[i], "CONNECT")) {
printf("\n");
break;
}
i += r;
if (i >= sizeof(buf) - 1) {
i = 0;
}
}
else {
printf(".");
fflush(stdout);
}
}
/* Send primary file */
if (!filename) {
printf("Please specify firmware file name (-f option)!\n");
return -1;
}
if (stat(filename, &sbuf)) {
printf("Cannot open firmware file %s!\n", filename);
return -1;
}
ffd = open(filename, O_RDONLY);
if (ffd == -1) {
printf("Cannot open firmware file %s!\n", filename);
return -1;
}
s = sbuf.st_size;
printf("Sending %s (%i bytes)...\n", filename, s);
write(pfd, (const void *)&s, 4);
i = 0;
r = read(ffd, buf, 1);
while (r > 0) {
do {
usleep(first_delay);
c = write(pfd, (const void *)buf, r);
}
while (c < r);
i += r;
printf("Written %i\r", i);
fflush(stdout);
r = read(ffd, buf, 1);
}
printf("\n");
/* Secondary loader wait loop */
if (second || zerolen) {
/* Wait for ready */
printf("Sending secondary file (waiting for ready)...\n");
i = 0;
while (1) {
sleep(1);
r = read(pfd, &buf[i], sizeof(buf) - 1 - i);
if (r > 0) {
buf[i + r] = '\0';
printf("%s", &buf[i]);
fflush(stdout);
if (strstr(buf, "ready")) {
printf("\n");
break;
}
i += r;
if (i >= sizeof(buf) - 1) {
i = 0;
}
}
else {
printf(".");
fflush(stdout);
}
}
/* Send secondary file */
if (second) {
if (stat(second, &sbuf)) {
printf("Cannot open secondary file %s!\n", second);
return -1;
}
sfd = open(second, O_RDONLY);
if (sfd == -1) {
printf("Cannot open secondary file %s!\n", second);
return -1;
}
s = sbuf.st_size;
printf("Sending %s (%i bytes)...\n", second, s);
write(pfd, (const void *)&s, 4);
i = 0;
r = read(sfd, buf, 1);
while (r > 0) {
do {
usleep(second_delay);
c = write(pfd, (const void *)buf, r);
}
while (c < r);
i += r;
printf("Written %i\r", i);
fflush(stdout);
r = read(sfd, buf, 1);
}
printf("\n");
}
else if (zerolen) {
s = 0;
printf("Sending %i...\n", s);
write(pfd, (const void *)&s, 4);
}
}
/* Send the remaining arguments */
if (args) {
printf("Sending %s\n", args);
write(pfd, (const void *)args, strlen(args));
r = write(pfd, (const void *)",", 1);
}
/* Drop in echo mode */
if (!do_exit) {
while (1) {
r = read(pfd, buf, sizeof(buf));
if (r > 0) {
buf[r] = '\0';
printf("%s", buf);
fflush(stdout);
}
}
}
}
void help(void)
{
printf("Example usage: mc1322x-load -f foo.bin -t /dev/ttyS0 -b 9600\n");
printf(" or : mc1322x-load -f flasher.bin -s flashme.bin 0x1e000,0x11223344,0x55667788\n");
printf(" or : mc1322x-load -f flasher.bin -z 0x1e000,0x11223344,0x55667788\n");
printf(" -f required: binary file to load\n");
printf(" -s optional: secondary binary file to send\n");
printf(" -z optional: send a zero length file as secondary\n");
printf(" -t, terminal default: /dev/ttyUSB0\n");
printf(" -u, baud rate default: 115200\n");
printf(" -r [none|rts] flow control default: rts\n");
printf(" -c command to run for autoreset: \n");
printf(" e.g. -c 'bbmc -l redbee-econotag -i 0 reset'\n");
printf(" -e exit instead of dropping to terminal display\n");
printf(" -a first intercharacter delay, passed to usleep\n");
printf(" -b second intercharacter delay, passed to usleep\n");
printf("\n");
printf("Anything on the command line is sent after all of the files.\n\n");
}

View File

@ -1,170 +0,0 @@
#!/usr/bin/perl -w
use Device::SerialPort;
use Term::ReadKey;
use Getopt::Long;
use Time::HiRes qw(usleep);
use strict;
my $filename = '';
my $second = '';
my $term = '/dev/ttyUSB0';
my $baud = '115200';
my $verbose;
my $rts = 'rts';
my $command = '';
my $first_delay = 50;
my $second_delay = 100;
my $do_exit;
my $zerolen;
GetOptions ('file=s' => \$filename,
'secondfile=s' => \$second,
'zerolen' => \$zerolen,
'terminal=s' => \$term,
'verbose' => \$verbose,
'u|baud=s' => \$baud,
'rts=s' => \$rts,
'command=s' => \$command,
'a=s' => \$first_delay,
'b=s' => \$second_delay,
'exit' => \$do_exit,
) or die 'bad options';
$| = 1;
if($filename eq '') {
print "Example usage: mc1322x-load.pl -f foo.bin -t /dev/ttyS0 -b 9600\n";
print " or : mc1322x-load.pl -f flasher.bin -s flashme.bin 0x1e000,0x11223344,0x55667788\n";
print " or : mc1322x-load.pl -f flasher.bin -z 0x1e000,0x11223344,0x55667788\n";
print " -f required: binary file to load\n";
print " -s optional: secondary binary file to send\n";
print " -z optional: send a zero length file as secondary\n";
print " -t, terminal default: /dev/ttyUSB0\n";
print " -u, --baud baud rate default: 115200\n";
print " -r [none|rts] flow control default: rts\n";
print " -c command to run for autoreset: \n";
print " e.g. -c 'bbmc -l redbee-econotag -i 0 reset'\n";
print " -e exit instead of dropping to terminal display\n";
print " -a first intercharacter delay, passed to usleep\n";
print " -b second intercharacter delay, passed to usleep\n";
print "\n";
print "anything on the command line is sent\n";
print "after all of the files.\n\n";
exit;
}
if (!(-e $filename)) { die "file $filename not found\n"; }
if (($second ne '') && !(-e $second)) { die "secondary file $second not found\n"; }
my $ob = Device::SerialPort->new ($term) or die "Can't start $term\n";
# next test will die at runtime unless $ob
$ob->baudrate($baud);
$ob->parity('none');
$ob->databits(8);
$ob->stopbits(1);
if($rts eq 'rts') {
$ob->handshake('rts');
} else {
$ob->handshake('none');
}
$ob->read_const_time(1000); # 1 second per unfulfilled "read" call
$ob->rts_active(1);
my $s = 0;
my $reset = 0;
my $size = 0;
while(1) {
my $c; my $count; my $ret = ''; my $test='';
if($s == 1) { print "secondary send...\n"; }
$ob->write(pack('C','0'));
if(($command ne '') &&
($reset eq 0)) {
$reset++;
system($command);
}
if($s == 1) {
$test = 'ready';
} else {
$test = 'CONNECT';
}
until($ret =~ /$test$/) {
($count,$c) = $ob->read(1);
if ($count == 0) {
print '.';
$ob->write(pack('C','0'));
next;
}
$ret .= $c;
}
print $ret . "\n";
if (-e $filename || (defined($zerolen) && ($s == 1))) {
if(defined($zerolen) && ($s == 1)) {
$size = 0;
} else {
$size = -s $filename;
}
print ("Size: $size bytes\n");
$ob->write(pack('V',$size));
if(($s == 0) ||
((!defined($zerolen)) && ($s == 1))) {
open(FILE, $filename) or die($!);
print "Sending $filename\n";
my $i = 1;
while(read(FILE, $c, 1)) {
$i++;
usleep($first_delay) if ( $s == 0 ) && ($first_delay != 0);
usleep($second_delay) if ( $s == 1 ) && ($second_delay != 0);
$ob->write($c);
}
}
}
last if ($s==1);
if((-e $second) || defined($zerolen)) {
$s=1; $filename = $second;
} else {
last;
}
}
print "done sending files.\n";
if(scalar(@ARGV)!=0) {
print "sending " ;
print @ARGV;
print ",\n";
$ob->write(@ARGV);
$ob->write(',');
}
if(defined($do_exit)) {
exit;
}
my $c; my $count;
while(1) {
($count, $c) = $ob->read(1);
print $c if (defined($count) && ($count != 0));
}
$ob -> close or die "Close failed: $!\n";
ReadMode 0;
undef $ob; # closes port AND frees memory in perl
exit;