cyg_bool cyg_hal_plf_duart_getc_timeout(void* __ch_data, cyg_uint8* ch) { int delay_count; channel_data_t* chan = (channel_data_t*)__ch_data; cyg_bool res; CYGARC_HAL_SAVE_GP(); delay_count = chan->msec_timeout * 10; // delay in .1 ms steps for (;;) { res = cyg_hal_plf_duart_getc_nonblock(__ch_data, ch); if (res || 0 == delay_count--) break; CYGACC_CALL_IF_DELAY_US(100); } CYGARC_HAL_RESTORE_GP(); return res; }
cyg_bool CYGOPT_HAL_KINETIS_DIAG_FLASH_SECTION_ATTR cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* p_ch_in) { int delay_count; cyg_bool res; CYGARC_HAL_SAVE_GP(); // delay in .1 ms steps delay_count = ((channel_data_t*)__ch_data)->msec_timeout * 10; for(;;) { res = cyg_hal_plf_serial_getc_nonblock(__ch_data, p_ch_in); if (res || 0 == delay_count--) break; CYGACC_CALL_IF_DELAY_US(100); } CYGARC_HAL_RESTORE_GP(); return res; }
/* * Deal with an overflow condition. This code follows the procedure set * out in section 7.0 of the datasheet. */ static void dp83902a_Overflow(void) { struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)&nic; u8 *base = dp->base; u8 isr; /* Issue a stop command and wait 1.6ms for it to complete. */ DP_OUT(base, DP_CR, DP_CR_STOP | DP_CR_NODMA); CYGACC_CALL_IF_DELAY_US(1600); /* Clear the remote byte counter registers. */ DP_OUT(base, DP_RBCL, 0); DP_OUT(base, DP_RBCH, 0); /* Enter loopback mode while we clear the buffer. */ DP_OUT(base, DP_TCR, DP_TCR_LOCAL); DP_OUT(base, DP_CR, DP_CR_START | DP_CR_NODMA); /* * Read in as many packets as we can and acknowledge any and receive * interrupts. Since the buffer has overflowed, a receive event of * some kind will have occured. */ dp83902a_RxEvent(); DP_OUT(base, DP_ISR, DP_ISR_RxP|DP_ISR_RxE); /* Clear the overflow condition and leave loopback mode. */ DP_OUT(base, DP_ISR, DP_ISR_OFLW); DP_OUT(base, DP_TCR, DP_TCR_NORMAL); /* * If a transmit command was issued, but no transmit event has occured, * restart it here. */ DP_IN(base, DP_ISR, isr); if (dp->tx_started && !(isr & (DP_ISR_TxP|DP_ISR_TxE))) { DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START); } }
externC bool hal_ppc405_i2c_get_bytes(int addr, cyg_uint8 *val, int len) { cyg_uint8 stat, extstat, _val, cmd; int i, j, size; for (i = 0; i < len; i += size) { cmd = IIC0_CNTL_RW_READ|IIC0_CNTL_PT; size = (len - i); if (size > 4) { size = 4; cmd |= IIC0_CNTL_CHT; } cmd |= ((size-1)<<IIC0_CNTL_TCT_SHIFT); HAL_WRITE_UINT8(IIC0_LMADR, addr); HAL_WRITE_UINT8(IIC0_CNTL, cmd); while (true) { CYGACC_CALL_IF_DELAY_US(10); // 10us HAL_READ_UINT8(IIC0_STS, stat); if ((stat & IIC0_STS_PT) == 0) { if ((stat & IIC0_STS_ERR) != 0) { // Some sort of error HAL_READ_UINT8(IIC0_EXTSTS, extstat); HAL_WRITE_UINT8(IIC0_EXTSTS, extstat); HAL_WRITE_UINT8(IIC0_MDCNTL, (IIC0_MDCNTL_FSDB|IIC0_MDCNTL_FMDB)); HAL_WRITE_UINT8(IIC0_STS, (IIC0_STS_SCMP|IIC0_STS_IRQA)); diag_printf("%s addr: %x, len: %d, err: %x/%x\n", __FUNCTION__, addr, len, stat, extstat); return false; } break; } } for (j = 0; j < size; j++) { HAL_READ_UINT8(IIC0_MDBUF, _val); val[i+j] = _val; } } return true; }
static bool ics189x_stat(eth_phy_access_t *f, int *state) { unsigned short phy_state; int tries; // Read negotiated state from the Quick Poll Detailed Status Register if (_eth_phy_read(f, 17, f->phy_addr, &phy_state)) { if ((phy_state & Bit(4)) == 0) { eth_phy_printf("... waiting for auto-negotiation"); for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME; tries++) { if (_eth_phy_read(f, 17, f->phy_addr, &phy_state)) { if ((phy_state & Bit(4)) != 0) { break; } } CYGACC_CALL_IF_DELAY_US(1000000); // 1 second eth_phy_printf("."); } eth_phy_printf("\n"); } if ((phy_state & Bit(4)) != 0) { *state = 0; if (phy_state & Bit(0)) *state |= ETH_PHY_STAT_LINK; if (phy_state & Bit(14)) *state |= ETH_PHY_STAT_FDX; if (phy_state & Bit(15)) *state |= ETH_PHY_STAT_100MB; return true; } } return false; }
cyg_bool cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch) { int delay_count; channel_data_t* chan; cyg_bool res; // Some of the diagnostic print code calls through here with no idea what the ch_data is. // Go ahead and assume it is channels[0]. if (__ch_data == 0) __ch_data = (void*)&channels[0]; chan = (channel_data_t*)__ch_data; delay_count = chan->msec_timeout; // delay in 1000 us steps for(;;) { res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch); if (res || 0 == delay_count--) break; CYGACC_CALL_IF_DELAY_US(1000); } return res; }
/* This function is called as a result of the "eth_drv_recv()" call above. It's job is to actually fetch data for a packet from the hardware once memory buffers have been allocated for the packet. Note that the buffers may come in pieces, using a scatter-gather list. This allows for more efficient processing in the upper layers of the stack. */ static void dp83902a_recv(unsigned char *data, int len) { struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; cyg_uint8 *base = dp->base; int i, mlen; cyg_uint8 saved_char = 0; bool saved; #if DEBUG & 4 int dx; #endif DEBUG_FUNCTION(); #if DEBUG & 5 printf("Rx packet %d length %d\n", dp->rx_next, len); #endif /* Read incoming packet data */ DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); DP_OUT(base, DP_RBCL, len & 0xFF); DP_OUT(base, DP_RBCH, len >> 8); DP_OUT(base, DP_RSAL, 4); /* Past header */ DP_OUT(base, DP_RSAH, dp->rx_next); DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */ DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START); #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA CYGACC_CALL_IF_DELAY_US(10); #endif saved = false; for (i = 0; i < 1; i++) { if (data) { mlen = len; #if DEBUG & 4 printf(" sg buf %08lx len %08x \n", (unsigned long) data, mlen); dx = 0; #endif while (0 < mlen) { /* Saved byte from previous loop? */ if (saved) { *data++ = saved_char; mlen--; saved = false; continue; } { cyg_uint8 tmp; DP_IN_DATA(dp->data, tmp); #if DEBUG & 4 printf(" %02x", tmp); if (0 == (++dx % 16)) printf("\n "); #endif *data++ = tmp;; mlen--; } } #if DEBUG & 4 printf("\n"); #endif } } }
static inline void dm9000_reset(struct dm9000 *p) { putreg(p, DM_NCR, NCR_RST); CYGACC_CALL_IF_DELAY_US(100); }
void eth_drv_write(char *eth_hdr, char *buf, int len) { struct eth_drv_sg sg_list[MAX_ETH_DRV_SG]; struct eth_drv_sc *sc = __local_enet_sc; int sg_len = 2; void *dbg = CYGACC_CALL_IF_DBG_DATA(); int old_state; int wait_time = 5; // Timeout before giving up void *eth_drv_old = 0; if (dbg) { sc = (struct eth_drv_sc *)dbg; // Use control from installed driver eth_drv_old = sc->funs->eth_drv_old; if (eth_drv_old == 0) { sc->funs->eth_drv_old = sc->funs->eth_drv; sc->funs->eth_drv = ð_drv_funs; // Substitute stand-alone driver old_state = sc->state; if (!old_state & ETH_DRV_STATE_ACTIVE) { // This interface not fully initialized, do it now (sc->funs->start)(sc, (unsigned char *)&__local_enet_addr, 0); sc->state |= ETH_DRV_STATE_ACTIVE; } } } while (!(sc->funs->can_send)(sc)) { // Give driver a chance to service hardware (sc->funs->poll)(sc); CYGACC_CALL_IF_DELAY_US(2*100000); if (--wait_time <= 0) goto reset_and_out; // Give up on sending packet } sg_list[0].buf = (CYG_ADDRESS)eth_hdr; sg_list[0].len = 14; // FIXME sg_list[1].buf = (CYG_ADDRESS)buf; sg_list[1].len = len; packet_sent = 0; #ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG if (cyg_io_eth_net_debug) { int old_console; old_console = start_console(); diag_printf("Ethernet send:\n"); DIAG_DUMP_BUF_HDR(eth_hdr, 14); DIAG_DUMP_BUF_BDY(buf, len); end_console(old_console); } #endif (sc->funs->send)(sc, sg_list, sg_len, len+14, (CYG_ADDRWORD)&packet_sent); wait_time = 50000; while (1) { (sc->funs->poll)(sc); if(packet_sent) break; CYGACC_CALL_IF_DELAY_US(2*10); if (--wait_time <= 0) goto reset_and_out; // Give up on sending packet } reset_and_out: if (dbg) { // if (!old_state & ETH_DRV_STATE_ACTIVE) { // // This interface was not fully initialized, shut it back down // (sc->funs->stop)(sc); // } if (eth_drv_old == 0) { sc->funs->eth_drv = sc->funs->eth_drv_old; sc->funs->eth_drv_old = (struct eth_drv_funs *)0; } } }
/* This routine is called to send data to the hardware. It is known a-priori that there is free buffer space (dp->tx_next). */ static void dp83902a_send(unsigned char *data, int total_len, unsigned long key) { struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; cyg_uint8 *base = dp->base; int len, start_page, pkt_len, i, isr; #if DEBUG & 4 int dx; #endif DEBUG_FUNCTION(); len = pkt_len = total_len; if (pkt_len < IEEE_8023_MIN_FRAME) pkt_len = IEEE_8023_MIN_FRAME; start_page = dp->tx_next; if (dp->tx_next == dp->tx_buf1) { dp->tx1 = start_page; dp->tx1_len = pkt_len; dp->tx1_key = key; dp->tx_next = dp->tx_buf2; } else { dp->tx2 = start_page; dp->tx2_len = pkt_len; dp->tx2_key = key; dp->tx_next = dp->tx_buf1; } #if DEBUG & 5 printf("TX prep page %d len %d\n", start_page, pkt_len); #endif DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */ { /* Dummy read. The manual sez something slightly different, */ /* but the code is extended a bit to do what Hitachi's monitor */ /* does (i.e., also read data). */ cyg_uint16 tmp; int len = 1; DP_OUT(base, DP_RSAL, 0x100-len); DP_OUT(base, DP_RSAH, (start_page-1) & 0xff); DP_OUT(base, DP_RBCL, len); DP_OUT(base, DP_RBCH, 0); DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_RDMA | DP_CR_START); DP_IN_DATA(dp->data, tmp); } #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA /* Stall for a bit before continuing to work around random data */ /* corruption problems on some platforms. */ CYGACC_CALL_IF_DELAY_US(1); #endif /* Send data to device buffer(s) */ DP_OUT(base, DP_RSAL, 0); DP_OUT(base, DP_RSAH, start_page); DP_OUT(base, DP_RBCL, pkt_len & 0xFF); DP_OUT(base, DP_RBCH, pkt_len >> 8); DP_OUT(base, DP_CR, DP_CR_WDMA | DP_CR_START); /* Put data into buffer */ #if DEBUG & 4 printf(" sg buf %08lx len %08x\n ", (unsigned long) data, len); dx = 0; #endif while (len > 0) { #if DEBUG & 4 printf(" %02x", *data); if (0 == (++dx % 16)) printf("\n "); #endif DP_OUT_DATA(dp->data, *data++); len--; } #if DEBUG & 4 printf("\n"); #endif if (total_len < pkt_len) { #if DEBUG & 4 printf(" + %d bytes of padding\n", pkt_len - total_len); #endif /* Padding to 802.3 length was required */ for (i = total_len; i < pkt_len;) { i++; DP_OUT_DATA(dp->data, 0); } } #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA /* After last data write, delay for a bit before accessing the */ /* device again, or we may get random data corruption in the last */ /* datum (on some platforms). */ CYGACC_CALL_IF_DELAY_US(1); #endif /* Wait for DMA to complete */ do { DP_IN(base, DP_ISR, isr); } while ((isr & DP_ISR_RDC) == 0); /* Then disable DMA */ DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); /* Start transmit if not already going */ if (!dp->tx_started) { if (start_page == dp->tx1) { dp->tx_int = 1; /* Expecting interrupt from BUF1 */ } else { dp->tx_int = 2; /* Expecting interrupt from BUF2 */ } dp83902a_start_xmit(start_page, pkt_len); } }
void do_displayTempVoltage(int argc, char *argv[]) { struct option_info opts[3]; bool continuous = false; bool peak = false; bool allRegs = false; bool opt058; bool opt057; opt058 = isOptionInstalled((cyg_uint16 *)P4205_BOARD_ID_STATUS, 0x58); opt057 = isOptionInstalled((cyg_uint16 *)P4205_BOARD_ID_STATUS, 0x57); /* Check for continuous flag */ init_opts(&opts[0], 'c', false, OPTION_ARG_TYPE_FLG, (void **)&continuous, (bool *)0, "View results once a second"); init_opts(&opts[1], 'p', false, OPTION_ARG_TYPE_FLG, (void **)&peak, (bool *)0, "View peak conditions"); init_opts(&opts[2], 'a', false, OPTION_ARG_TYPE_FLG, (void **)&allRegs, (bool *)0, "View contents of all registers"); scan_opts(argc, argv, 1, opts, 3, 0, 0, ""); do { /* Display Settings */ if (!peak && !allRegs) { #if 0 if ((values.ext_temp2_value == -128) && (values.ext_temp1_value == -128) && (values.int_temp_value == -128)) diag_printf("Error reading current settings, Cycle Power\n"); else #endif P4205PrintTempVoltage(); } else if (!peak) { diag_printf("ADM1024 #1 Register Settings\n"); ADM1024PrintAllRegisters(GT64260_CPU_REG_BASE, P4205_I2C_ADM1024_SADDR_1); diag_printf("ADM1024 #2 Register Settings\n"); ADM1024PrintAllRegisters(GT64260_CPU_REG_BASE, P4205_I2C_ADM1024_SADDR_2); } else /* peak */ { P4205_PEAK_TEMP_VOLTAGE *peakTbl = (P4205_PEAK_TEMP_VOLTAGE *)P4205_PEAK_TEMP_VOLT_VALUES; diag_printf("\n Peak Voltage and Temperature Settings\n"); #ifdef CYGPKG_LIBC_STDIO printf("+1.5V Min = %3.3f Max = %3.3f\n", peakTbl->plus_1_5v_min, peakTbl->plus_1_5v_max); if (opt057 | opt058) printf("+1.3V Min = %3.3f Max = %3.3f\n", peakTbl->plus_1_6v_min, peakTbl->plus_1_6v_max); else printf("+1.6V Min = %3.3f Max = %3.3f\n", peakTbl->plus_1_6v_min, peakTbl->plus_1_6v_max); printf("+1.8V Min = %3.3f Max = %3.3f\n", peakTbl->plus_1_8v_min, peakTbl->plus_1_8v_max); printf("+2.5V Min = %3.3f Max = %3.3f\n", peakTbl->plus_2_5v_min, peakTbl->plus_2_5v_max); printf("Adm1024 #1 +3.3V Min = %3.3f Max = %3.3f\n", peakTbl->plus_3_3v_min_0, peakTbl->plus_3_3v_max_0); printf("Adm1024 #2 +3.3V Min = %3.3f Max = %3.3f\n", peakTbl->plus_3_3v_min_1, peakTbl->plus_3_3v_max_1); printf("Adm1024 #1 +5V Min = %3.3f Max = %3.3f\n", peakTbl->plus_5v_min_0, peakTbl->plus_5v_max_0); printf("Adm1024 #2 +5V Min = %3.3f Max = %3.3f\n", peakTbl->plus_5v_min_1, peakTbl->plus_5v_max_1); printf("Adm1024 #1 +12V Min = %3.3f Max = %3.3f\n", peakTbl->plus_12v_min_0, peakTbl->plus_12v_max_0); printf("Adm1024 #2 +12V Min = %3.3f Max = %3.3f\n", peakTbl->plus_12v_min_1, peakTbl->plus_12v_max_1); #endif diag_printf("Adm1024 #1 Internal Temperature Peak Value = %3d %%C\n", peakTbl->int_temp_max_0); diag_printf("Adm1024 #2 Internal Temperature Peak Value = %3d %%C\n", peakTbl->int_temp_max_1); diag_printf("VIM A/B FPGA Temperature Peak Value = %3d %%C\n", peakTbl->vim_ab_fpga_temp_max_0); diag_printf("VIM C/D FPGA Temperature Peak Value = %3d %%C\n", peakTbl->vim_cd_fpga_temp_max_0); diag_printf("PCB Temperature Peak Value(near heat sink) = %3d %%C\n", peakTbl->pcb_temp_max_1); } /* If continuous readout, delay 1 second and update */ if (continuous) CYGACC_CALL_IF_DELAY_US(1000000); } while (continuous); }
static void spi_at91_transfer(cyg_spi_at91_device_t *dev, cyg_uint32 count, const cyg_uint8 *tx_data, cyg_uint8 *rx_data) { cyg_spi_at91_bus_t *spi_bus = (cyg_spi_at91_bus_t *)dev->spi_device.spi_bus; // Since PDC transfer buffer counters are 16 bit long, // we have to split longer transfers into chunks. while (count > 0) { cyg_uint16 tr_count = count > 0xFFFF ? 0xFFFF : count; // Set rx buf pointer and counter if (NULL != rx_data) { HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_RPR, (cyg_uint32)rx_data); HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_RCR, (cyg_uint32)tr_count); } // Set tx buf pointer and counter HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_TPR, (cyg_uint32)tx_data); HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_TCR, (cyg_uint32)tr_count); // Enable the SPI int events we are interested in HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_IER, AT91_SPI_SR_ENDRX | AT91_SPI_SR_ENDTX); cyg_drv_mutex_lock(&spi_bus->transfer_mx); { spi_bus->transfer_end = false; // Unmask the SPI int cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_SPI); // Wait for its completition cyg_drv_dsr_lock(); { while (!spi_bus->transfer_end) cyg_drv_cond_wait(&spi_bus->transfer_cond); } cyg_drv_dsr_unlock(); } cyg_drv_mutex_unlock(&spi_bus->transfer_mx); if (NULL == rx_data) { cyg_uint32 val; // If rx buffer was NULL, then the PDC receiver data transfer // was not started and we didn't wait for ENDRX, but only for // ENDTX. Meaning that right now the last byte is being serialized // over the line and when finished input data will appear in // rx data reg. We have to wait for this to happen here, if we // don't we'll get the last received byte as the first one in the // next transfer! // FIXME: is there any better way to do this? // If not, then precalculate this value. val = 8000000/dev->cl_brate; CYGACC_CALL_IF_DELAY_US(val > 1 ? val : 1); // Clear the rx data reg HAL_READ_UINT32(AT91_SPI+AT91_SPI_RDR, val); } // Adjust running variables if (NULL != rx_data) rx_data += tr_count; tx_data += tr_count; count -= tr_count; } }
int xyzModem_stream_open (connection_info_t * info, int *err) { #ifdef REDBOOT int console_chan; #endif int stat = 0; int retries = xyzModem_MAX_RETRIES; int crc_retries = xyzModem_MAX_RETRIES_WITH_CRC; /* ZM_DEBUG(zm_out = zm_out_start); */ #ifdef xyzModem_zmodem if (info->mode == xyzModem_zmodem) { *err = xyzModem_noZmodem; return -1; } #endif #ifdef REDBOOT /* Set up the I/O channel. Note: this allows for using a different port in the future */ console_chan = CYGACC_CALL_IF_SET_CONSOLE_COMM (CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); if (info->chan >= 0) { CYGACC_CALL_IF_SET_CONSOLE_COMM (info->chan); } else { CYGACC_CALL_IF_SET_CONSOLE_COMM (console_chan); } xyz.__chan = CYGACC_CALL_IF_CONSOLE_PROCS (); CYGACC_CALL_IF_SET_CONSOLE_COMM (console_chan); CYGACC_COMM_IF_CONTROL (*xyz.__chan, __COMMCTL_SET_TIMEOUT, xyzModem_CHAR_TIMEOUT); #else /* TODO: CHECK ! */ int dummy; xyz.__chan = &dummy; #endif xyz.len = 0; xyz.crc_mode = true; xyz.at_eof = false; xyz.tx_ack = false; xyz.mode = info->mode; xyz.total_retries = 0; xyz.total_SOH = 0; xyz.total_STX = 0; xyz.total_CAN = 0; #ifdef USE_YMODEM_LENGTH xyz.read_length = 0; xyz.file_length = 0; #endif CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); if (xyz.mode == xyzModem_xmodem) { /* X-modem doesn't have an information header - exit here */ xyz.next_blk = 1; return 0; } while (retries-- > 0) { stat = xyzModem_get_hdr (); if (stat == 0) { /* Y-modem file information header */ if (xyz.blk == 0) { #ifdef USE_YMODEM_LENGTH /* skip filename */ while (*xyz.bufp++); /* get the length */ parse_num ((char *) xyz.bufp, &xyz.file_length, NULL, " "); #endif /* The rest of the file name data block quietly discarded */ xyz.tx_ack = true; } xyz.next_blk = 1; xyz.len = 0; return 0; } else if (stat == xyzModem_timeout) { if (--crc_retries <= 0) xyz.crc_mode = false; CYGACC_CALL_IF_DELAY_US (5 * 100000); /* Extra delay for startup */ CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); xyz.total_retries++; ZM_DEBUG (zm_dprintf ("NAK (%d)\n", __LINE__)); } if (stat == xyzModem_cancel) { break; } } *err = stat; ZM_DEBUG (zm_flush ()); return -1; }
/* * This function is called when a packet has been received. It's job is * to prepare to unload the packet from the hardware. Once the length of * the packet is known, the upper layer of the driver can be told. When * the upper layer is ready to unload the packet, the internal function * 'dp83902a_recv' will be called to actually fetch it from the hardware. */ static void dp83902a_RxEvent(void) { struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; u8 *base = dp->base; __maybe_unused u8 rsr; u8 rcv_hdr[4]; int i, len, pkt, cur; DEBUG_FUNCTION(); DP_IN(base, DP_RSR, rsr); while (true) { /* Read incoming packet header */ DP_OUT(base, DP_CR, DP_CR_PAGE1 | DP_CR_NODMA | DP_CR_START); DP_IN(base, DP_P1_CURP, cur); DP_OUT(base, DP_P1_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); DP_IN(base, DP_BNDRY, pkt); pkt += 1; if (pkt == dp->rx_buf_end) pkt = dp->rx_buf_start; if (pkt == cur) { break; } DP_OUT(base, DP_RBCL, sizeof(rcv_hdr)); DP_OUT(base, DP_RBCH, 0); DP_OUT(base, DP_RSAL, 0); DP_OUT(base, DP_RSAH, pkt); if (dp->rx_next == pkt) { if (cur == dp->rx_buf_start) DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1); else DP_OUT(base, DP_BNDRY, cur - 1); /* Update pointer */ return; } dp->rx_next = pkt; DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */ DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START); #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA CYGACC_CALL_IF_DELAY_US(10); #endif /* read header (get data size)*/ for (i = 0; i < sizeof(rcv_hdr);) { DP_IN_DATA(dp->data, rcv_hdr[i++]); } #if DEBUG & 5 printf("rx hdr %02x %02x %02x %02x\n", rcv_hdr[0], rcv_hdr[1], rcv_hdr[2], rcv_hdr[3]); #endif len = ((rcv_hdr[3] << 8) | rcv_hdr[2]) - sizeof(rcv_hdr); /* data read */ uboot_push_packet_len(len); if (rcv_hdr[1] == dp->rx_buf_start) DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1); else DP_OUT(base, DP_BNDRY, rcv_hdr[1] - 1); /* Update pointer */ } }
// // Initialize the interface - performed at system startup // This function must set up the interface, including arranging to // handle interrupts, etc, so that it may be "started" cheaply later. // static bool fec_eth_init(struct cyg_netdevtab_entry *tab) { struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance; struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private; volatile EPPC *eppc = (volatile EPPC *)eppc_base(); volatile struct fec *fec = (volatile struct fec *)((unsigned char *)eppc + FEC_OFFSET); unsigned short phy_state = 0; int cache_state; int i; unsigned long proc_rev; bool esa_ok, phy_ok; int phy_timeout = 5*1000; // Wait 5 seconds max for link to clear // Ensure consistent state between cache and what the FEC sees HAL_DCACHE_IS_ENABLED(cache_state); HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); qi->fec = fec; fec_eth_stop(sc); // Make sure it's not running yet #ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED #ifdef _FEC_USE_INTS // Set up to handle interrupts cyg_drv_interrupt_create(FEC_ETH_INT, CYGARC_SIU_PRIORITY_HIGH, (cyg_addrword_t)sc, // Data item passed to interrupt handler (cyg_ISR_t *)fec_eth_isr, (cyg_DSR_t *)eth_drv_dsr, &fec_eth_interrupt_handle, &fec_eth_interrupt); cyg_drv_interrupt_attach(fec_eth_interrupt_handle); cyg_drv_interrupt_acknowledge(FEC_ETH_INT); cyg_drv_interrupt_unmask(FEC_ETH_INT); #else // _FEC_USE_INTS // Hack - use a thread to simulate interrupts cyg_thread_create(1, // Priority fec_fake_int, // entry (cyg_addrword_t)sc, // entry parameter "CS8900 int", // Name &fec_fake_int_stack[0], // Stack STACK_SIZE, // Size &fec_fake_int_thread_handle, // Handle &fec_fake_int_thread_data // Thread data structure ); cyg_thread_resume(fec_fake_int_thread_handle); // Start it #endif #endif // Set up parallel port for connection to ethernet tranceiver eppc->pio_pdpar = 0x1FFF; CYGARC_MFSPR( CYGARC_REG_PVR, proc_rev ); #define PROC_REVB 0x0020 if ((proc_rev & 0x0000FFFF) == PROC_REVB) { eppc->pio_pddir = 0x1C58; } else { eppc->pio_pddir = 0x1FFF; } // Get physical device address #ifdef CYGPKG_REDBOOT esa_ok = flash_get_config("fec_esa", enaddr, CONFIG_ESA); #else esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET, "fec_esa", enaddr, CONFIG_ESA); #endif if (!esa_ok) { // Can't figure out ESA os_printf("FEC_ETH - Warning! ESA unknown\n"); memcpy(&enaddr, &_default_enaddr, sizeof(enaddr)); } // Configure the device if (!fec_eth_reset(sc, enaddr, 0)) { return false; } // Reset PHY (transceiver) eppc->pip_pbdat &= ~0x00004000; // Reset PHY chip CYGACC_CALL_IF_DELAY_US(10000); // 10ms eppc->pip_pbdat |= 0x00004000; // Enable PHY chip // Enable transceiver (PHY) phy_ok = 0; phy_write(PHY_BMCR, 0, PHY_BMCR_RESET); for (i = 0; i < 10; i++) { phy_ok = phy_read(PHY_BMCR, 0, &phy_state); if (!phy_ok) break; if (!(phy_state & PHY_BMCR_RESET)) break; } if (!phy_ok || (phy_state & PHY_BMCR_RESET)) { os_printf("FEC: Can't get PHY unit to reset: %x\n", phy_state); return false; } fec->iEvent = 0xFFFFFFFF; // Clear all interrupts phy_write(PHY_BMCR, 0, PHY_BMCR_AUTO_NEG|PHY_BMCR_RESTART); while (phy_timeout-- >= 0) { int ev = fec->iEvent; unsigned short state; fec->iEvent = ev; if (ev & iEvent_MII) { phy_ok = phy_read(PHY_BMSR, 0, &state); if (phy_ok && (state & PHY_BMSR_AUTO_NEG)) { // os_printf("State: %x\n", state); break; } else { CYGACC_CALL_IF_DELAY_US(1000); // 1ms } } } if (phy_timeout <= 0) { os_printf("** FEC Warning: PHY auto-negotiation failed\n"); } // Initialize upper level driver (sc->funs->eth_drv->init)(sc, (unsigned char *)&enaddr); return true; }
// // This is the main entry point for RedBoot // void cyg_start(void) { int res = 0; bool prompt = true; static char line[CYGPKG_REDBOOT_MAX_CMD_LINE]; char *command; struct cmd *cmd; int cur; struct init_tab_entry *init_entry; // Make sure the channels are properly initialized. diag_init_putc(_mon_write_char); hal_if_diag_init(); // Force console to output raw text - but remember the old setting // so it can be restored if interaction with a debugger is // required. cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL); #ifdef CYGPKG_REDBOOT_ANY_CONSOLE console_selected = false; #endif console_echo = true; CYGACC_CALL_IF_DELAY_US((cyg_int32)2*100000); ram_start = (unsigned char *)CYGMEM_REGION_ram; ram_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE); #ifdef HAL_MEM_REAL_REGION_TOP { unsigned char *ram_end_tmp = ram_end; ram_end = HAL_MEM_REAL_REGION_TOP( ram_end_tmp ); } #endif #ifdef CYGMEM_SECTION_heap1 workspace_start = (unsigned char *)CYGMEM_SECTION_heap1; workspace_end = (unsigned char *)(CYGMEM_SECTION_heap1+CYGMEM_SECTION_heap1_SIZE); workspace_size = CYGMEM_SECTION_heap1_SIZE; #else workspace_start = (unsigned char *)CYGMEM_REGION_ram; workspace_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE); workspace_size = CYGMEM_REGION_ram_SIZE; #endif if ( ram_end < workspace_end ) { // when *less* SDRAM is installed than the possible maximum, // but the heap1 region remains greater... workspace_end = ram_end; workspace_size = workspace_end - workspace_start; } bist(); for (init_entry = __RedBoot_INIT_TAB__; init_entry != &__RedBoot_INIT_TAB_END__; init_entry++) { (*init_entry->fun)(); } user_ram_start = workspace_start; user_ram_end = workspace_end; do_version(0,0); #ifdef CYGFUN_REDBOOT_BOOT_SCRIPT # ifdef CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT if (!script) { script = CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT; # ifndef CYGSEM_REDBOOT_FLASH_CONFIG script_timeout = CYGNUM_REDBOOT_BOOT_SCRIPT_DEFAULT_TIMEOUT; # endif } # endif if (script) { // Give the guy a chance to abort any boot script unsigned char *hold_script = script; int script_timeout_ms = script_timeout * CYGNUM_REDBOOT_BOOT_SCRIPT_TIMEOUT_RESOLUTION; diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", script_timeout_ms/1000, script_timeout_ms%1000); script = (unsigned char *)0; res = _GETS_CTRLC; // Treat 0 timeout as ^C while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) { res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); if (res >= _GETS_OK) { diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", script_timeout_ms/1000, script_timeout_ms%1000); continue; // Ignore anything but ^C } if (res != _GETS_TIMEOUT) break; script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT; } if (res == _GETS_CTRLC) { script = (unsigned char *)0; // Disable script } else { script = hold_script; // Re-enable script } } #endif while (true) { if (prompt) { diag_printf("RedBoot> "); prompt = false; } #if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0 cmd_history = true; // Enable history collection #endif res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); #if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0 cmd_history = false; // Enable history collection #endif if (res == _GETS_TIMEOUT) { // No input arrived } else { #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS if (res == _GETS_GDB) { int dbgchan; hal_virtual_comm_table_t *__chan; int i; // Special case of '$' - need to start GDB protocol gdb_active = true; // Mask interrupts on all channels for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS; i++) { CYGACC_CALL_IF_SET_CONSOLE_COMM(i); __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE ); } CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); #ifdef HAL_ARCH_PROGRAM_NEW_STACK HAL_ARCH_PROGRAM_NEW_STACK(breakpoint); #else breakpoint(); // Get GDB stubs started, with a proper environment, etc. #endif dbgchan = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); CYGACC_CALL_IF_SET_CONSOLE_COMM(dbgchan); } else #endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS { expand_aliases(line, sizeof(line)); command = (char *)&line; if ((*command == '#') || (*command == '=')) { // Special cases if (*command == '=') { // Print line on console diag_printf("%s\n", &line[2]); } } else { while (strlen(command) > 0) { if ((cmd = parse(&command, &argc, &argv[0])) != (struct cmd *)0) { (cmd->fun)(argc, argv); } else { diag_printf("** Error: Illegal command: \"%s\"\n", argv[0]); } } } prompt = true; } } } }
externC void cyg_start( void ) { int stat; void *err_addr; CYG_ADDRWORD flash_start, flash_end; void **flash_start_addr = (void *)&flash_start; void **flash_end_addr = (void *)&flash_end; void *flash_test_start, *flash_addr; cyg_int32 flash_block_size, flash_num_blocks; CYG_ADDRWORD test_buf1, test_buf2; cyg_uint32 *lp1, *lp2; int i, len; cyg_bool passed, ok; CYG_TEST_INIT(); #if 0 int j; diag_printf("Testing udelay: "); for (i = 0; i < 30; i++) { for (j = 0; j < 1000; j++) { CYGACC_CALL_IF_DELAY_US(1000); // Should be 1 second } diag_printf("."); } diag_printf("\n"); #endif passed = true; if ((stat = flash_init(diag_printf)) != 0) { diag_printf("FLASH: driver init failed: %s\n", flash_errmsg(stat)); CYG_TEST_FAIL_FINISH("FLASH driver init failed"); } flash_get_limits((void *)0, flash_start_addr, flash_end_addr); // Keep 'end' address as last valid location, to avoid wrap around problems flash_end = flash_end - 1; flash_get_block_info(&flash_block_size, &flash_num_blocks); diag_printf("FLASH: 0x%x - 0x%x, %d blocks of 0x%x bytes each.\n", flash_start, flash_end + 1, flash_num_blocks, flash_block_size); // Verify that the testing limits are within the bounds of the // physical device. Also verify that the size matches with // the erase block size on the device if ((CYGNUM_IO_FLASH_TEST_OFFSET > (flash_end - flash_start)) || ((CYGNUM_IO_FLASH_TEST_OFFSET + CYGNUM_IO_FLASH_TEST_LENGTH) > (flash_end - flash_start))) { CYG_TEST_FAIL_FINISH("FLASH test region outside physical limits"); } if ((CYGNUM_IO_FLASH_TEST_LENGTH % flash_block_size) != 0) { CYG_TEST_FAIL_FINISH("FLASH test region must be integral multiple of erase block size"); } // Allocate two buffers large enough for the test test_buf1 = (CYG_ADDRWORD)CYGMEM_SECTION_heap1; test_buf2 = test_buf1 + CYGNUM_IO_FLASH_TEST_LENGTH; if (CYGMEM_SECTION_heap1_SIZE < (CYGNUM_IO_FLASH_TEST_LENGTH * 2)) { CYG_TEST_FAIL_FINISH("FLASH not enough heap space - reduce size of test region"); } diag_printf("... Using test buffers at %p and %p\n", (void *)test_buf1, (void *)test_buf2); flash_test_start = (void *)(flash_start + CYGNUM_IO_FLASH_TEST_OFFSET); #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING // Unlock test diag_printf("... Unlock test\n"); ok = true; if ((stat = flash_unlock(flash_test_start, CYGNUM_IO_FLASH_TEST_LENGTH, &err_addr)) != CYG_FLASH_ERR_OK) { diag_printf("FLASH: unlock failed: %s\n", flash_errmsg(stat)); ok = false; } #endif // Erase test diag_printf("... Erase test\n"); ok = true; if ((stat = flash_erase(flash_test_start, CYGNUM_IO_FLASH_TEST_LENGTH, &err_addr)) != CYG_FLASH_ERR_OK) { diag_printf("FLASH: erase failed: %s\n", flash_errmsg(stat)); ok = false; } if (ok && (stat = flash_read(flash_test_start, (void *)test_buf1, CYGNUM_IO_FLASH_TEST_LENGTH, &err_addr)) != CYG_FLASH_ERR_OK) { diag_printf("FLASH: read/verify after erase failed: %s\n", flash_errmsg(stat)); ok = false; } lp1 = (cyg_uint32 *)test_buf1; for (i = 0; i < CYGNUM_IO_FLASH_TEST_LENGTH; i += sizeof(cyg_uint32)) { if (*lp1++ != 0xFFFFFFFF) { diag_printf("FLASH: non-erased data found at offset %x\n", (CYG_ADDRWORD)(lp1-1) - test_buf1); diag_dump_buf((void *)(lp1-1), 32); ok = false; break; } } // Try reading in little pieces len = CYGNUM_IO_FLASH_TEST_LENGTH; flash_addr = flash_test_start; while (len > 0) { if ((stat = flash_read(flash_addr, (void *)test_buf1, 0x200, &err_addr)) != CYG_FLASH_ERR_OK) { diag_printf("FLASH: read[short]/verify after erase failed: %s\n", flash_errmsg(stat)); ok = false; break; } flash_addr = (cyg_uint8 *)flash_addr + 0x200; len -= 0x200; lp1 = (cyg_uint32 *)test_buf1; for (i = 0; i < 0x200; i += sizeof(cyg_uint32)) { if (*lp1++ != 0xFFFFFFFF) { diag_printf("FLASH: non-erased data found at offset %p\n", (cyg_uint8 *)flash_addr + (CYG_ADDRWORD)((lp1-1) - test_buf1)); diag_dump_buf((void *)(lp1-1), 32); ok = false; len = 0; break; } } } if (!ok) { CYG_TEST_INFO("FLASH erase failed"); passed = false; } // Simple write/verify test diag_printf("... Write/verify test\n"); lp1 = (cyg_uint32 *)test_buf1; for (i = 0; i < CYGNUM_IO_FLASH_TEST_LENGTH; i += sizeof(cyg_uint32)) { *lp1 = (cyg_uint32)lp1; lp1++; } ok = true; if (ok && (stat = flash_program(flash_test_start, (void *)test_buf1, CYGNUM_IO_FLASH_TEST_LENGTH, &err_addr)) != CYG_FLASH_ERR_OK) { diag_printf("FLASH: write failed: %s\n", flash_errmsg(stat)); ok = false; } if (ok && (stat = flash_read(flash_test_start, (void *)test_buf2, CYGNUM_IO_FLASH_TEST_LENGTH, &err_addr)) != CYG_FLASH_ERR_OK) { diag_printf("FLASH: read/verify after write failed: %s\n", flash_errmsg(stat)); ok = false; } lp1 = (cyg_uint32 *)test_buf1; lp2 = (cyg_uint32 *)test_buf2; for (i = 0; i < CYGNUM_IO_FLASH_TEST_LENGTH; i += sizeof(cyg_uint32)) { if (*lp2++ != *lp1++) { diag_printf("FLASH: incorrect data found at offset %x\n", (CYG_ADDRWORD)(lp2-1) - test_buf2); diag_dump_buf((void *)(lp2-1), 32); ok = false; break; } } // Try reading in little pieces len = CYGNUM_IO_FLASH_TEST_LENGTH; flash_addr = flash_test_start; lp1 = (cyg_uint32 *)test_buf1; lp2 = (cyg_uint32 *)test_buf2; while (len > 0) { if ((stat = flash_read(flash_addr, lp2, 0x200, &err_addr)) != CYG_FLASH_ERR_OK) { diag_printf("FLASH: read[short]/verify after erase failed: %s\n", flash_errmsg(stat)); ok = false; break; } flash_addr = (cyg_uint8 *)flash_addr + 0x200; len -= 0x200; for (i = 0; i < 0x200; i += sizeof(cyg_uint32)) { if (*lp2++ != *lp1++) { diag_printf("FLASH: incorrect data found at offset %p\n", (cyg_uint8 *)flash_addr + (CYG_ADDRWORD)((lp2-1) - test_buf2)); diag_dump_buf((void *)(lp2-1), 32); ok = false; len = 0; break; } } } if (!ok) { CYG_TEST_INFO("FLASH write/verify failed"); } #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING // Lock test diag_printf("... Lock test\n"); ok = true; if ((stat = flash_lock(flash_test_start, CYGNUM_IO_FLASH_TEST_LENGTH, &err_addr)) != CYG_FLASH_ERR_OK) { diag_printf("FLASH: unlock failed: %s\n", flash_errmsg(stat)); ok = false; } #endif if (passed) { CYG_TEST_PASS_FINISH("FLASH test1"); } else { CYG_TEST_FAIL_FINISH("FLASH test1"); } }
static bool ksz8041_stat (eth_phy_access_t * f, int *state) { cyg_uint16 phy_state; cyg_uint16 phy_100ctrl_reg; cyg_uint32 tries; cyg_uint32 ms; #ifdef CYGDBG_DEVS_ETH_PHY ksz8041_diag (f); #endif if (_eth_phy_read (f, PHY_BMSR, f->phy_addr, &phy_state)) { if ((phy_state & PHY_BMSR_AUTO_NEG) == 0) { eth_phy_printf ("... waiting for auto-negotiation"); for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME; tries++) { if (_eth_phy_read (f, PHY_BMSR, f->phy_addr, &phy_state)) { if ((phy_state & PHY_BMSR_AUTO_NEG) != 0) { break; } } else { eth_phy_printf ("error: _eth_phy_read()\n"); } // // Wait for 1 second // for (ms = 0; ms < 1000; ++ms) { CYGACC_CALL_IF_DELAY_US (1000); // 1 ms } eth_phy_printf ("."); } eth_phy_printf ("\n"); } if ((phy_state & PHY_BMSR_AUTO_NEG) != 0) { *state = 0; if ((phy_state & PHY_BMSR_LINK) != 0) { *state |= ETH_PHY_STAT_LINK; } _eth_phy_read (f, PHY_100BASE_CTRL, f->phy_addr, &phy_100ctrl_reg); phy_100ctrl_reg &= PHY_100BASE_CTRL_OP_MODE_MASK; switch (phy_100ctrl_reg) { case PHY_100BASE_CTRL_10T_HDX: break; case PHY_100BASE_CTRL_100T_HDX: *state |= ETH_PHY_STAT_100MB; break; case PHY_100BASE_CTRL_10T_FDX: *state |= ETH_PHY_STAT_FDX; break; case PHY_100BASE_CTRL_100T_FDX: *state |= ETH_PHY_STAT_100MB | ETH_PHY_STAT_FDX; break; default: // force to set default 100 Full Duplex *state |= ETH_PHY_STAT_100MB | ETH_PHY_STAT_FDX; } // switch (phy_100ctrl_reg) return true; } } return false; }
// // This is the main entry point for RedBoot // void cyg_start(void) { int res = 0; bool prompt = true; static char line[CYGPKG_REDBOOT_MAX_CMD_LINE]; char *command; struct cmd *cmd; int cur; struct init_tab_entry *init_entry; extern char RedBoot_version[]; #if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1 int seg; #endif // Export version information CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version); CYGACC_CALL_IF_MONITOR_RETURN_SET(return_to_redboot); // Make sure the channels are properly initialized. diag_init_putc(_mon_write_char); hal_if_diag_init(); // Force console to output raw text - but remember the old setting // so it can be restored if interaction with a debugger is // required. cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL); #ifdef CYGPKG_REDBOOT_ANY_CONSOLE console_selected = false; #endif console_echo = true; CYGACC_CALL_IF_DELAY_US((cyg_int32)2*100000); ram_start = (unsigned char *)CYGMEM_REGION_ram; ram_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE); #ifdef HAL_MEM_REAL_REGION_TOP { unsigned char *ram_end_tmp = ram_end; ram_end = HAL_MEM_REAL_REGION_TOP( ram_end_tmp ); } #endif #ifdef CYGMEM_SECTION_heap1 workspace_start = (unsigned char *)CYGMEM_SECTION_heap1; workspace_end = (unsigned char *)(CYGMEM_SECTION_heap1+CYGMEM_SECTION_heap1_SIZE); #else workspace_start = (unsigned char *)CYGMEM_REGION_ram; workspace_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE); #endif if ( ram_end < workspace_end ) { // when *less* SDRAM is installed than the possible maximum, // but the heap1 region remains greater... workspace_end = ram_end; } // Nothing has ever been loaded into memory entry_address = (unsigned long)NO_MEMORY; bist(); #if defined(CYGPRI_REDBOOT_ZLIB_FLASH) && defined(CYGOPT_REDBOOT_FIS_ZLIB_COMMON_BUFFER) fis_zlib_common_buffer = workspace_end -= CYGNUM_REDBOOT_FIS_ZLIB_COMMON_BUFFER_SIZE; #endif #ifdef CYGFUN_REDBOOT_BOOT_SCRIPT script_timeout = CYGNUM_REDBOOT_BOOT_SCRIPT_DEFAULT_TIMEOUT; #endif for (init_entry = __RedBoot_INIT_TAB__; init_entry != &__RedBoot_INIT_TAB_END__; init_entry++) { (*init_entry->fun)(); } mem_segments[0].start = workspace_start; mem_segments[0].end = workspace_end; #if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1 for (seg = 1; seg < CYGBLD_REDBOOT_MAX_MEM_SEGMENTS; seg++) { cyg_plf_memory_segment(seg, &mem_segments[seg].start, &mem_segments[seg].end); } #endif #ifdef CYGSEM_REDBOOT_PLF_STARTUP cyg_plf_redboot_startup(); #endif do_version(0,0); #ifdef CYGFUN_REDBOOT_BOOT_SCRIPT # ifdef CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT if (!script) { script = CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT; } # endif if (script) { // Give the guy a chance to abort any boot script unsigned char *hold_script = script; int script_timeout_ms = script_timeout * CYGNUM_REDBOOT_BOOT_SCRIPT_TIMEOUT_RESOLUTION; diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", script_timeout_ms/1000, script_timeout_ms%1000); script = (unsigned char *)0; res = _GETS_CTRLC; // Treat 0 timeout as ^C while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) { res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); if (res >= _GETS_OK) { diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", script_timeout_ms/1000, script_timeout_ms%1000); continue; // Ignore anything but ^C } if (res != _GETS_TIMEOUT) break; script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT; } if (res == _GETS_CTRLC) { script = (unsigned char *)0; // Disable script } else { script = hold_script; // Re-enable script } } #endif while (true) { if (prompt) { diag_printf("RedBoot> "); prompt = false; } #if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0 cmd_history = true; // Enable history collection #endif res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); #if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0 cmd_history = false; // Enable history collection #endif if (res == _GETS_TIMEOUT) { // No input arrived } else { #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS if (res == _GETS_GDB) { int dbgchan; hal_virtual_comm_table_t *__chan; int i; // Special case of '$' - need to start GDB protocol gdb_active = true; // Mask interrupts on all channels for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS; i++) { CYGACC_CALL_IF_SET_CONSOLE_COMM(i); __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE ); } CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); // set up a temporary context that will take us to the trampoline HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end, breakpoint, trampoline, 0); // switch context to trampoline (get GDB stubs started) HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end); gdb_active = false; dbgchan = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); CYGACC_CALL_IF_SET_CONSOLE_COMM(dbgchan); } else #endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS { #ifdef CYGSEM_REDBOOT_FLASH_ALIASES expand_aliases(line, sizeof(line)); #endif command = (char *)&line; if ((*command == '#') || (*command == '=')) { // Special cases if (*command == '=') { // Print line on console diag_printf("%s\n", &line[2]); } } else { while (strlen(command) > 0) { if ((cmd = parse(&command, &argc, &argv[0])) != (struct cmd *)0) { // Try to handle aborts - messy because of the stack unwinding... __mem_fault_handler = error_handler; if (hal_setjmp(error_jmpbuf)) { diag_printf("** command abort - illegal memory access?\n"); } else { (cmd->fun)(argc, argv); } __mem_fault_handler = 0; } else { diag_printf("** Error: Illegal command: \"%s\"\n", argv[0]); } } } prompt = true; } } } }
static int xyzModem_get_hdr (void) { char c; int res; bool hdr_found = false; int i, can_total, hdr_chars; unsigned short cksum; ZM_DEBUG (zm_new ()); /* Find the start of a header */ can_total = 0; hdr_chars = 0; if (xyz.tx_ack) { CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK); xyz.tx_ack = false; } while (!hdr_found) { res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, &c); ZM_DEBUG (zm_save (c)); if (res) { hdr_chars++; switch (c) { case SOH: xyz.total_SOH++; case STX: if (c == STX) xyz.total_STX++; hdr_found = true; break; case CAN: xyz.total_CAN++; ZM_DEBUG (zm_dump (__LINE__)); if (++can_total == xyzModem_CAN_COUNT) { return xyzModem_cancel; } else { /* Wait for multiple CAN to avoid early quits */ break; } case EOT: /* EOT only supported if no noise */ if (hdr_chars == 1) { CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK); ZM_DEBUG (zm_dprintf ("ACK on EOT #%d\n", __LINE__)); ZM_DEBUG (zm_dump (__LINE__)); return xyzModem_eof; } default: /* Ignore, waiting for start of header */ ; } } else { /* Data stream timed out */ xyzModem_flush (); /* Toss any current input */ ZM_DEBUG (zm_dump (__LINE__)); CYGACC_CALL_IF_DELAY_US ((cyg_int32) 250000); return xyzModem_timeout; } } /* Header found, now read the data */ res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.blk); ZM_DEBUG (zm_save (xyz.blk)); if (!res) { ZM_DEBUG (zm_dump (__LINE__)); return xyzModem_timeout; } res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.cblk); ZM_DEBUG (zm_save (xyz.cblk)); if (!res) { ZM_DEBUG (zm_dump (__LINE__)); return xyzModem_timeout; } xyz.len = (c == SOH) ? 128 : 1024; xyz.bufp = xyz.pkt; for (i = 0; i < xyz.len; i++) { res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, &c); ZM_DEBUG (zm_save (c)); if (res) { xyz.pkt[i] = c; } else { ZM_DEBUG (zm_dump (__LINE__)); return xyzModem_timeout; } } res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.crc1); ZM_DEBUG (zm_save (xyz.crc1)); if (!res) { ZM_DEBUG (zm_dump (__LINE__)); return xyzModem_timeout; } if (xyz.crc_mode) { res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.crc2); ZM_DEBUG (zm_save (xyz.crc2)); if (!res) { ZM_DEBUG (zm_dump (__LINE__)); return xyzModem_timeout; } } ZM_DEBUG (zm_dump (__LINE__)); /* Validate the message */ if ((xyz.blk ^ xyz.cblk) != (unsigned char) 0xFF) { ZM_DEBUG (zm_dprintf ("Framing error - blk: %x/%x/%x\n", xyz.blk, xyz.cblk, (xyz.blk ^ xyz.cblk))); ZM_DEBUG (zm_dump_buf (xyz.pkt, xyz.len)); xyzModem_flush (); return xyzModem_frame; } /* Verify checksum/CRC */ if (xyz.crc_mode) { cksum = cyg_crc16 (xyz.pkt, xyz.len); if (cksum != ((xyz.crc1 << 8) | xyz.crc2)) { ZM_DEBUG (zm_dprintf ("CRC error - recvd: %02x%02x, computed: %x\n", xyz.crc1, xyz.crc2, cksum & 0xFFFF)); return xyzModem_cksum; } } else { cksum = 0; for (i = 0; i < xyz.len; i++) { cksum += xyz.pkt[i]; } if (xyz.crc1 != (cksum & 0xFF)) { ZM_DEBUG (zm_dprintf ("Checksum error - recvd: %x, computed: %x\n", xyz.crc1, cksum & 0xFF)); return xyzModem_cksum; } } /* If we get here, the message passes [structural] muster */ return 0; }
cyg_bool cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch) { #if 1 int delay_count; channel_data_t* chan = (channel_data_t*)__ch_data; cyg_uint8* base = chan->base; cyg_uint8 last, val; cyg_bool res; CYGARC_HAL_SAVE_GP(); /* see if there's any cached data in the FIFO */ res = cyg_hal_plf_serial_getc_nonblock(__ch_data,ch); if (!res) { /* there isn't - open the flood gates */ delay_count = chan->msec_timeout * 125; // want delay in 8uS steps HAL_WRITE_UINT8(TM0BR,200); // IOCLK is 25MHz, we want 125KHz HAL_WRITE_UINT8(TM0MD,0x40); // stop and load HAL_WRITE_UINT8(TM0MD,0x80); // set source to be IOCLK and go HAL_READ_UINT8(TM0BC,last); while (delay_count>0 && !FLOWCTL_QUERY(DSR)) { HAL_READ_UINT8(TM0BC,val); if (val==last) continue; if (val>last) delay_count--; // count the underflows last = val; } if (delay_count==0) goto timeout; FLOWCTL_SET(RTS); while (delay_count>0 && !LSR_QUERY(DR)) { HAL_READ_UINT8(TM0BC,val); if (val==last) continue; if (val>last) delay_count--; // count the underflows last = val; } FLOWCTL_CLEAR(RTS); if (LSR_QUERY(DR)) { HAL_READ_UINT8(base+CYG_DEV_RBR, *ch); res = true; } timeout: HAL_WRITE_UINT8(TM0MD,0x00); // stop h/w timer } CYGARC_HAL_RESTORE_GP(); return res; #else int delay_count; channel_data_t* chan = (channel_data_t*)__ch_data; cyg_uint8* base = chan->base; cyg_bool res; CYGARC_HAL_SAVE_GP(); /* see if there's some cached data in the FIFO */ res = cyg_hal_plf_serial_getc_nonblock(__ch_data,ch); if (!res) { /* there isn't - open the flood gates */ delay_count = chan->msec_timeout * 1000; // want delay in uS steps for (; delay_count>0 && !FLOWCTL_QUERY(DSR); delay_count--) CYGACC_CALL_IF_DELAY_US(1); if (delay_count==0) goto timeout; FLOWCTL_SET(RTS); for (; delay_count>0 && !LSR_QUERY(DR); delay_count--) CYGACC_CALL_IF_DELAY_US(1); FLOWCTL_CLEAR(RTS); if (LSR_QUERY(DR)) { HAL_READ_UINT8(base+CYG_DEV_RBR, *ch); res = true; } } timeout: CYGARC_HAL_RESTORE_GP(); return res; #endif }