예제 #1
0
    /*======================================================================
     | FUNCTIONS
     | =====================================================================*/
    static void _blast_async(int handle, int txnlen, int iter)
    {
        double elapsed = 0;

        byte[] noresult = new byte[1];

        // Make a simple queue to just assert OE.
        CheetahApi.ch_spi_queue_clear(handle);
        CheetahApi.ch_spi_queue_oe(handle, (byte)1);
        CheetahApi.ch_spi_batch_shift(handle, 0, noresult);


        // Queue the batch which is a sequence of SPI packets
        // (back-to-back) each of length 4.
        CheetahApi.ch_spi_queue_clear(handle);
        int i;
        int count = 0;

        byte[] data_out = new byte[4];
        for (i = 0; i < txnlen; ++i)
        {
            CheetahApi.ch_spi_queue_ss(handle, 0x1);

            data_out[0] = (byte)((count >> 24) & 0xff);
            data_out[1] = (byte)((count >> 16) & 0xff);
            data_out[2] = (byte)((count >> 8) & 0xff);
            data_out[3] = (byte)((count >> 0) & 0xff);

            ++count;

            CheetahApi.ch_spi_queue_array(handle, 4, data_out);
            CheetahApi.ch_spi_queue_ss(handle, 0x0);
        }

        ulong start = _timeMillis();

        // First, submit first batch
        CheetahApi.ch_spi_async_submit(handle);

        int n, ret;

        for (n = 0; n < iter - 1; ++n)
        {
            // Submit another batch, while the previous one is in
            // progress.  The application may even clear the current
            // batch queue and queue a different set of SPI
            // transactions before submitting this batch
            // asynchronously.
            CheetahApi.ch_spi_async_submit(handle);

            // The application can now perform some other functions
            // while the Cheetah is both finishing the previous batch
            // and shifting the current batch as well.  In order to
            // keep the Cheetah's pipe full, this entire loop must
            // complete AND another batch must be submitted
            // before the current batch completes.
            CheetahApi.ch_sleep_ms(25);

            // Collect the previous batch
            ret     = CheetahApi.ch_spi_async_collect(handle, 0, noresult);
            elapsed = ((double)(_timeMillis() - start)) / 1000;
            Console.Write("collected batch #{0:d3} in {1:f2} seconds\n",
                          n + 1, elapsed);
            if (ret < 0)
            {
                Console.Write("status error: {0:s}\n",
                              CheetahApi.ch_status_string(ret));
            }
            Console.Out.Flush();

            start = _timeMillis();

            // The current batch is now shifting out on the SPI
            // interface. The application can again do some more tasks
            // here but this entire loop must finish so that a new
            // batch is armed before the current batch completes.
            CheetahApi.ch_sleep_ms(25);
        }

        // Collect batch the last batch
        ret     = CheetahApi.ch_spi_async_collect(handle, 0, noresult);
        elapsed = ((double)(_timeMillis() - start)) / 1000;
        Console.Write("collected batch #{0:d3} in {1:f2} seconds\n",
                      n + 1, elapsed);
        if (ret < 0)
        {
            Console.Write("status error: {0:s}\n",
                          CheetahApi.ch_status_string(ret));
        }
        Console.Out.Flush();
    }
