From 7e071464a8d5b6789a0b32b415a50e58171dbbab Mon Sep 17 00:00:00 2001 From: Kaspar Schleiser Date: Wed, 22 Sep 2010 15:10:42 +0200 Subject: [PATCH] * import from old firekernel repository --- Jamfile | 3 + eZ430-Chronos/Jamfile | 10 + eZ430-Chronos/Jamrules.eZ430-Chronos | 12 + eZ430-Chronos/board_init.c | 2 + eZ430-Chronos/debug_uart.c | 21 + eZ430-Chronos/drivers/Jamfile | 5 + eZ430-Chronos/drivers/display.c | 519 +++++++++++++ eZ430-Chronos/drivers/display.h | 360 +++++++++ eZ430-Chronos/drivers/display1.c | 226 ++++++ eZ430-Chronos/include/board.h | 10 + msb-430h/Jamfile | 35 + msb-430h/Jamrules.msb-430h | 37 + msb-430h/board_init.c | 207 ++++++ msb-430h/debug_uart.c | 21 + msb-430h/driver_cc1100.c | 343 +++++++++ msb-430h/include/board.h | 69 ++ msba2/Jamfile | 35 + msba2/Jamfile.msba2 | 31 + msba2/Jamrules.msba2 | 33 + msba2/board_init.c | 156 ++++ msba2/drivers/Jamfile | 6 + msba2/drivers/include/hal-board.h | 68 ++ msba2/drivers/include/sht11-board.h | 63 ++ msba2/drivers/msba2-cc1100.c | 243 +++++++ msba2/drivers/msba2-ltc4150.c | 65 ++ msba2/drivers/msba2-uart0.c | 205 ++++++ msba2/include/board-conf.h | 68 ++ msba2/include/board.h | 62 ++ msba2/lpc2387-timer3.c | 37 + msba2/tools/CHANGES | 23 + msba2/tools/COPYING | 339 +++++++++ msba2/tools/Makefile | 43 ++ msba2/tools/README.txt | 144 ++++ msba2/tools/armtools.txt | 15 + msba2/tools/flash.cmd | 2 + msba2/tools/flashutil.sh | 113 +++ msba2/tools/mkbootc | 28 + msba2/tools/mkstaticlist | 47 ++ msba2/tools/obj/boot_23xx.d | 3 + msba2/tools/obj/boot_2xxx.d | 3 + msba2/tools/obj/chipinfo.d | 8 + msba2/tools/obj/control_2xxx.d | 6 + msba2/tools/obj/download.d | 19 + msba2/tools/obj/ihex.d | 3 + msba2/tools/obj/lpc2k_pgm.d | 8 + msba2/tools/obj/pseudoterm.d | 6 + msba2/tools/obj/serial.d | 3 + msba2/tools/obj/uuencode.d | 3 + msba2/tools/src/Jamfile | 9 + msba2/tools/src/boot.h | 9 + msba2/tools/src/boot_23xx.armasm | 32 + msba2/tools/src/boot_23xx.c | 5 + msba2/tools/src/boot_23xx.h | 2 + msba2/tools/src/boot_2xxx.armasm | 15 + msba2/tools/src/boot_2xxx.c | 5 + msba2/tools/src/boot_2xxx.h | 2 + msba2/tools/src/chipinfo.c | 159 ++++ msba2/tools/src/chipinfo.h | 20 + msba2/tools/src/cksum_test.c | 76 ++ msba2/tools/src/control_2xxx.c | 31 + msba2/tools/src/control_2xxx.h | 8 + msba2/tools/src/download.c | 972 +++++++++++++++++++++++++ msba2/tools/src/download.h | 8 + msba2/tools/src/gui.c | 387 ++++++++++ msba2/tools/src/gui.h | 3 + msba2/tools/src/ihex.c | 229 ++++++ msba2/tools/src/ihex.h | 7 + msba2/tools/src/lpc2k_pgm.c | 98 +++ msba2/tools/src/lpc2k_pgm.h | 12 + msba2/tools/src/pseudoterm.c | 135 ++++ msba2/tools/src/serial.c | 350 +++++++++ msba2/tools/src/serial.h | 19 + msba2/tools/src/settings.c | 172 +++++ msba2/tools/src/settings.h | 12 + msba2/tools/src/uuencode.c | 98 +++ msba2/tools/src/uuencode.h | 3 + msba2/tools/termctrl.sh | 22 + olimex_lpc2148/Jamfile | 10 + olimex_lpc2148/Jamfile.olimex_lpc2148 | 4 + olimex_lpc2148/Jamrules.olimex_lpc2148 | 9 + olimex_lpc2148/board_init.c | 88 +++ olimex_lpc2148/debug_uart.c | 14 + olimex_lpc2148/include/board.h | 1 + olimex_lpc2148/include/rs232.h | 40 + olimex_lpc2148/rs232.c | 65 ++ olimex_lpc2148/tick.c | 63 ++ olimex_lpc2148/tools/lpc2148_flash.gdb | 22 + pttu/Jamfile | 35 + pttu/Jamfile.pttu | 28 + pttu/Jamrules.pttu | 37 + pttu/board_init.c | 239 ++++++ pttu/drivers/Jamfile | 4 + pttu/drivers/pttu-uart0.c | 204 ++++++ pttu/include/board.h | 56 ++ pttu/tools/jtag.txt | 14 + pttu/tools/olimex-arm-usb-ocd.cfg | 9 + pttu/tools/openocd-pttu.cfg | 75 ++ pttu/tools/openocd-pttu.sh | 30 + pttu/tools/pttu_debug.gdb | 15 + 99 files changed, 7730 insertions(+) create mode 100644 Jamfile create mode 100644 eZ430-Chronos/Jamfile create mode 100644 eZ430-Chronos/Jamrules.eZ430-Chronos create mode 100644 eZ430-Chronos/board_init.c create mode 100644 eZ430-Chronos/debug_uart.c create mode 100644 eZ430-Chronos/drivers/Jamfile create mode 100644 eZ430-Chronos/drivers/display.c create mode 100644 eZ430-Chronos/drivers/display.h create mode 100644 eZ430-Chronos/drivers/display1.c create mode 100644 eZ430-Chronos/include/board.h create mode 100644 msb-430h/Jamfile create mode 100644 msb-430h/Jamrules.msb-430h create mode 100644 msb-430h/board_init.c create mode 100644 msb-430h/debug_uart.c create mode 100644 msb-430h/driver_cc1100.c create mode 100644 msb-430h/include/board.h create mode 100644 msba2/Jamfile create mode 100644 msba2/Jamfile.msba2 create mode 100644 msba2/Jamrules.msba2 create mode 100644 msba2/board_init.c create mode 100644 msba2/drivers/Jamfile create mode 100644 msba2/drivers/include/hal-board.h create mode 100644 msba2/drivers/include/sht11-board.h create mode 100644 msba2/drivers/msba2-cc1100.c create mode 100644 msba2/drivers/msba2-ltc4150.c create mode 100644 msba2/drivers/msba2-uart0.c create mode 100644 msba2/include/board-conf.h create mode 100644 msba2/include/board.h create mode 100644 msba2/lpc2387-timer3.c create mode 100644 msba2/tools/CHANGES create mode 100644 msba2/tools/COPYING create mode 100644 msba2/tools/Makefile create mode 100644 msba2/tools/README.txt create mode 100644 msba2/tools/armtools.txt create mode 100755 msba2/tools/flash.cmd create mode 100755 msba2/tools/flashutil.sh create mode 100644 msba2/tools/mkbootc create mode 100644 msba2/tools/mkstaticlist create mode 100644 msba2/tools/obj/boot_23xx.d create mode 100644 msba2/tools/obj/boot_2xxx.d create mode 100644 msba2/tools/obj/chipinfo.d create mode 100644 msba2/tools/obj/control_2xxx.d create mode 100644 msba2/tools/obj/download.d create mode 100644 msba2/tools/obj/ihex.d create mode 100644 msba2/tools/obj/lpc2k_pgm.d create mode 100644 msba2/tools/obj/pseudoterm.d create mode 100644 msba2/tools/obj/serial.d create mode 100644 msba2/tools/obj/uuencode.d create mode 100644 msba2/tools/src/Jamfile create mode 100644 msba2/tools/src/boot.h create mode 100644 msba2/tools/src/boot_23xx.armasm create mode 100644 msba2/tools/src/boot_23xx.c create mode 100644 msba2/tools/src/boot_23xx.h create mode 100644 msba2/tools/src/boot_2xxx.armasm create mode 100644 msba2/tools/src/boot_2xxx.c create mode 100644 msba2/tools/src/boot_2xxx.h create mode 100644 msba2/tools/src/chipinfo.c create mode 100644 msba2/tools/src/chipinfo.h create mode 100644 msba2/tools/src/cksum_test.c create mode 100644 msba2/tools/src/control_2xxx.c create mode 100644 msba2/tools/src/control_2xxx.h create mode 100644 msba2/tools/src/download.c create mode 100644 msba2/tools/src/download.h create mode 100644 msba2/tools/src/gui.c create mode 100644 msba2/tools/src/gui.h create mode 100644 msba2/tools/src/ihex.c create mode 100644 msba2/tools/src/ihex.h create mode 100644 msba2/tools/src/lpc2k_pgm.c create mode 100644 msba2/tools/src/lpc2k_pgm.h create mode 100644 msba2/tools/src/pseudoterm.c create mode 100644 msba2/tools/src/serial.c create mode 100644 msba2/tools/src/serial.h create mode 100644 msba2/tools/src/settings.c create mode 100644 msba2/tools/src/settings.h create mode 100644 msba2/tools/src/uuencode.c create mode 100644 msba2/tools/src/uuencode.h create mode 100755 msba2/tools/termctrl.sh create mode 100644 olimex_lpc2148/Jamfile create mode 100644 olimex_lpc2148/Jamfile.olimex_lpc2148 create mode 100644 olimex_lpc2148/Jamrules.olimex_lpc2148 create mode 100644 olimex_lpc2148/board_init.c create mode 100644 olimex_lpc2148/debug_uart.c create mode 100644 olimex_lpc2148/include/board.h create mode 100644 olimex_lpc2148/include/rs232.h create mode 100644 olimex_lpc2148/rs232.c create mode 100644 olimex_lpc2148/tick.c create mode 100644 olimex_lpc2148/tools/lpc2148_flash.gdb create mode 100644 pttu/Jamfile create mode 100644 pttu/Jamfile.pttu create mode 100644 pttu/Jamrules.pttu create mode 100644 pttu/board_init.c create mode 100644 pttu/drivers/Jamfile create mode 100644 pttu/drivers/pttu-uart0.c create mode 100644 pttu/include/board.h create mode 100644 pttu/tools/jtag.txt create mode 100644 pttu/tools/olimex-arm-usb-ocd.cfg create mode 100644 pttu/tools/openocd-pttu.cfg create mode 100755 pttu/tools/openocd-pttu.sh create mode 100644 pttu/tools/pttu_debug.gdb diff --git a/Jamfile b/Jamfile new file mode 100644 index 000000000..ad37fbe5b --- /dev/null +++ b/Jamfile @@ -0,0 +1,3 @@ +SubDir TOP board ; + +SubInclude TOP board $(BOARD) ; diff --git a/eZ430-Chronos/Jamfile b/eZ430-Chronos/Jamfile new file mode 100644 index 000000000..ea723c95a --- /dev/null +++ b/eZ430-Chronos/Jamfile @@ -0,0 +1,10 @@ +SubDir TOP board eZ430-Chronos ; + +HDRS += $(TOP)/board/$(CPU)/include ; + +Module board : debug_uart.c board_init.c ; +UseModule board ; + +SubInclude TOP board $(BOARD) drivers ; +SubInclude TOP cpu $(CPU) ; + diff --git a/eZ430-Chronos/Jamrules.eZ430-Chronos b/eZ430-Chronos/Jamrules.eZ430-Chronos new file mode 100644 index 000000000..eef3a0301 --- /dev/null +++ b/eZ430-Chronos/Jamrules.eZ430-Chronos @@ -0,0 +1,12 @@ +# ****************************************************************************** +# Copyright 2010, Freie Universitaet Berlin (FUB). All rights reserved. +# ****************************************************************************** +# $Id$ + +BOARD = eZ430-Chronos ; +CPU = msp430 ; +MCU = cc430x6137 ; + +FLASHER ?= mspdebug ; +FLASHFLAGS ?= rf2500 ; + diff --git a/eZ430-Chronos/board_init.c b/eZ430-Chronos/board_init.c new file mode 100644 index 000000000..aa52e65af --- /dev/null +++ b/eZ430-Chronos/board_init.c @@ -0,0 +1,2 @@ +void board_init() { +} diff --git a/eZ430-Chronos/debug_uart.c b/eZ430-Chronos/debug_uart.c new file mode 100644 index 000000000..d80c9c6e8 --- /dev/null +++ b/eZ430-Chronos/debug_uart.c @@ -0,0 +1,21 @@ +#include +#include "board.h" + +#define UART1_TX TXBUF1 +#define UART1_WAIT_TXDONE() while( (UTCTL1 & TXEPT) == 0 ) { _NOP(); } + + +int putchar(int c) +{ +// UART1_TX = c; +// UART1_WAIT_TXDONE(); +// +// if (c == 10) { +// UART1_TX = 13; +// UART1_WAIT_TXDONE(); +// } + + return c; +} + + diff --git a/eZ430-Chronos/drivers/Jamfile b/eZ430-Chronos/drivers/Jamfile new file mode 100644 index 000000000..b2fb968fa --- /dev/null +++ b/eZ430-Chronos/drivers/Jamfile @@ -0,0 +1,5 @@ +SubDir TOP board eZ430-Chronos drivers ; + +UseModule board_common ; + +Module board_common : display.c display1.c ; diff --git a/eZ430-Chronos/drivers/display.c b/eZ430-Chronos/drivers/display.c new file mode 100644 index 000000000..c0418f544 --- /dev/null +++ b/eZ430-Chronos/drivers/display.c @@ -0,0 +1,519 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 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. +// +// Neither the name of Texas Instruments Incorporated 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 COPYRIGHT HOLDERS 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 COPYRIGHT +// OWNER 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. +// +// ************************************************************************************************* +// Display functions. +// ************************************************************************************************* + + +// ************************************************************************************************* +// Include section + +// system +#include + +// driver +#include "cc430x613x.h" +#include "display.h" + + +// ************************************************************************************************* +// Prototypes section +void write_lcd_mem(uint8_t * lcdmem, uint8_t bits, uint8_t bitmask, uint8_t state); +void clear_line(uint8_t line); +void display_symbol(uint8_t symbol, uint8_t mode); +void display_char(uint8_t segment, uint8_t chr, uint8_t mode); +void display_chars(uint8_t segments, uint8_t * str, uint8_t mode); + + +// ************************************************************************************************* +// Defines section + + + +// ************************************************************************************************* +// Global Variable section + +// Display flags +volatile s_display_flags display; + +// Global return string for itoa function +uint8_t itoa_str[8]; + + + +// ************************************************************************************************* +// @fn lcd_init +// @brief Erase LCD memory. Init LCD peripheral. +// @param none +// @return none +// ************************************************************************************************* +void lcd_init(void) +{ + // Clear entire display memory + LCDBMEMCTL |= LCDCLRBM + LCDCLRM; + + // LCD_FREQ = ACLK/16/8 = 256Hz + // Frame frequency = 256Hz/4 = 64Hz, LCD mux 4, LCD on + LCDBCTL0 = (LCDDIV0 + LCDDIV1 + LCDDIV2 + LCDDIV3) | (LCDPRE0 + LCDPRE1) | LCD4MUX | LCDON; + + // LCB_BLK_FREQ = ACLK/8/4096 = 1Hz + LCDBBLKCTL = LCDBLKPRE0 | LCDBLKPRE1 | LCDBLKDIV0 | LCDBLKDIV1 | LCDBLKDIV2 | LCDBLKMOD0; + + // I/O to COM outputs + P5SEL |= (BIT5 | BIT6 | BIT7); + P5DIR |= (BIT5 | BIT6 | BIT7); + + // Activate LCD output + LCDBPCTL0 = 0xFFFF; // Select LCD segments S0-S15 + LCDBPCTL1 = 0x00FF; // Select LCD segments S16-S22 + +#ifdef USE_LCD_CHARGE_PUMP + // Charge pump voltage generated internally, internal bias (V2-V4) generation + LCDBVCTL = LCDCPEN | VLCD_2_72; +#endif +} + + +// ************************************************************************************************* +// @fn clear_display_all +// @brief Erase LINE1 and LINE2 segments. Clear also function-specific content. +// @param none +// @return none +// ************************************************************************************************* +void clear_display_all(void) +{ + // Clear generic content + clear_line(LINE1); + clear_line(LINE2); + + +} + + +// ************************************************************************************************* +// @fn clear_display +// @brief Erase LINE1 and LINE2 segments. Keep icons. +// @param none +// @return none +// ************************************************************************************************* +void clear_display(void) +{ + clear_line(LINE1); + clear_line(LINE2); +} + + +// ************************************************************************************************* +// @fn clear_line +// @brief Erase segments of a given line. +// @param uint8_t line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void clear_line(uint8_t line) +{ + display_chars(switch_seg(line, LCD_SEG_L1_3_0, LCD_SEG_L2_5_0), NULL, SEG_OFF); + if (line == LINE1) + { + display_symbol(LCD_SEG_L1_DP1, SEG_OFF); + display_symbol(LCD_SEG_L1_DP0, SEG_OFF); + display_symbol(LCD_SEG_L1_COL, SEG_OFF); + } + else // line == LINE2 + { + display_symbol(LCD_SEG_L2_DP, SEG_OFF); + display_symbol(LCD_SEG_L2_COL1, SEG_OFF); + display_symbol(LCD_SEG_L2_COL0, SEG_OFF); + } +} + + +// ************************************************************************************************* +// @fn write_segment +// @brief Write to one or multiple LCD segments +// @param lcdmem Pointer to LCD byte memory +// bits Segments to address +// bitmask Bitmask for particular display item +// mode On, off or blink segments +// @return +// ************************************************************************************************* +void write_lcd_mem(uint8_t * lcdmem, uint8_t bits, uint8_t bitmask, uint8_t state) +{ + if (state == SEG_ON) + { + // Clear segments before writing + *lcdmem = (uint8_t)(*lcdmem & ~bitmask); + + // Set visible segments + *lcdmem = (uint8_t)(*lcdmem | bits); + } + else if (state == SEG_OFF) + { + // Clear segments + *lcdmem = (uint8_t)(*lcdmem & ~bitmask); + } + else if (state == SEG_ON_BLINK_ON) + { + // Clear visible / blink segments before writing + *lcdmem = (uint8_t)(*lcdmem & ~bitmask); + *(lcdmem+0x20) = (uint8_t)(*(lcdmem+0x20) & ~bitmask); + + // Set visible / blink segments + *lcdmem = (uint8_t)(*lcdmem | bits); + *(lcdmem+0x20) = (uint8_t)(*(lcdmem+0x20) | bits); + } + else if (state == SEG_ON_BLINK_OFF) + { + // Clear visible segments before writing + *lcdmem = (uint8_t)(*lcdmem & ~bitmask); + + // Set visible segments + *lcdmem = (uint8_t)(*lcdmem | bits); + + // Clear blink segments + *(lcdmem+0x20) = (uint8_t)(*(lcdmem+0x20) & ~bitmask); + } + else if (state == SEG_OFF_BLINK_OFF) + { + // Clear segments + *lcdmem = (uint8_t)(*lcdmem & ~bitmask); + + // Clear blink segments + *(lcdmem+0x20) = (uint8_t)(*(lcdmem+0x20) & ~bitmask); + } +} + + +// ************************************************************************************************* +// @fn itoa +// @brief Generic integer to array routine. Converts integer n to string. +// Default conversion result has leading zeros, e.g. "00123" +// Option to convert leading '0' into whitespace (blanks) +// @param uint32_t n integer to convert +// uint8_t digits number of digits +// uint8_t blanks fill up result string with number of whitespaces instead of leading zeros +// @return uint8_t string +// ************************************************************************************************* +uint8_t * itoa(uint32_t n, uint8_t digits, uint8_t blanks) +{ + uint8_t i; + uint8_t digits1 = digits; + + // Preset result string + memcpy(itoa_str, "0000000", 7); + + // Return empty string if number of digits is invalid (valid range for digits: 1-7) + if ((digits == 0) || (digits > 7)) return (itoa_str); + + // Numbers 0 .. 180 can be copied from itoa_conversion_table without conversion + if (n <= 180) + { + if (digits >= 3) + { + memcpy(itoa_str+(digits-3), itoa_conversion_table[n], 3); + } + else // digits == 1 || 2 + { + memcpy(itoa_str, itoa_conversion_table[n]+(3-digits), digits); + } + } + else // For n > 180 need to calculate string content + { + // Calculate digits from least to most significant number + do + { + itoa_str[digits-1] = n % 10 + '0'; + n /= 10; + } while (--digits > 0); + } + + // Remove specified number of leading '0', always keep last one + i = 0; + while ((itoa_str[i] == '0') && (i < digits1-1)) + { + if (blanks > 0) + { + // Convert only specified number of leading '0' + itoa_str[i]=' '; + blanks--; + } + i++; + } + + return (itoa_str); +} + + +// ************************************************************************************************* +// @fn display_value1 +// @brief Generic decimal display routine. Used exclusively by set_value function. +// @param uint8_t segments LCD segments where value is displayed +// uint32_t value Integer value to be displayed +// uint8_t digits Number of digits to convert +// uint8_t blanks Number of leadings blanks in itoa result string +// @return none +// ************************************************************************************************* +void display_value1(uint8_t segments, uint32_t value, uint8_t digits, uint8_t blanks, uint8_t disp_mode) +{ + uint8_t * str; + + str = itoa(value, digits, blanks); + + // Display string in blink mode + display_chars(segments, str, disp_mode); +} + + +// ************************************************************************************************* +// @fn display_symbol +// @brief Switch symbol on or off on LCD. +// @param uint8_t symbol A valid LCD symbol (index 0..42) +// uint8_t state SEG_ON, SEG_OFF, SEG_BLINK +// @return none +// ************************************************************************************************* +void display_symbol(uint8_t symbol, uint8_t mode) +{ + uint8_t * lcdmem; + uint8_t bits; + uint8_t bitmask; + + if (symbol <= LCD_SEG_L2_DP) + { + // Get LCD memory address for symbol from table + lcdmem = (uint8_t *)segments_lcdmem[symbol]; + + // Get bits for symbol from table + bits = segments_bitmask[symbol]; + + // Bitmask for symbols equals bits + bitmask = bits; + + // Write LCD memory + write_lcd_mem(lcdmem, bits, bitmask, mode); + } +} + + +// ************************************************************************************************* +// @fn display_char +// @brief Write to 7-segment characters. +// @param uint8_t segment A valid LCD segment +// uint8_t chr Character to display +// uint8_t mode SEG_ON, SEG_OFF, SEG_BLINK +// @return none +// ************************************************************************************************* +void display_char(uint8_t segment, uint8_t chr, uint8_t mode) +{ + uint8_t * lcdmem; // Pointer to LCD memory + uint8_t bitmask; // Bitmask for character + uint8_t bits, bits1; // Bits to write + + // Write to single 7-segment character + if ((segment >= LCD_SEG_L1_3) && (segment <= LCD_SEG_L2_DP)) + { + // Get LCD memory address for segment from table + lcdmem = (uint8_t *)segments_lcdmem[segment]; + + // Get bitmask for character from table + bitmask = segments_bitmask[segment]; + + // Get bits from font set + if ((chr >= 0x30) && (chr <= 0x5A)) + { + // Use font set + bits = lcd_font[chr-0x30]; + } + else if (chr == 0x2D) + { + // '-' not in font set + bits = BIT1; + } + else + { + // Other characters map to ' ' (blank) + bits = 0; + } + + // When addressing LINE2 7-segment characters need to swap high- and low-nibble, + // because LCD COM/SEG assignment is mirrored against LINE1 + if (segment >= LCD_SEG_L2_5) + { + bits1 = ((bits << 4) & 0xF0) | ((bits >> 4) & 0x0F); + bits = bits1; + + // When addressing LCD_SEG_L2_5, need to convert ASCII '1' and 'L' to 1 bit, + // because LCD COM/SEG assignment is special for this incomplete character + if (segment == LCD_SEG_L2_5) + { + if ((chr == '1') || (chr == 'L')) bits = BIT7; + } + } + + // Physically write to LCD memory + write_lcd_mem(lcdmem, bits, bitmask, mode); + } +} + + +// ************************************************************************************************* +// @fn display_chars +// @brief Write to consecutive 7-segment characters. +// @param uint8_t segments LCD segment array +// uint8_t * str Pointer to a string +// uint8_t mode SEG_ON, SEG_OFF, SEG_BLINK +// @return none +// ************************************************************************************************* +void display_chars(uint8_t segments, uint8_t * str, uint8_t mode) +{ + uint8_t i; + uint8_t length = 0; // Write length + uint8_t char_start = 0; // Starting point for consecutive write + + switch (segments) + { + // LINE1 + case LCD_SEG_L1_3_0: length=4; char_start=LCD_SEG_L1_3; break; + case LCD_SEG_L1_2_0: length=3; char_start=LCD_SEG_L1_2; break; + case LCD_SEG_L1_1_0: length=2; char_start=LCD_SEG_L1_1; break; + case LCD_SEG_L1_3_1: length=3; char_start=LCD_SEG_L1_3; break; + case LCD_SEG_L1_3_2: length=2; char_start=LCD_SEG_L1_3; break; + + // LINE2 + case LCD_SEG_L2_5_0: length=6; char_start=LCD_SEG_L2_5; break; + case LCD_SEG_L2_4_0: length=5; char_start=LCD_SEG_L2_4; break; + case LCD_SEG_L2_3_0: length=4; char_start=LCD_SEG_L2_3; break; + case LCD_SEG_L2_2_0: length=3; char_start=LCD_SEG_L2_2; break; + case LCD_SEG_L2_1_0: length=2; char_start=LCD_SEG_L2_1; break; + case LCD_SEG_L2_5_4: length=2; char_start=LCD_SEG_L2_5; break; + case LCD_SEG_L2_5_2: length=4; char_start=LCD_SEG_L2_5; break; + case LCD_SEG_L2_3_2: length=2; char_start=LCD_SEG_L2_3; break; + case LCD_SEG_L2_4_2: length=3; char_start=LCD_SEG_L2_4; break; + } + + // Write to consecutive digits + for(i=0; i) + SEG_A+SEG_B+ SEG_E+ SEG_G, // Displays "?" + 0 , // Displays " " (@) + SEG_A+SEG_B+SEG_C+ SEG_E+SEG_F+SEG_G, // Displays "A" + SEG_C+SEG_D+SEG_E+SEG_F+SEG_G, // Displays "b" + SEG_D+SEG_E+ SEG_G, // Displays "c" + SEG_B+SEG_C+SEG_D+SEG_E+ SEG_G, // Displays "d" + SEG_A+ +SEG_D+SEG_E+SEG_F+SEG_G, // Displays "E" + SEG_A+ SEG_E+SEG_F+SEG_G, // Displays "f" + SEG_A+SEG_B+SEG_C+SEG_D+ SEG_F+SEG_G, // Displays "g" same as 9 + SEG_C+ SEG_E+SEG_F+SEG_G, // Displays "h" + SEG_E , // Displays "i" + SEG_A+SEG_B+SEG_C+SEG_D , // Displays "J" + SEG_D+ SEG_F+SEG_G, // Displays "k" + SEG_D+SEG_E+SEG_F , // Displays "L" + SEG_A+SEG_B+SEG_C+ SEG_E+SEG_F , // Displays "M" + SEG_C+ SEG_E+ SEG_G, // Displays "n" + SEG_C+SEG_D+SEG_E+ SEG_G, // Displays "o" + SEG_A+SEG_B+ SEG_E+SEG_F+SEG_G, // Displays "P" + SEG_A+SEG_B+SEG_C+ SEG_F+SEG_G, // Displays "q" + SEG_E+ SEG_G, // Displays "r" + SEG_A+ SEG_C+SEG_D+ SEG_F+SEG_G, // Displays "S" same as 5 + SEG_D+SEG_E+SEG_F+SEG_G, // Displays "t" + SEG_C+SEG_D+SEG_E , // Displays "u" + SEG_C+SEG_D+SEG_E , // Displays "v" same as u + SEG_B+SEG_C+SEG_D+SEG_E+SEG_F+SEG_G, // Displays "W" + SEG_B+SEG_C+ +SEG_E+SEG_F+SEG_G, // Displays "X" as H + SEG_B+SEG_C+SEG_D+ SEG_F+SEG_G, // Displays "Y" + SEG_A+SEG_B+ SEG_D+SEG_E+ SEG_G, // Displays "Z" same as 2 +}; + + +// Table with memory address for each display element +const uint8_t * segments_lcdmem[] = +{ + LCD_SYMB_AM_MEM, + LCD_SYMB_PM_MEM, + LCD_SYMB_ARROW_UP_MEM, + LCD_SYMB_ARROW_DOWN_MEM, + LCD_SYMB_PERCENT_MEM, + LCD_SYMB_TOTAL_MEM, + LCD_SYMB_AVERAGE_MEM, + LCD_SYMB_MAX_MEM, + LCD_SYMB_BATTERY_MEM, + LCD_UNIT_L1_FT_MEM, + LCD_UNIT_L1_K_MEM, + LCD_UNIT_L1_M_MEM, + LCD_UNIT_L1_I_MEM, + LCD_UNIT_L1_PER_S_MEM, + LCD_UNIT_L1_PER_H_MEM, + LCD_UNIT_L1_DEGREE_MEM, + LCD_UNIT_L2_KCAL_MEM, + LCD_UNIT_L2_KM_MEM, + LCD_UNIT_L2_MI_MEM, + LCD_ICON_HEART_MEM, + LCD_ICON_STOPWATCH_MEM, + LCD_ICON_RECORD_MEM, + LCD_ICON_ALARM_MEM, + LCD_ICON_BEEPER1_MEM, + LCD_ICON_BEEPER2_MEM, + LCD_ICON_BEEPER3_MEM, + LCD_SEG_L1_3_MEM, + LCD_SEG_L1_2_MEM, + LCD_SEG_L1_1_MEM, + LCD_SEG_L1_0_MEM, + LCD_SEG_L1_COL_MEM, + LCD_SEG_L1_DP1_MEM, + LCD_SEG_L1_DP0_MEM, + LCD_SEG_L2_5_MEM, + LCD_SEG_L2_4_MEM, + LCD_SEG_L2_3_MEM, + LCD_SEG_L2_2_MEM, + LCD_SEG_L2_1_MEM, + LCD_SEG_L2_0_MEM, + LCD_SEG_L2_COL1_MEM, + LCD_SEG_L2_COL0_MEM, + LCD_SEG_L2_DP_MEM, +}; + + +// Table with bit mask for each display element +const uint8_t segments_bitmask[] = +{ + LCD_SYMB_AM_MASK, + LCD_SYMB_PM_MASK, + LCD_SYMB_ARROW_UP_MASK, + LCD_SYMB_ARROW_DOWN_MASK, + LCD_SYMB_PERCENT_MASK, + LCD_SYMB_TOTAL_MASK, + LCD_SYMB_AVERAGE_MASK, + LCD_SYMB_MAX_MASK, + LCD_SYMB_BATTERY_MASK, + LCD_UNIT_L1_FT_MASK, + LCD_UNIT_L1_K_MASK, + LCD_UNIT_L1_M_MASK, + LCD_UNIT_L1_I_MASK, + LCD_UNIT_L1_PER_S_MASK, + LCD_UNIT_L1_PER_H_MASK, + LCD_UNIT_L1_DEGREE_MASK, + LCD_UNIT_L2_KCAL_MASK, + LCD_UNIT_L2_KM_MASK, + LCD_UNIT_L2_MI_MASK, + LCD_ICON_HEART_MASK, + LCD_ICON_STOPWATCH_MASK, + LCD_ICON_RECORD_MASK, + LCD_ICON_ALARM_MASK, + LCD_ICON_BEEPER1_MASK, + LCD_ICON_BEEPER2_MASK, + LCD_ICON_BEEPER3_MASK, + LCD_SEG_L1_3_MASK, + LCD_SEG_L1_2_MASK, + LCD_SEG_L1_1_MASK, + LCD_SEG_L1_0_MASK, + LCD_SEG_L1_COL_MASK, + LCD_SEG_L1_DP1_MASK, + LCD_SEG_L1_DP0_MASK, + LCD_SEG_L2_5_MASK, + LCD_SEG_L2_4_MASK, + LCD_SEG_L2_3_MASK, + LCD_SEG_L2_2_MASK, + LCD_SEG_L2_1_MASK, + LCD_SEG_L2_0_MASK, + LCD_SEG_L2_COL1_MASK, + LCD_SEG_L2_COL0_MASK, + LCD_SEG_L2_DP_MASK, +}; + + +// Quick integer to array conversion table for most common integer values +const uint8_t itoa_conversion_table[][3] = +{ + "000", "001", "002", "003", "004", "005", "006", "007", "008", "009", "010", "011", "012", "013", "014", "015", + "016", "017", "018", "019", "020", "021", "022", "023", "024", "025", "026", "027", "028", "029", "030", "031", + "032", "033", "034", "035", "036", "037", "038", "039", "040", "041", "042", "043", "044", "045", "046", "047", + "048", "049", "050", "051", "052", "053", "054", "055", "056", "057", "058", "059", "060", "061", "062", "063", + "064", "065", "066", "067", "068", "069", "070", "071", "072", "073", "074", "075", "076", "077", "078", "079", + "080", "081", "082", "083", "084", "085", "086", "087", "088", "089", "090", "091", "092", "093", "094", "095", + "096", "097", "098", "099", "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", "110", "111", + "112", "113", "114", "115", "116", "117", "118", "119", "120", "121", "122", "123", "124", "125", "126", "127", + "128", "129", "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "140", "141", "142", "143", + "144", "145", "146", "147", "148", "149", "150", "151", "152", "153", "154", "155", "156", "157", "158", "159", + "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", "170", "171", "172", "173", "174", "175", + "176", "177", "178", "179", "180", +}; + diff --git a/eZ430-Chronos/include/board.h b/eZ430-Chronos/include/board.h new file mode 100644 index 000000000..af0a99b5d --- /dev/null +++ b/eZ430-Chronos/include/board.h @@ -0,0 +1,10 @@ +#ifndef _MSB_BOARD_H +#define _MSB_BOARD_H + +#include + +#define MSP430_INITIAL_CPU_SPEED 7372800uL +#define MSP430_HAS_DCOR 1 +#define MSP430_HAS_EXTERNAL_CRYSTAL 1 + +#endif // _MSB_BOARD_H diff --git a/msb-430h/Jamfile b/msb-430h/Jamfile new file mode 100644 index 000000000..b1181a57d --- /dev/null +++ b/msb-430h/Jamfile @@ -0,0 +1,35 @@ +# ****************************************************************************** +# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved. +# +# These sources were developed at the Freie Universitaet Berlin, Computer +# Systems and Telematics group (http://cst.mi.fu-berlin.de). +# ------------------------------------------------------------------------------ +# This file is part of FeuerWare. +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# FeuerWare is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see http://www.gnu.org/licenses/ . +# ------------------------------------------------------------------------------ +# For further information and questions please use the web site +# http://scatterweb.mi.fu-berlin.de +# and the mailinglist (subscription via web site) +# scatterweb@lists.spline.inf.fu-berlin.de +# ****************************************************************************** +# $Id$ + +SubDir TOP board msb-430h ; + +Module board : board_init.c debug_uart.c ; +UseModule board ; + +Module board_cc1100 : driver_cc1100.c ; + +SubInclude TOP cpu $(CPU) ; diff --git a/msb-430h/Jamrules.msb-430h b/msb-430h/Jamrules.msb-430h new file mode 100644 index 000000000..41bf0779d --- /dev/null +++ b/msb-430h/Jamrules.msb-430h @@ -0,0 +1,37 @@ +# ****************************************************************************** +# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved. +# +# These sources were developed at the Freie Universitaet Berlin, Computer +# Systems and Telematics group (http://cst.mi.fu-berlin.de). +# ------------------------------------------------------------------------------ +# This file is part of FeuerWare. +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# FeuerWare is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see http://www.gnu.org/licenses/ . +# ------------------------------------------------------------------------------ +# For further information and questions please use the web site +# http://scatterweb.mi.fu-berlin.de +# and the mailinglist (subscription via web site) +# scatterweb@lists.spline.inf.fu-berlin.de +# ****************************************************************************** +# $Id$ + +BOARD = msb-430h ; +CPU = msp430 ; +MCU = msp430x1612 ; + +FLASH_PORT ?= /dev/ttyUSB0 ; +FLASHER ?= mspdebug ; +FLASHFLAGS ?= -d $(FLASH_PORT) -j uif ; + +RESET ?= $(FLASHER) $(FLASHFLAGS) reset ; + diff --git a/msb-430h/board_init.c b/msb-430h/board_init.c new file mode 100644 index 000000000..7dee70e3b --- /dev/null +++ b/msb-430h/board_init.c @@ -0,0 +1,207 @@ +#include "cpu.h" +#include "board.h" +#include "kernel_intern.h" +#include "msp430.h" +#include "debug.h" + +volatile static uint32_t __msp430_cpu_speed = MSP430_INITIAL_CPU_SPEED; + +/*---------------------------------------------------------------------------*/ +static uint8_t calc_umctl(uint16_t br) { + // from TI slaa049 + register uint8_t CMOD = 256 * br - 256 * (br + 1) / 2; + register uint8_t c = 0; + register int i = 0; + register uint8_t a = CMOD; + a <<= 1; + do { + if( a & 0x80 ) { // Overflow to integer? + a = a - 128 + CMOD; // Yes, subtract 1.000000 + c |= 0x80; + } else { + a += CMOD; // No, add fraction + } + if( i == 7 ) + return c; + i++; + c >>= 1; + } while(1); +} + +static void msb_ports_init(void) +{ + // Port 1: Free port, for energy saving all outputs are set to zero. + P1SEL = 0x00; // Port1 Zweitfunktion + P1OUT = 0x00; // Port1 Ausgangsregister: 00000000 = 0x00 + P1DIR = 0xFF; // Port1 Direction: 11111111 = 0xFF + + P2SEL = 0x20; // Port2 Zweitfunktion + P2OUT = 0x00; // Port2 Ausgangsregister: 00000000 = 0x00 + P2DIR = 0x1C; // Port2 Direction: 00011010 = 0x1C + // 0 - P2.0 [IN ] - + // 0 - P2.1 [OUT] - + // 1 - P2.2 [IN ] - + // 1 - P2.3 [OUT] - + // 1 - P2.4 [OUT] - + // 0 - P2.5 [IN ] - + // 0 - P2.6 [IN ] - SD-KARTE Protect + // 0 - P2.7 [IN ] - SD-KARTE Detect + + P3SEL = 0xC0; // Port3 Zweitfunktion + P3OUT = 0x09; // Port3 Ausgangsregister: 00001001 = 0x09 + P3DIR = 0x2B; // Port3 Direction + // 1 - P3.0 + // 1 - P3.1 + // 0 - P3.2 + // 1 - P3.3 + // 0 - P3.4 [IN ] - SHT 11 DATA (OUT/IN) + // 1 - P3.5 [OUT] - SHT 11 CLK + // 0 - P3.6 [2-Funktion] - RS232_RxD + // 0 - P3.7 [2-Funktion] - RS232_TxD + + // Port 4: Free port, for energy saving all outputs are set to zero. + P4SEL = 0x00; // Port4 Zweitfunktion + P4OUT = 0x00; // Port4 Ausgangsregister: 00000000 = 0x00 + P4DIR = 0xFF; // Port4 Direction: 11111111 = 0xFF + // 1 - P4.0 [OUT] - unused + // 1 - P4.1 [OUT] - unused + // 1 - P4.2 [OUT] - unused + // 1 - P4.3 [OUT] - unused + // 1 - P4.4 [OUT] - unused + // 1 - P4.5 [OUT] - unused + // 1 - P4.6 [OUT] - unused + // 1 - P4.7 [OUT] - unused + + P5SEL = 0x00; // Port5 Zweitfunktion: 00000000 = 0x00 + P5OUT = 0x80; // Port5 Ausgangsregister: 00001001 = 0x09 + P5DIR = 0xFF; // Port5 Direction: 11111011 = 0xFB + // 1 - P5.0 [OUT] - SD-KARTE /CS + // 1 - P5.1 [OUT] - SD-KARTE DI + // 0 - P5.2 [IN ] - SD-KARTE DO + // 1 - P5.3 [OUT] - SD-KARTE DCLK + // 1 - P5.4 [OUT] - MMA GS1 + // 1 - P5.5 [OUT] - MMA GS2 + // 1 - P5.6 [OUT] - MMA /SLEEP + // 1 - P5.7 [OUT] - LED_ROT 0-an, 1-aus + + P6SEL = 0x00; // Port6 Zweitfunktion = 0x07 + P6OUT = 0x00; // Port6 Ausgangsregister: 00000000 = 0x00 + P6DIR = 0xFF; // Port6 Direction: 11111000 = 0xF8 + // 0 - P6.0 [AD-IN] - MMA X-Achse + // 0 - P6.1 [AD-IN] - MMA Y-Achse + // 0 - P6.2 [AD-IN] - MMA Z-Achse + // 1 - P6.3 [OUT] - unused + // 1 - P6.4 [OUT] - unused + // 1 - P6.5 [OUT] - unused + // 1 - P6.6 [OUT] - unused + // 1 - P6.7 [OUT] - unused +} + +void msp430_set_cpu_speed(uint32_t speed) +{ + dint(); + __msp430_cpu_speed = speed; + msp430_init_dco(); + uint16_t br; + UCTL1 = SWRST | CHAR; // 8-bit character + UTCTL1 |= SSEL1 | URXSE; // UCLK = MCLK + // activate + U1ME |= UTXE1 | URXE1; // Enable USART1 TXD/RXD + br = (uint16_t)(__msp430_cpu_speed / 115200uL); + UBR01 = br; // set baudrate + UBR11 = br>>8; + UMCTL1 = calc_umctl(br); // set modulation + + UCTL1 &= ~SWRST; + //clock_init(); + eint(); +} + +/*---------------------------------------------------------------------------*/ +void +msp430_init_dco() +{ + #if MSP430_HAS_EXTERNAL_CRYSTAL + /*------------------ use external oszillator -----------------------*/ + uint16_t i; + + // Stop watchdog + WDTCTL = WDTPW + WDTHOLD; + + //Init crystal for mclk + //XT2 = HF XTAL + BCSCTL1 = RSEL2; + + // Wait for xtal to stabilize + do { + IFG1 &= ~OFIFG; // Clear oscillator fault flag + for (i = 0xFF; i > 0; i--); // Time for flag to set + } + while ((IFG1 & OFIFG) != 0); // Oscillator fault flag still set? + BCSCTL2 = SELM_2 + SELS; // MCLK und SMCLK = XT2 (safe) + #else + /* Thdeltais code taken from the FU Berlin sources and reformatted. */ + int delta = __msp430_cpu_speed >> 12; + //#define DELTA 600 + + unsigned int compare, oldcapture = 0; + unsigned int i; + + + BCSCTL1 = 0xa4; /* ACLK is devided by 4. RSEL=6 no division for MCLK + and SSMCLK. XT2 is off. */ + + // Init FLL to desired frequency using the 32762Hz crystal + #if MSP430_HAS_DCOR + BCSCTL2 = 0x01; + #else + BCSCTL2 = 0x00; + #endif + + WDTCTL = WDTPW + WDTHOLD; /* Stop WDT */ + BCSCTL1 |= DIVA1 + DIVA0; /* ACLK = LFXT1CLK/8 */ + for(i = 0xffff; i > 0; i--); /* Delay for XTAL to settle */ + + CCTL2 = CCIS0 + CM0 + CAP; // Define CCR2, CAP, ACLK + TACTL = TASSEL1 + TACLR + MC1; // SMCLK, continous mode + + + while(1) { + + while((CCTL2 & CCIFG) != CCIFG); /* Wait until capture occured! */ + CCTL2 &= ~CCIFG; /* Capture occured, clear flag */ + compare = CCR2; /* Get current captured SMCLK */ + compare = compare - oldcapture; /* SMCLK difference */ + oldcapture = CCR2; /* Save current captured SMCLK */ + + if(delta == compare) { + break; /* if equal, leave "while(1)" */ + } else if(delta < compare) { /* DCO is too fast, slow it down */ + DCOCTL--; + if(DCOCTL == 0xFF) { /* Did DCO role under? */ + BCSCTL1--; + } + } else { /* -> Select next lower RSEL */ + DCOCTL++; + if(DCOCTL == 0x00) { /* Did DCO role over? */ + BCSCTL1++; + } + /* -> Select next higher RSEL */ + } + } + + CCTL2 = 0; /* Stop CCR2 function */ + TACTL = 0; /* Stop Timer_A */ + + BCSCTL1 &= ~(DIVA1 + DIVA0); /* remove /8 divisor from ACLK again */ + #endif +} + +void board_init() { + msp430_cpu_init(); + msb_ports_init(); + + RED_ON; + + msp430_set_cpu_speed(7372800uL); +} diff --git a/msb-430h/debug_uart.c b/msb-430h/debug_uart.c new file mode 100644 index 000000000..7abad1d4e --- /dev/null +++ b/msb-430h/debug_uart.c @@ -0,0 +1,21 @@ +#include "board.h" + +#define UART1_TX TXBUF1 +#define UART1_WAIT_TXDONE() while( (UTCTL1 & TXEPT) == 0 ) { _NOP(); } + +#include + +int putchar(int c) +{ + UART1_TX = c; + UART1_WAIT_TXDONE(); + + if (c == 10) { + UART1_TX = 13; + UART1_WAIT_TXDONE(); + } + + return c; +} + + diff --git a/msb-430h/driver_cc1100.c b/msb-430h/driver_cc1100.c new file mode 100644 index 000000000..9575bee6a --- /dev/null +++ b/msb-430h/driver_cc1100.c @@ -0,0 +1,343 @@ +/* Copyright (C) 2005, 2006, 2007, 2008 by Thomas Hillebrandt and Heiko Will + +This file is part of the Micro-mesh SensorWeb Firmware. + +Micro-Mesh is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +Micro-Mesh is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Micro-Mesh; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include + +#include +#include +#include + +#include +#include + +#define CC1100_GDO0 (P2IN & 0x02) // read serial I/O (GDO0) +#define CC1100_GDO1 (P3IN & 0x04) // read serial I/O (GDO1) +#define CC1100_GDO2 (P2IN & 0x01) // read serial I/O (GDO2) + +#define CC1100_CS_LOW (P3OUT &= ~0x01) +#define CC1100_CS_HIGH (P3OUT |= 0x01) + +#define CC1100_GDO1_LOW_COUNT (2700) // loop count (timeout ~ 500 us) to wait +#define CC1100_GDO1_LOW_RETRY (100) // max. retries for GDO1 to go low + +volatile int abort_count; +volatile int retry_count = 0; + +void cc1100_gdo0_enable(void) +{ + P2IFG &= ~0x02; /* Clear IFG for GDO0 */ + P2IE |= 0x02; /* Enable interrupt for GDO0 */ +} + +void cc1100_gdo0_disable(void) +{ + P2IE &= ~0x02; /* Disable interrupt for GDO0 */ + P2IFG &= ~0x02; /* Clear IFG for GDO0 */ +} + +void cc1100_gdo2_enable(void) +{ + P2IFG &= ~0x01; /* Clear IFG for GDO2 */ + P2IE |= 0x01; /* Enable interrupt for GDO2 */ +} + +void cc1100_gdo2_disable(void) +{ + P2IE &= ~0x01; /* Disable interrupt for GDO2 */ + P2IFG &= ~0x01; /* Clear IFG for GDO2 */ +} + +void cc1100_before_send(void) +{ + // Disable GDO2 interrupt before sending packet + cc1100_gdo2_disable(); +} + +void cc1100_after_send(void) +{ + // Enable GDO2 interrupt after sending packet + cc1100_gdo2_enable(); +} + + +int cc1100_get_gdo0(void) { + return CC1100_GDO0; +} + +int cc1100_get_gdo1(void) { + return CC1100_GDO1; +} + +int cc1100_get_gdo2(void) { + return CC1100_GDO2; +} + +void cc1100_spi_cs(void) +{ + CC1100_CS_LOW; +} + +uint8_t cc1100_txrx(uint8_t data) +{ + /* Ensure TX Buf is empty */ + long c = 0; + IFG1 &= ~UTXIFG0; + IFG1 &= ~URXIFG0; + TXBUF0 = data; + while(!(IFG1 & UTXIFG0)) + { + if (c++ == 1000000) + puts("cc1100_txrx alarm()"); + } + /* Wait for Byte received */ + c = 0; + while(!(IFG1 & URXIFG0)) + { + if (c++ == 1000000) + puts("cc1100_txrx alarm()"); + } + return RXBUF0; +} + + +void cc1100_spi_select(void) +{ + // Switch to GDO mode + P3SEL &= ~0x04; + P3DIR &= ~0x04; + cs_low: + // CS to low + abort_count = 0; + CC1100_CS_LOW; + // Wait for SO to go low (voltage regulator + // has stabilized and the crystal is running) + loop: +// asm volatile ("nop"); + if (CC1100_GDO1) { + abort_count++; + if (abort_count > CC1100_GDO1_LOW_COUNT) { + retry_count++; + if (retry_count > CC1100_GDO1_LOW_RETRY) { + puts("[CC1100 SPI] fatal error\n"); + goto final; + } + CC1100_CS_HIGH; + goto cs_low; // try again + } + goto loop; + } + final: + /* Switch to SPI mode */ + P3SEL |= 0x04; +} + +void cc1100_spi_unselect(void) { + CC1100_CS_HIGH; +} + +void cc1100_init_interrupts(void) +{ + unsigned int state = disableIRQ(); /* Disable all interrupts */ + P2SEL = 0x00; /* must be <> 1 to use interrupts */ + P2IES |= 0x01; /* Enables external interrupt on low edge (for GDO2) */ + P2IE |= 0x01; /* Enable interrupt */ + P2IFG &= ~0x01; /* Clears the interrupt flag */ + P2IE &= ~0x02; /* Disable interrupt for GDO0 */ + P2IFG &= ~0x02; /* Clear IFG for GDO0 */ + restoreIRQ(state); /* Enable all interrupts */ +} + +void cc1100_spi_init(uint8_t clockrate) +{ + // Switch off async UART + while(!(UTCTL0 & TXEPT)); // Wait for empty UxTXBUF register + IE1 &= ~(URXIE0 + UTXIE0); // Disable USART0 receive&transmit interrupt + ME1 &= ~(UTXE0 + URXE0); + P3SEL |= 0x0E; // Set pin as SPI + + // Keep peripheral in reset state + UCTL0 = SWRST; + + // 8-bit SPI Master 3-pin mode, with SMCLK as clock source + // CKPL works also, but not CKPH+CKPL or none of them!! + UCTL0 |= CHAR + SYNC + MM; + UTCTL0 = CKPH + SSEL1 + SSEL0 + STC; + + // Ignore clockrate argument for now, just use clock source/2 + // SMCLK = 7,3728 MHz + UBR00 = 0x02; // Ensure baud rate >= 2 + UBR10 = 0x00; + UMCTL0 = 0x00; // No modulation + URCTL0 = 0x00; // Reset Receive Control Register + + // Enable SPI mode + ME1 |= USPIE0; + + // Release for operation + UCTL0 &= ~SWRST; +} + + +// #include +// #include +// #include "type.h" +// #include "cc1100_defines.h" +// #include "driver_cc1100.h" +// #include "driver_system.h" +// #include "spi0.h" +// +// static callback_t _paket_cb; +// static callback_t _cs_cb; +// +// //------------------------------------------------------------------------------------------------------- +// // Public CC1100 communication functions (SPI) +// //------------------------------------------------------------------------------------------------------- +// +// //------------------------------------------------------------------------------------------------------- +// // void spiInitTrx(void) +// // +// // DESCRIPTION: +// // This function puts the cc1100 into spi mode. You have to call this bevore every spi transaction. +// // +// //------------------------------------------------------------------------------------------------------- +// +// +// void drivercc1100_spiwriteburstreg(uint8_t addr, unsigned char *buffer, uint8_t count) +// { +// uint8_t i; +// long c; +// drivercc1100_spiinittrx(); +// drivercc1100_trxspi(addr | CC1100_WRITE_BURST); +// for (i = 0; i < count; i++) +// { +// c = 0; +// IFG1 &= ~UTXIFG0; +// IFG1 &= ~URXIFG0; +// TXBUF0 = buffer[i]; +// /* Wait for TX to finish */ +// while(!(IFG1 & UTXIFG0)) +// { +// if (c++ == 1000000) +// alarm(); +// } +// } +// /* Wait for Byte received */ +// c = 0; +// while(!(IFG1 & URXIFG0)) +// { +// if (c++ == 1000000) +// alarm(); +// } +// CC1100_CS_HIGH; +// } +// +// void drivercc1100_spireadburstreg(uint8_t addr, char *buffer, uint8_t count) +// { +// uint8_t i; +// drivercc1100_spiinittrx(); +// drivercc1100_trxspi(addr | CC1100_READ_BURST); +// for (i = 0; i < count; i++) +// { +// long c = 0; +// IFG1 &= ~UTXIFG0; +// IFG1 &= ~URXIFG0; +// TXBUF0 = NOBYTE; +// while(!(IFG1 & UTXIFG0)) +// { +// if (c++ == 1000000) +// alarm(); +// } +// /* Wait for Byte received */ +// c = 0; +// while(!(IFG1 & URXIFG0)) +// { +// if (c++ == 1000000) +// alarm(); +// } +// buffer[i] = RXBUF0; +// } +// CC1100_CS_HIGH; +// } +// +// void drivercc1100_load(callback_t cs_cb,callback_t paket_cb) +// { +// _paket_cb = paket_cb; +// _cs_cb = cs_cb; +// spi0_init(0); +// } +// +// void drivercc1100_aftersend(void) +// { +// CLEAR(P2IFG, 0x01); +// SET(P2IE, 0x01); /* Enable interrupts on port 2 pin 0 */ +// CLEAR(P4OUT, 0x08); /* Turn off Sending Led*/ +// } +// +// void drivercc1100_initinterrupts(void) +// { +// _DINT(); /* Disable all interrupts */ +// P2SEL = 0x00; /* must be <> 1 to use interrupts */ +// SET(P2IES, 0x01); /* Enables external interrupt on low edge (for GDO2) */ +// SET(P2IE, 0x01); /* Enable interrupt */ +// CLEAR(P2IFG, 0x01); /* Clears the interrupt flag */ +// CLEAR(P2IE, 0x02); /* Disable interrupt for GDO0 */ +// CLEAR(P2IFG, 0x02); /* Clear IFG for GDO0 */ +// _EINT(); /* Enable all interrupts */ +// } +// +// void drivercc1100_beforesend(void) +// { +// /* Turn on Led while sending paket for debug reasons */ +// SET(P4OUT, 0x08); +// /* Disable interrupts on port 2 pin 0 */ +// CLEAR(P2IE, 0x01); +// } +// +// +// /* +// * Private functions +// */ +// +// + +/* + * CC1100 receive interrupt + */ +interrupt (PORT2_VECTOR) __attribute__ ((naked)) cc1100_isr(void){ + __enter_isr(); +puts("cc1100_isr()"); +// if (system_state.POWERDOWN) SPI_INIT; /* Initialize SPI after wakeup */ + /* Check IFG */ + if ((P2IFG & 0x01) != 0) { + P2IFG &= ~0x01; + cc1100_gdo2_irq(); + } + else if ((P2IFG & 0x02) != 0) { + cc1100_gdo0_irq(); + P2IE &= ~0x02; // Disable interrupt for GDO0 + P2IFG &= ~0x02; // Clear IFG for GDO0 + } else { + puts("cc1100_isr(): unexpected IFG!"); + /* Should not occur - only Port 2 Pin 0 interrupts are enabled */ +// CLEAR(P2IFG, 0xFF); /* Clear all flags */ + } +// if (system_state.POWERDOWN != 0) END_LPM3; + __exit_isr(); +} + diff --git a/msb-430h/include/board.h b/msb-430h/include/board.h new file mode 100644 index 000000000..ef2bbb658 --- /dev/null +++ b/msb-430h/include/board.h @@ -0,0 +1,69 @@ +/****************************************************************************** +Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved. + +These sources were developed at the Freie Universitaet Berlin, Computer Systems +and Telematics group (http://cst.mi.fu-berlin.de). +------------------------------------------------------------------------------- +This file is part of FeuerWare. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +FeuerWare is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see http://www.gnu.org/licenses/ . +-------------------------------------------------------------------------------- +For further information and questions please use the web site + http://scatterweb.mi.fu-berlin.de +and the mailinglist (subscription via web site) + scatterweb@lists.spline.inf.fu-berlin.de +*******************************************************************************/ + +#ifndef _MSB_BOARD_H +#define _MSB_BOARD_H + +/** + * @defgroup msb_430h ScatterWeb MSB-430H + * @ingroup msp430 + * +

