/* -*- c -*- */ /* * Copyright 2007,2008 Free Software Foundation, Inc. * * 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. * * 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, see . */ // conditionalized on HAL_IO_USES_DBOARD_PINS && HAL_IO_USES_UART #include "hal_io.h" #include "memory_map.h" #include "hal_uart.h" #include #include #include //#include /* * ======================================================================== * GPIOS * ======================================================================== */ void hal_gpio_set_ddr(int bank, int value, int mask) { bank &= 0x1; if (bank == GPIO_TX_BANK){ // tx in top half value <<= 16; mask <<= 16; } else { value &= 0xffff; mask &= 0xffff; } int ei = hal_disable_ints(); gpio_base->ddr = (gpio_base->ddr & ~mask) | (value & mask); hal_restore_ints(ei); } static bool code_to_int(char code, int *val) { switch(code){ case 's': *val = GPIO_SEL_SW; return true; case 'a': *val = GPIO_SEL_ATR; return true; case '0': *val = GPIO_SEL_DEBUG_0; return true; case '1': *val = GPIO_SEL_DEBUG_1; return true; case '.': default: return false; } } void hal_gpio_set_sel(int bank, int bitno, char code) { bank &= 0x1; int t; if (!code_to_int(code, &t)) return; int val = t << (2 * bitno); int mask = 0x3 << (2 * bitno); volatile uint32_t *sel = bank == GPIO_TX_BANK ? &gpio_base->tx_sel : &gpio_base->rx_sel; int ei = hal_disable_ints(); int v = (*sel & ~mask) | (val & mask); *sel = v; hal_restore_ints(ei); if (0) printf("hal_gpio_set_sel(bank=%d, bitno=%d, code=%c) *sel = 0x%x\n", bank, bitno, code, v); } void hal_gpio_set_sels(int bank, char *codes) { //assert(strlen(codes) == 16); int val = 0; int mask = 0; int i; for (i = 15; i >= 0; i--){ val <<= 2; mask <<= 2; int t; if (code_to_int(codes[i], &t)){ val |= t; mask |= 0x3; } } volatile uint32_t *sel = bank == GPIO_TX_BANK ? &gpio_base->tx_sel : &gpio_base->rx_sel; int ei = hal_disable_ints(); *sel = (*sel & ~mask) | (val & mask); hal_restore_ints(ei); } /*! * \brief write \p value to gpio pins specified by \p mask. */ void hal_gpio_write(int bank, int value, int mask) { static uint32_t _gpio_io_shadow; bank &= 0x1; if (bank == GPIO_TX_BANK){ // tx in top half value <<= 16; mask <<= 16; } else { value &= 0xffff; mask &= 0xffff; } //int ei = hal_disable_ints(); _gpio_io_shadow = (_gpio_io_shadow & ~mask) | (value & mask); gpio_base->io = _gpio_io_shadow; //hal_restore_ints(ei); } /*! * \brief read GPIO bits */ int hal_gpio_read(int bank) { bank &= 0x1; int r = gpio_base->io; if (bank == GPIO_TX_BANK) r >>= 16; return r & 0xffff; } /* * ======================================================================== * leds * ======================================================================== */ static unsigned long leds_shadow = 0; static unsigned long led_src_shadow = 0; void hal_set_leds(int value, int mask) { int ei = hal_disable_ints(); leds_shadow = (leds_shadow & ~mask) | (value & mask); output_regs->leds = leds_shadow; hal_restore_ints(ei); } // Allow hardware control over leds. 1 = hardware, 0 = software void hal_set_led_src(int value, int mask) { int ei = hal_disable_ints(); led_src_shadow = (led_src_shadow & ~mask) | (value & mask); output_regs->led_src = led_src_shadow; hal_restore_ints(ei); } void hal_toggle_leds(int mask) { int ei = hal_disable_ints(); leds_shadow ^= mask; output_regs->leds = leds_shadow; hal_restore_ints(ei); } // ================================================================ // primitives // ================================================================ #if defined(HAL_IO_USES_DBOARD_PINS) // // Does i/o using high 9-bits of rx daughterboard pins. // // 1 1 1 1 1 1 // 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | char |W| | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // // // Asserts W when writing char // #define W 0x0080 void hal_io_init(void) { // make high 9 bits of tx daughterboard outputs hal_gpio_set_rx_mode(15, 7, GPIOM_OUTPUT); // and set them to zero hal_gpio_set_rx(0x0000, 0xff80); } void hal_finish(void) { volatile unsigned long *p = (unsigned long *) 0xC2F0; *p = 0; } // %c inline int putchar(int ch) { hal_gpio_set_rx((s << 8) | W, 0xff80); hal_gpio_set_rx(0, 0xff80); return ch; } #elif defined(HAL_IO_USES_UART) void hal_io_init(void) { hal_uart_init(); } void hal_finish(void) { } // %c inline int putchar(int ch) { hal_uart_putc(ch); return ch; } int getchar(void) { return hal_uart_getc(); } #else // nop all i/o void hal_io_init(void) { } void hal_finish(void) { } // %c inline int putchar(int ch) { return ch; } int getchar(void) { return EOF; } #endif // ================================================================ // (slightly) higher level functions // // These are here so we can inline the calls to putchar. // The rest of the stuff was moved to nonstdio.c // ================================================================ // \n inline void newline(void) { putchar('\n'); } int putstr(const char *s) { while (*s) putchar(*s++); return 0; } int puts(const char *s) { putstr(s); putchar('\n'); return 0; }