예제 #2
0
    static int _write(int handle, int addr, string binfile)
    {
        ulong start = _timeMicroseconds();
        //Read bin file
        BinaryReader br;

        try
        {
            br = new BinaryReader(new FileStream(binfile,
                                                 FileMode.Open));
        }
        catch (IOException e)
        {
            Console.WriteLine(e.Message + "\n Cannot open file.");
            return(-1);
        }

        int data_length     = Convert.ToInt32(br.BaseStream.Length);
        int data_pad_length = 1024 - data_length % 1024;

        byte[] bin_data = new byte[data_length];
        bin_data = br.ReadBytes(data_length);
        byte[] data      = new byte[data_length + data_pad_length];
        byte[] data_in   = new byte[data_length + data_pad_length];;
        int    addr_back = addr;

        bin_data.CopyTo(data, 0);

        if (data_pad_length != 0)
        {
            for (int i = 0; i < data_pad_length; i++)
            {
                data[data_length + i] = (byte)(255);
            }
        }


        br.Close();
        //Upate data_length to data_length + data_pad_length
        data_length = data_length + data_pad_length;

        // Buffer for outgoing data.
        byte[] data_page = new byte[4 + PAGE_SIZE];

        byte[] noresult  = new byte[1];
        byte[] data_back = new byte[5];

        //Erase first

        _erase(handle, addr / 4, (data.Length / (4 * 1024)) + 1);
        // Reset the state of the bus.
        CheetahApi.ch_spi_queue_clear(handle);
        CheetahApi.ch_spi_queue_ss(handle, 0);
        CheetahApi.ch_spi_queue_oe(handle, 1);
        CheetahApi.ch_spi_batch_shift(handle, 0, noresult);

        // Convert address and length from KB to bytes
        addr *= 1024;


        // Set the starting counter based on the address.
        int val   = addr / 4;
        int pages = 0;
        int retry = 0;

        while (data_length != 0)
        {
            // Start the write sequence.
            CheetahApi.ch_spi_queue_clear(handle);
            CheetahApi.ch_spi_queue_oe(handle, 1);


            // Send PAGE_WRITE_BATCH_SIZE number of pages to the Cheetah per
            // batch shift. Here we only program one page each batch
            for (int i = 0; i < PAGE_WRITE_BATCH_SIZE; i++)
            {
                // Check if we've reached the end.
                if (data_length == 0)
                {
                    break;
                }
                CheetahApi.ch_spi_queue_ss(handle, 0x1);
                CheetahApi.ch_spi_queue_byte(handle, 1, 0x06);
                CheetahApi.ch_spi_queue_ss(handle, 0);
                //while (((data_back[0]>>1 & 0x01) != 1) && (retry++ < 100) ) {
                //    // Queue the write enable instruction for the flash.
                //    //Write enable command 0x06
                //    CheetahApi.ch_spi_queue_ss(handle, 0x1);
                //    CheetahApi.ch_spi_queue_byte(handle, 1, 0x06);
                //    CheetahApi.ch_spi_queue_ss(handle, 0);
                //    CheetahApi.ch_spi_batch_shift(handle, 0, noresult);
                //    CheetahApi.ch_spi_queue_clear(handle);

                //    //Send RDSR Command check WEL bit = 1?
                //    //Shift out RDSR Command First 0x05
                //    CheetahApi.ch_spi_queue_ss(handle, 0x1);
                //    CheetahApi.ch_spi_queue_byte(handle, 1, 0x05);
                //    CheetahApi.ch_spi_queue_ss(handle, 0);
                //    CheetahApi.ch_spi_batch_shift(handle, 0,noresult);
                //    CheetahApi.ch_spi_queue_clear(handle);


                //    //Read One Byte Data Back
                //    CheetahApi.ch_spi_queue_ss(handle, 0x1);
                //    CheetahApi.ch_spi_queue_byte(handle, 1, 0x00);
                //    CheetahApi.ch_spi_queue_ss(handle, 0);
                //    CheetahApi.ch_spi_batch_shift(handle,1, data_back);
                //    CheetahApi.ch_spi_queue_clear(handle);

                //}
                //if (retry >= 100)
                //{
                //    Console.Write("Write Enable Failed.\n");
                //    Console.Out.Flush();
                //    return 1;
                //}
                // Queue the write instruction for the flash.
                // Page write command 0x02 + ADDR[3] + BYTE[256]
                CheetahApi.ch_spi_queue_ss(handle, 0x1);
                data_page[0] = 0x02;
                data_page[1] = (byte)((addr >> 16) & 0xff);
                data_page[2] = (byte)((addr >> 8) & 0xff);
                data_page[3] = (byte)((addr >> 0) & 0xff);

                Console.Write("addr = 0x{0:x6}; num bytes = {1:d}\n",
                              addr, PAGE_SIZE);
                Console.Out.Flush();

                // Set the data to be written to the flash to incrementing
                // 32-bit values starting from 0.
                int j = 0;
                while (j < PAGE_SIZE)
                {
                    data_page[4 + j] = data[j + pages * 256];
                    j += 1;
                }

                CheetahApi.ch_spi_queue_array(handle, 4 + PAGE_SIZE, data_page);
                CheetahApi.ch_spi_queue_ss(handle, 0);

                // Give the flash time to commit the written values.
                // Using ch_spi_queue_delay_ns is much more accurate than
                // using ch_sleep_ms.
                CheetahApi.ch_spi_queue_delay_ns(handle,
                                                 PAGE_PROGRAM_CYCLE_TIME_NS);
                addr        += PAGE_SIZE;
                data_length -= PAGE_SIZE;
                pages       += 1;
            }

            // Shift out the write command.  (Don't need the data back.)
            Console.Write("Shifting data\n");
            Console.Out.Flush();
            int batch = CheetahApi.ch_spi_batch_length(handle);
            int count = CheetahApi.ch_spi_batch_shift(handle, 0, noresult);
            if (count != batch)
            {
                Console.Write("Expected {0:d} bytes but only received " +
                              "{1:d} bytes\n", batch, count);
                return(1);
            }

            ////Wait Programming Page Finished. Check WIP = 0?
            //retry = 0;
            //data_back[0] = (byte)(0xff);
            //while (((data_back[0] & 0x01) != 0) && (retry++ < 100))
            //{

            //    CheetahApi.ch_spi_queue_clear(handle);
            //    //Send RDSR Command check WIP bit = 0?
            //    //Shift out RDSR Command First 0x05
            //    CheetahApi.ch_spi_queue_ss(handle, 0x1);
            //    CheetahApi.ch_spi_queue_byte(handle, 1, 0x05);
            //    CheetahApi.ch_spi_queue_ss(handle, 0);
            //    CheetahApi.ch_spi_batch_length(handle);
            //    CheetahApi.ch_spi_batch_shift(handle, 0, noresult);
            //    CheetahApi.ch_spi_queue_clear(handle);

            //    //Read One Byte Data Back
            //    CheetahApi.ch_spi_queue_ss(handle, 0x1);
            //    CheetahApi.ch_spi_queue_byte(handle, 1, 0x00);
            //    CheetahApi.ch_spi_queue_ss(handle, 0);
            //    CheetahApi.ch_spi_batch_shift(handle, 1, data_back);
            //    CheetahApi.ch_spi_queue_clear(handle);

            //}

            //if (retry >= 100)
            //{
            //    Console.Write("Write Enable Failed.\n");
            //    Console.Out.Flush();
            //    return 1;
            //}
            Console.Write("Shift complete\n");
            Console.Out.Flush();
            //    //Check Programming Result
            //    //Send RDSCUR Command 2B
            //    //Read Security Register bit 5
            //    CheetahApi.ch_spi_queue_ss(handle, 0x1);
            //    CheetahApi.ch_spi_queue_byte(handle, 1, 0x2b);
            //    CheetahApi.ch_spi_queue_ss(handle, 0);
            //    CheetahApi.ch_spi_batch_shift(handle, 0, noresult);
            //    CheetahApi.ch_spi_queue_clear(handle);

            //    //Read One Byte Data Back
            //    data_back[0] = (byte)(0xff);
            //    CheetahApi.ch_spi_queue_ss(handle, 0x1);
            //    CheetahApi.ch_spi_queue_byte(handle, 1, 0x00);
            //    CheetahApi.ch_spi_queue_ss(handle, 0);
            //    CheetahApi.ch_spi_batch_shift(handle, 1, data_back);
            //    CheetahApi.ch_spi_queue_clear(handle);

            //    //Check P_FAIL bit = 0? 0-> PP pass ,1-> PP fail
            //    if ((data_back[0]>>5 & 0x01) != 0)
            //    {
            //        Console.Write("PP Failed...,PFAIL Flag == 1.\n");
            //        Console.Out.Flush();
            //        return 1;
            //    }
        }

        // Reset the state of the bus.
        CheetahApi.ch_spi_queue_clear(handle);
        CheetahApi.ch_spi_queue_oe(handle, 0);
        CheetahApi.ch_spi_batch_shift(handle, 0, noresult);
        ulong end = _timeMicroseconds();

        Console.Write("Flashing take {0 :f3} seconds\n",
                      (double)(end - start) / 1000000);
        Console.Out.Flush();

        //verify the programming data is correct...
        _read(handle, addr_back, data.Length / 1024, out data_in);

        bool compare_result = false;

        for (int k = 0; k < data.Length; k++)
        {
            if (data[k] != data_in[k])
            {
                compare_result = true;
                break;
            }
        }
        end = _timeMicroseconds();
        Console.Write("Totally take {0 :f3} seconds\n", (double)(end - start) / 1000000);

        if (!compare_result)
        {
            Console.Write("Flashing Successfull...\n");
            Console.Out.Flush();
            return(0);
        }
        else
        {
            Console.Write("Flashing Failed...\n");
            Console.Out.Flush();
            return(-1);
        }
    }
