Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
/*
 * 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);
    }
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
/*
  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
		}
	}
}
Пример #8
0
static inline void dm9000_reset(struct dm9000 *p)
{
    putreg(p, DM_NCR, NCR_RST);
    CYGACC_CALL_IF_DELAY_US(100);
}
Пример #9
0
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 = &eth_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;
        }
    }
}
Пример #10
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);
	}
}
Пример #11
0
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);
}
Пример #12
0
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;
    }
}
Пример #13
0
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;
}
Пример #14
0
/*
 * 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 */
    }
}
Пример #15
0
//
// 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;
}
Пример #16
0
//
// 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;
            }
        }
    }
}
Пример #17
0
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");
    }
}
Пример #18
0
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;
}
Пример #19
0
//
// 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;
            }
        }
    }
}
Пример #20
0
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;
}
Пример #21
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
}