Compontents

+\li MSP430 +\li CC1100 + +* @{ +*/ + +/** + * @file + * @brief MSB-430H Board + * + * @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project + * @version $Revision$ + * + * @note $Id$ + */ + +//MSB430 core +#define MSP430_INITIAL_CPU_SPEED 7372800uL +#define MSP430_HAS_DCOR 1 +#define MSP430_HAS_EXTERNAL_CRYSTAL 1 + +/* LEDs ports MSB430 */ +#define LEDS_PxDIR P5DIR +#define LEDS_PxOUT P5OUT +#define LEDS_CONF_RED 0x80 +#define LEDS_CONF_GREEN 0x00 +#define LEDS_CONF_YELLOW 0x00 + +#define RED_ON LEDS_PxOUT &=~LEDS_CONF_RED +#define RED_OFF LEDS_PxOUT |= LEDS_CONF_RED + +#include + +/** @} */ +#endif // _MSB_BOARD_H diff --git a/msba2/Jamfile b/msba2/Jamfile new file mode 100644 index 000000000..88106e45c --- /dev/null +++ b/msba2/Jamfile @@ -0,0 +1,35 @@ +# ****************************************************************************** +# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved. +# +# These sources were developed at the Freie Universitaet Berlin, Computer +# Systems and Telematics group (http://cst.mi.fu-berlin.de). +# ------------------------------------------------------------------------------ +# This file is part of FeuerWare. +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# FeuerWare is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see http://www.gnu.org/licenses/ . +# ------------------------------------------------------------------------------ +# For further information and questions please use the web site +# http://scatterweb.mi.fu-berlin.de +# and the mailinglist (subscription via web site) +# scatterweb@lists.spline.inf.fu-berlin.de +# ****************************************************************************** +# $Id$ + +SubDir TOP board msba2 ; + +Module board : board_init.c ; +UseModule board ; +UseModule board_common ; + +SubInclude TOP board $(BOARD) drivers ; +SubInclude TOP cpu $(CPU) ; diff --git a/msba2/Jamfile.msba2 b/msba2/Jamfile.msba2 new file mode 100644 index 000000000..44014a6c9 --- /dev/null +++ b/msba2/Jamfile.msba2 @@ -0,0 +1,31 @@ +# ****************************************************************************** +# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved. +# +# These sources were developed at the Freie Universitaet Berlin, Computer +# Systems and Telematics group (http://cst.mi.fu-berlin.de). +# ------------------------------------------------------------------------------ +# This file is part of FeuerWare. +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# FeuerWare is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see http://www.gnu.org/licenses/ . +# ------------------------------------------------------------------------------ +# For further information and questions please use the web site +# http://scatterweb.mi.fu-berlin.de +# and the mailinglist (subscription via web site) +# scatterweb@lists.spline.inf.fu-berlin.de +# ****************************************************************************** +# $Id$ + +#LinkLibraries $(BOARD).elf : sys-drivers.a net_mm.a sys-lib.a fat-lib.a +# cpu_drivers.a board_drivers.a cc110x.a hal.a hal_drivers.a lpc2387_hal.a ; + +include [ FPath $(TOP) cpu arm_common Jamfile.arm_common ] ; diff --git a/msba2/Jamrules.msba2 b/msba2/Jamrules.msba2 new file mode 100644 index 000000000..fdcf4b6f6 --- /dev/null +++ b/msba2/Jamrules.msba2 @@ -0,0 +1,33 @@ +# ****************************************************************************** +# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved. +# +# These sources were developed at the Freie Universitaet Berlin, Computer +# Systems and Telematics group (http://cst.mi.fu-berlin.de). +# ------------------------------------------------------------------------------ +# This file is part of FeuerWare. +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# FeuerWare is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see http://www.gnu.org/licenses/ . +# ------------------------------------------------------------------------------ +# For further information and questions please use the web site +# http://scatterweb.mi.fu-berlin.de +# and the mailinglist (subscription via web site) +# scatterweb@lists.spline.inf.fu-berlin.de +# ****************************************************************************** +# $Id$ + +CPU = lpc2387 ; + +HDRS += [ FPath $(TOP) board $(BOARD) drivers include ] ; + +FLASHER = $(POSIXSHELL) $(TOP)/board/msba2/tools/flashutil.sh ; +FLASHFLAGS = --basedir $(TOP)/board/msba2/tools --id "MSB-A2" --ports "$(PORT)" ; diff --git a/msba2/board_init.c b/msba2/board_init.c new file mode 100644 index 000000000..d12cc4058 --- /dev/null +++ b/msba2/board_init.c @@ -0,0 +1,156 @@ +/****************************************************************************** +Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved. + +These sources were developed at the Freie Universitaet Berlin, Computer Systems +and Telematics group (http://cst.mi.fu-berlin.de). +------------------------------------------------------------------------------- +This file is part of FeuerWare. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +FeuerWare is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see http://www.gnu.org/licenses/ . +-------------------------------------------------------------------------------- +For further information and questions please use the web site + http://scatterweb.mi.fu-berlin.de +and the mailinglist (subscription via web site) + scatterweb@lists.spline.inf.fu-berlin.de +*******************************************************************************/ + +/** + * @ingroup pttu + * @{ + */ + +/** + * @file + * @brief MSB-A2 board initialization + * + * @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project + * @author Heiko Will + * @author Kaspar Schleiser + * @author Michael Baar + * + * @note $Id$ + */ +#include +#include +#include "VIC.h" +#include "cpu.h" + +#define PCRTC BIT9 +#define CL_CPU_DIV 4 + +/*---------------------------------------------------------------------------*/ +/** + * @brief Enabling MAM and setting number of clocks used for Flash memory fetch + * @internal + */ +static void +init_mam(void) +{ + MAMCR = 0x0000; + MAMTIM = 0x0003; + MAMCR = 0x0002; +} +/*---------------------------------------------------------------------------*/ +static inline void +pllfeed(void) +{ + PLLFEED = 0xAA; + PLLFEED = 0x55; +} +/*---------------------------------------------------------------------------*/ +void init_clks1(void) +{ + // Disconnect PLL + PLLCON &= ~0x0002; + pllfeed(); + + // Disable PLL + PLLCON &= ~0x0001; + pllfeed(); + + SCS |= 0x20; // Enable main OSC + while( !(SCS & 0x40) ); // Wait until main OSC is usable + + /* select main OSC, 16MHz, as the PLL clock source */ + CLKSRCSEL = 0x0001; + + // Setting Multiplier and Divider values + PLLCFG = 0x0008; // M=9 N=1 Fcco = 288 MHz + pllfeed(); + + // Enabling the PLL */ + PLLCON = 0x0001; + pllfeed(); + + /* Set clock divider to 4 (value+1) */ + CCLKCFG = CL_CPU_DIV - 1; // Fcpu = 72 MHz + +#if USE_USB + USBCLKCFG = USBCLKDivValue; /* usbclk = 288 MHz/6 = 48 MHz */ +#endif +} + +void init_clks2(void){ + // Wait for the PLL to lock to set frequency + while(!(PLLSTAT & BIT26)); + + // Connect the PLL as the clock source + PLLCON = 0x0003; + pllfeed(); + + /* Check connect bit status */ + while (!(PLLSTAT & BIT25)); +} + +void bl_init_clks(void) +{ + PCONP = PCRTC; // switch off everything except RTC + init_clks1(); + init_clks2(); + init_mam(); +} + +void bl_init_ports(void) +{ + SCS |= BIT0; // Set IO Ports to fast switching mode + + /* UART0 */ + PINSEL0 |= BIT4 + BIT6; // RxD0 and TxD0 + PINSEL0 &= ~(BIT5 + BIT7); + + /* LEDS */ + FIO3DIR |= LED_RED_PIN; + FIO3DIR |= LED_GREEN_PIN; + LED_RED_OFF; + LED_GREEN_OFF; +} + +void loop_delay(void) { + volatile uint16_t i, j; + for (i = 1; i < 30; i++) { + for (j = 1; j != 0; j++) { + asm volatile (" nop "); + } + } +} + +void bl_blink(void) { + LED_RED_ON; + LED_GREEN_ON; + + loop_delay(); + + LED_RED_OFF; + LED_GREEN_OFF; +} + diff --git a/msba2/drivers/Jamfile b/msba2/drivers/Jamfile new file mode 100644 index 000000000..79705aca0 --- /dev/null +++ b/msba2/drivers/Jamfile @@ -0,0 +1,6 @@ +SubDir TOP board msba2 drivers ; + +Module board_cc1100 : msba2-cc1100.c ; +Module board_hal : msba2-hal.c ; +Module board_ltc4150 : msba2-ltc4150.c : gpioint ; +Module board_common : msba2-uart0.c ; diff --git a/msba2/drivers/include/hal-board.h b/msba2/drivers/include/hal-board.h new file mode 100644 index 000000000..a4dfc293a --- /dev/null +++ b/msba2/drivers/include/hal-board.h @@ -0,0 +1,68 @@ +/****************************************************************************** +Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved. + +These sources were developed at the Freie Universitaet Berlin, Computer Systems +and Telematics group (http://cst.mi.fu-berlin.de). +------------------------------------------------------------------------------- +This file is part of FeuerWare. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +FeuerWare is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see http://www.gnu.org/licenses/ . +-------------------------------------------------------------------------------- +For further information and questions please use the web site + http://scatterweb.mi.fu-berlin.de +and the mailinglist (subscription via web site) + scatterweb@lists.spline.inf.fu-berlin.de +*******************************************************************************/ + +#ifndef HALPLATFORM_H_ +#define HALPLATFORM_H_ + +/** + * @ingroup msba2 + * @{ + */ + +/** + * @file + * @brief + * + * @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project + * @author baar + * @version $Revision$ + * + * @note $Id$ + */ + +#include "vdevice.h" +#include "device-gpio.h" +#include "device-rs232.h" +#include "device-serial.h" + +VDEVICE_NAME(vdevice_gpio, gpio_led_green); +VDEVICE_NAME(vdevice_gpio, gpio_led_red); +VDEVICE_NAME(vdevice_gpio, gpio_led_usb); + +/** + * @var tty0 + * @brief RS232 TTY0 device on UART0 + */ +VDEVICE_NAME(vdevice_rs232, tty0); + +/** + * @var console0 + * @brief console device on tty0 + */ +VDEVICE_NAME(vdevice_serial, console0); + +/** @} */ +#endif /* HALPLATFORM_H_ */ diff --git a/msba2/drivers/include/sht11-board.h b/msba2/drivers/include/sht11-board.h new file mode 100644 index 000000000..fc0313906 --- /dev/null +++ b/msba2/drivers/include/sht11-board.h @@ -0,0 +1,63 @@ +/****************************************************************************** +Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved. + +These sources were developed at the Freie Universitaet Berlin, Computer Systems +and Telematics group (http://cst.mi.fu-berlin.de). +------------------------------------------------------------------------------- +This file is part of FeuerWare. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +FeuerWare is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see http://www.gnu.org/licenses/ . +-------------------------------------------------------------------------------- +For further information and questions please use the web site + http://scatterweb.mi.fu-berlin.de +and the mailinglist (subscription via web site) + scatterweb@lists.spline.inf.fu-berlin.de +*******************************************************************************/ + +#ifndef SHT11BOARD_H_ +#define SHT11BOARD_H_ + +/** + * @ingroup lpc2387 + * @{ + */ + +/** + * @file + * @brief LPC2387 SHT11 Device Driver + * + * @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project + * @version $Revision$ + * + * @note $Id$ + */ + +#include +#include + +#define SHT11_SCK_LOW FIO1CLR = BIT25; // serial clock line low +#define SHT11_SCK_HIGH FIO1SET = BIT25; // serial clock line high +#define SHT11_DATA ((FIO1PIN & BIT26) != 0) // read serial I/O +#define SHT11_DATA_LOW (FIO1CLR = BIT26); // serial I/O line low +#define SHT11_DATA_HIGH (FIO1SET = BIT26); // serial I/O line high +#define SHT11_DATA_IN (FIO1DIR &= ~BIT26) // serial I/O as input +#define SHT11_DATA_OUT (FIO1DIR |= BIT26) // serial I/O as output +#define SHT11_INIT FIO1DIR |= BIT25; PINSEL3 &= ~(BIT14|BIT15 | BIT16|BIT17); + +/* time to wait after toggling the data line */ +#define SHT11_DATA_WAIT (50) +/* time to wait after toggling the clock line */ +#define SHT11_CLK_WAIT (10) + +/** @} */ +#endif /* SHT11BOARD_H_ */ diff --git a/msba2/drivers/msba2-cc1100.c b/msba2/drivers/msba2-cc1100.c new file mode 100644 index 000000000..726d58550 --- /dev/null +++ b/msba2/drivers/msba2-cc1100.c @@ -0,0 +1,243 @@ +/****************************************************************************** +Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved. + +These sources were developed at the Freie Universitaet Berlin, Computer Systems +and Telematics group (http://cst.mi.fu-berlin.de). +------------------------------------------------------------------------------- +This file is part of FeuerWare. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +FeuerWare is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see http://www.gnu.org/licenses/ . +-------------------------------------------------------------------------------- +For further information and questions please use the web site + http://scatterweb.mi.fu-berlin.de +and the mailinglist (subscription via web site) + scatterweb@lists.spline.inf.fu-berlin.de +*******************************************************************************/ + +/** + * @file + * @ingroup LPC2387 + * @brief CC1100 LPC2387 dependend functions + * + * @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project + * @author Heiko Will + * @author Thomas Hillebrandt + * @version $Revision: 1781 $ + * + * @note $Id: msba2-cc1100.c 1781 2010-01-26 13:39:36Z hillebra $ + */ + +#include +#include +// core +#include +#include +// sys +#include "cc1100.h" +#include "arch_cc1100.h" +#include "cc1100_spi.h" +#include "gpioint.h" + +#define CC1100_GDO0 (FIO0PIN & BIT27) // read serial I/O (GDO0) +#define CC1100_GDO1 (FIO1PIN & BIT23) // read serial I/O (GDO1) +#define CC1100_GDO2 (FIO0PIN & BIT28) // read serial I/O (GDO2) + +#define SPI_TX_EMPTY (SSP0SR & SSPSR_TFE) +#define SPI_BUSY (SSP0SR & SSPSR_BSY) +#define SPI_RX_AVAIL (SSP0SR & SSPSR_RNE) + +#define CC1100_GDO1_LOW_RETRY (100) // max. retries for GDO1 to go low +#define CC1100_GDO1_LOW_COUNT (2700) // loop count (timeout ~ 500 us) to wait + // for GDO1 to go low when CS low + +//#define DEBUG +#ifdef DEBUG + +#include "stdio.h" + +static unsigned long time_value; + +static void set_time(void) { + time_value = 0; +} + +static int test_time(int code) { + time_value++; + if (time_value > 10000000) { + printf("CC1100 SPI alarm: %u!\n", code); + time_value = 0; + return 1; + } + return 0; +} +#endif + +int cc1100_get_gdo0(void) { + return CC1100_GDO0; +} + +int cc1100_get_gdo1(void) { + return CC1100_GDO1; +} + +int cc1100_get_gdo2(void) { + return CC1100_GDO2; +} + +void cc1100_spi_init(void) +{ + // configure chip-select + FIO1DIR |= BIT21; + FIO1SET = BIT21; + + // Power + PCONP |= PCSSP0; // Enable power for SSP0 (default is on) + + // PIN Setup + PINSEL3 |= BIT8 + BIT9; // Set CLK function to SPI + PINSEL3 |= BIT14 + BIT15; // Set MISO function to SPI + PINSEL3 |= BIT16 + BIT17; // Set MOSI function to SPI + + // Interface Setup + SSP0CR0 = 7; + + // Clock Setup + uint32_t pclksel; + uint32_t cpsr; + lpc2387_pclk_scale(F_CPU/1000, 6000, &pclksel, &cpsr); + PCLKSEL1 &= ~(BIT10|BIT11); // CCLK to PCLK divider + PCLKSEL1 |= pclksel << 10; + SSP0CPSR = cpsr; + + // Enable + SSP0CR1 |= BIT1; // SSP-Enable + int dummy; + // Clear RxFIFO: + while( SPI_RX_AVAIL ) { // while RNE (Receive FIFO Not Empty)... + dummy = SSP0DR; // read data + } +} + +uint8_t +cc1100_txrx(uint8_t c) { + uint8_t result; + SSP0DR = c; +#ifdef DEBUG + set_time(); +#endif + while (!SPI_TX_EMPTY) { +#ifdef DEBUG + test_time(0); +#endif + } +#ifdef DEBUG + set_time(); +#endif + while (SPI_BUSY) { +#ifdef DEBUG + test_time(1); +#endif + } +#ifdef DEBUG + set_time(); +#endif + while (!SPI_RX_AVAIL) { +#ifdef DEBUG + test_time(2); +#endif + } + result = (uint8_t)SSP0DR; + return result; +} + +void cc1100_spi_cs(void) +{ + FIO1CLR = BIT21; +} + +void +cc1100_spi_select(void) +{ + volatile int retry_count = 0; + volatile int abort_count; + // Switch to GDO mode input + PINSEL3 &= ~(BIT14 + BIT15);// Set MISO function to GPIO + FIO1DIR &= ~BIT23; + cs_low: + // CS to low + abort_count = 0; + FIO1CLR = BIT21; + // Wait for SO to go low (voltage regulator + // has stabilized and the crystal is running) + loop: + asm volatile ("nop"); + if (CC1100_GDO1) { + abort_count++; + if (abort_count > CC1100_GDO1_LOW_COUNT) { + retry_count++; + if (retry_count > CC1100_GDO1_LOW_RETRY) { + puts("[CC1100 SPI] fatal error\n"); + goto final; + } + FIO1SET = BIT21; // CS to high + goto cs_low; // try again + } + goto loop; + } + final: + // Switch to SPI mode + PINSEL3 |= (BIT14 + BIT15); // Set MISO function to SPI +} + +void +cc1100_spi_unselect(void) +{ + FIO1SET = BIT21; +} + +void cc1100_before_send(void) +{ + // Disable GDO2 interrupt before sending packet + cc1100_gdo2_disable(); +} + +void cc1100_after_send(void) +{ + // Enable GDO2 interrupt after sending packet + cc1100_gdo2_enable(); +} + +void cc1100_gdo0_enable(void) { + gpioint_set(0, BIT27, GPIOINT_RISING_EDGE, &cc1100_gdo0_irq); +} + +void cc1100_gdo0_disable(void) { + gpioint_set(0, BIT27, GPIOINT_DISABLE, NULL); +} + +void cc1100_gdo2_disable(void) { + gpioint_set(0, BIT28, GPIOINT_DISABLE, NULL); +} + +void cc1100_gdo2_enable(void) { + gpioint_set(0, BIT28, GPIOINT_FALLING_EDGE, &cc1100_gdo2_irq); +} + +void cc1100_init_interrupts(void) +{ + // Enable external interrupt on low edge (for GDO2) + FIO0DIR &= ~BIT28; + cc1100_gdo2_enable(); + // Enable external interrupt on low edge (for GDO0) + FIO0DIR &= ~BIT27; +} diff --git a/msba2/drivers/msba2-ltc4150.c b/msba2/drivers/msba2-ltc4150.c new file mode 100644 index 000000000..c590dee8d --- /dev/null +++ b/msba2/drivers/msba2-ltc4150.c @@ -0,0 +1,65 @@ +/****************************************************************************** +Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved. + +These sources were developed at the Freie Universitaet Berlin, Computer Systems +and Telematics group (http://cst.mi.fu-berlin.de). +------------------------------------------------------------------------------- +This file is part of FeuerWare. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +FeuerWare is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see http://www.gnu.org/licenses/ . +-------------------------------------------------------------------------------- +For further information and questions please use the web site + http://scatterweb.mi.fu-berlin.de +and the mailinglist (subscription via web site) + scatterweb@lists.spline.inf.fu-berlin.de +*******************************************************************************/ + +/** + * @ingroup msba2 + * @ingroup ltc4150 + * @{ + */ + +/** + * @file + * @brief LTC4150 MSB-A2 specific implemetation + * + * @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project + * @author Heiko Will + * @author Michael Baar + * @author Kaspar Schleiser + */ + +#include +#include "lpc2387.h" +#include "ltc4150_arch.h" +#include "gpioint.h" + +void ltc4150_disable_int(void) { + gpioint_set(0, BIT4, GPIOINT_DISABLE, NULL); +} + +void ltc4150_enable_int(void) { + gpioint_set(0, BIT4, GPIOINT_FALLING_EDGE, <c4150_interrupt); +} + +void ltc4150_sync_blocking(void) { + while(!(FIO0PIN & BIT4)) {}; +} + +void ltc4150_arch_init() { + FIO0DIR |= BIT5; + FIO0SET = BIT5; +} + +/** @} */ diff --git a/msba2/drivers/msba2-uart0.c b/msba2/drivers/msba2-uart0.c new file mode 100644 index 000000000..01aaf609d --- /dev/null +++ b/msba2/drivers/msba2-uart0.c @@ -0,0 +1,205 @@ +/****************************************************************************** +Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved. + +These sources were developed at the Freie Universitaet Berlin, Computer Systems +and Telematics group (http://cst.mi.fu-berlin.de). +------------------------------------------------------------------------------- +This file is part of FeuerWare. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +FeuerWare is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see http://www.gnu.org/licenses/ . +-------------------------------------------------------------------------------- +For further information and questions please use the web site + http://scatterweb.mi.fu-berlin.de +and the mailinglist (subscription via web site) + scatterweb@lists.spline.inf.fu-berlin.de +*******************************************************************************/ + +/* + * debug_uart.c: provides initial serial debug output + * + * Copyright (C) 2008, 2009 Kaspar Schleiser + * Heiko Will + */ +#include +#include +#include +#include "lpc23xx.h" +#include "VIC.h" + +/** + * @file + * @ingroup lpc2387 + * + * @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project + * @version $Revision$ + * + * @note $Id$ + */ + +typedef struct toprint { + unsigned int len; + char content[]; +}toprint; + +#define QUEUESIZE 255 +static volatile toprint* queue[QUEUESIZE]; +static volatile unsigned char queue_head = 0; +static volatile unsigned char queue_tail = 0; +static volatile unsigned char queue_items = 0; + +static volatile unsigned int actual_pos = 0; +static volatile unsigned int running = 0; +static volatile unsigned int fifo = 0; + +static volatile toprint* actual = NULL; +void (*uart0_callback)(int); + +static inline void enqueue(void) { + queue_items++; + queue_tail++; +} + +static inline void dequeue(void) { + actual = (queue[queue_head]); + queue_items--; + queue_head++; +} + +static void push_queue(void) { + running = 1; +start: + if (!actual) { + if (queue_items) { + dequeue(); + } else { + running = 0; + if (!fifo) + while(!(U0LSR & BIT6)){}; + return; + } + } + while ((actual_pos < actual->len) && (fifo++ < 16)){ + U0THR = actual->content[actual_pos++]; + } + if (actual_pos == actual->len) { + free((void*)actual); + actual = NULL; + actual_pos = 0; + goto start; + } +} + +int uart_active(void){ + return (running || fifo); +} + +static inline void receive(int c) +{ + if (uart0_callback != NULL) uart0_callback(c); +} + +void stdio_flush(void) +{ + U0IER &= ~BIT1; // disable THRE interrupt + while(running) { + while(!(U0LSR & (BIT5|BIT6))){}; // transmit fifo + fifo=0; + push_queue(); // dequeue to fifo + } + U0IER |= BIT1; // enable THRE interrupt +} + +void UART0_IRQHandler(void) __attribute__((interrupt("IRQ"))); +void UART0_IRQHandler(void) +{ + int iir; + iir = U0IIR; + + switch(iir & UIIR_ID_MASK) { + case UIIR_THRE_INT: // Transmit Holding Register Empty + fifo=0; + push_queue(); + break; + + case UIIR_CTI_INT: // Character Timeout Indicator + case UIIR_RDA_INT: // Receive Data Available + do { + int c = U0RBR; + receive(c); + } while (U0LSR & ULSR_RDR); + break; + + default: + U0LSR; + U0RBR; + break; + } // switch + VICVectAddr = 0; // Acknowledge Interrupt +} + +static inline int uart0_puts(char *astring,int length) +{ + while (queue_items == (QUEUESIZE-1)) {} ; + U0IER = 0; + queue[queue_tail] = malloc(length+sizeof(unsigned int)); + queue[queue_tail]->len = length; + memcpy(&queue[queue_tail]->content,astring,length); + enqueue(); + if (!running) + push_queue(); + U0IER |= BIT0 | BIT1; // enable RX irq + + /* alternative without queue: + int i; + for (i=0;iconfig->speed + /* + * Baudrate calculation + * BR = PCLK (9 MHz) / (16 x 256 x DLM + DLL) x (1/(DIVADDVAL/MULVAL)) + */ + U0FDR = 0x92; // DIVADDVAL = 0010 = 2, MULVAL = 1001 = 9 + U0DLM = 0x00; + U0DLL = 0x04; + + U0LCR = 0x03; // DLAB = 0 + U0FCR = 0x07; // Enable and reset TX and RX FIFO + + /* irq */ + install_irq(UART0_INT, UART0_IRQHandler, 6); + U0IER |= BIT0 | BIT1; // enable RX+TX irq + return 1; +} + diff --git a/msba2/include/board-conf.h b/msba2/include/board-conf.h new file mode 100644 index 000000000..2c8824f1f --- /dev/null +++ b/msba2/include/board-conf.h @@ -0,0 +1,68 @@ +/****************************************************************************** +Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved. + +These sources were developed at the Freie Universitaet Berlin, Computer Systems +and Telematics group (http://cst.mi.fu-berlin.de). +------------------------------------------------------------------------------- +This file is part of FeuerWare. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +FeuerWare is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see http://www.gnu.org/licenses/ . +-------------------------------------------------------------------------------- +For further information and questions please use the web site + http://scatterweb.mi.fu-berlin.de +and the mailinglist (subscription via web site) + scatterweb@lists.spline.inf.fu-berlin.de +*******************************************************************************/ + +#ifndef BOARDCONF_H_ +#define BOARDCONF_H_ + +/** + * @ingroup conf + * @ingroup msba2 + * + * @{ + */ + +/** + * @file + * @brief MSB-A2 board configuration + * + * @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project + * @author baar + * @version $Revision$ + * + * @note $Id$ + */ + +#define FEUERWARE_CONF_BOARD_NAME "FU Berlin MSB-A2" + +#ifdef MODULE_CC110X +#define FEUERWARE_CONF_NUM_RADIOS 1 +#else +#define FEUERWARE_CONF_NUM_RADIOS 0 +#endif + +// if FAT is enabled this board supports files +#define FEUERWARE_CONF_CORE_SUPPORTS_FILES defined(MODULE_FAT) + +#ifdef MODULE_FAT +#define CFG_CONF_MEM_SIZE 0x7FFFFFFF +#define SYSLOG_CONF_NUM_INTERFACES 2 +#else +#define SYSLOG_CONF_NUM_INTERFACES 1 +#endif + + +/** @} */ +#endif /* BOARDCONF_H_ */ diff --git a/msba2/include/board.h b/msba2/include/board.h new file mode 100644 index 000000000..4356e4423 --- /dev/null +++ b/msba2/include/board.h @@ -0,0 +1,62 @@ +/****************************************************************************** +Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved. + +These sources were developed at the Freie Universitaet Berlin, Computer Systems +and Telematics group (http://cst.mi.fu-berlin.de). +------------------------------------------------------------------------------- +This file is part of FeuerWare. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +FeuerWare is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see http://www.gnu.org/licenses/ . +-------------------------------------------------------------------------------- +For further information and questions please use the web site + http://scatterweb.mi.fu-berlin.de +and the mailinglist (subscription via web site) + scatterweb@lists.spline.inf.fu-berlin.de +*******************************************************************************/ + +#ifndef __BOARD_H +#define __BOARD_H + +/** + * @ingroup msb_a2 + * @{ + */ + +/** + * @file + * @brief MSB-A2 Board + * + * @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project + * @author Kaspar Schleiser + * @version $Revision$ + * + * @note $Id$ + */ + +#include + +#define VICIntEnClear VICIntEnClr + +#define LED_RED_PIN (BIT25) +#define LED_GREEN_PIN (BIT26) + +#define LED_GREEN_OFF (FIO3SET = LED_GREEN_PIN) +#define LED_GREEN_ON (FIO3CLR = LED_GREEN_PIN) +#define LED_GREEN_TOGGLE (FIO3PIN ^= LED_GREEN_PIN) + +#define LED_RED_OFF (FIO3SET = LED_RED_PIN) +#define LED_RED_ON (FIO3CLR = LED_RED_PIN) +#define LED_RED_TOGGLE (FIO3PIN ^= LED_RED_PIN) + +/** @} */ +#endif // __BOARD_H diff --git a/msba2/lpc2387-timer3.c b/msba2/lpc2387-timer3.c new file mode 100644 index 000000000..8978390e9 --- /dev/null +++ b/msba2/lpc2387-timer3.c @@ -0,0 +1,37 @@ +/* + * lpc2387_timer0.c + * + * Created on: 13.01.2009 + * Author: heiko + */ + +#include +#include +#include "lpc2387.h" +#include "benchmark.h" + +void benchmark_init(void) +{ + PCLKSEL1 = (PCLKSEL1 & ~(BIT14|BIT15)) | (1 << 14); // CCLK to PCLK divider + PCONP |= PCTIM3; + T3TCR = 0; // disable timer + T3MCR = 0; // disable interrupt + T3CCR = 0; // capture is disabled. + T3EMR = 0; // no external match output. + T3PR = 0; // set prescaler + T3TC = 0; // reset counter +} + +void benchmark_reset_start(void) +{ + T3TCR = 0; // disable timer + T3TC = 0; // reset counter + T3TCR = BIT0; +} + +unsigned int benchmark_read_stop(void) +{ + T3TCR = 0; // disable timer + return T3TC; +} + diff --git a/msba2/tools/CHANGES b/msba2/tools/CHANGES new file mode 100644 index 000000000..dd9e6ec1e --- /dev/null +++ b/msba2/tools/CHANGES @@ -0,0 +1,23 @@ +(heavily hacked by Heiko Will & Kaspar Schleiser since then) + +1.05 (9-Apr-2007) +----------------- +Added boot jump code specific to 2378 (and similar chips) to +disable the PLL before jumping to the user's code. + +1.04 (19-Dec-2006) +------------------ +Added 2364, 2366, 2368, 2378 & 2468 to list. Untested. + +1.03 (2-Jun-2006) +----------------- +Added 2103 chip to chip list. ID numbers for 2101 and 2102 unknown + +1.02 (31-Jul-2005) +------------------ +Added support for other chips +Added soft boot code +Added user configurable crystal value (for baud sync protocol) + + + diff --git a/msba2/tools/COPYING b/msba2/tools/COPYING new file mode 100644 index 000000000..a43ea2126 --- /dev/null +++ b/msba2/tools/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/msba2/tools/Makefile b/msba2/tools/Makefile new file mode 100644 index 000000000..91d44fdf7 --- /dev/null +++ b/msba2/tools/Makefile @@ -0,0 +1,43 @@ +CFLAGS = -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" +CC = gcc + +all: lpc2k_pgm pseudoterm + +SRC = lpc2k_pgm.c download.c uuencode.c ihex.c serial.c chipinfo.c boot_2xxx.c boot_23xx.c control_2xxx.c +OBJS = ${addprefix obj/,${patsubst %.c,%.o,$(SRC)}} + +PSEUDOTERM_SRC = pseudoterm.c serial.c control_2xxx.c +PSEUDOTERM_OBJS = ${addprefix obj/,${patsubst %.c,%.o,$(PSEUDOTERM_SRC)}} + +TARGETDIR = bin + +lpc2k_pgm: $(OBJS) + $(CC) -o $(TARGETDIR)/lpc2k_pgm $(OBJS) + +pseudoterm: $(PSEUDOTERM_OBJS) + $(CC) -lpthread -o $(TARGETDIR)/pseudoterm $(PSEUDOTERM_OBJS) + +chipinfo.o: boot_2xxx.h boot_23xx.h + +static: $(OBJS) mkstaticlist + $(CC) -o $(TARGETDIR)/lpc2k_pgm $(OBJS) `./mkstaticlist` + +obj/%.o : src/%.c + $(CC) $(CFLAGS) -c $< -o $@ + +cksum_test: cksum_test.c uuencode.o cksum_test.o + $(CC) $(CFLAGS) -o $(TARGETDIR)/cksum_test obj/cksum_test.o obj/uuencode.o + +boot_2xxx.c boot_2xxx.h: boot_2xxx.armasm mkbootc + arm-elf-as -o boot_2xxx.armobj boot_2xxx.armasm + arm-elf-objdump -d boot_2xxx.armobj | ./mkbootc boot_2xxx + +boot_23xx.c boot_23xx.h: src/boot_23xx.armasm mkbootc + arm-elf-as -o obj/boot_23xx.armobj src/boot_23xx.armasm + arm-elf-objdump -d obj/boot_23xx.armobj | ./mkbootc boot_23xx + +clean: + rm -f bin/lpc2k_pgm cksum_test obj/*.o core core.* obj/*.armobj bin/pseudoterm + +obj/gui.o: src/gui.c + $(CC) $(CFLAGS) `gtk-config --cflags` -c src/gui.c -o obj/gui.o diff --git a/msba2/tools/README.txt b/msba2/tools/README.txt new file mode 100644 index 000000000..8fd6adb01 --- /dev/null +++ b/msba2/tools/README.txt @@ -0,0 +1,144 @@ +This utility downloads code to Philip LPC 2000 series chips, using the +bootloader communication protocol documented in the LPC2106/2105/2104 +User Manual, Sept 2003 revision, pages 177 to 192. This code has also +been tested with LPC2131 and LPC2138 chips (thanks to New Micros for +providing eval boards). It may work with other Philips ARM LPC parts. + + + +Usage: +----- + +When you start the program, it's small control window appears, and a +xterm terminal window is launched. The Xterm window allows you to +simply leave lpc2k_pgm running and interface with the LPC uart using +that window. Most people configure "printf" on in their code to print +to UART0, which will appear in this window. + +This program has 4 settings: + +Firmware: The intel-hex file with your LPC firmware to program. +Port: Which serial device to use. +Baud: The baud rate to communicate. +Crystal: The speed of the crystal on your LPC board. + +Once you have set up these values, simply press the "Program Now" +button to write your firmware to the LPC flash memory, and automatically +run it. If your firmware communicates on UART0, its messages will appear +in the xterm window, and anything you type in that window will be +transmitted to your board. + +The "Reboot" button may be used to reboot your code (assuming you have +connected DTR appropriately). The "Bootloader" button may be used to +stop your code by rebooting into the bootloader, rather than your program. + + + +Hardware Requirements: +--------------------- + +You must have a compatible Philips LPC chip with its UART0 interfaced +to a serial port on your PC. + +You must be able to reset the chip and cause it to enter bootloader mode. +Normally, this is done by connecting the (TTL level translated) DTR signal +to the LPC reset, so that when DTR is high (the TTL version is low), the +Philips chip is in reset mode. Alternately, a pushbutton may be used, +but you will need to manually press the button every time you want to get +back into bootloader mode (while this program attempts to sync baud rates), +rather than letting DTR do it automatically. A few minutes spent wiring +up your circuit so DTR can reset the board will save you much trouble as +you develop code. + +P0.14 must be connected low shortly after reset. Normally, this pin +is just shorted to ground using a jumper. Starting with version 1.02, +you can simply leave this shorted to ground. If your design needs to +use this pin, you may also build a simple circuit that forces this pin +to ground when RTS is high. + + + +Software Requirements: +--------------------- + +You must have a Linux-based system running X Windows. This code has +been tested with Linux kernel 2.4.20 and 2.6.8, and should work with +almost any linux system. + +You must have the "xterm" program installed. Nearly all linux +distrubtions provide this, and it is often installed by default. If +you do not have it, simply install from your linux distribution. + +Your serial port device file (usually /dev/ttyS0 or /dev/ttyS1) must +allow permission for you to use the serial port. + +GTK 1.2 is used for the GUI. Many newer systems only have GTK version +2 (or higher). If you have one of these systems, perhaps you can +install GTK 1.2 (including the development libraries) to allow you to +compile this code. Alternately, you may be able to use the semi-static +build, which includes a copy of this code built into the program. + + + +Building and Installation: +------------------------- + +This software is only provided semi-static binary and source code form. + +To use the semi-static binary, simply copy it to a location where you +can run it, and change the permissions if necessary: + + cp lpc2k_pgm /usr/local/bin + chmod 755 /usr/local/bin/lpc2k_pgm + +The semi-static binary has all of the GTK and X11 libraries statically +linked into it, for maximum compatibility with all linux distributions. +The only disadvantage is, of course, that this uses an extra 1.4 megs +of RAM, with (might) otherwise be shared with other programs. If you +simply want to run this program with minimal work, using the semi-static +binary may be the easiest way. + +If you compile from the source code, the result should be a small +binary that is optimal for your system. + +To build from source, you must have GTK+ 1.2 development libraries +and GCC properly installed. Nearly all linux distributions provide +these as packages, but you may need to install them before you can +compile the code. + +TODO: specific instructions for Debian stable +TODO: specific instructions for Debian testing/unstable +TODO: specific instructions for Fedora +TODO: specific instructions for Suse + +Simply type "make" to build the code. The resulting "lpc2k_pgm" +program can be run from any location. Simply copy to /usr/local/bin, +or where ever you like. + + + +Contact Info: +------------ + +Paul Stoffregen +paul@pjrc.com +http://www.pjrc.com/arm/lpc2k_pgm + +If you discover a bug, you want to request a new feature, or you have +a new Philips LPC chip which is not recognized, please attempt to +provide COMPLETE information in your message. + +If you have problems building from source, please contact me with ALL +of the following: + +1: Complete copy of all messages during the build. +2: Output of "gtk-config --version" +3: Output of "gtk-config --libs" +4: Output of "gtk-config --cflags" +5: Output of "uname -a" +6: Other info... which linux distribution, version, other software + +If you get "Command not found" when trying to run "gtk-config", this +is a sure sign that you do not have GTK+ 1.2 installed. + + diff --git a/msba2/tools/armtools.txt b/msba2/tools/armtools.txt new file mode 100644 index 000000000..c91a4853f --- /dev/null +++ b/msba2/tools/armtools.txt @@ -0,0 +1,15 @@ +This directory contains flash & terminal-utilities for use with +the msb_av2 platform used by the FeuerWhere-Project. + +Usage: +Running "./pseudoterm /dev/ttyUSB1" will start the terminal-emulator, +open the specified port and reset the connected msb_av2-board. +If it receives a SIGUSR2, the terminal closes the port an waits. +On reception of a SIGUSR1, it reopens the port and resets the ARM. + +"./lpc2k_pgm /dev/ttyUSB1 /path/to/firmware.ihex" will do what you +expect, but it will additionally run "killall -SIGUSR2 pseudoterm" before +anѕ "killall -SIGUSR1 pseudoterm" after flashing. + +Together, the tools enable you to have a terminal connected to the board +at all times, but let you flash whenever you feel like. diff --git a/msba2/tools/flash.cmd b/msba2/tools/flash.cmd new file mode 100755 index 000000000..e957ca2b6 --- /dev/null +++ b/msba2/tools/flash.cmd @@ -0,0 +1,2 @@ +fm.exe "COM(%1, 230400) DEVICE(LPC2387, 16.000000) HARDWARE(BOOTEXEC, 50, 100) HIGHSPEED(0, 230400) ERASEUSED(%2, PROTECTISP) HEXFILE(%2, NOCHECKSUMS, NOFILL, PROTECTISP) RESET" +sleep 2 diff --git a/msba2/tools/flashutil.sh b/msba2/tools/flashutil.sh new file mode 100755 index 000000000..c97d7c9a6 --- /dev/null +++ b/msba2/tools/flashutil.sh @@ -0,0 +1,113 @@ +#/bin/bash + +linux_checkid() { + udevinfo -a -n ${1} | grep -q "ATTRS{product}==\"${2}\"" +} + +windows_flash_fm() { + echo "Checking FTDI device on COM${1}" + PORTINFO=`${BASEDIR}/../../../tools/windows/ftdiinfo/bin/Debug/ftdiinfo.exe /l COM${1}` + PORTCHECK=`echo ${PORTINFO} | awk '{ print $1 }'` + BOARDCHECK=`echo ${PORTINFO} | awk '{ print $3 }'` + SERIAL=`echo ${PORTINFO} | awk '{ print $2 }'` + if [ "${PORTCHECK}" != "COM${1}" ]; then + echo " port mismatch / ftdiinfo failed" + exit 1 + fi + if [ "${BOARDCHECK}" != "\"${FTDI_ID}\"" ]; then + echo " target mismatch: target board is \"${FTDI_ID}\", connected is ${BOARDCHECK}" + exit 1 + fi + + echo "Flashing ${HEXFILE} to COM${1} (${BOARDCHECK} serial ${SERIAL})" + # Using FlashMagic on Windows (in separate window) + cmd /C start "FlashMagic ${HEXFILE} to ${BOARDCHECK} on COM${1}" fm.exe "COM(${1}, 230400) DEVICE(LPC2387, 16.000000) HARDWARE(BOOTEXEC, 50, 100) HIGHSPEED(0, 230400) ERASEUSED(${HEXFILE}, PROTECTISP) HEXFILE(${HEXFILE}, NOCHECKSUMS, NOFILL, PROTECTISP) RESET" +} + +windows_flash_openocd() { + echo "Flashing ${HEXFILE} through JTAG" + # Using OpenOcd on Windows + #cmd /C start "OpenOCD ${HEXFILE} to ${BOARDCHECK}" + bash -x ${OPENOCD} ${OPENOCD_IF} "mt_flash ${HEXFILE}; reset run; shutdown" +} + +TEMP=`getopt -a -o b:i:p:f:: --long basedir:,id:,ports:,file:,openocd:,openocd-if:,xxx:: \ + -n 'flashutil.sh' -- "$@"` + +if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi + +# Note the quotes around `$TEMP': they are essential! +eval set -- "$TEMP" + +while true ; do + echo $1: $2 + case "$1" in + -b|--basedir) BASEDIR=$2 ; shift 2 ;; + -i|--id) FTDI_ID=$2; shift 2 ;; + -p|--ports) PORTS=`echo $2 | sed -e 's:,: :g'`; shift 2 ;; + --openocd) OPENOCD=$2; shift 2 ;; + --openocd-if) OPENOCD_IF=$2; shift 2 ;; + + --) HEXFILE=$2 ; shift ; break ;; + *) echo "Internal error!" ; exit 1 ;; + esac +done + +if [ "${OS}" = "Windows_NT" ]; then + WINDOWS=1 +fi + +FLASHUTIL_SHELL=${FLASHUTIL_SHELL:-"xterm -e"} + +if [ "x${WINDOWS}x" = "xx" ]; then + echo Pausing terminal + ${BASEDIR}/termctrl.sh pause +else + HEXFILE=`echo ${HEXFILE} | sed -e 's:/:\\\\:g'` + BASEDIRWIN=`echo ${BASEDIR} | sed -e 's:/:\\\\:g'` +fi + +pids="" + +# +# for OpenOCD let the user verify, that the correct board is connected +# +if [ ${PORTS} = "openocd" ]; then + [ "$OPENOCD" != "" ] || exit 1 + [ "$OPENOCD_IF" != "" ] || exit 1 +# echo -n "Is the board connected to the JTAG a '${FTDI_ID}' (y/n)? " +# read REPLY +# [ "$REPLY" = "y" ] || exit 1 +fi +# +# start a flasher for each port +# +for PORT in $PORTS; do + if [ "x${WINDOWS}x" != "xx" ]; then + if [ "${PORT}" = "openocd" ]; then + windows_flash_openocd + else + windows_flash_fm ${PORT} + fi + else + if [ "${PORT}" = "openocd" ]; then + ${OPENOCD} ${OPENOCD_IF} "mt_flash ${HEXFILE}; reset run; shutdown" + else + echo Flashing ${HEXFILE} to ${PORT} + # using homemade lpc2k_pgm else + ${FLASHUTIL_SHELL} "${BASEDIR}/bin/lpc2k_pgm ${PORT} ${HEXFILE}; sleep 2" & + pids="${pids} $!" + fi + fi +done + +### wait for all flasher processes to finish +echo Waiting until all devices have been programmed... +for pid in "${pids}"; do + wait ${pid} +done + +if [ "x${WINDOWS}x" = "xx" ]; then + echo Resuming terminal + ${BASEDIR}/termctrl.sh continue +fi diff --git a/msba2/tools/mkbootc b/msba2/tools/mkbootc new file mode 100644 index 000000000..4c0d9554d --- /dev/null +++ b/msba2/tools/mkbootc @@ -0,0 +1,28 @@ +#! /usr/bin/perl + +$h = '[0-9A-Fa-f]'; +$n = 1; +while () { + next unless /^\s*$h+:\s+($h{8})/; + $data[$n++] = "0x$1"; +} +$data[0] = $n; +#$size = $ARGV[0]; +#$size =~ tr/a-z/A-Z/; +#$size .= '_SIZE'; + +open H, ">$ARGV[0].h" or die "unable to write boot.h\n"; +print H "/* automatically generated from $ARGV[0].armasm */\n"; +#print H "#define $size $n\n"; +print H "extern const unsigned int ${ARGV[0]}[];\n"; +close H; + +open C, ">$ARGV[0].c" or die "unable to write boot.c\n"; +print C "/* automatically generated from $ARGV[0].armasm */\n"; +print C "#include \"$ARGV[0].h\"\n"; +print C "const unsigned int ${ARGV[0]}[] = {\n"; +print C "\t", join(', ', @data), "\n"; +print C "};\n"; +close C; + + diff --git a/msba2/tools/mkstaticlist b/msba2/tools/mkstaticlist new file mode 100644 index 000000000..4ad31030c --- /dev/null +++ b/msba2/tools/mkstaticlist @@ -0,0 +1,47 @@ +#! /usr/bin/perl + +@arg = split(/\s+/, `gtk-config --libs`); + +%liblist = ( + 'libgtk.a', '/usr/lib/libgtk.a', + 'libgdk.a', '/usr/lib/libgdk.a', + 'libgmodule.a', '/usr/lib/libgmodule.a', + 'libglib.a', '/usr/lib/libglib.a', + 'libXi.a', '/usr/X11R6/lib/libXi.a', + 'libXext.a', '/usr/X11R6/lib/libXext.a', + 'libX11.a', '/usr/X11R6/lib/libX11.a' +); + + +for ($i=0; $i<@arg; $i++) { + $a = $arg[$i]; + next if $a eq '-rdynamic'; # always delete -rdynamic + if (($a eq '-lm') || ($a eq '-ldl') || ($a =~ /^-L/)) { + # a few things we never change + print "$a "; + next; + } + if ($a =~ /^-l/) { + $lib = $'; + $lib = 'lib' . $lib . '.a'; + # first check if it's in the known location + if (-f $liblist{$lib}) { + print $liblist{$lib}, " "; + next; + } + # resort to trying whereis to find it + @source = split(/\s+/, `whereis $lib`); + undef($static); + for ($j=0; $j<@source; $j++) { + $static = $source[$j] if $source[$j] =~ /$lib$/; + } + # if we found a static lib, use it. + if ($static) { + print $static, " "; + } else { + print $a, " "; + } + } +} +print "\n"; + diff --git a/msba2/tools/obj/boot_23xx.d b/msba2/tools/obj/boot_23xx.d new file mode 100644 index 000000000..874c0d70e --- /dev/null +++ b/msba2/tools/obj/boot_23xx.d @@ -0,0 +1,3 @@ +obj/boot_23xx.d obj/boot_23xx.o: src/boot_23xx.c src/boot_23xx.h + +src/boot_23xx.h: diff --git a/msba2/tools/obj/boot_2xxx.d b/msba2/tools/obj/boot_2xxx.d new file mode 100644 index 000000000..b33d06578 --- /dev/null +++ b/msba2/tools/obj/boot_2xxx.d @@ -0,0 +1,3 @@ +obj/boot_2xxx.d obj/boot_2xxx.o: src/boot_2xxx.c src/boot_2xxx.h + +src/boot_2xxx.h: diff --git a/msba2/tools/obj/chipinfo.d b/msba2/tools/obj/chipinfo.d new file mode 100644 index 000000000..b6840f4c8 --- /dev/null +++ b/msba2/tools/obj/chipinfo.d @@ -0,0 +1,8 @@ +obj/chipinfo.d obj/chipinfo.o: src/chipinfo.c src/chipinfo.h \ + src/boot_2xxx.h src/boot_23xx.h + +src/chipinfo.h: + +src/boot_2xxx.h: + +src/boot_23xx.h: diff --git a/msba2/tools/obj/control_2xxx.d b/msba2/tools/obj/control_2xxx.d new file mode 100644 index 000000000..d91c1b90f --- /dev/null +++ b/msba2/tools/obj/control_2xxx.d @@ -0,0 +1,6 @@ +obj/control_2xxx.d obj/control_2xxx.o: src/control_2xxx.c \ + src/control_2xxx.h src/serial.h + +src/control_2xxx.h: + +src/serial.h: diff --git a/msba2/tools/obj/download.d b/msba2/tools/obj/download.d new file mode 100644 index 000000000..1bdc25ec4 --- /dev/null +++ b/msba2/tools/obj/download.d @@ -0,0 +1,19 @@ +obj/download.d obj/download.o: src/download.c src/lpc2k_pgm.h \ + src/download.h src/serial.h src/ihex.h src/uuencode.h src/chipinfo.h \ + src/boot.h src/control_2xxx.h + +src/lpc2k_pgm.h: + +src/download.h: + +src/serial.h: + +src/ihex.h: + +src/uuencode.h: + +src/chipinfo.h: + +src/boot.h: + +src/control_2xxx.h: diff --git a/msba2/tools/obj/ihex.d b/msba2/tools/obj/ihex.d new file mode 100644 index 000000000..e2430e90c --- /dev/null +++ b/msba2/tools/obj/ihex.d @@ -0,0 +1,3 @@ +obj/ihex.d obj/ihex.o: src/ihex.c src/ihex.h + +src/ihex.h: diff --git a/msba2/tools/obj/lpc2k_pgm.d b/msba2/tools/obj/lpc2k_pgm.d new file mode 100644 index 000000000..50838bbfc --- /dev/null +++ b/msba2/tools/obj/lpc2k_pgm.d @@ -0,0 +1,8 @@ +obj/lpc2k_pgm.d obj/lpc2k_pgm.o: src/lpc2k_pgm.c src/lpc2k_pgm.h \ + src/serial.h src/download.h + +src/lpc2k_pgm.h: + +src/serial.h: + +src/download.h: diff --git a/msba2/tools/obj/pseudoterm.d b/msba2/tools/obj/pseudoterm.d new file mode 100644 index 000000000..3524292e4 --- /dev/null +++ b/msba2/tools/obj/pseudoterm.d @@ -0,0 +1,6 @@ +obj/pseudoterm.d obj/pseudoterm.o: src/pseudoterm.c src/serial.h \ + src/download.h + +src/serial.h: + +src/download.h: diff --git a/msba2/tools/obj/serial.d b/msba2/tools/obj/serial.d new file mode 100644 index 000000000..70d6d9d7d --- /dev/null +++ b/msba2/tools/obj/serial.d @@ -0,0 +1,3 @@ +obj/serial.d obj/serial.o: src/serial.c src/serial.h + +src/serial.h: diff --git a/msba2/tools/obj/uuencode.d b/msba2/tools/obj/uuencode.d new file mode 100644 index 000000000..fa6d25aca --- /dev/null +++ b/msba2/tools/obj/uuencode.d @@ -0,0 +1,3 @@ +obj/uuencode.d obj/uuencode.o: src/uuencode.c src/uuencode.h + +src/uuencode.h: diff --git a/msba2/tools/src/Jamfile b/msba2/tools/src/Jamfile new file mode 100644 index 000000000..43ead81f9 --- /dev/null +++ b/msba2/tools/src/Jamfile @@ -0,0 +1,9 @@ +Library liblpc2k : download.c uuencode.c ihex.c serial.c chipinfo.c boot_2xxx.c boot_23xx.c control_2xxx.c ; + +LinkLibraries lpc2k_pgm : liblpc2k ; + +LinkLibraries pseudoterm : liblpc2k ; +LINKFLAGS on pseudoterm = -lrt ; + +Main lpc2k_pgm : lpc2k_pgm.c ; +Main pseudoterm : pseudoterm.c ; diff --git a/msba2/tools/src/boot.h b/msba2/tools/src/boot.h new file mode 100644 index 000000000..1560f1038 --- /dev/null +++ b/msba2/tools/src/boot.h @@ -0,0 +1,9 @@ + +typedef struct { + int size; + const int *prog; +} boot_t; + + + + diff --git a/msba2/tools/src/boot_23xx.armasm b/msba2/tools/src/boot_23xx.armasm new file mode 100644 index 000000000..50e29957f --- /dev/null +++ b/msba2/tools/src/boot_23xx.armasm @@ -0,0 +1,32 @@ + /* ARM code to run user code */ + /* on the LPC23xx chips, the bootloader defaults to using the RC */ + /* osciallator and it activates the PLL to create 14.78 MHz, even */ + /* if there is no crystal. However, when we use try to jump to */ + /* the user's code, their startup routine may (incorrectly) assume */ + /* the PLL is not enabled and crash if it is. So in addition to */ + /* remapping the reset vector to flash, we have to shut off the */ + /* PLL so the user's startup code sees the same conditions as it */ + /* would following a hard reset */ +begin: + adr r0, const + ldr r1, [r0] /* r1 points to MEMMAP register */ + ldr r2, [r0,#4] /* r2 points to PLLCON */ + ldr r3, [r0,#8] /* r3 points to PLLFEED */ + mov r0, #1 + str r0, [r1] /* remap interrupt vectors to flash */ + mov r4, #0xAA + mov r5, #0x55 + str r0, [r2] /* disconnect the PLL, PLLCON = 1 */ + str r4, [r3] + str r5, [r3] + mov r0, #0 + str r0, [r2] /* disable the PLL, PLLCON = 0 */ + str r4, [r3] + str r5, [r3] + mov pc, #0 /* and then jump to the user's code */ +const: + .int 0xE01FC040 /* MEMMAP register */ + .int 0xE01FC080 /* PLLCON */ + .int 0xE01FC08C /* PLLFEED */ + + diff --git a/msba2/tools/src/boot_23xx.c b/msba2/tools/src/boot_23xx.c new file mode 100644 index 000000000..9901171cc --- /dev/null +++ b/msba2/tools/src/boot_23xx.c @@ -0,0 +1,5 @@ +/* automatically generated from boot_23xx.armasm */ +#include "boot_23xx.h" +const unsigned int boot_23xx[] = { + 20, 0xe28f0038, 0xe5901000, 0xe5902004, 0xe5903008, 0xe3a00001, 0xe5810000, 0xe3a040aa, 0xe3a05055, 0xe5820000, 0xe5834000, 0xe5835000, 0xe3a00000, 0xe5820000, 0xe5834000, 0xe5835000, 0xe3a0f000, 0xe01fc040, 0xe01fc080, 0xe01fc08c +}; diff --git a/msba2/tools/src/boot_23xx.h b/msba2/tools/src/boot_23xx.h new file mode 100644 index 000000000..0696a2931 --- /dev/null +++ b/msba2/tools/src/boot_23xx.h @@ -0,0 +1,2 @@ +/* automatically generated from boot_23xx.armasm */ +extern const unsigned int boot_23xx[]; diff --git a/msba2/tools/src/boot_2xxx.armasm b/msba2/tools/src/boot_2xxx.armasm new file mode 100644 index 000000000..38e171520 --- /dev/null +++ b/msba2/tools/src/boot_2xxx.armasm @@ -0,0 +1,15 @@ + /* ARM code to run user code */ + /* This allows us to jump to the user's code in flash. We have */ + /* to remap the flash before jumping. */ +begin: + adr r0, const + ldr r1, [r0] /* r1 points to MEMMAP register */ + mov r0, #1 + str r0, [r1] /* remap interrupt vectors to flash */ + mov pc, #0 /* and then jump to the user's code */ +const: + .int 0xE01FC040 /* MEMMAP register */ + + + + diff --git a/msba2/tools/src/boot_2xxx.c b/msba2/tools/src/boot_2xxx.c new file mode 100644 index 000000000..4d9b367eb --- /dev/null +++ b/msba2/tools/src/boot_2xxx.c @@ -0,0 +1,5 @@ +/* automatically generated from boot_2xxx.armasm */ +#include "boot_2xxx.h" +const unsigned int boot_2xxx[] = { + 7, 0xe28f000c, 0xe5901000, 0xe3a00001, 0xe5810000, 0xe3a0f000, 0xe01fc040 +}; diff --git a/msba2/tools/src/boot_2xxx.h b/msba2/tools/src/boot_2xxx.h new file mode 100644 index 000000000..333188def --- /dev/null +++ b/msba2/tools/src/boot_2xxx.h @@ -0,0 +1,2 @@ +/* automatically generated from boot_2xxx.armasm */ +extern const unsigned int boot_2xxx[]; diff --git a/msba2/tools/src/chipinfo.c b/msba2/tools/src/chipinfo.c new file mode 100644 index 000000000..4f3f1a9d7 --- /dev/null +++ b/msba2/tools/src/chipinfo.c @@ -0,0 +1,159 @@ +/* + * LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm + * Copyright (c) 2004, PJRC.COM, LLC, + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include +#include "chipinfo.h" +#include "boot_2xxx.h" +#include "boot_23xx.h" + + +struct sector_info_struct lpc2106_layout[] = { + {0x00000000, 0x2000}, + {0x00002000, 0x2000}, + {0x00004000, 0x2000}, + {0x00006000, 0x2000}, + {0x00008000, 0x2000}, + {0x0000A000, 0x2000}, + {0x0000C000, 0x2000}, + {0x0000E000, 0x2000}, + {0x00010000, 0x2000}, + {0x00012000, 0x2000}, + {0x00014000, 0x2000}, + {0x00016000, 0x2000}, + {0x00018000, 0x2000}, + {0x0001A000, 0x2000}, + {0x0001C000, 0x2000} +}; + +struct sector_info_struct lpc2214_layout[] = { + {0x00000000, 0x2000}, + {0x00002000, 0x2000}, + {0x00004000, 0x2000}, + {0x00006000, 0x2000}, + {0x00008000, 0x2000}, + {0x0000A000, 0x2000}, + {0x0000C000, 0x2000}, + {0x0000E000, 0x2000}, + {0x00010000, 0x10000}, + {0x00020000, 0x10000}, + {0x00030000, 0x2000}, + {0x00032000, 0x2000}, + {0x00034000, 0x2000}, + {0x00036000, 0x2000}, + {0x00038000, 0x2000}, + {0x0003A000, 0x2000}, + {0x0003C000, 0x2000} +}; + +struct sector_info_struct lpc2138_layout[] = { + {0x00000000, 0x1000}, + {0x00001000, 0x1000}, + {0x00002000, 0x1000}, + {0x00003000, 0x1000}, + {0x00004000, 0x1000}, + {0x00005000, 0x1000}, + {0x00006000, 0x1000}, + {0x00007000, 0x1000}, + {0x00008000, 0x8000}, + {0x00010000, 0x8000}, + {0x00018000, 0x8000}, + {0x00020000, 0x8000}, + {0x00028000, 0x8000}, + {0x00030000, 0x8000}, + {0x00038000, 0x8000}, + {0x00040000, 0x8000}, + {0x00048000, 0x8000}, + {0x00050000, 0x8000}, + {0x00058000, 0x8000}, + {0x00060000, 0x8000}, + {0x00068000, 0x8000}, + {0x00070000, 0x8000}, + {0x00078000, 0x1000}, + {0x00079000, 0x1000}, + {0x0007A000, 0x1000}, + {0x0007B000, 0x1000}, + {0x0007C000, 0x1000} +}; + + + +// chunk_size is the number of bytes that will be sent with each +// "C" (Copy RAM to Flash) command. This must be one of the sizes +// supported by that command. Beware that different chips support +// different sets of sizes, so check the user manual specific to +// the chip. You must choose a chunk_size which is an an integer +// multiple of all the sector sizes, and it must be able to fit +// entirely within the RAM (allowing for the bootloader memory and +// stack usage). Currently, all available chunk sizes meet these +// requirements, but who knows what Philips will do in the future? +// +// ram_addr is the location in RAM where the chunks are sent by the +// "W" (Write to RAM) command. + + +struct chip_info_struct chip_info[] = { +// chunk num +//part_number id_string ram_addr _size sec sector layout boot code +{"LPC2104 (120k)", "4293984018", 0x40000200, 0x2000, 15, lpc2106_layout, boot_2xxx}, +{"LPC2105 (120k)", "4293984034", 0x40000200, 0x2000, 15, lpc2106_layout, boot_2xxx}, +{"LPC2106 (120k)", "4293984050", 0x40000200, 0x2000, 15, lpc2106_layout, boot_2xxx}, +{"LPC2114 (120k)", "16908050", 0x40000200, 0x2000, 15, lpc2106_layout, boot_2xxx}, +{"LPC2119 (120k)", "33685266", 0x40000200, 0x2000, 15, lpc2106_layout, boot_2xxx}, +{"LPC2124 (120k)", "16908051", 0x40000200, 0x2000, 15, lpc2106_layout, boot_2xxx}, +{"LPC2129 (248k)", "33685267", 0x40000200, 0x2000, 17, lpc2214_layout, boot_2xxx}, +{"LPC2131 (32k)", "196353", 0x40000200, 0x1000, 8, lpc2138_layout, boot_2xxx}, +{"LPC2132 (64k)", "196369", 0x40000200, 0x1000, 9, lpc2138_layout, boot_2xxx}, +{"LPC2134 (128k)", "196370", 0x40000200, 0x1000, 11, lpc2138_layout, boot_2xxx}, +{"LPC2136 (256k)", "196387", 0x40000200, 0x1000, 15, lpc2138_layout, boot_2xxx}, +{"LPC2138 (500k)", "196389", 0x40000200, 0x1000, 27, lpc2138_layout, boot_2xxx}, +{"LPC2141 (32k)", "67305217", 0x40000200, 0x1000, 8, lpc2138_layout, boot_2xxx}, +{"LPC2142 (64k)", "67305233", 0x40000200, 0x1000, 9, lpc2138_layout, boot_2xxx}, +{"LPC2144 (128k)", "67305234", 0x40000200, 0x1000, 11, lpc2138_layout, boot_2xxx}, +{"LPC2146 (256k)", "67305251", 0x40000200, 0x1000, 15, lpc2138_layout, boot_2xxx}, +{"LPC2148 (500k)", "67305253", 0x40000200, 0x1000, 27, lpc2138_layout, boot_2xxx}, +{"LPC2194 (248k)", "50462483", 0x40000200, 0x2000, 17, lpc2214_layout, boot_2xxx}, +{"LPC2212 (248k)", "67239698", 0x40000200, 0x2000, 17, lpc2214_layout, boot_2xxx}, +{"LPC2214 (248k)", "100794131", 0x40000200, 0x2000, 17, lpc2214_layout, boot_2xxx}, +{"LPC2292 (248k)", "67239699", 0x40000200, 0x2000, 17, lpc2214_layout, boot_2xxx}, +{"LPC2294 (248k)", "84016915", 0x40000200, 0x2000, 17, lpc2214_layout, boot_2xxx}, +//{"LPC2101 (8k)", "??????", 0x40000200, 0x1000, 2, lpc2138_layout, boot_2xxx}, +//{"LPC2102 (16k)", "??????", 0x40000200, 0x1000, 4, lpc2138_layout, boot_2xxx}, +{"LPC2103 (32k)", "327441", 0x40000200, 0x1000, 8, lpc2138_layout, boot_2xxx}, +{"LPC2364 (128k)", "100924162", 0x40000200, 0x1000, 11, lpc2138_layout, boot_23xx}, +{"LPC2366 (256k)", "100924195", 0x40000200, 0x1000, 15, lpc2138_layout, boot_23xx}, +{"LPC2368 (500k)", "100924197", 0x40000200, 0x1000, 27, lpc2138_layout, boot_23xx}, +{"LPC2378 (500k)", "117702437", 0x40000200, 0x1000, 27, lpc2138_layout, boot_23xx}, +{"LPC2387 (500k)", "402716981", 0x40000200, 0x1000, 27, lpc2138_layout, boot_23xx}, +{"LPC2387 (500k)", "385941301", 0x40000200, 0x1000, 27, lpc2138_layout, boot_23xx}, +{"LPC2468 (500k)", "100925237", 0x40000200, 0x1000, 27, lpc2138_layout, boot_23xx}, +{NULL, NULL, 0, 0, 0, NULL} +}; + + + +char *lpc_return_strings[] = { + "CMD_SUCCESS", "INVALID_COMMAND", "SRC_ADDR_ERROR", "DST_ADDR_ERROR", + "SRC_ADDR_NOT_MAPPED", "DST_ADDR_NOT_MAPPED", "COUNT_ERROR", "INVALID_SECTOR", + "SECTOR_NOT_BLANK", "SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION", "COMPARE_ERROR", + "BUSY", "PARAM_ERROR", "ADDR_ERROR", "ADDR_NOT_MAPPED", "CMD_LOCKED", + "INVALID_CODE", "INVALID_BAUD_RATE", "INVALID_STOP_BIT", + "CODE_READ_PROTECTION_ENABLED" +}; + diff --git a/msba2/tools/src/chipinfo.h b/msba2/tools/src/chipinfo.h new file mode 100644 index 000000000..1b12bb366 --- /dev/null +++ b/msba2/tools/src/chipinfo.h @@ -0,0 +1,20 @@ +extern char *lpc_return_strings[]; + +struct sector_info_struct { // an array of + int address; // where each sector is located + int size; // and how big it is +}; + +struct chip_info_struct { + char *part_number; // human readable part number + char *id_string; // id string sent by "J" command + unsigned int ram_addr; // where to download into RAM + int chunk_size; // download to ram chunk size + int num_sector; // number of flash sectors + struct sector_info_struct *layout; // layout of sectors + const unsigned int *bootprog; // code that boots into user program (NULL = DTR/RTS only) +}; + +extern struct chip_info_struct chip_info[]; + + diff --git a/msba2/tools/src/cksum_test.c b/msba2/tools/src/cksum_test.c new file mode 100644 index 000000000..8cff9b55e --- /dev/null +++ b/msba2/tools/src/cksum_test.c @@ -0,0 +1,76 @@ +/* + * LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm + * Copyright (c) 2004, PJRC.COM, LLC, + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +/* If this code fails to build, please provide at least the following + * information when requesting (free) technical support. + * + * 1: Complete copy of all messages during the build. + * 2: Output of "gtk-config --version" + * 3: Output of "gtk-config --libs" + * 4: Output of "gtk-config --cflags" + * 5: Output of "uname -a" + * 6: Version of GTK installed... eg, type: ls -l /lib/libgtk* + * 7: Other info... which linux distribution, version, other software + */ + + +#include +#include +#include + +#include "uuencode.h" + + +unsigned int sum=0; + + + +void cksum(const char *str) +{ + int num, i; + unsigned char data[256]; + + if (str == NULL) return; + num = uudecode(str, data, sizeof(data)); + for (i=0; i +#include +#include + +#include "serial.h" + +void hard_reset_to_bootloader(void) +{ + printf("Reset CPU (into bootloader)\r\n"); + set_rts(1); // RTS (ttl level) connects to P0.14 + set_dtr(1); // DTR (ttl level) connects to RST + send_break_signal(); // or break detect circuit to RST + usleep(75000); + set_dtr(0); // allow the CPU to run + set_baud(baud_rate); + set_rts(1); // set RTS again (as it has been reset by set_baudrate) + usleep(40000); +} + +void hard_reset_to_user_code(void) +{ + printf("Reset CPU (into user code)\r\n"); + set_rts(0); // RTS (ttl level) connects to P0.14 + set_dtr(1); // DTR (ttl level) connects to RST + send_break_signal(); // or break detect circuit to RST + usleep(75000); + set_dtr(0); // allow the CPU to run + usleep(40000); +} diff --git a/msba2/tools/src/control_2xxx.h b/msba2/tools/src/control_2xxx.h new file mode 100644 index 000000000..e37e2e29d --- /dev/null +++ b/msba2/tools/src/control_2xxx.h @@ -0,0 +1,8 @@ +#ifndef CONTROL_2XXXX_H +#define CONTROL_2XXXX_H + +void hard_reset_to_bootloader(void); +void hard_reset_to_user_code(void); + +#endif // ..._H + diff --git a/msba2/tools/src/download.c b/msba2/tools/src/download.c new file mode 100644 index 000000000..5494661df --- /dev/null +++ b/msba2/tools/src/download.c @@ -0,0 +1,972 @@ +/* + * LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm + * Copyright (c) 2004, PJRC.COM, LLC, + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +/* If this code fails to build, please provide at least the following + * information when requesting (free) technical support. + * + * 1: Complete copy of all messages during the build. + * 2: Output of "gtk-config --version" + * 3: Output of "gtk-config --libs" + * 4: Output of "gtk-config --cflags" + * 5: Output of "uname -a" + * 6: Version of GTK installed... eg, type: ls -l /lib/libgtk* + * 7: Other info... which linux distribution, version, other software + */ + +#include +#include +#include +#include +#include +#include + +#include "lpc2k_pgm.h" +#include "download.h" +#include "serial.h" +#include "ihex.h" +#include "uuencode.h" +//#include "gui.h" +#include "chipinfo.h" +#include "boot.h" +#include "control_2xxx.h" + + +// This will cause all bytes send and received to be printed as hex. +// It's a LOT of extra output, but useful for difficult debugging +// of what's _really_ being sent and received. +//#define PRINT_TX_RX_BYTES + + +static void download_main(int event); +static void xmit_cmd(const char *cmd, int max_time); +static void mk_valid_code_vector(void); +static unsigned int sum(unsigned char *data, int num); + + +static int state=0; +static int reboot_only=0; +static char expected_echo_buf[4096]; +static char *expected_echo_ptr=NULL; +static char parsed_response_buf[4096]; +static char *parsed_response_ptr=NULL; +static int response_timer=0; + +extern int programming_done; +extern int done_program(int); + + +char* port_name = "/dev/ttyUSB1"; +char* file_name = ""; +char* crystal = "16"; + +/****************************************************************/ +/* */ +/* Main Download Section */ +/* */ +/****************************************************************/ + +// possible states +#define SYNC_1 1 +#define SYNC_2 2 +#define SYNC_3 3 +#define CHIP_ID 4 +#define UNLOCK 5 +#define BLANK_CHECK_SECTOR 6 +#define ERASE_PREPARE 7 +#define ERASE_SECTOR 8 +#define DOWNLOAD_CODE 9 +#define XMIT_DATA 10 +#define XMIT_CKSUM 11 +#define WRITE_PREPARE 12 +#define WRITE_SECTOR 13 +#define BOOT_HARD 14 +#define BOOT_SOFT 15 +#define BOOT_XMIT_DATA 16 +#define BOOT_XMIT_CKSUM 17 +#define BOOT_RUN_CODE 18 + + +// possible input values for "event" +#define BEGIN 1 +#define RESPONSE 2 +#define TIMEOUT 3 +#define RETRY 4 + + + + +int download_begin(char* file) +{ + int r; + + file_name = file; + + printf("\r\nEntering Bootloader Mode\r\n"); + hard_reset_to_bootloader(); + printf("Read \"%s\"", file_name); + r = read_intel_hex(file_name); + if (r < 0) { + /* abort on ioerror */ + return 0; + } + printf(": %d bytes\r\n", r); + mk_valid_code_vector(); + state = SYNC_1; + reboot_only = 0; + download_main(BEGIN); + return 1; +} + + +void soft_reboot_begin(void) +{ + printf("\r\nEntering Bootloader Mode\r\n"); + hard_reset_to_bootloader(); + state = SYNC_1; + reboot_only = 1; + download_main(BEGIN); +} + +static void mk_valid_code_vector(void) +{ + unsigned char b[4]; + unsigned int sum=0; + int addr; + + for (addr=0; addr<0x20; addr+=4) { + if (addr != 0x14) { + get_ihex_data(addr, 4, b); + sum += (b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24)); + } + } + sum ^= 0xFFFFFFFF; + sum++; + b[0] = (sum >> 0) & 255; + b[1] = (sum >> 8) & 255; + b[2] = (sum >> 16) & 255; + b[3] = (sum >> 24) & 255; + put_ihex_data(0x14, 4, b); +} + + +static unsigned int sum(unsigned char *data, int num) +{ + unsigned int sum=0; + + while (num > 0) { + sum += *data++; + num--; + } + return sum; +} + + +static int num_lines(const char *buf) +{ + const char *p; + int count=0; + + p = buf; + while (p != NULL) { + p = strstr(p, "\r\n"); + if (p != NULL) { + count++; + p += 2; + } + } + return count; +} + +void trim_crlf(char *str) +{ + char *p; + p = strstr(str, "\r\n"); + if (p != NULL) *p = '\0'; +} + +void copy_boot_code_to_memory(struct chip_info_struct *chip) +{ + int i; + unsigned char c[4]; + + for (i=0; i < chip->bootprog[0]; i++) { + c[3] = (chip->bootprog[i+1] >> 24) & 255; + c[2] = (chip->bootprog[i+1] >> 16) & 255; + c[1] = (chip->bootprog[i+1] >> 8) & 255; + c[0] = (chip->bootprog[i+1]) & 255; + put_ihex_data(i * 4, 4, c); + } +} + + +#define NO_SYNC_ERR "\r\n\ +ERROR: Unable to sync to baud rate.\r\n\ +This probably means the LPC2xxx chip is not connected\r\n\ +or it is not being reset, or P0.14 is not low after\r\n\ +reset to cause it to enter the bootloader mode.\r\n\r\n\ +Please check the serial port connection, make sure\r\n\ +pin P0.14 is low (or tied to RTS via RS-232 level\r\n\ +translator), and the chip has been reset (or reset\r\n\ +is tied to DTR via RS-232 level translator).\r\n" + +#define UNKNOWN_CHIP_ERROR "\r\n\ +Unknown chip ID: \"%s\".\r\n\r\n\ +Perhaps you have a new Philips LPC chip which does not\r\n\ +have its ID string and sector map defined in this program?\r\n\ +Please contact paul@pjrc.com. Please include an exact copy\r\n\ +of this message and any info about the chip and other\r\n\ +hardware you may be using. Thanks :-)\r\n" + + +static void download_main(int event) +{ + char buf[4096]; + unsigned char bytes[256]; + double xtal; + int n; + static unsigned int cksum; + static int retry=0; + static int sector; // current sector we're doing + static int sector_offset; + static struct chip_info_struct *chip; // which chip + static int current_addr, num_to_xmit, linecount; + + + while (1) { + switch (state) { + case SYNC_1: + switch (event) { + case BEGIN: + printf("Attempting baud sync"); + retry = 0; + case RETRY: + printf("."); + fflush(stdout); + xmit_cmd("?", 2); + return; + case RESPONSE: + if (strcmp(parsed_response_buf, "Synchronized\r\n") == 0) { + //printf("response: sync'd\n"); + state = SYNC_2; + event = BEGIN; + break; + } + if (strcmp(parsed_response_buf, "?") == 0) { + //printf("response: echo only\n"); + retry++; + if (retry > 150) { + download_cancel(NO_SYNC_ERR); return; + } + event = RETRY; + usleep(30000); + break; + } + snprintf(buf, sizeof(buf), "Unexpected response to sync, \"%s\"", + parsed_response_buf); + download_cancel(buf); return; + case TIMEOUT: + if (retry < 100) { + retry++; + event = RETRY; + break; + } + download_cancel(NO_SYNC_ERR); + return; + } + break; + + + case SYNC_2: + switch(event) { + case BEGIN: + xmit_cmd("Synchronized\r\n", 3); + return; + case RESPONSE: + if (num_lines(parsed_response_buf) != 1) return; + if (strcmp(parsed_response_buf, "OK\r\n") == 0) { + state = SYNC_3; + event = BEGIN; + break; + } else { + snprintf(buf, sizeof(buf), "Unable to complete baud sync, %s", + parsed_response_buf); + download_cancel(buf); return; + } + return; + case TIMEOUT: + download_cancel("No response to complete baud sync"); return; + } + break; + + + case SYNC_3: + switch(event) { + case BEGIN: + if (sscanf(crystal, "%lf", &xtal) != 1) { + printf("\r\n"); + download_cancel("Crystal frequency is required for 3rd step of baud rate sync"); + return; + } + if (xtal < 10.0 || xtal > 25.0) { + printf("\r\n"); + printf("Warning: crystal frequency out of range (10.0 to 25.0), continuing anyway! (hope you know what you're doing)\r\n"); + } + snprintf(buf, sizeof(buf), "%d\r\n", (int)(xtal * 1000.0 + 0.5)); + xmit_cmd(buf, 3); + return; + case RESPONSE: + if (num_lines(parsed_response_buf) != 1) return; + if (strcmp(parsed_response_buf, "OK\r\n") == 0) { + printf("Baud sync sucessful\r\n"); + state = CHIP_ID; + event = BEGIN; + break; + } else { + snprintf(buf, sizeof(buf), "wrong response to crystal: %s", + parsed_response_buf); + download_cancel(buf); return; + } + return; + case TIMEOUT: + download_cancel("No response to crystal speed"); return; + } + break; + + + case CHIP_ID: + switch(event) { + case BEGIN: + xmit_cmd("J\r\n", 3); + return; + case RESPONSE: + if (num_lines(parsed_response_buf) < 2) return; + if (strncmp(parsed_response_buf, "0\r\n", 3) == 0) { + trim_crlf(parsed_response_buf+3); + for (chip=chip_info; chip->part_number != NULL; chip++) { + if (strcmp(parsed_response_buf+3, chip->id_string) == 0) + break; + } + if (chip->part_number == NULL) { + snprintf(buf, sizeof(buf), UNKNOWN_CHIP_ERROR, + parsed_response_buf+3); + download_cancel(buf); + break; + } + printf("Found chip: \"%s\"\r\n", chip->part_number); + //download_cancel("stop here, remove this later"); + state = UNLOCK; + event = BEGIN; + break; + } else { + snprintf(buf, sizeof(buf), "wrong response to ID: %s", + parsed_response_buf); + download_cancel(buf); return; + } + return; + case TIMEOUT: + download_cancel("No response to unlock command"); return; + } + break; + + + case UNLOCK: + switch(event) { + case BEGIN: + xmit_cmd("U 23130\r\n", 3); + return; + case RESPONSE: + if (num_lines(parsed_response_buf) != 1) return; + if (strcmp(parsed_response_buf, "0\r\n") == 0) { + printf("Device Unlocked\r\n"); + if (reboot_only) { + state = BOOT_SOFT; + } else { + state = BLANK_CHECK_SECTOR; + printf("Erasing....\r\n"); + sector = 0; + } + event = BEGIN; + break; + } else { + snprintf(buf, sizeof(buf), "wrong response unlock: %s", + parsed_response_buf); + download_cancel(buf); return; + } + return; + case TIMEOUT: + download_cancel("No response to unlock command"); return; + } + break; + + + case BLANK_CHECK_SECTOR: + switch(event) { + case BEGIN: + if (sector >= chip->num_sector) { + printf("Programming....\r\n"); + state = DOWNLOAD_CODE; + sector = sector_offset = 0; + event = BEGIN; + break; + } + printf(" Sector %2d: ", sector); + fflush(stdout); + if (!bytes_within_range(chip->layout[sector].address, + chip->layout[sector].address + chip->layout[sector].size - 1)) { + printf("not used\r\n"); + sector++; + break; + } + if (sector == 0) { + // can't blank check sector 0, so always erase it + state = ERASE_PREPARE; + break; + } + snprintf(buf, sizeof(buf), "I %d %d\r\n", sector, sector); + xmit_cmd(buf, 5); + return; + case RESPONSE: + if (num_lines(parsed_response_buf) == 1 && + strcmp(parsed_response_buf, "0\r\n") == 0) { + printf("already blank\r\n"); + sector++; + event = BEGIN; + break; + } else { + if (num_lines(parsed_response_buf) < 3) return; + state = ERASE_PREPARE; + event = BEGIN; + break; + } + case TIMEOUT: + download_cancel("No response to blank check"); return; + } + break; + + + + case ERASE_PREPARE: + switch(event) { + case BEGIN: + printf("prep, "); + fflush(stdout); + snprintf(buf, sizeof(buf), "P %d %d\r\n", sector, sector); + xmit_cmd(buf, 8); + return; + case RESPONSE: + if (num_lines(parsed_response_buf) != 1) return; + if (strcmp(parsed_response_buf, "0\r\n") == 0) { + state = ERASE_SECTOR; + event = BEGIN; + break; + } else { + download_cancel("Unable to prep for write"); return; + } + case TIMEOUT: + download_cancel("No response"); return; + } + break; + + + + case ERASE_SECTOR: + switch(event) { + case BEGIN: + printf("erase... "); + fflush(stdout); + snprintf(buf, sizeof(buf), "E %d %d\r\n", sector, sector); + xmit_cmd(buf, 25); + return; + case RESPONSE: + if (num_lines(parsed_response_buf) < 1) return; + if (strcmp(parsed_response_buf, "0\r\n") == 0) { + printf("Ok\r\n"); + sector++; + state = BLANK_CHECK_SECTOR; + event = BEGIN; + break; + } else { + printf("Error\r\n"); + download_cancel("Unable to erase flash"); return; + } + case TIMEOUT: + download_cancel("No response"); return; + } + break; + + + + case DOWNLOAD_CODE: + switch(event) { + case BEGIN: + if (sector >= chip->num_sector) { + state = BOOT_HARD; + sector = 0; + event = BEGIN; + break; + } + printf(" Sector %2d (0x%08X-0x%08X): ", sector, + chip->layout[sector].address + sector_offset, + chip->layout[sector].address + sector_offset + chip->chunk_size - 1); + fflush(stdout); + if (!bytes_within_range(chip->layout[sector].address + sector_offset, + chip->layout[sector].address + sector_offset + chip->chunk_size - 1)) { + printf("not used\r\n"); + sector_offset += chip->chunk_size; + if (sector_offset >= chip->layout[sector].size) { + sector_offset = 0; + sector++; + } + break; + } + snprintf(buf, sizeof(buf), "W %d %d\r\n", chip->ram_addr, chip->chunk_size); + xmit_cmd(buf, 4); + return; + case RESPONSE: + if (num_lines(parsed_response_buf) != 1) return; + if (strcmp(parsed_response_buf, "0\r\n") == 0) { + state = XMIT_DATA; + printf("xmit"); + current_addr = chip->layout[sector].address + sector_offset; + num_to_xmit = chip->chunk_size; + linecount = 0; + cksum = 0; + event = BEGIN; + break; + } else { + download_cancel("can't xmit to ram"); return; + } + case TIMEOUT: + download_cancel("No response"); return; + } + break; + + + case XMIT_DATA: + switch(event) { + case BEGIN: + n = num_to_xmit; + if (n > 45) n = 45; + get_ihex_data(current_addr, n, bytes); + cksum += sum(bytes, n); + uuencode(buf, bytes, n); + current_addr += n; + num_to_xmit -= n; + linecount++; + xmit_cmd(buf, 5); + write_serial_port("\r\n", 2); + return; + case RESPONSE: + if (num_lines(parsed_response_buf) != 1) return; + if (strcmp(parsed_response_buf, "\r\n") == 0) { + if (linecount >= 20 || num_to_xmit <= 0) { + state = XMIT_CKSUM; + } + event = BEGIN; + break; + } else { + download_cancel("data xmit did not echo"); return; + } + case TIMEOUT: + download_cancel("No response"); return; + } + break; + + + case XMIT_CKSUM: + switch(event) { + case BEGIN: + snprintf(buf, sizeof(buf), "%d\r\n", cksum); + xmit_cmd(buf, 3); + return; + case RESPONSE: + if (num_lines(parsed_response_buf) != 1) return; + if (strcmp(parsed_response_buf, "OK\r\n") == 0) { + if (num_to_xmit > 0) { + printf("."); + fflush(stdout); + state = XMIT_DATA; + event = BEGIN; + linecount = 0; + cksum = 0; + break; + } + state = WRITE_PREPARE; + event = BEGIN; + break; + } else { + download_cancel("bad checksum"); return; + } + case TIMEOUT: + download_cancel("No response"); return; + } + break; + + + case WRITE_PREPARE: + switch(event) { + case BEGIN: + printf("prep, "); + fflush(stdout); + snprintf(buf, sizeof(buf), "P %d %d\r\n", sector, sector); + xmit_cmd(buf, 5); + return; + case RESPONSE: + if (num_lines(parsed_response_buf) != 1) return; + if (strcmp(parsed_response_buf, "0\r\n") == 0) { + state = WRITE_SECTOR; + event = BEGIN; + break; + } else { + download_cancel("Unable to prep for write"); return; + } + case TIMEOUT: + download_cancel("No response"); return; + } + break; + + + case WRITE_SECTOR: + switch(event) { + case BEGIN: + printf("write, "); + fflush(stdout); + snprintf(buf, sizeof(buf), "C %d %d %d\r\n", + chip->layout[sector].address + sector_offset, + chip->ram_addr, chip->chunk_size); + xmit_cmd(buf, 5); + return; + case RESPONSE: + if (num_lines(parsed_response_buf) != 1) return; + if (strcmp(parsed_response_buf, "0\r\n") == 0) { + printf("Ok\r\n"); + sector_offset += chip->chunk_size; + if (sector_offset >= chip->layout[sector].size) { + sector_offset = 0; + sector++; + } + state = DOWNLOAD_CODE; + event = BEGIN; + } else { + download_cancel("Unable to prep for write"); return; + } + break; + case TIMEOUT: + download_cancel("No response"); return; + } + break; + + + case BOOT_HARD: + // if (chip->bootprog) { + // state = BOOT_SOFT; + // break; + // } else { + printf("Booting (hardware reset)...\r\n\r\n"); + hard_reset_to_user_code(); + done_program(0); + return; + // } + + case BOOT_SOFT: + switch(event) { + case BEGIN: + printf("Booting (soft jump)...\r\n"); + printf("loading jump code\r\n"); + // would be nice if we could simply jump to the user's code, but + // Philips didn't think of that. The interrupt vector table stays + // mapped to the bootloader, so jumping to zero only runs the + // bootloader again. Intead, we need to download a tiny ARM + // program that reconfigures the hardware and then jumps to zero. + //snprintf(buf, sizeof(buf), "G %d A\r\n", 0); + snprintf(buf, sizeof(buf), "W %d %d\r\n", chip->ram_addr, chip->bootprog[0] * 4); + xmit_cmd(buf, 4); + return; + case RESPONSE: + if (num_lines(parsed_response_buf) < 1) return; + if (strcmp(parsed_response_buf, "0\r\n") == 0) { + current_addr = 0; + num_to_xmit = chip->bootprog[0] * 4; + copy_boot_code_to_memory(chip); + linecount = 0; + cksum = 0; + state = BOOT_XMIT_DATA; + event = BEGIN; + } else { + download_cancel("can't xmit to ram"); return; + } + break; + case TIMEOUT: + download_cancel("No response"); return; + } + break; + + + case BOOT_XMIT_DATA: + switch(event) { + case BEGIN: + n = num_to_xmit; + if (n > 45) n = 45; + get_ihex_data(current_addr, n, bytes); + cksum += sum(bytes, n); + uuencode(buf, bytes, n); + current_addr += n; + num_to_xmit -= n; + linecount++; + //printf("send: %s\r\n", buf); + xmit_cmd(buf, 5); + write_serial_port("\r\n", 2); + return; + case RESPONSE: + if (num_lines(parsed_response_buf) != 1) return; + if (strcmp(parsed_response_buf, "\r\n") == 0) { + if (linecount >= 20 || num_to_xmit <= 0) { + state = BOOT_XMIT_CKSUM; + } + event = BEGIN; + break; + } else { + download_cancel("data xmit did not echo"); return; + } + case TIMEOUT: + download_cancel("No response"); return; + } + break; + + + case BOOT_XMIT_CKSUM: + switch(event) { + case BEGIN: + snprintf(buf, sizeof(buf), "%d\r\n", cksum); + //printf("send: %s", buf); + xmit_cmd(buf, 3); + return; + case RESPONSE: + if (num_lines(parsed_response_buf) != 1) return; + if (strcmp(parsed_response_buf, "OK\r\n") == 0) { + if (num_to_xmit > 0) { + printf("."); + fflush(stdout); + state = BOOT_XMIT_DATA; + event = BEGIN; + linecount = 0; + cksum = 0; + break; + } + state = BOOT_RUN_CODE; + event = BEGIN; + break; + } else { + download_cancel("bad checksum"); return; + } + case TIMEOUT: + download_cancel("No response"); return; + } + break; + + + case BOOT_RUN_CODE: + switch(event) { + case BEGIN: + printf("jumping now!\r\n"); + snprintf(buf, sizeof(buf), "G %d A\r\n", chip->ram_addr); + xmit_cmd(buf, 4); + return; + case RESPONSE: + if (num_lines(parsed_response_buf) < 1) return; + if (strcmp(parsed_response_buf, "0\r\n") == 0) { + done_program(0); + return; + } else { + printf("response = %s", parsed_response_buf); + download_cancel("couldn't run program"); return; + } + break; + case TIMEOUT: + done_program(0); + return; + // Philips user name says it responds, but it does not. + // It seems to just immediately jump to the code without + // any "0" response. + //download_cancel("No response"); return; + } + break; + + + + default: + snprintf(buf, sizeof(buf), "unknown state %d\r\n", state); + download_cancel(buf); + return; + } + } +} + + +void download_cancel(const char *mesg) +{ + printf("\r\nDownload Canceled"); + if (mesg && *mesg) printf(": %s", mesg); + printf("\r\n"); + // need to do some cleanup for various states??? + done_program(1); +} + + +/****************************************************************/ +/* */ +/* Transmit Commands to Bootloader */ +/* */ +/****************************************************************/ + + + +static void xmit_cmd(const char *cmd, int max_time) +{ + int len; + + if (cmd == NULL || *cmd == '\0') return; + len = strlen(cmd); + +#ifdef PRINT_TX_RX_BYTES + printf("tx %d bytes: %s\n", len, cmd); +#endif + + input_flush_serial_port(); + + write_serial_port(cmd, len); + + snprintf(expected_echo_buf, sizeof(expected_echo_buf), "%s", cmd); + if (state == SYNC_1) { + // special case, baud sync doesn't echo + expected_echo_buf[0] = '\0'; + } + expected_echo_ptr = expected_echo_buf; + parsed_response_ptr = parsed_response_buf; + + response_timer = max_time; +} + + + +/****************************************************************/ +/* */ +/* Handlers that respond to input */ +/* */ +/****************************************************************/ + + +/* +Whenever the main gtk event loop detects more input has arrived from the +serial port, and we're in the process of a download, it calls here to +hand off the data. We're supposed to match it up to the echo buffer, +and then store it into the parsed response buffer and if it looks like +this might be a complete response, call download_main with a response +event. +*/ +void download_rx_port(const unsigned char *buf, int num) +{ + int i=0; + + if (num <= 0) return; + + // echo the data + //write(term_fd, buf, num); + +#ifdef PRINT_TX_RX_BYTES + printf("rx %d bytes:", num); + for (i=0; i "); +#endif + // ignore incorrect echo (will timeout) + expected_echo_ptr = NULL; + return; + } + expected_echo_ptr++; + continue; + } + // store this into a parsed response buffer + *parsed_response_ptr++ = buf[i]; + } + + // if the last two characters of the response are "\r\n", + // then it's likely we've got a complete response. + *parsed_response_ptr = '\0'; + if (parsed_response_ptr > parsed_response_buf + 1 + && *(parsed_response_ptr - 2) == '\r' + && *(parsed_response_ptr - 1) == '\n') { + //response_timer = 0; + download_main(RESPONSE); + } +} + + + +/* +During a download, this is supposed to get called at 100 Hz. Whenever +something is transmitted and we expect a response, the response_timer +is initialized to the maximum time we will wait. +*/ +void download_timer(void) +{ + if (response_timer > 0) { + response_timer--; + if (response_timer == 0) { + expected_echo_ptr = NULL; + download_main(TIMEOUT); + } + } +} + +/* +During a download, all input the user types into the terminal is sent +to this function, instead of passing it to xterm for display +*/ +void download_rx_term(const unsigned char *buf, int num) +{ + // discard anything the user types into the terminal + // while we are in the middle of downloading. Maybe + // we should look for CTRL-C and abort?? +} + + diff --git a/msba2/tools/src/download.h b/msba2/tools/src/download.h new file mode 100644 index 000000000..4d57bfa5d --- /dev/null +++ b/msba2/tools/src/download.h @@ -0,0 +1,8 @@ +extern int download_begin(char* file); +extern void soft_reboot_begin(void); +extern void hard_reset_to_bootloader(void); +extern void hard_reset_to_user_code(void); +extern void download_cancel(const char *mesg); +extern void download_rx_term(const unsigned char *buf, int num); +extern void download_rx_port(const unsigned char *buf, int num); +extern void download_timer(void); diff --git a/msba2/tools/src/gui.c b/msba2/tools/src/gui.c new file mode 100644 index 000000000..ce6d13c96 --- /dev/null +++ b/msba2/tools/src/gui.c @@ -0,0 +1,387 @@ +/* + * LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm + * Copyright (c) 2004, PJRC.COM, LLC, + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +/* If this code fails to build, please provide at least the following + * information when requesting (free) technical support. + * + * 1: Complete copy of all messages during the build. + * 2: Output of "gtk-config --version" + * 3: Output of "gtk-config --libs" + * 4: Output of "gtk-config --cflags" + * 5: Output of "uname -a" + * 6: Version of GTK installed... eg, type: ls -l /lib/libgtk* + * 7: Other info... which linux distribution, version, other software + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gui.h" +#include "settings.h" +#include "serial.h" +#include "lpc2k_pgm.h" +#include "download.h" + + +static GtkWidget *firmware_label, *firmware_entry, *program_button; +static GtkWidget *port_label, *port_entry, *baud_label, *baud_combo; +static GtkWidget *crystal_label, *crystal_entry, *mhz_label; +static GtkWidget *reboot_button, *bootloader_button, *quit_button; +static GtkWidget *line1_hbox, *line2_hbox, *line3_hbox, *line4_hbox; +static GtkWidget *main_vbox, *main_window; + +static int port_timeout=0; +static int baud_timeout=0; +static int download_in_progress=0; + +gint do_quit(GtkWidget *widget, gpointer *data) +{ + gtk_main_quit(); + return FALSE; +} + +gint do_program(GtkWidget *widget, gpointer *data) +{ + if (download_in_progress) { + // error... not supposed to get here + gtk_widget_set_sensitive(program_button, FALSE); + return FALSE; + } + download_in_progress = 1; + gtk_widget_set_sensitive(program_button, FALSE); + gtk_widget_set_sensitive(reboot_button, FALSE); + gtk_widget_set_sensitive(bootloader_button, TRUE); + download_begin(); + return FALSE; +} + +int file_exists(const char *filename) +{ + struct stat file_stats; + int r; + + r = stat(filename, &file_stats); + if (r != 0) return 0; + if (!S_ISREG(file_stats.st_mode)) return 0; + return 1; +} + +void done_program(int still_in_bootloader) +{ + download_in_progress = 0; + + if (file_exists(gtk_entry_get_text(GTK_ENTRY(firmware_entry)))) { + gtk_widget_set_sensitive(program_button, TRUE); + } else { + gtk_widget_set_sensitive(program_button, FALSE); + } + gtk_widget_set_sensitive(bootloader_button, TRUE); + gtk_widget_set_sensitive(reboot_button, TRUE); +} + +gint do_reboot(GtkWidget *widget, gpointer *data) +{ + if (download_in_progress) { + download_cancel(NULL); + gtk_widget_set_sensitive(program_button, FALSE); + gtk_widget_set_sensitive(reboot_button, FALSE); + gtk_widget_set_sensitive(bootloader_button, FALSE); + } + gtk_widget_set_sensitive(program_button, FALSE); + gtk_widget_set_sensitive(reboot_button, FALSE); + gtk_widget_set_sensitive(bootloader_button, FALSE); + + hard_reset_to_user_code(); + +#if 0 + download_in_progress = 1; + soft_reboot_begin(); +#endif + if (file_exists(gtk_entry_get_text(GTK_ENTRY(firmware_entry)))) { + gtk_widget_set_sensitive(program_button, TRUE); + } else { + gtk_widget_set_sensitive(program_button, FALSE); + } + gtk_widget_set_sensitive(bootloader_button, TRUE); + return FALSE; +} + +gint do_bootloader(GtkWidget *widget, gpointer *data) +{ + if (download_in_progress) { + download_cancel(NULL); + gtk_widget_set_sensitive(program_button, FALSE); + gtk_widget_set_sensitive(reboot_button, FALSE); + gtk_widget_set_sensitive(bootloader_button, FALSE); + } + + hard_reset_to_bootloader(); + + if (file_exists(gtk_entry_get_text(GTK_ENTRY(firmware_entry)))) { + gtk_widget_set_sensitive(program_button, TRUE); + } else { + gtk_widget_set_sensitive(program_button, FALSE); + } + gtk_widget_set_sensitive(reboot_button, TRUE); + gtk_widget_set_sensitive(bootloader_button, TRUE); + return FALSE; +} + +gint do_new_port(GtkWidget *widget, gpointer *data) +{ + port_timeout = 12; + return FALSE; +} + +gint do_new_baud(GtkWidget *widget, gpointer *data) +{ + baud_timeout = 7; + return FALSE; +} + +gint do_new_file(GtkWidget *widget, gpointer *data) +{ + const char *filename; + + filename = gtk_entry_get_text(GTK_ENTRY(firmware_entry)); + if (file_exists(filename)) { + new_file_setting(filename); + if (download_in_progress) { + gtk_widget_set_sensitive(program_button, FALSE); + } else { + gtk_widget_set_sensitive(program_button, TRUE); + } + } else { + gtk_widget_set_sensitive(program_button, FALSE); + } + return FALSE; +} + +gint do_new_crystal(GtkWidget *widget, gpointer *data) +{ + const char *xtal; + + xtal = gtk_entry_get_text(GTK_ENTRY(crystal_entry)); + new_crystal_setting(xtal); + return FALSE; +} + + +gint do_timer(gpointer data) +{ + if (port_timeout && --port_timeout == 0) { + open_serial_port(gtk_entry_get_text(GTK_ENTRY(port_entry))); + } + if (baud_timeout && --baud_timeout == 0) { + change_baud(gtk_entry_get_text(GTK_ENTRY( + GTK_COMBO(baud_combo)->entry))); + } + if (download_in_progress) { + download_timer(); + } + return TRUE; +} + +void do_term_input(gpointer data, int fd, GdkInputCondition cond) +{ + char buf[256]; + int num, flags; + + flags = fcntl(term_fd, F_GETFL); + fcntl(term_fd, F_SETFL, flags | O_NONBLOCK); + num = read(term_fd, buf, sizeof(buf)); + fcntl(term_fd, F_SETFL, flags); + if (num > 0) { + if (download_in_progress) { + download_rx_term(buf, num); + } else { + write_serial_port(buf, num); + } + } +} + +void do_port_input(gpointer data, int fd, GdkInputCondition cond) +{ + char buf[256]; + int num; + + num = read_serial_port_nb((unsigned char *)buf, sizeof(buf)); + if (num > 0) { + if (download_in_progress) { + download_rx_port(buf, num); + } else { + write(term_fd, buf, num); + } + } +} + + +void run_gui(void) +{ + gtk_signal_connect(GTK_OBJECT(main_window), "delete_event", + GTK_SIGNAL_FUNC(do_quit), NULL); + gtk_signal_connect(GTK_OBJECT(quit_button), "pressed", + GTK_SIGNAL_FUNC(do_quit), NULL); + gtk_signal_connect(GTK_OBJECT(port_entry), "changed", + GTK_SIGNAL_FUNC(do_new_port), NULL); + gtk_signal_connect(GTK_OBJECT(GTK_COMBO(baud_combo)->entry), "changed", + GTK_SIGNAL_FUNC(do_new_baud), NULL); + gtk_signal_connect(GTK_OBJECT(firmware_entry), "changed", + GTK_SIGNAL_FUNC(do_new_file), NULL); + gtk_signal_connect(GTK_OBJECT(crystal_entry), "changed", + GTK_SIGNAL_FUNC(do_new_crystal), NULL); + gtk_signal_connect(GTK_OBJECT(program_button), "pressed", + GTK_SIGNAL_FUNC(do_program), NULL); + gtk_signal_connect(GTK_OBJECT(reboot_button), "pressed", + GTK_SIGNAL_FUNC(do_reboot), NULL); + gtk_signal_connect(GTK_OBJECT(bootloader_button), "pressed", + GTK_SIGNAL_FUNC(do_bootloader), NULL); + + gtk_timeout_add(100, do_timer, NULL); + gdk_input_add(term_fd, GDK_INPUT_READ, do_term_input, NULL); + gdk_input_add(serial_port_fd(), GDK_INPUT_READ, do_port_input, NULL); + + gtk_main(); +} + + +void create_window(int *argc, char ***argv) +{ + GList *gtk_baud_list=NULL; + int i; + + gtk_init(argc, argv); + + firmware_label = gtk_label_new("Firmware:"); + gtk_label_set_justify(GTK_LABEL(firmware_label), GTK_JUSTIFY_RIGHT); + gtk_widget_show(firmware_label); + + firmware_entry = gtk_entry_new(); + gtk_widget_set_usize(firmware_entry, 110, 0); + gtk_entry_set_text(GTK_ENTRY(firmware_entry), file_setting()); + gtk_widget_show(firmware_entry); + + program_button = gtk_button_new_with_label("Program Now"); + if (file_exists(file_setting())) { + gtk_widget_set_sensitive(program_button, TRUE); + } else { + gtk_widget_set_sensitive(program_button, FALSE); + } + gtk_widget_show(program_button); + + line1_hbox = gtk_hbox_new(FALSE, 2); + gtk_box_pack_start(GTK_BOX(line1_hbox), firmware_label, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(line1_hbox), firmware_entry, TRUE, TRUE, 2); + gtk_box_pack_start(GTK_BOX(line1_hbox), program_button, FALSE, FALSE, 2); + gtk_widget_show(line1_hbox); + + + port_label = gtk_label_new("Port:"); + gtk_label_set_justify(GTK_LABEL(port_label), GTK_JUSTIFY_RIGHT); + gtk_widget_show(port_label); + + port_entry = gtk_entry_new(); + gtk_widget_set_usize(port_entry, 80, 0); + gtk_entry_set_text(GTK_ENTRY(port_entry), port_setting()); + open_serial_port(port_setting()); + gtk_widget_show(port_entry); + + baud_label = gtk_label_new("Baud:"); + gtk_label_set_justify(GTK_LABEL(baud_label), GTK_JUSTIFY_RIGHT); + gtk_widget_show(baud_label); + + baud_combo = gtk_combo_new(); + for (i=0; baud_list[i] != NULL; i++) { + gtk_baud_list = g_list_append(gtk_baud_list, baud_list[i]); + } + gtk_combo_set_popdown_strings(GTK_COMBO(baud_combo), gtk_baud_list); + gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(baud_combo)->entry), FALSE); + gtk_widget_set_usize(baud_combo, 75, 0); + for (i=0; baud_list[i] != NULL; i++) { + if (strcmp(baud_list[i], baud_setting()) == 0) { + gtk_list_select_item(GTK_LIST(GTK_COMBO(baud_combo)->list), i); + break; + } + } + gtk_widget_show(baud_combo); + + line2_hbox = gtk_hbox_new(FALSE, 2); + gtk_box_pack_start(GTK_BOX(line2_hbox), port_label, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(line2_hbox), port_entry, TRUE, TRUE, 2); + gtk_box_pack_start(GTK_BOX(line2_hbox), baud_label, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(line2_hbox), baud_combo, FALSE, FALSE, 2); + gtk_widget_show(line2_hbox); + + + crystal_label = gtk_label_new("Crystal:"); + gtk_label_set_justify(GTK_LABEL(crystal_label), GTK_JUSTIFY_RIGHT); + gtk_widget_show(crystal_label); + + crystal_entry = gtk_entry_new(); + gtk_widget_set_usize(crystal_entry, 80, 0); + gtk_entry_set_text(GTK_ENTRY(crystal_entry), crystal_setting()); + gtk_widget_show(crystal_entry); + + mhz_label = gtk_label_new("(MHz)"); + gtk_label_set_justify(GTK_LABEL(mhz_label), GTK_JUSTIFY_LEFT); + gtk_widget_show(mhz_label); + + line3_hbox = gtk_hbox_new(FALSE, 2); + gtk_box_pack_start(GTK_BOX(line3_hbox), crystal_label, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(line3_hbox), crystal_entry, TRUE, TRUE, 2); + gtk_box_pack_start(GTK_BOX(line3_hbox), mhz_label, FALSE, FALSE, 2); + gtk_widget_show(line3_hbox); + + + reboot_button = gtk_button_new_with_label("Reboot"); + gtk_widget_set_sensitive(reboot_button, TRUE); + gtk_widget_show(reboot_button); + + bootloader_button = gtk_button_new_with_label("Booloader"); + gtk_widget_show(bootloader_button); + + quit_button = gtk_button_new_with_label("Quit"); + gtk_widget_show(quit_button); + + line4_hbox = gtk_hbox_new(TRUE, 2); + gtk_box_pack_start(GTK_BOX(line4_hbox), reboot_button, TRUE, TRUE, 2); + gtk_box_pack_start(GTK_BOX(line4_hbox), bootloader_button, TRUE, TRUE, 2); + gtk_box_pack_start(GTK_BOX(line4_hbox), quit_button, TRUE, TRUE, 2); + gtk_widget_show(line4_hbox); + + main_vbox = gtk_vbox_new(FALSE, 2); + gtk_box_pack_start(GTK_BOX(main_vbox), line1_hbox, TRUE, TRUE, 2); + gtk_box_pack_start(GTK_BOX(main_vbox), line2_hbox, TRUE, TRUE, 2); + gtk_box_pack_start(GTK_BOX(main_vbox), line3_hbox, TRUE, TRUE, 2); + gtk_box_pack_start(GTK_BOX(main_vbox), line4_hbox, TRUE, TRUE, 2); + gtk_widget_show(main_vbox); + + main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_container_add(GTK_CONTAINER(main_window), main_vbox); + gtk_widget_show(main_window); +} diff --git a/msba2/tools/src/gui.h b/msba2/tools/src/gui.h new file mode 100644 index 000000000..fadde6db6 --- /dev/null +++ b/msba2/tools/src/gui.h @@ -0,0 +1,3 @@ +extern void create_window(int *argc, char ***argv); +extern void run_gui(void); +extern void done_program(int still_in_bootloader); diff --git a/msba2/tools/src/ihex.c b/msba2/tools/src/ihex.c new file mode 100644 index 000000000..cda37af66 --- /dev/null +++ b/msba2/tools/src/ihex.c @@ -0,0 +1,229 @@ +/* + * LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm + * Copyright (c) 2004, PJRC.COM, LLC, + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +/* If this code fails to build, please provide at least the following + * information when requesting (free) technical support. + * + * 1: Complete copy of all messages during the build. + * 2: Output of "gtk-config --version" + * 3: Output of "gtk-config --libs" + * 4: Output of "gtk-config --cflags" + * 5: Output of "uname -a" + * 6: Version of GTK installed... eg, type: ls -l /lib/libgtk* + * 7: Other info... which linux distribution, version, other software + */ + +#include +#include + + +// the maximum flash image size we can support +// chips with larger memory may be used, but only this +// much intel-hex data can be loaded into memory! +#define MAX_MEMORY_SIZE 0x80000 + + +#include "ihex.h" + + +static unsigned char firmware_image[MAX_MEMORY_SIZE]; +static unsigned char firmware_mask[MAX_MEMORY_SIZE]; +static int end_record_seen=0; +static int byte_count; +static unsigned int extended_addr = 0; + + +static int parse_hex_line(char *line); + + +/****************************************************************/ +/* */ +/* Read Intel Hex File */ +/* */ +/****************************************************************/ + + + +int read_intel_hex(const char *filename) +{ + FILE *fp; + int i, lineno=0; + char buf[1024]; + + byte_count = 0; + end_record_seen = 0; + for (i=0; i= MAX_MEMORY_SIZE) return 0; + ptr += 2; + sum = (len & 255) + ((addr >> 8) & 255) + (addr & 255) + (code & 255); + if (code != 0) { + if (code == 1) { + end_record_seen = 1; + return 1; + } + if (code == 2 && len == 2) { + if (!sscanf(ptr, "%04x", &i)) return 1; + ptr += 4; + sum += ((i >> 8) & 255) + (i & 255); + if (!sscanf(ptr, "%02x", &cksum)) return 1; + if (((sum & 255) + (cksum & 255)) & 255) return 1; + extended_addr = i << 4; + //printf("ext addr = %05X\n", extended_addr); + } + if (code == 4 && len == 2) { + if (!sscanf(ptr, "%04x", &i)) return 1; + ptr += 4; + sum += ((i >> 8) & 255) + (i & 255); + if (!sscanf(ptr, "%02x", &cksum)) return 1; + if (((sum & 255) + (cksum & 255)) & 255) return 1; + extended_addr = i << 16; + //printf("ext addr = %08X\n", extended_addr); + } + return 1; // non-data line + } + byte_count += len; + while (num != len) { + if (sscanf(ptr, "%02x", &i) != 1) return 0; + i &= 255; + firmware_image[addr + extended_addr + num] = i; + firmware_mask[addr + extended_addr + num] = 1; + ptr += 2; + sum += i; + (num)++; + if (num >= 256) return 0; + } + if (!sscanf(ptr, "%02x", &cksum)) return 0; + if (((sum & 255) + (cksum & 255)) & 255) return 0; /* checksum error */ + return 1; +} + + +int bytes_within_range(int begin, int end) +{ + int i; + + if (begin < 0 || begin >= MAX_MEMORY_SIZE || + end < 0 || end >= MAX_MEMORY_SIZE) { + return 0; + } + for (i=begin; i<=end; i++) { + if (firmware_mask[i]) return 1; + } + return 0; +} + +void get_ihex_data(int addr, int len, unsigned char *bytes) +{ + int i; + + if (addr < 0 || len < 0 || addr + len >= MAX_MEMORY_SIZE) { + for (i=0; i= MAX_MEMORY_SIZE) { + return; + } + for (i=0; i + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +/* If this code fails to build, please provide at least the following + * information when requesting (free) technical support. + * + * 1: Complete copy of all messages during the build. + * 2: Output of "gtk-config --version" + * 3: Output of "gtk-config --libs" + * 4: Output of "gtk-config --cflags" + * 5: Output of "uname -a" + * 6: Version of GTK installed... eg, type: ls -l /lib/libgtk* + * 7: Other info... which linux distribution, version, other software + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lpc2k_pgm.h" +#include "serial.h" +#include "download.h" + +int programming_done = 0; + +int done_program(int i) { + printf("Programming done.\n"); + programming_done = 1; + return 0; +} + +void handle_port_input() { + unsigned char buf[256]; + int num; + + num = read_serial_port(buf, sizeof(buf)); + if (num > 0) { + download_rx_port(buf, num); + } +} + +void usage() { + printf("usage: lpc2k_pgm \n"); +} + +int main(int argc, char **argv) +{ + if (argc < 3 ) { + usage(); + exit(1); + } + + char* port_name = argv[1]; + char* file_name = argv[2]; + + sleep(1); + + if (open_serial_port(port_name) < 0) { + return(1); + } + + if (!download_begin(file_name)) { + return 1; + } + while (!programming_done) { + handle_port_input(); + } + + close_serial_port(); + + return 0; +} + diff --git a/msba2/tools/src/lpc2k_pgm.h b/msba2/tools/src/lpc2k_pgm.h new file mode 100644 index 000000000..0a5f5a7ee --- /dev/null +++ b/msba2/tools/src/lpc2k_pgm.h @@ -0,0 +1,12 @@ +#ifndef LPC2K_PGM +#define LPC2K_PGM + +/* gets a name like "115200", sets baudrate accordingly. */ +void change_baud(const char *baud_name); + +/* called before/after using serial device, used to have terminal + * close the device. +*/ +void signal_terminal(); + +#endif // LPC2K_PGM diff --git a/msba2/tools/src/pseudoterm.c b/msba2/tools/src/pseudoterm.c new file mode 100644 index 000000000..ce8a446b3 --- /dev/null +++ b/msba2/tools/src/pseudoterm.c @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "serial.h" +#include "pthread.h" +#include "download.h" + +int tty_fd; +int stopped = 0; +char* port_name = "/dev/ttyUSB1"; +pthread_t serial_reader; + +void* serial_reader_func(void* arg) { + unsigned char buf[255]; + while(1) { + int n = read_serial_port(buf, sizeof(buf)); + if (n > 0) { + write(tty_fd, buf, n); + } + } +} + +int init() { + int result = open_serial_port(port_name); + pthread_create(&serial_reader, NULL, serial_reader_func, NULL); + hard_reset_to_user_code(); + return result; +} + +void sig_handler(int signal) { + if (signal == SIGUSR1) { + if (stopped) { + stopped = 0; + printf("\nSignal received, opening port.\r\n"); + if (init() < 0) { + printf("Cannot open port.\r\n"); + exit(1); + } + } + } else if (signal == SIGUSR2) { + if (!stopped) { + stopped = 1; + printf("\nSignal received, closing port. \r\n"); + pthread_cancel(serial_reader); + close_serial_port(); + } + } +} + +int open_tty(void) +{ + int r, fd; + struct termios term_setting; + + fd = open("/dev/tty", O_RDWR); + if (fd < 0) return -1; + r = tcgetattr(fd, &term_setting); + if (r != 0) return -2; + term_setting.c_oflag |= ( ONLRET ); + term_setting.c_iflag |= (IGNBRK | IGNPAR); + term_setting.c_iflag &= ~(ISTRIP | BRKINT); + term_setting.c_lflag &= ~(ICANON | ISIG | ECHO); + term_setting.c_cflag |= CREAD; + term_setting.c_cc[VMIN] = 1; + term_setting.c_cc[VTIME] = 1; + r = tcsetattr(fd, TCSANOW, &term_setting); + if (r != 0) return -3; + return fd; +} + +void install_sighandler() { + struct sigaction action; + sigemptyset (&action.sa_mask); + sigaddset( &action.sa_mask, SIGUSR1 ); + sigaddset( &action.sa_mask, SIGUSR2 ); + action.sa_flags = 0; + action.sa_handler = sig_handler; + sigaction(SIGUSR1, &action, NULL); + sigaction(SIGUSR2, &action, NULL); +} + +int main(int argc, char** argv) { + if (argc == 2) { + port_name = argv[1]; + } + + printf("Using %s as serial device.\n", port_name); + + char ttybuf[255]; + tty_fd = open_tty(); + if (tty_fd < 0) { + printf("Error opening terminal.\n"); + return(1); + } + + install_sighandler(); + + if (init() < 0) { + printf("Cannot open port.\r\n"); + exit(1); + } + + while (1) { + int n = read(tty_fd, ttybuf, sizeof(ttybuf)); + int i; + + /* check for 0x3 (ctrl-c), clean exit */ + for (i = 0; i < n; i++) { + if (ttybuf[i] == 0x3) { + if (i > 0) { + write_serial_port(ttybuf, i); + } + close_serial_port(); + system("tset -c"); + return 0; + } + + } + write_serial_port(ttybuf,n); + } + + close_serial_port(); + return 0; +} + + diff --git a/msba2/tools/src/serial.c b/msba2/tools/src/serial.c new file mode 100644 index 000000000..cd51e1cc5 --- /dev/null +++ b/msba2/tools/src/serial.c @@ -0,0 +1,350 @@ +/* + * LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm + * Copyright (c) 2004, PJRC.COM, LLC, + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +/* If this code fails to build, please provide at least the following + * information when requesting (free) technical support. + * + * 1: Complete copy of all messages during the build. + * 2: Output of "gtk-config --version" + * 3: Output of "gtk-config --libs" + * 4: Output of "gtk-config --cflags" + * 5: Output of "uname -a" + * 6: Version of GTK installed... eg, type: ls -l /lib/libgtk* + * 7: Other info... which linux distribution, version, other software + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef LINUX +#include +#endif + +#include "serial.h" + +static int port_fd=-1; + +static tcflag_t baud_name_to_flags(const char *baud_name); +static void report_open_error(const char *filename, int err); + +char* baud_rate = "115200"; + +int open_serial_port(const char *port_name) +{ + int r; + + if (port_fd >= 0) { + close(port_fd); + } + port_fd = open(port_name, O_RDWR); + if (port_fd < 0) { + report_open_error(port_name, errno); + return -1; + } + r = set_baud(baud_rate); + if (r == 0) { + printf("Port \"%s\" opened at %s baud\r\n", + port_name, baud_rate); + } else { + printf("Port \"%s\" opened, unable to set baud to %s\r\n", + port_name, baud_rate); + } + #ifdef LINUX + { + struct serial_struct kernel_serial_settings; + /* attempt to set low latency mode, but don't worry if we can't */ + r = ioctl(port_fd, TIOCGSERIAL, &kernel_serial_settings); + if (r < 0) return 0; + kernel_serial_settings.flags |= ASYNC_LOW_LATENCY; + ioctl(port_fd, TIOCSSERIAL, &kernel_serial_settings); + } + #endif + return 0; +} + + +/* if the port can't be opened, try to print as much info as + * possible, so the problem can be resolved (usually permissions) + */ +static void report_open_error(const char *filename, int err) +{ + struct stat info; + uid_t my_uid; + gid_t my_gid; + char my_uname[64], my_gname[64], file_uname[64], file_gname[64]; + struct passwd *p; + struct group *g; + mode_t perm; + int r, perm_ok=0; + + printf("\r\n"); + printf("Unable to open \"%s\"\r\n", filename); + if (err == EACCES) { + printf("You don't have permission to access %s\r\n", filename); + } + //printf("Attemping to find more information about %s....\r\n", filename); + r = stat(filename, &info); + if (r < 0) { + if (errno == ENOENT) { + printf("file %s does not exist\r\n", filename); + } else if (errno == ELOOP) { + printf("too many symbolic links\r\n"); + } else if (errno == EACCES) { + printf("permission denied to get file status\r\n"); + } else { + printf("Unable to get file status, err%d\r\n", errno); + } + return; + } + my_uid = getuid(); + my_gid = getgid(); + + p = getpwuid(my_uid); + if (p) { + snprintf(my_uname, sizeof(my_uname), + "\"%s\" (gid=%d)", p->pw_name, (int)my_uid); + } else { + snprintf(my_uname, sizeof(my_uname), + "(gid=%d)", (int)my_uid); + } + + p = getpwuid(info.st_uid); + if (p) { + snprintf(file_uname, sizeof(file_uname), + "\"%s\" (uid=%d)", p->pw_name, (int)info.st_uid); + } else { + snprintf(file_uname, sizeof(file_uname), + "(uid=%d)", (int)info.st_uid); + } + + g = getgrgid(my_gid); + if (g) { + snprintf(my_gname, sizeof(my_gname), + "\"%s\" (gid=%d)", g->gr_name, (int)my_gid); + } else { + snprintf(my_gname, sizeof(my_gname), + "(gid=%d)", (int)my_gid); + } + + g = getgrgid(info.st_gid); + if (g) { + snprintf(file_gname, sizeof(file_gname), + "\"%s\" (uid=%d)", g->gr_name, (int)info.st_gid); + } else { + snprintf(file_gname, sizeof(file_gname), + "(uid=%d)", (int)info.st_gid); + } + + /* printf("%s is owned by: user %s, group %s\r\n", + filename, file_uname, file_gname); */ + + perm = info.st_mode; + + if ((perm & S_IROTH) && (perm & S_IWOTH)) { + printf("%s has read/write permission for everybody\r\n", + filename); + } else { + printf("%s is not read/write for everybody, so\r\n", filename); + printf(" you must match either user or group permission\r\n"); + if ((perm & S_IRUSR) && (perm & S_IWUSR)) { + printf("%s has read/write permission for user %s\r\n", + filename, file_uname); + perm_ok = 1; + } + if ((perm & S_IRGRP) && (perm & S_IWGRP)) { + printf("%s has read/write permission for group %s\r\n", + filename, file_gname); + perm_ok = 1; + } + if (perm_ok == 0) { + printf("%s does not read/write permission for user or group!\r\n", + filename); + } else { + printf("Your access privs: user %s, group %s\r\n", + my_uname, my_gname); + } + } + printf("\r\n"); +} + + + +int write_serial_port(const void *buf, int num) +{ + return(write(port_fd, buf, num)); +} + + +void input_flush_serial_port(void) +{ + tcflush(port_fd, TCIFLUSH); +} + + +int read_serial_port_nb(unsigned char *buf, int bufsize) +{ + int num, flags; + + flags = fcntl(port_fd, F_GETFL); + fcntl(port_fd, F_SETFL, flags | O_NONBLOCK); + num = read(port_fd, buf, bufsize); + fcntl(port_fd, F_SETFL, flags); + return num; +} + +int read_serial_port(unsigned char *buf, int bufsize) +{ + int num; + + num = read(port_fd, buf, bufsize); + + return num; +} + + +void send_break_signal(void) +{ + tcsendbreak(port_fd, 0); +} + + +void close_serial_port(void) +{ + if (port_fd >= 0) { + close(port_fd); + port_fd = -1; + } +} + + +tcflag_t baud_name_to_flags(const char *baud_name) +{ + if (strcmp(baud_name, "230400") == 0) return B230400; + if (strcmp(baud_name, "115200") == 0) return B115200; + if (strcmp(baud_name, "57600") == 0) return B57600; + if (strcmp(baud_name, "38400") == 0) return B38400; + if (strcmp(baud_name, "19200") == 0) return B19200; + if (strcmp(baud_name, "9600") == 0) return B9600; + if (strcmp(baud_name, "4800") == 0) return B4800; + if (strcmp(baud_name, "2400") == 0) return B2400; + if (strcmp(baud_name, "1200") == 0) return B1200; + if (strcmp(baud_name, "300") == 0) return B300; + return B0; +} + + +int set_baud(const char *baud_name) +{ + struct termios port_setting; + tcflag_t baud; + int r; + + if (port_fd < 0) return -1; + baud = baud_name_to_flags(baud_name); + if (baud == B0) return -2; + r = tcgetattr(port_fd, &port_setting); + if (r != 0) return -3; + //port_setting.c_iflag = IGNBRK | IGNPAR | IXANY | IXON; + port_setting.c_iflag = IGNBRK | IGNPAR; + port_setting.c_cflag = baud | CS8 | CREAD | HUPCL | CLOCAL; + port_setting.c_oflag = 0; + port_setting.c_lflag = 0; + r = tcsetattr(port_fd, TCSAFLUSH, &port_setting); + if (r != 0) return -4; + return 0; +} + + +// Normally this should never be used... except to pass the port +// file descriptor to the GTK event monitoring loop. All other +// use of the serial port is supposed to happen in the file. +int serial_port_fd(void) +{ + return port_fd; +} + + + +void set_rts(int val) +{ + int flags; + int result; + + result = ioctl(port_fd, TIOCMGET, &flags); + if( result == -1 ) { + printf("Error %i while reading port io flags\n", errno); + return; + } + + if (val) { + flags |= TIOCM_RTS; + } else { + flags &= ~(TIOCM_RTS); + } + + result = ioctl(port_fd, TIOCMSET, &flags); + if( result == -1 ) + printf("Error %i while setting port io flags\n", errno); +} + + + + + + + +void set_dtr(int val) +{ + int flags; + int result; + + result = ioctl(port_fd, TIOCMGET, &flags); + if( result == -1 ) { + printf("Error %i while reading port io flags\n", errno); + return; + } + + if (val) { + flags |= TIOCM_DTR; + } else { + flags &= ~(TIOCM_DTR); + } + + result = ioctl(port_fd, TIOCMSET, &flags); + if( result == -1 ) + printf("Error %i while setting port io flags\n", errno); +} + + + + + + diff --git a/msba2/tools/src/serial.h b/msba2/tools/src/serial.h new file mode 100644 index 000000000..4ef9a82e5 --- /dev/null +++ b/msba2/tools/src/serial.h @@ -0,0 +1,19 @@ +#ifndef SERIAL_H +#define SERIAL_H + +extern char* baud_rate; + +int open_serial_port(const char *port_name); +int write_serial_port(const void *buf, int num); +void input_flush_serial_port(void); +int read_serial_port_nb(unsigned char *buf, int bufsize); +int read_serial_port(unsigned char *buf, int bufsize); +void close_serial_port(void); +void send_break_signal(void); +int set_baud(const char *baud_name); +int serial_port_fd(void); +void set_rts(int val); +void set_dtr(int val); +void change_baud(const char *baud_name); + +#endif // SERIAL_H diff --git a/msba2/tools/src/settings.c b/msba2/tools/src/settings.c new file mode 100644 index 000000000..d52e24a03 --- /dev/null +++ b/msba2/tools/src/settings.c @@ -0,0 +1,172 @@ +/* + * LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm + * Copyright (c) 2004, PJRC.COM, LLC, + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +/* If this code fails to build, please provide at least the following + * information when requesting (free) technical support. + * + * 1: Complete copy of all messages during the build. + * 2: Output of "gtk-config --version" + * 3: Output of "gtk-config --libs" + * 4: Output of "gtk-config --cflags" + * 5: Output of "uname -a" + * 6: Version of GTK installed... eg, type: ls -l /lib/libgtk* + * 7: Other info... which linux distribution, version, other software + */ + + +#include +#include +#include +#include + +#include "settings.h" + +#define DEFAULT_FILE "" +#define DEFAULT_PORT "/dev/ttyS0" +#define DEFAULT_BAUD "115200" +#define DEFAULT_CRYSTAL "16" + +char *baud_list[]={"115200", "57600", "38400", + "19200", "9600", "4800", "2400", "1200", "300", NULL}; + +static char file[128]={DEFAULT_FILE}; +static char port[64]={DEFAULT_PORT}; +static char baud[64]={DEFAULT_BAUD}; +static char crystal[64]={DEFAULT_CRYSTAL}; + +static char settings_file[256]={'\0'}; + + +void init_settings(void) +{ + const char *home_dir; + FILE *fp; + char buf[1024], *p, *q; + + home_dir = getenv("HOME"); + if (home_dir && *home_dir) { + snprintf(settings_file, sizeof(settings_file), + "%s/.lpc2k_pgm", home_dir); + fp = fopen(settings_file, "r"); + if (fp == NULL) return; + while (!feof(fp)) { + buf[0] = '\0'; + fgets(buf, sizeof(buf), fp); + if (strncmp(buf, "file:", 5) == 0) { + for (p=buf+5; isspace(*p); p++) ; + q = rindex(p, '\n'); if (q) *q = '\0'; + q = rindex(p, '\r'); if (q) *q = '\0'; + snprintf(file, sizeof(file), "%s", p); + } + if (strncmp(buf, "port:", 5) == 0) { + for (p=buf+5; isspace(*p); p++) ; + q = rindex(p, '\n'); if (q) *q = '\0'; + q = rindex(p, '\r'); if (q) *q = '\0'; + snprintf(port, sizeof(port), "%s", p); + } + if (strncmp(buf, "baud:", 5) == 0) { + for (p=buf+5; isspace(*p); p++) ; + q = rindex(p, '\n'); if (q) *q = '\0'; + q = rindex(p, '\r'); if (q) *q = '\0'; + snprintf(baud, sizeof(baud), "%s", p); + } + if (strncmp(buf, "xtal:", 5) == 0) { + for (p=buf+5; isspace(*p); p++) ; + q = rindex(p, '\n'); if (q) *q = '\0'; + q = rindex(p, '\r'); if (q) *q = '\0'; + snprintf(crystal, sizeof(crystal), "%s", p); + } + } + fclose(fp); + } +} + +void write_settings_file(void) +{ + FILE *fp; + + if (settings_file[0] == '\0') return; + fp = fopen(settings_file, "w"); + if (fp == NULL) return; + fprintf(fp, "file: %s\n", file); + fprintf(fp, "port: %s\n", port); + fprintf(fp, "baud: %s\n", baud); + fprintf(fp, "xtal: %s\n", crystal); + fflush(fp); + fclose(fp); +} + +const char * file_setting(void) +{ + return file; +} + +const char * port_setting(void) +{ + return port; +} + +const char * baud_setting(void) +{ + return baud; +} + +const char * crystal_setting(void) +{ + return crystal; +} + +void new_file_setting(const char *new_file) +{ + if (strcmp(file, new_file)) { + snprintf(file, sizeof(file), "%s", new_file); + write_settings_file(); + } +} + +void new_port_setting(const char *new_port) +{ + if (strcmp(port, new_port)) { + snprintf(port, sizeof(port), "%s", new_port); + write_settings_file(); + } +} + +void new_baud_setting(const char *new_baud) +{ + if (strcmp(baud, new_baud)) { + snprintf(baud, sizeof(baud), "%s", new_baud); + write_settings_file(); + } +} + +void new_crystal_setting(const char *new_xtal) +{ + if (strcmp(crystal, new_xtal)) { + snprintf(crystal, sizeof(crystal), "%s", new_xtal); + write_settings_file(); + } +} + + + + + + diff --git a/msba2/tools/src/settings.h b/msba2/tools/src/settings.h new file mode 100644 index 000000000..20686821a --- /dev/null +++ b/msba2/tools/src/settings.h @@ -0,0 +1,12 @@ + +extern void init_settings(void); +extern const char * file_setting(void); +extern const char * port_setting(void); +extern const char * baud_setting(void); +extern const char * crystal_setting(void); +extern void new_file_setting(const char *new_file); +extern void new_port_setting(const char *new_port); +extern void new_baud_setting(const char *new_baud); +extern void new_crystal_setting(const char *new_xtal); + +extern char *baud_list[]; diff --git a/msba2/tools/src/uuencode.c b/msba2/tools/src/uuencode.c new file mode 100644 index 000000000..5cc76e796 --- /dev/null +++ b/msba2/tools/src/uuencode.c @@ -0,0 +1,98 @@ +/* + * LPC 2000 Loader, http://www.pjrc.com/arm/lpc2k_pgm + * Copyright (c) 2004, PJRC.COM, LLC, + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +/* If this code fails to build, please provide at least the following + * information when requesting (free) technical support. + * + * 1: Complete copy of all messages during the build. + * 2: Output of "gtk-config --version" + * 3: Output of "gtk-config --libs" + * 4: Output of "gtk-config --cflags" + * 5: Output of "uname -a" + * 6: Version of GTK installed... eg, type: ls -l /lib/libgtk* + * 7: Other info... which linux distribution, version, other software + */ + +#include "uuencode.h" + +static char uuchar(unsigned int val); + + +void uuencode(char *str, const unsigned char *data, int num) +{ + int i, n; + unsigned int val; + + *str++ = uuchar(num); + + n = (num + 2) / 3; + for (i=0; i> 18); + *str++ = uuchar(val >> 12); + *str++ = uuchar(val >> 6); + *str++ = uuchar(val >> 0); + data += 3; + } + *str = '\0'; +} + +int uudecode(const char *str, unsigned char *data, int max) +{ + int num=0; + int i, n; + unsigned int val; + + if (*str == '\0') return 0; + + num = *str++ - 32; + if (num < 1 || num > 45) return 0; + + n = (num + 2) / 3; + for (i=0; i 96) return 0; + if (str[1] < 32 || str[1] > 96) return 0; + if (str[2] < 32 || str[2] > 96) return 0; + if (str[3] < 32 || str[3] > 96) return 0; + val = (((str[0] - 32) & 0x3F) << 18) + | (((str[1] - 32) & 0x3F) << 12) + | (((str[2] - 32) & 0x3F) << 6) + | (((str[3] - 32) & 0x3F) << 0); + *data++ = (val >> 16) & 0xFF; + *data++ = (val >> 8) & 0xFF; + *data++ = (val >> 0) & 0xFF; + str += 4; + } + return num; +} + + +static char uuchar(unsigned int val) +{ + val &= 0x3F; + val += 0x20; + if (val == 0x20) val = 0x60; + return val; +} + + + diff --git a/msba2/tools/src/uuencode.h b/msba2/tools/src/uuencode.h new file mode 100644 index 000000000..92fecb7d3 --- /dev/null +++ b/msba2/tools/src/uuencode.h @@ -0,0 +1,3 @@ +extern void uuencode(char *str, const unsigned char *data, int num); +extern int uudecode(const char *str, unsigned char *data, int max); + diff --git a/msba2/tools/termctrl.sh b/msba2/tools/termctrl.sh new file mode 100755 index 000000000..75e87ab21 --- /dev/null +++ b/msba2/tools/termctrl.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +pid=`pgrep pseudoterm` + +if test "$pid" = "" ; then + + echo " Pseudoterm not running." + +else + + if test "$1" = "continue" ; then + kill -s USR1 $pid; + elif test "$1" = "pause" ; then + kill -s USR2 $pid ; + elif test "$1" = "stop" ; then + kill $pid ; + else + echo "Usage:"; + echo "termctrl.sh continue/pause/stop"; + fi + +fi diff --git a/olimex_lpc2148/Jamfile b/olimex_lpc2148/Jamfile new file mode 100644 index 000000000..43ad7d1ba --- /dev/null +++ b/olimex_lpc2148/Jamfile @@ -0,0 +1,10 @@ +SubDir TOP board olimex_lpc2148 ; + +CPU = lpc214x ; + +HDRS += $(TOP)/board/olimex_lpc2148/include ; + +Module board : board_init.c debug_uart.c rs232.c ; +UseModule board ; + +SubInclude TOP cpu lpc214x ; diff --git a/olimex_lpc2148/Jamfile.olimex_lpc2148 b/olimex_lpc2148/Jamfile.olimex_lpc2148 new file mode 100644 index 000000000..057aa7b32 --- /dev/null +++ b/olimex_lpc2148/Jamfile.olimex_lpc2148 @@ -0,0 +1,4 @@ +################## + +include $(TOP)/Jamfile.arm_common ; + diff --git a/olimex_lpc2148/Jamrules.olimex_lpc2148 b/olimex_lpc2148/Jamrules.olimex_lpc2148 new file mode 100644 index 000000000..7a7086d5b --- /dev/null +++ b/olimex_lpc2148/Jamrules.olimex_lpc2148 @@ -0,0 +1,9 @@ +############################ + +BOARD = olimex_lpc2148 ; +CPU = lpc214x ; + +GDB = arm-elf-gdb ; +GDBFLAGS = -x board/olimex_lpc2148/tools/lpc2148_flash.gdb ; + +include $(TOP)/Jamrules.arm_common ; diff --git a/olimex_lpc2148/board_init.c b/olimex_lpc2148/board_init.c new file mode 100644 index 000000000..874feb881 --- /dev/null +++ b/olimex_lpc2148/board_init.c @@ -0,0 +1,88 @@ +/* + * bl_board_init.c + * + * Created on: 19.08.2008 + * Author: heiko, kaspar + */ + +#include "cpu.h" +#include "bits.h" +#include "VIC.h" + +#define PLOCK 0x400 + +static void feed(void) +{ + PLL0FEED = 0xAA; + PLL0FEED = 0x55; +} + +void bl_init_clks(void) +{ + + // Setting the Phased Lock Loop (PLL) + // ---------------------------------- + // + // Olimex LPC-P2148 has a 12.0000 mhz crystal + // + // We'd like the LPC2148 to run at 60 mhz (has to be an even multiple of crystal) + // + // According to the Philips LPC2148 manual: M = cclk / Fosc where: M = PLL multiplier (bits 0-4 of PLLCFG) + // cclk = 60000000 hz + // Fosc = 12000000 hz + // + // Solving: M = 60000000 / 12000000 = 5 + // + // Note: M - 1 must be entered into bits 0-4 of PLLCFG (assign 4 to these bits) + // + // + // The Current Controlled Oscilator (CCO) must operate in the range 156 mhz to 320 mhz + // + // According to the Philips LPC2148 manual: Fcco = cclk * 2 * P where: Fcco = CCO frequency + // cclk = 60000000 hz + // P = PLL divisor (bits 5-6 of PLLCFG) + // + // Solving: Fcco = 60000000 * 2 * P + // P = 2 (trial value) + // Fcco = 60000000 * 2 * 2 + // Fcc0 = 240000000 hz (good choice for P since it's within the 156 mhz to 320 mhz range) + // + // From Table 22 (page 34) of Philips LPC2148 manual P = 2, PLLCFG bits 5-6 = 1 (assign 1 to these bits) + // + // Finally: PLLCFG = 0 01 00100 = 0x24 + // + // Final note: to load PLLCFG register, we must use the 0xAA followed 0x55 write sequence to the PLLFEED register + // this is done in the short function feed() below + // + + // Setting Multiplier and Divider values + PLL0CFG = 0x24; + feed(); + + // Enabling the PLL */ + PLL0CON = 0x1; + feed(); + + // Wait for the PLL to lock to set frequency + while(!(PLL0STAT & PLOCK)) ; + + // Connect the PLL as the clock source + PLL0CON = 0x3; + feed(); + + // Enabling MAM and setting number of clocks used for Flash memory fetch + MAMTIM = 0x3; + MAMCR = 0x2; + + // Setting peripheral Clock (pclk) to 1/2 System Clock (cclk) + VPBDIV = PCLK_DIV; +} + + + + +void bl_init_ports(void) +{ + +} + diff --git a/olimex_lpc2148/debug_uart.c b/olimex_lpc2148/debug_uart.c new file mode 100644 index 000000000..90f5144df --- /dev/null +++ b/olimex_lpc2148/debug_uart.c @@ -0,0 +1,14 @@ +#include "lpc214x.h" +#include "bits.h" + +#include "rs232.h" + +void debug_putchar(int character) +{ + UART1WriteChar(character); +} + +void bl_uart_init(void) +{ + UART1Initialize(115200U); +} diff --git a/olimex_lpc2148/include/board.h b/olimex_lpc2148/include/board.h new file mode 100644 index 000000000..eaf536b00 --- /dev/null +++ b/olimex_lpc2148/include/board.h @@ -0,0 +1 @@ +#include diff --git a/olimex_lpc2148/include/rs232.h b/olimex_lpc2148/include/rs232.h new file mode 100644 index 000000000..9fe0bf2c8 --- /dev/null +++ b/olimex_lpc2148/include/rs232.h @@ -0,0 +1,40 @@ +//rs232.h +//#include + +#include "lpc214x.h" + +//#define OSCILLATOR_CLOCK_FREQUENCY 14745600 //in MHz +#define OSCILLATOR_CLOCK_FREQUENCY 12000000 //in MHz + +//get real processor clock frequency +unsigned int processorClockFrequency(void); +//get peripheral clock frequency +unsigned int peripheralClockFrequency(void); + +/**** UART0 ****/ +//initialize UART0 interface +void UART0Initialize(unsigned int baud); +//write char to UART0 (RS232); +void UART0WriteChar(int ch0); +//read char from RS232 +unsigned char UART0ReadChar(void); + +//this function read/write char from RS232, +//but they not wait to read/write +unsigned char UART0ReadChar_nostop(void); +void UART0WriteChar_nostop(unsigned char ch0); + + +/**** UART1 ****/ +//initialize UART0 interface +void UART1Initialize(unsigned int baud); +//write char to UART0 (RS232); +void UART1WriteChar(int ch0); +//read char from RS232 +unsigned char UART0ReadChar(void); + +//this function read/write char from RS232, +//but they not wait to read/write +unsigned char UART1ReadChar_nostop(void); +void UART1WriteChar_nostop(unsigned char ch0); + diff --git a/olimex_lpc2148/rs232.c b/olimex_lpc2148/rs232.c new file mode 100644 index 000000000..43e70a00f --- /dev/null +++ b/olimex_lpc2148/rs232.c @@ -0,0 +1,65 @@ +//rs232.c +#include "rs232.h" + +unsigned int processorClockFrequency(void) +{ + //return real processor clock speed + return OSCILLATOR_CLOCK_FREQUENCY * (PLL0CON & 1 ? (PLL0CFG & 0xF) + 1 : 1); +} + +unsigned int peripheralClockFrequency(void) +{ + //VPBDIV - determines the relationship between the processor clock (cclk) + //and the clock used by peripheral devices (pclk). + unsigned int divider = 0; + switch (VPBDIV & 3) + { + case 0: divider = 4; break; + case 1: divider = 1; break; + case 2: divider = 2; break; + } + return processorClockFrequency() / divider; +} + +/**** UART0 ****/ +void UART1Initialize(unsigned int baud) +{ + unsigned int divisor = peripheralClockFrequency() / (16 * baud); + + //set Line Control Register (8 bit, 1 stop bit, no parity, enable DLAB) +// U0LCR_bit.WLS = 0x3; //8 bit +// U0LCR_bit.SBS = 0x0; //1 stop bit +// U0LCR_bit.PE = 0x0; //no parity +// U0LCR_bit.DLAB = 0x1; //enable DLAB + //with one row + U1LCR = 0x83; + + + //devisor + U1DLL = divisor & 0xFF; + U1DLM = (divisor >> 8) & 0xFF; + U1LCR &= ~0x80; + + //set functionalite to pins: port0.0 -> TX0, port0.1 -> RXD0 +// PINSEL0_bit.P0_0 = 0x1; +// PINSEL0_bit.P0_1 = 0x1; + //with one row + PINSEL0 |= BIT16; + PINSEL0 &= ~BIT17; + +} + +void UART1WriteChar(int ch0) +{ + while (!(U1LSR & BIT5)); + U1THR = ch0; +} + +unsigned char UART0ReadChar(void) +{ + //when U0LSR_bit.DR is 1 - U0RBR contains valid data +// while (U0LSR_bit.DR == 0); + return U0RBR; +} + + diff --git a/olimex_lpc2148/tick.c b/olimex_lpc2148/tick.c new file mode 100644 index 000000000..08b3dcb0b --- /dev/null +++ b/olimex_lpc2148/tick.c @@ -0,0 +1,63 @@ +/* Copyright (C) 2005, 2006, 2007, 2008 by Thomas Hillebrandt and Heiko Will + +This file is part of the Micro-mesh SensorWeb Firmware. + +Micro-Mesh is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +Micro-Mesh is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Micro-Mesh; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "lpc214x.h" +#include "bits.h" +//#include "tick.h" +#include "minimal_dbg_console.h" +#include "VIC.h" + +void Timer0_IRQHandler (void) __attribute__((interrupt("IRQ"))); + +extern void eINT(); +extern void dINT(); + + +void driver_timer_load(void) +{ + T0TCR = 0; // Disable timer 0. + T0PR = 3000; // Prescaler is set to relevant pclk , counter is incremented every T0PR tact. + T0CCR = 0; // Capture is disabled. + T0EMR = 0; // No external match output. + T0TC= 0; + T0MR0= 1000; + T0MCR|= BIT0 + BIT1; + T0TCR = BIT0; // Enable timer 0. + + dINT(); // Disable all interrupts + VICIntEnable = BIT4; // Enable Interrupthandling for Timer0 + VICVectCntl3 = 4 + BIT5; // Assign Timer0 to IRQ Slot 3 + VICVectAddr3 = (unsigned int)Timer0_IRQHandler; // Assign Isr Address + eINT(); +} + +int counter = 0; + +void Timer0_IRQHandler (void) +{ + extern unsigned int fk_context_switch_request; + counter++; + T0IR |= 0xff; // reset timer1 interrupt flag + sl_printf("#"); + + fk_context_switch_request = 1; + + VICVectAddr = 0; // acknowledge interrupt (if using VIC IRQ) +} + diff --git a/olimex_lpc2148/tools/lpc2148_flash.gdb b/olimex_lpc2148/tools/lpc2148_flash.gdb new file mode 100644 index 000000000..cb308752a --- /dev/null +++ b/olimex_lpc2148/tools/lpc2148_flash.gdb @@ -0,0 +1,22 @@ +#winheight regs 11 +set history save on +set history size 1000 +target remote localhost:3333 +monitor reset +monitor sleep 100 +monitor halt +monitor poll +#monitor arm7_9 sw_bkpts disable +#monitor arm7_9 force_hw_bkpts enable +monitor mww 0xE01FC040 0x0001 +monitor mdw 0xE01FC040 +monitor flash erase_sector 0 0 14 +#monitor flash auto_erase on +monitor flash erase_check 0 +#monitor flash write_image /home/kaspar/FeuerWhere/src/x/bin/arm.elf +set remote hardware-watchpoint-limit 2 +load +break bootloader +mon soft_reset_halt +continue +d b 1 diff --git a/pttu/Jamfile b/pttu/Jamfile new file mode 100644 index 000000000..a7b4d6df1 --- /dev/null +++ b/pttu/Jamfile @@ -0,0 +1,35 @@ +# ****************************************************************************** +# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved. +# +# These sources were developed at the Freie Universitaet Berlin, Computer +# Systems and Telematics group (http://cst.mi.fu-berlin.de). +# ------------------------------------------------------------------------------ +# This file is part of FeuerWare. +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# FeuerWare is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see http://www.gnu.org/licenses/ . +# ------------------------------------------------------------------------------ +# For further information and questions please use the web site +# http://scatterweb.mi.fu-berlin.de +# and the mailinglist (subscription via web site) +# scatterweb@lists.spline.inf.fu-berlin.de +# ****************************************************************************** +# $Id: Jamfile 922 2009-03-26 12:52:27Z baar $ + +SubDir TOP board pttu ; + +Module board : board_init.c ; +UseModule board ; +UseModule board_common ; + +SubInclude TOP board $(BOARD) drivers ; +SubInclude TOP cpu $(CPU) ; diff --git a/pttu/Jamfile.pttu b/pttu/Jamfile.pttu new file mode 100644 index 000000000..1bce8934f --- /dev/null +++ b/pttu/Jamfile.pttu @@ -0,0 +1,28 @@ +# ****************************************************************************** +# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved. +# +# These sources were developed at the Freie Universitaet Berlin, Computer +# Systems and Telematics group (http://cst.mi.fu-berlin.de). +# ------------------------------------------------------------------------------ +# This file is part of FeuerWare. +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# FeuerWare is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see http://www.gnu.org/licenses/ . +# ------------------------------------------------------------------------------ +# For further information and questions please use the web site +# http://scatterweb.mi.fu-berlin.de +# and the mailinglist (subscription via web site) +# scatterweb@lists.spline.inf.fu-berlin.de +# ****************************************************************************** +# $Id: Jamfile.msba2 832 2009-03-13 16:45:41Z kaspar $ + +include [ FPath $(TOP) cpu arm_common Jamfile.arm_common ] ; diff --git a/pttu/Jamrules.pttu b/pttu/Jamrules.pttu new file mode 100644 index 000000000..7eff15f0b --- /dev/null +++ b/pttu/Jamrules.pttu @@ -0,0 +1,37 @@ +# ****************************************************************************** +# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved. +# +# These sources were developed at the Freie Universitaet Berlin, Computer +# Systems and Telematics group (http://cst.mi.fu-berlin.de). +# ------------------------------------------------------------------------------ +# This file is part of FeuerWare. +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# FeuerWare is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see http://www.gnu.org/licenses/ . +# ------------------------------------------------------------------------------ +# For further information and questions please use the web site +# http://scatterweb.mi.fu-berlin.de +# and the mailinglist (subscription via web site) +# scatterweb@lists.spline.inf.fu-berlin.de +# ****************************************************************************** +# $Id: Jamrules.msba2 881 2009-03-20 12:24:58Z kaspar $ + +CPU = lpc2387 ; + +HDRS += [ FPath $(TOP) board $(BOARD) drivers include ] ; + +FLASHER = $(POSIXSHELL) $(TOP)/board/msba2/tools/flashutil.sh ; +FLASHFLAGS = --basedir $(TOP)/board/msba2/tools --id PTTU --ports "$(PORT)" --openocd $(TOP)/board/pttu/tools/openocd-pttu.sh --openocd-if $(OPENOCD_IF) ; + +GDB = arm-elf-gdb ; +GDBFLAGS = -x board/pttu/tools/pttu_debug.gdb ; + diff --git a/pttu/board_init.c b/pttu/board_init.c new file mode 100644 index 000000000..3070bdfce --- /dev/null +++ b/pttu/board_init.c @@ -0,0 +1,239 @@ +/****************************************************************************** +Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved. + +These sources were developed at the Freie Universitaet Berlin, Computer Systems +and Telematics group (http://cst.mi.fu-berlin.de). +------------------------------------------------------------------------------- +This file is part of FeuerWare. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +FeuerWare is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see http://www.gnu.org/licenses/ . +-------------------------------------------------------------------------------- +For further information and questions please use the web site + http://scatterweb.mi.fu-berlin.de +and the mailinglist (subscription via web site) + scatterweb@lists.spline.inf.fu-berlin.de +*******************************************************************************/ + +/** + * @ingroup pttu + * @{ + */ + +/** + * @file + * @brief PTTU board initialization + * + * @author Freie Universit�t Berlin, Computer Systems & Telematics, FeuerWhere project + * @author Heiko Will + * @author Kaspar Schleise + * @author Michael Baar + * + * @note $Id: cmdengine-out.c 971 2009-04-07 13:41:36Z baar $ + */ +#include "lpc23xx.h" +#include "VIC.h" +#include "cpu.h" + +#define PCRTC BIT9 +#define CL_CPU_DIV 4 + +/*---------------------------------------------------------------------------*/ +/** + * @brief Enabling MAM and setting number of clocks used for Flash memory fetch + * @internal + */ +void +init_mam(void) +{ + MAMCR = 0x0000; + MAMTIM = 0x0003; + MAMCR = 0x0002; +} +/*---------------------------------------------------------------------------*/ +static inline void +pllfeed(void) +{ + PLLFEED = 0xAA; + PLLFEED = 0x55; +} +/*---------------------------------------------------------------------------*/ +void init_clks1(void) +{ + // Disconnect PLL + PLLCON &= ~0x0002; + pllfeed(); + + // Disable PLL + PLLCON &= ~0x0001; + pllfeed(); + + SCS |= 0x20; // Enable main OSC + while( !(SCS & 0x40) ); // Wait until main OSC is usable + + /* select main OSC, 16MHz, as the PLL clock source */ + CLKSRCSEL = 0x0001; + + // Setting Multiplier and Divider values + PLLCFG = 0x0008; // M=9 N=1 Fcco = 288 MHz + pllfeed(); + + // Enabling the PLL */ + PLLCON = 0x0001; + pllfeed(); + + /* Set clock divider to 4 (value+1) */ + CCLKCFG = CL_CPU_DIV - 1; // Fcpu = 72 MHz + +#if USE_USB + USBCLKCFG = USBCLKDivValue; /* usbclk = 288 MHz/6 = 48 MHz */ +#endif +} + +void init_clks2(void){ + // Wait for the PLL to lock to set frequency + while(!(PLLSTAT & BIT26)); + + // Connect the PLL as the clock source + PLLCON = 0x0003; + pllfeed(); + + /* Check connect bit status */ + while (!(PLLSTAT & BIT25)); +} + +void bl_init_clks(void) +{ + PCONP = PCRTC; // switch off everything except RTC + init_clks1(); + init_clks2(); + init_mam(); +} + + +// Michael, Do not change anything here! even not the redundant parts! +void bl_init_ports(void) +{ + SCS |= BIT0; // Set IO Ports to fast switching mode + + /* UART0 */ + PINSEL0 |= BIT4 + BIT6; // RxD0 and TxD0 + PINSEL0 &= ~(BIT5 + BIT7); + + /*Turn Board on*/ + PINMODE0 |= BIT1; + FIO0DIR |= BIT27; + FIO0CLR = BIT27; + + /* 5V*/ + FIO1DIR |= BIT28; // Synch + FIO1SET = BIT28; // No Powersave + + FIO1DIR |= BIT27; // 5V off + FIO1CLR = BIT27; + + /* Disable Resistors on Buttons */ + PINMODE4 |= BIT9 + BIT11; + + /* Disable Resistors on LED - and Ports to output*/ + PINMODE7 |= BIT19 + BIT21; + PINMODE2 |= BIT1; + FIO1DIR |= BIT0; + FIO3DIR |= BIT25 + BIT26; + FIO1SET = BIT0; + FIO3SET = BIT25 + BIT26; + + // Config and Disable PA + FIO1DIR |= BIT25 + BIT26 + BIT22; + FIO1SET = BIT26; + FIO1CLR = BIT25; + FIO1CLR = BIT22; // PA /Shutdown + FIO0DIR |= BIT26; // ** // Important: First put this Port as DA 2.0V and then turn on PA!! + FIO0SET = BIT26; // ** + + // Configure GPS + PINMODE3 |= BIT3 + BIT7; // No Pullup on 1.17 & 1.19 + PINMODE9 |= BIT27 + BIT25; // No Pullup for Uart + FIO1DIR |= BIT17; + FIO1CLR = BIT17; // Turn off GPS + FIO1DIR |= BIT19; + FIO1CLR = BIT19; // Hold in Reset + PINSEL9 |= BIT24 + BIT25 + BIT26 + BIT27; //4.28 & 4.29 as Uart3 + + // Nanotron + FIO2DIR &= ~BIT8; // nanotron uC IRQ as input + FIO1DIR |= BIT15; // nanotron power on reset + FIO1DIR &= ~BIT14; // nanotron uC RESET as input + FIO1DIR &= ~BIT10; // nanotron uC Vcc as input + FIO1DIR |= BIT9; // nanotron ENABLE as output + FIO1DIR &= ~BIT4; // nanotron Rx/Tx as input + + FIO1CLR = BIT15; + FIO1CLR = BIT9; // Enable power + + PINMODE1 |= BIT1; // No Pullup for CS + FIO0DIR |= BIT16; // CS as output + FIO0SET = BIT16; // drive cs inactive + FIO0DIR |= BIT18 + BIT15; // SPi Output + + // RFID + FIO1DIR |= BIT1; // RFID Power + FIO1CLR = BIT1; // + + FIO0DIR |= BIT1; // RFID Reset + FIO0SET = BIT1; // Hold in Reset + + FIO0DIR &= ~BIT10; // LED as INPUT + FIO0DIR &= ~BIT11; // DATA as INPUT + PINMODE0 |= BIT19 + BIT21; // No Pullups + + // LTC4150 ARM + FIO0DIR |= BIT5; + FIO0CLR = BIT5; + + // LTC4150 System + FIO0DIR |= BIT24; + FIO0CLR = BIT24; + + // Battery Voltage (AD) + PINMODE1 |= BIT19; + PINSEL1 &= ~BIT19; + PINSEL1 |= BIT18; + + //cc1100 + FIO0DIR |= BIT6 + BIT7 + BIT9; + FIO0SET = BIT6; + FIO0SET = BIT7 + BIT9; + + //SD + FIO2DIR |= BIT12 + BIT13 + BIT11; + FIO0DIR |= BIT20 + BIT22 + BIT21; + + //Tetra + FIO2DIR |= BIT0 + BIT7; + + + // No Pullups on any port + int nopullup = BIT1 + BIT3 + BIT5 + BIT7 + BIT9 + BIT11 + BIT13 + BIT15 + BIT17 + BIT19 + BIT21 + BIT23 + BIT25 + BIT27 + BIT29 + BIT31; + PINMODE0 = nopullup - BIT13 - BIT15 - BIT17 - BIT19; + PINMODE1 = BIT1 + BIT3 + BIT5 + BIT7 + BIT9 + BIT11 + BIT13 + BIT15 + BIT17 + BIT19 + BIT21; + PINMODE2 = nopullup; + PINMODE3 = nopullup; + PINMODE4 = nopullup; + PINMODE5 = nopullup; + PINMODE6 = nopullup; + PINMODE7 = nopullup; + PINMODE8 = nopullup; + PINMODE9 = nopullup; +} + +/** @} */ diff --git a/pttu/drivers/Jamfile b/pttu/drivers/Jamfile new file mode 100644 index 000000000..26a8b7c2a --- /dev/null +++ b/pttu/drivers/Jamfile @@ -0,0 +1,4 @@ +SubDir TOP board pttu drivers ; + +Module board_common : pttu-uart0.c ; + diff --git a/pttu/drivers/pttu-uart0.c b/pttu/drivers/pttu-uart0.c new file mode 100644 index 000000000..d542f2260 --- /dev/null +++ b/pttu/drivers/pttu-uart0.c @@ -0,0 +1,204 @@ +/****************************************************************************** +Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved. + +These sources were developed at the Freie Universitaet Berlin, Computer Systems +and Telematics group (http://cst.mi.fu-berlin.de). +------------------------------------------------------------------------------- +This file is part of FeuerWare. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +FeuerWare is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see http://www.gnu.org/licenses/ . +-------------------------------------------------------------------------------- +For further information and questions please use the web site + http://scatterweb.mi.fu-berlin.de +and the mailinglist (subscription via web site) + scatterweb@lists.spline.inf.fu-berlin.de +*******************************************************************************/ + +/* + * debug_uart.c: provides initial serial debug output + * + * Copyright (C) 2008, 2009 Kaspar Schleiser + * Heiko Will + */ +#include +#include +#include +#include "lpc23xx.h" +#include "VIC.h" + +/** + * @file + * @ingroup lpc2387 + * + * @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project + * @version $Revision$ + * + * @note $Id$ + */ + +typedef struct toprint { + unsigned int len; + char content[]; +}toprint; + +#define QUEUESIZE 255 +static volatile toprint* queue[QUEUESIZE]; +static volatile unsigned char queue_head = 0; +static volatile unsigned char queue_tail = 0; +static volatile unsigned char queue_items = 0; + +static volatile unsigned int actual_pos = 0; +static volatile unsigned int running = 0; +static volatile unsigned int fifo = 0; + +static volatile toprint* actual = NULL; +void (*uart0_callback)(int); + +static inline void enqueue(void) { + queue_items++; + queue_tail++; +} + +static inline void dequeue(void) { + actual = (queue[queue_head]); + queue_items--; + queue_head++; +} + +static void push_queue(void) { + running = 1; +start: + if (!actual) { + if (queue_items) { + dequeue(); + } else { + running = 0; + if (!fifo) + while(!(U0LSR & BIT6)){}; + return; + } + } + while ((actual_pos < actual->len) && (fifo++ < 16)){ + U0THR = actual->content[actual_pos++]; + } + if (actual_pos == actual->len) { + free((void*)actual); + actual = NULL; + actual_pos = 0; + goto start; + } +} + +int uart_active(void){ + return (running || fifo); +} + +static inline void receive(int c) +{ + if (uart0_callback != NULL) uart0_callback(c); +} + +void stdio_flush(void) +{ + U0IER &= ~BIT1; // disable THRE interrupt + while(running) { + while(!(U0LSR & (BIT5|BIT6))){}; // transmit fifo + fifo=0; + push_queue(); // dequeue to fifo + } + U0IER |= BIT1; // enable THRE interrupt +} + +void UART0_IRQHandler(void) __attribute__((interrupt("IRQ"))); +void UART0_IRQHandler(void) +{ + int iir; + iir = U0IIR; + + switch(iir & UIIR_ID_MASK) { + case UIIR_THRE_INT: // Transmit Holding Register Empty + fifo=0; + push_queue(); + break; + + case UIIR_CTI_INT: // Character Timeout Indicator + case UIIR_RDA_INT: // Receive Data Available + do { + int c = U0RBR; + receive(c); + } while (U0LSR & ULSR_RDR); + break; + + default: + U0LSR; + U0RBR; + break; + } // switch + VICVectAddr = 0; // Acknowledge Interrupt +} + +static inline int uart0_puts(char *astring,int length) +{ + while (queue_items == (QUEUESIZE-1)) {} ; + U0IER = 0; + queue[queue_tail] = malloc(length+sizeof(unsigned int)); + queue[queue_tail]->len = length; + memcpy(&queue[queue_tail]->content,astring,length); + enqueue(); + if (!running) + push_queue(); + U0IER |= BIT0 | BIT1; // enable RX irq + + // alternative without queue: +// int i; +// for (i=0;iconfig->speed + /* + * Baudrate calculation + * BR = PCLK (9 MHz) / (16 x 256 x DLM + DLL) x (1/(DIVADDVAL/MULVAL)) + */ + U0FDR = 0x92; // DIVADDVAL = 0010 = 2, MULVAL = 1001 = 9 + U0DLM = 0x00; + U0DLL = 0x04; + + U0LCR = 0x03; // DLAB = 0 + U0FCR = 0x07; // Enable and reset TX and RX FIFO + + /* irq */ + install_irq(UART0_INT, UART0_IRQHandler, 6); + U0IER |= BIT0 | BIT1; // enable RX+TX irq + return 1; +} + diff --git a/pttu/include/board.h b/pttu/include/board.h new file mode 100644 index 000000000..850f8d1d1 --- /dev/null +++ b/pttu/include/board.h @@ -0,0 +1,56 @@ +/****************************************************************************** +Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved. + +These sources were developed at the Freie Universitaet Berlin, Computer Systems +and Telematics group (http://cst.mi.fu-berlin.de). +------------------------------------------------------------------------------- +This file is part of FeuerWare. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +FeuerWare is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see http://www.gnu.org/licenses/ . +-------------------------------------------------------------------------------- +For further information and questions please use the web site + http://scatterweb.mi.fu-berlin.de +and the mailinglist (subscription via web site) + scatterweb@lists.spline.inf.fu-berlin.de +*******************************************************************************/ + +#ifndef __BOARD_H +#define __BOARD_H + +/** + * @ingroup pttu + * @{ + */ + +/** + * @file + * @brief PTTU Board + * + * @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project + * @author Kaspar Schleiser + * @version $Revision$ + * + * @note $Id: board.h 664 2009-02-19 10:54:44Z baar $ + */ + +#include +#include + +#define VICIntEnClear VICIntEnClr + +void init_clks1(void); +void init_clks2(void); +void bl_init_clks(void); + +/** @} */ +#endif // __BOARD_H diff --git a/pttu/tools/jtag.txt b/pttu/tools/jtag.txt new file mode 100644 index 000000000..586eea674 --- /dev/null +++ b/pttu/tools/jtag.txt @@ -0,0 +1,14 @@ +compile openocd release v0.1: +[extract to somewhere] +./configure --prefix=CHANGEMEtowhatever --enable-ft2232_libftdi +make +make install + +to flash run from within board/pttu/tools: +./openocd-pttu.sh olimex-usb-jtag-tiny-a "mt_flash CHANGEME/absolute/path/to/hexfile/pttu.hex;shutdown" + + +to debug, first start the following from within board/pttu/tools: +./openocd-pttu.sh olimex-usb-jtag-tiny-a + +then just run "jam debug". this will flash bin/pttu.hex, run it and stop at the bootloader. diff --git a/pttu/tools/olimex-arm-usb-ocd.cfg b/pttu/tools/olimex-arm-usb-ocd.cfg new file mode 100644 index 000000000..0aaba1d2b --- /dev/null +++ b/pttu/tools/olimex-arm-usb-ocd.cfg @@ -0,0 +1,9 @@ +# +set CPUTAPID 0x4f1f0f0f + +jtag_speed 100 + +source [find interface/olimex-arm-usb-ocd.cfg] +#source [find target/lpc2148.cfg] +source lpc2378.cfg + diff --git a/pttu/tools/openocd-pttu.cfg b/pttu/tools/openocd-pttu.cfg new file mode 100644 index 000000000..b58392f1e --- /dev/null +++ b/pttu/tools/openocd-pttu.cfg @@ -0,0 +1,75 @@ +###### +# parts taken from Martin Thomas +# http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/openocd_intro/index.html +# + +set CPUTAPID 0x4f1f0f0f +jtag_speed 100 + +source [find cpu/lpc2387/tools/openocd-lpc2387.cfg] + +fast disable + +# +# scipts/macros/user commands - this is TCL (variant JIM): +# +proc mt_internal_rc {} { + jtag_khz 100 + reset run + sleep 100 + reset + halt + wait_halt 2 + # PLL disconnect PLLCON + mww 0xE01FC080 0x01 + mww 0xE01FC08C 0xAA + mww 0xE01FC08C 0x55 + # PLL disable PLLCON + mww 0xE01FC080 0x00 + mww 0xE01FC08C 0xAA + mww 0xE01FC08C 0x55 + # no prescaler CCLKCFG + mww 0xE01FC104 0x00 + # internal RC CLKSRCSEL + mww 0xE01FC10C 0x00 + #### main oscil. CLKSRCSEL + #### mww 0xE01FC10C 0x01 + # remap to internal flash + mww 0xE01FC040 0x01 + sleep 100 + jtag_khz 500 + flash probe 0 +} + +proc mt_flash_bin {IMGFILE OFFSET} { + mt_internal_rc + flash write_image erase $IMGFILE $OFFSET + sleep 100 + verify_image $IMGFILE $OFFSET + sleep 100 +} + +proc mt_flash_v {IMGFILE} { + mt_internal_rc + flash write_image erase $IMGFILE + sleep 100 + verify_image $IMGFILE + sleep 100 +} + +proc mt_flash {IMGFILE} { + mt_internal_rc + flash write_image erase $IMGFILE +} + +flash bank lpc2000 0x0 0x7d000 0 0 0 lpc2000_v2 4000 calc_checksum + +arm7_9 dcc_downloads enable + +gdb_flash_program enable + +init + +fast enable +jtag_khz 500 +debug_level 1 diff --git a/pttu/tools/openocd-pttu.sh b/pttu/tools/openocd-pttu.sh new file mode 100755 index 000000000..95f11fa14 --- /dev/null +++ b/pttu/tools/openocd-pttu.sh @@ -0,0 +1,30 @@ +#/bin/bash + +if [ $# -le 0 ]; then + echo "usage: $0 [openocd interface name] [openocd args]" >&2 + echo " common interfaces: olimex-arm-usb-ocd olimex-jtag-tiny olimex-jtag-tiny-a" + echo "" + echo "using default olimex-jtag-tiny-a" + INTERFACE=olimex-jtag-tiny-a +else + INTERFACE=$1 + shift +fi + +if [ $# -ge 1 ]; then + COMMAND=$@ +else + COMMAND="debug_level 1" +fi + +if [ "${OS}" = "Windows_NT" ]; then + WINDOWS=1 +fi + +if [ "x${WINDOWS}x" = "xx" ]; then + xterm -e "openocd -s ../../.. -f interface/${INTERFACE}.cfg -f board/pttu/tools/openocd-pttu.cfg -c \"${COMMAND}\"|| read" & +else + echo ${COMMAND} + #cmd /C start "OpenOCD PTTU using ${INTERFACE}" + openocd-ftd2xx.exe -s ../../.. -f interface/${INTERFACE}.cfg -f board/pttu/tools/openocd-pttu.cfg -c "${COMMAND}" +fi diff --git a/pttu/tools/pttu_debug.gdb b/pttu/tools/pttu_debug.gdb new file mode 100644 index 000000000..2c8ec0df1 --- /dev/null +++ b/pttu/tools/pttu_debug.gdb @@ -0,0 +1,15 @@ +#winheight regs 11 +set history save on +set history size 1000 +target remote localhost:3333 +monitor mt_internal_rc +load +compare-sections +monitor soft_reset_halt +set mem inaccessible-by-default off +monitor debug_level 0 + +break bootloader +continue +d b 1 +