diff options
Diffstat (limited to 'avr')
-rw-r--r-- | avr/env.c | 39 | ||||
-rw-r--r-- | avr/i2c.c | 91 | ||||
-rw-r--r-- | avr/main.c | 85 |
3 files changed, 125 insertions, 90 deletions
@@ -775,28 +775,41 @@ int setenv_hex(const char *varname, unsigned long value) return setenv(varname, str); } + /** - * Get an environment variable as a hex value + * Decode the integer value of an environment variable and return it. * - * @param varname Environment variable to get - * @param default_val Return this, if variable does not exist - * @return hex value of variable or default_val + * @param name Name of environemnt variable + * @param base Number base to use (normally 10, or 16 for hex) + * @param default_val Default value to return if the variable is not + * found + * @return the decoded value, or default_val if not found */ -unsigned long getenv_hex(const char *varname, unsigned long default_val) +unsigned long getenv_ulong(const char *name, int base, unsigned long default_val) { - const char *s; + char buf[16]; unsigned long value; - char *endp; + char *vp, *endp; + + env_item_t *ep = envlist_search(name); - s = getenv(varname); - if (s) - value = strtoul(s, &endp, 16); - if (!s || endp == s) - return default_val; + if (ep != NULL ) { + if (ep->flags & EF_V_EEP) { + varval_get(buf, ep->val.eep, sizeof(buf)); + vp = buf; + } else + vp = ep->val.ram; + if (vp != NULL) { + value = strtoul(vp, &endp, base); + if (endp != vp) + return value; + } + } - return value; + return default_val; } + command_ret_t do_env_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { (void) cmdtp; @@ -99,12 +99,17 @@ uint8_t buf[CONFIG_SYS_I2C_BUFSIZE]; } i2c_msg_t; -static i2c_msg_t xmit; +static volatile i2c_msg_t xmit; ISR(TWI_vect) { - uint8_t next_twcr; + uint8_t tmp_stat; uint8_t tmp_idx; + uint8_t next_twcr; + uint8_t n; + + tmp_idx = xmit.idx; + tmp_stat = xmit.stat; uint8_t twsr = TWSR; @@ -112,62 +117,59 @@ ISR(TWI_vect) case TWI_START: case TWI_REP_START: - xmit.idx = 0; /* reset xmit_buf index */ - xmit.stat = BUSY | START; + tmp_stat = BUSY | START; + tmp_idx = 0; /* reset xmit_buf index */ - tmp_idx = xmit.idx; if (tmp_idx < xmit.len) { /* all bytes transmited? */ TWDR = xmit.buf[tmp_idx]; - xmit.idx = ++tmp_idx; + ++tmp_idx; next_twcr = (1<<TWEN)|(1<<TWIE)|(1<<TWINT); } else { - xmit.stat |= XMIT_DONE; - xmit.stat &= ~BUSY; + tmp_stat |= XMIT_DONE; + tmp_stat &= ~BUSY; next_twcr = (1<<TWEN)|(0<<TWIE)|(1<<TWINT)|(1<<TWSTO); } break; case TWI_MTX_ADR_ACK: - xmit.stat |= ADDR_ACK; + tmp_stat |= ADDR_ACK; - tmp_idx = xmit.idx; if (tmp_idx < xmit.len) { /* all bytes transmited? */ TWDR = xmit.buf[tmp_idx]; - xmit.idx = ++tmp_idx; + ++tmp_idx; next_twcr = (1<<TWEN)|(1<<TWIE)|(1<<TWINT); } else { - xmit.stat |= XMIT_DONE; - xmit.stat &= ~BUSY; + tmp_stat |= XMIT_DONE; + tmp_stat &= ~BUSY; next_twcr = (1<<TWEN)|(0<<TWIE)|(1<<TWINT)|(1<<TWSTO); } break; case TWI_MTX_DATA_ACK: - xmit.stat |= DATA_ACK; + tmp_stat |= DATA_ACK; - tmp_idx = xmit.idx; if (tmp_idx < xmit.len) { /* all bytes transmited? */ TWDR = xmit.buf[tmp_idx]; - xmit.idx = ++tmp_idx; + ++tmp_idx; next_twcr = (1<<TWEN)|(1<<TWIE)|(1<<TWINT); } else { - xmit.stat |= XMIT_DONE; - xmit.stat &= ~BUSY; + tmp_stat |= XMIT_DONE; + tmp_stat &= ~BUSY; next_twcr = (1<<TWEN)|(0<<TWIE)|(1<<TWINT)|(1<<TWSTO); } break; case TWI_MTX_DATA_NACK: - xmit.stat |= XMIT_DONE; - xmit.stat &= ~BUSY; + tmp_stat |= XMIT_DONE; + tmp_stat &= ~BUSY; next_twcr = (1<<TWEN)|(0<<TWIE)|(1<<TWINT)|(1<<TWSTO); break; case TWI_MRX_ADR_ACK: - xmit.stat |= ADDR_ACK; - tmp_idx = xmit.idx; - if (tmp_idx < xmit.len-1) { + tmp_stat |= ADDR_ACK; + n = xmit.len-1; + if (tmp_idx < n) { next_twcr = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA); } else { next_twcr = (1<<TWEN)|(1<<TWIE)|(1<<TWINT); @@ -175,11 +177,11 @@ ISR(TWI_vect) break; case TWI_MRX_DATA_ACK: - xmit.stat |= DATA_ACK; - tmp_idx = xmit.idx; + tmp_stat |= DATA_ACK; xmit.buf[tmp_idx] = TWDR; - xmit.idx = ++tmp_idx; - if (tmp_idx < xmit.len-1) { + ++tmp_idx; + n = xmit.len-1; + if (tmp_idx < n) { next_twcr = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA); } else { @@ -188,19 +190,21 @@ ISR(TWI_vect) break; case TWI_MRX_DATA_NACK: - xmit.stat |= ADDR_ACK | DATA_ACK; + tmp_stat |= ADDR_ACK | DATA_ACK; - tmp_idx = xmit.idx; xmit.buf[tmp_idx] = TWDR; - xmit.idx = ++tmp_idx; + ++tmp_idx; /* fall thru */ default: - xmit.stat &= ~BUSY; + tmp_stat &= ~BUSY; next_twcr = (1<<TWEN)|(0<<TWIE)|(1<<TWINT)|(1<<TWSTO); break; } + xmit.stat = tmp_stat; + xmit.idx = tmp_idx; + #ifdef DEBUG_I2C debug("|%02x", twsr); #endif @@ -217,32 +221,37 @@ static uint8_t twbr; static void _init(void) { xmit.stat = 0; -#ifdef DEBUG_I2C - memset((void *) xmit.buf, 0xdf, sizeof(xmit.buf)); -#endif /* Disable TWI, disable TWI interrupt. */ /* (Reset TWI hardware state machine.) */ TWCR = TWI_C_DISABLE; _delay_us(5); +#ifdef DEBUG_I2C + memset((void *) xmit.buf, 0xdf, sizeof(xmit.buf)); +#endif - TWBR = twbr; TWDR = 0xff; - TWCR = TWI_C_ENABLE + twps; + TWBR = twbr; + TWSR = twps & 0x03; + TWCR = TWI_C_ENABLE; } void i2c_init(uint32_t speed) { twps = 0; - uint32_t tmptwbr = F_CPU /2 / speed - 8; + uint32_t tmp_twbr = F_CPU /2 / speed - 8; - while (tmptwbr > 255) { - tmptwbr >>= 4; + while (tmp_twbr > 255) { + tmp_twbr >>= 4; twps += 1; } - debug_cond((twps > 3), "TWCLK too low: %lu Hz\n", speed); + debug_cond((twps > 3), "*** TWCLK too low: %lu Hz\n", speed); + + twbr = (uint8_t) tmp_twbr; + + debug("*** i2c_init: i2c_speed: %lu, twbr: %u, twps: %u\n", + speed, twbr, twps); - twbr = (uint8_t) tmptwbr; _init(); } @@ -19,26 +19,53 @@ #include "cli.h" #include "env.h" +#define udelay(n) _delay_us(n) + +static uint8_t mcusr; + /*--------------------------------------------------------------------------*/ #if DEBUG -void preset_ram (void) __attribute__ ((naked)) \ - __attribute__ ((section (".init3"))); -void -preset_ram (void) + +__attribute__ ((naked)) __attribute__ ((section (".init3"))) +void preset_ram (void) { for (uint8_t *p = RAMSTART; p <= (uint8_t *) RAMEND; p++) *p = 0xdd; } -#endif -/*--------------------------------------------------------------------------*/ -static uint8_t mcusr; +static const FLASH char * const FLASH rreasons[] = { + FSTR("Power on"), + FSTR("External"), + FSTR("Brown out"), + FSTR("Watchdog"), + FSTR("JTAG"), + }; + +static +void print_reset_reason(void) +{ + uint8_t r = mcusr & 0x1f; + const FLASH char * const FLASH *p = rreasons; + + printf_P(PSTR("### Reset reason(s): %s"), r ? "" : "none"); + for ( ; r; p++, r >>= 1) { + if (r & 1) { + my_puts_P(*p); + if (r & ~1) + printf_P(PSTR(", ")); + } + } + printf_P(PSTR(".\n")); +} + +#endif static void setup_avr(void) { /* save and clear reset reason(s) */ + /* TODO: move to init section? */ mcusr = MCUSR; MCUSR = 0; @@ -70,36 +97,13 @@ void setup_avr(void) TIMSK1 = _BV(OCIE1A); // Enable TC1.oca interrupt } -static const FLASH char * const FLASH rreasons[] = { - FSTR("Power on"), - FSTR("External"), - FSTR("Brown out"), - FSTR("Watchdog"), - FSTR("JTAG"), - }; - static -void print_reset_reason(void) +int reset_reason_is_power_on(void) { - uint8_t r = mcusr & 0x1f; - const FLASH char * const FLASH *p = rreasons; - - printf_P(PSTR("Reset reason(s): %s"), r ? "" : "none"); - for ( ; r; p++, r >>= 1) { - if (r & 1) { - my_puts_P(*p); - if (r & ~1) - printf_P(PSTR(", ")); - } - } - printf_P(PSTR(".\n")); + return (mcusr & _BV(PORF)) != 0; } - -/*******************************************************************************/ - -#define udelay(n) _delay_us(n) - +/*--------------------------------------------------------------------------*/ /* Stored value of bootdelay, used by autoboot_command() */ static int stored_bootdelay; @@ -160,8 +164,7 @@ const char *bootdelay_process(void) char *s; int bootdelay; - s = getenv("bootdelay"); - bootdelay = s ? atoi(s) : CONFIG_BOOTDELAY; + bootdelay = (int) getenv_ulong("bootdelay", 10, CONFIG_BOOTDELAY); debug("### main_loop entered: bootdelay=%d\n\n", bootdelay); @@ -199,6 +202,9 @@ int main(void) setup_avr(); z80_setup_bus(); + + if (reset_reason_is_power_on()) + _delay_ms(CONFIG_POWRON_DELAY); serial_setup(); sei(); @@ -209,7 +215,14 @@ int main(void) #endif env_init(); - i2c_init(34920); + +#if DEBUG + unsigned long i_speed = getenv_ulong("i2c_clock", 10, CONFIG_SYS_I2C_CLOCK); + debug("### Setting I2C clock Frequency to %lu Hz.\n", i_speed); + i2c_init(i_speed); +#else + i2c_init(CONFIG_SYS_I2C_CLOCK); +#endif printf_P(PSTR("\n(ATMEGA1281+HD64180)_stamp Tester\n")); |