예제 #3
0
    /*=====================================================================
     | FUNCTIONS
     | ====================================================================*/
    static void _writeMemory(int handle, ushort addr, ushort length, int zero)
    {
        short i, j, n;
        int   batch, count;

        byte[] data_out = new byte[3 + PAGE_SIZE];

        byte[] noresult = new byte[1];

        // Write to the SPI EEPROM
        //
        // The AT25080A EEPROM has 32 byte pages.  Data can be written
        // in pages, to reduce the number of overall SPI transactions
        // executed through the Cheetah adapter.
        n = 0;
        while (n < length)
        {
            CheetahApi.ch_spi_queue_clear(handle);
            CheetahApi.ch_spi_queue_oe(handle, 1);

            // Send PAGE_WRITE_BATCH_SIZE number of pages to the Cheetah per
            // batch shift
            for (i = 0; i < PAGE_WRITE_BATCH_SIZE; i++)
            {
                if (n >= length)
                {
                    break;
                }

                // Send write enable command
                CheetahApi.ch_spi_queue_ss(handle, 0x1);
                CheetahApi.ch_spi_queue_byte(handle, 1, 0x06);
                CheetahApi.ch_spi_queue_ss(handle, 0);

                // Assemble the write command and address
                Console.Write("addr = 0x{0:x4}; ", addr);
                data_out[0] = (byte)0x02;
                data_out[1] = (byte)((addr >> 8) & 0xff);
                data_out[2] = (byte)((addr >> 0) & 0xff);

                // Assemble the data
                j = 3;
                do
                {
                    data_out[j++] = (zero != 0) ? (byte)0 : (byte)n;
                    ++addr; ++n;
                } while ((n < length) && ((addr & (PAGE_SIZE - 1)) != 0));

                Console.Write("num bytes = {0:d}\n", j - 3);
                Console.Out.Flush();

                // Queue the write transaction
                CheetahApi.ch_spi_queue_ss(handle, 0x1);
                CheetahApi.ch_spi_queue_array(handle, j, data_out);
                CheetahApi.ch_spi_queue_ss(handle, 0);

                // Put in a wait for the write cycle time
                CheetahApi.ch_spi_queue_delay_ns(handle, PAGE_WRITE_DELAY_NS);
            }

            // Shift the page writes
            // Don't need the results back from the shift
            Console.Write("Shifting data\n");
            Console.Out.Flush();
            batch = CheetahApi.ch_spi_batch_length(handle);
            count = CheetahApi.ch_spi_batch_shift(handle, 0, noresult);
            if (count != batch)
            {
                Console.Write("Expected {0:d} bytes but only received " +
                              "{1:d} bytes\n", batch, count);
                return;
            }
            Console.Write("Shift complete\n");
            Console.Out.Flush();
        }
    }