Skip to main content

Show Posts

This section allows you to view all Show Posts made by this member. Note that you can only see Show Posts made in areas you currently have access to.

Messages - udif

1
CPLD programmable logic / Re: XC9572 Development ???
Don't be fooled by the EPM570. it's not a 72-macrocell vs 570 thing.
For the XC9572, each macrocell  can accept one or more product terms, where each one is a 54-input AND gate. just like other PAL and CPLD devices.
The EPM570 macrocells are more like 4-bit LUTs, so if you have a wide expression, you will quickly see you're wasting many macrocells to implement it.

The EPM570 is more like a tiny FPGA with built-in nonvolatile configuration memory, and no internal memories (AFAIR).
The best way to benchmark such devices is to take a tiny piece of vhdl/verilog code which you fin useful/representative of what yoiu need, try to fit it using the vendor's tools, and checking the final utilization.
2
General discussion / Re: A neat trick for high-speed addressing of RAM modules
[quote author="nickjohnson"]
Yup, if you're in a position to use a CPLD, of course, then all this goes out the window. :)[/quote]

Not necessarily.
I've used this technique for creating a simple clock divider in my 7400 contest entry (game of life in CPLD).
The benefit of using a LFSR vs a counter (I wanted a ~1:1000 divider) is that a LFSR-based counter takes far less product terms.
3
Open 7400 Competition / [Entry]A CPLD based 8x8 game-of-life
Sorry for the terse post, but my time is running out (deadline in a few hours).

My entry to the 7400 competition is a CPLD based 8x8 game of life.
Yes, I saw there was another 8x8 game of life posted in the competition forum, but when I saw it in the forum it was too late for me to change mine, and anyhow the designs are entirely different.

Please be sure to check the REAMDME.txt file in the attached ZIP with  all the details.

Pictures:
https://picasaweb.google.com/udi.finkel ... _Suo6my7wE

Video:
http://youtu.be/2Ykv4kL7CUk

Here is a short quote from the README file:
Quote
Algorithm:
A 64 bit cyclic shift register is shifted to the right on every cycle. cell 0 is always the center cell, and a 6 bit row/column counter tracks the logical position of this cell. The neighbouring cells are collected, taking into account the playing field edges (we dont wrap around), and the resulting nine bits are summed. The sum output and current cell value are used to calculate the new cell value. The output value is then pushed into a shift register so that the new value won't affect the remaining calculation for this generation. The shift register replaces the old value at the point where it can no longer affect current gen calculations.
New starting patters can be entered by a joystick that moves up/down/left/right and a center button that toggles the current cell value.
The next gen is calculated by pressing a switch.

Implementation:
The project was coded in Verilog, using many small modules. The reason for that was that I wanted to be able to easily fit it into multiple XC9572XL boards I had. The naive approach would have been to put the large data shift register in one device, and the rest of the logic in a 2nd device, but this turned out to be impossible due to lack of I/O's in the other device. I ended up parametrically splitting the data array between the two devices so I can easily balance a few macorcells here or there in each device, if the need arises. I also made sure the design fits in an XC2C128 device I had.
The design itself is fully parameterized, and changing the X,Y parameter at the top level will infer the correct logic for any size chosen. Two extra redundant parameters, LOG2X and LOG2Y were added because Icarus Verilog does not support constant functions yet (which would have enabled us to calculate the LOG2 value within each block).
A test bench was prepared that generated a test pattern, and watched the LED output signals to reconstruct the display on each generation. The output was then displayed.

A third device was added for side tasks such as debouncing the input switches, dividing the original clock, and leaving room for a future capacitive touch input.

The following diagram helps understanding the core logic that calculates the game:

All the project files are attached in the zip file.
The only thing missing is a true schematics, but I ran out of time. The schematics can be easily inferred from the 3 CPLD UCF I/O pin lists (all pins with identical names should be connected together).
clk_in driven by a 23MHz oscillator
row<n> drives a ULN2803A, which sinks the low side of a 8x8 LED array
col<n> drives a 74LS245 , which drives the high side of a 8x8 LED array through 1.1K resistors.
key_XXX are hooked up to a mini 40way digital thumb joystick.
One I/O button on the CPLD breakout boards is used for reset
Another I/O button on the cap_touch CPLD is used as key_next (advance game state).
5
Pirate PIC programmer / Re: Strange ICSP PIC programming problem
What happens if I set the jumper on the PIC programming adapter to 5V?
(In practice, I already tried setting this jumper to 5V, but it didn't help).

As far as I could understand from the schematics, this sets the target's VDD (The V+ pin on the adapter's ICSP) minus the forward voltage on D2, as well as driving it on pin 6 towards the BP. On the BP I see this is used for driving the pullups on pins 1-4, which drive all the PIC adapter's relevant pins (PGC,PGD). Wouldn't this be enough to drive those signals high enough? How are these signals driven from the BP? Are they open collector or normal outputs?

[some time later]OK, I dug through my piratePICprog sources, and came back with some new speculations:

according to this line:
buspirate.c:128      if (BP_WriteToPirate(fd, "x4F")){
The pullups themselves are already enabled (bit 2).

However, it seems that the output pins are set to 3.3V mode and not HiZ.
buspirate.c:115       if (BP_WriteToPirate(fd, "x88")){
This makes the pullups irrelevant, since the output pins will be pulled to the output voltage that are much stronger than the pullup's 10K resistance.

According to http://dangerousprototypes.com/docs/Raw ... 3Dnot_used , this should have been 0x80 to enable HiZ mode.

It seems that changing line 115 to 0x80, and setting the HVP adapter's jumper to 5V should fix the problem.
I'll try this later tonight.

Udi
6
Pirate PIC programmer / Strange ICSP PIC programming problem
Hi,

I'm back to my PIC experiments...
I'm trying to bring up my PIC board after doing some other stuff for the last few weeks.
The board is a partially-populated "RGB color changer" and has a PIC 18F2553, a 8MHz xtal + 2x33pf caps (not sure it's the right value), two 0.1uF caps for VUSB, connectors for ICSP, USB and serial. MCLR is pulled high by a diode and a resistor, as in all DP's PIC circuits.
I hook it though a BP v3a with the PIC programming adapter. PGC,PGD, GND and MCLR are connected. V+ on the PIC programming adapter is disconnected.
When I hook up the board's VDD to 3.3V, I can successfully read the PIC using piratePICprog. When VDD is 5V, my 18F2553 is not recognized??!!

This is very consistent - the board is fed with VCC from a bench lab power supply. At 3.3V, reading is fine. at approx 4.5V, the device starts acting flaky, and is no longer recognized.

Any ideas?
7
Pirate PIC programmer / Re: PIC programming adapter problem
I think you can commit the changes.

After all my efforts have made no change on the result (set full tblptr on each write, increase write delay to 2ms, etc.) I decided to take a close look at the actual data.
Here is the relevant data from the diolan bootrom:
Code: [Select]
:020000040030CA
:0100000021DE
:010001004EB0
:0100020038C5
:010003001EDE
:010005008377
:010006008178
:010008000FE8
:01000900C036
:01000A000FE6
:01000B008074
:01000C000FE4
:01000D0040B2
:00000001FF
Here is the same data, read back from the 18F2553:
Code: [Select]
:020000040030CA
:0E000000214E011E0083C4000FC00F800F4070
:00000001FF
At first, I noticed that the fist two bytes were and the last 6 bytes Identical, but not the middle bytes. I couldn't explain the other difference.

Then last night I noticed for the first time that the original Hex file skipped some addresses, namely 0x300004 and 0x300007.
Earlier, before I noticed this, I thought some of the data was written to the wrong locations (specifically, 0x83 at 0x300005), when in fact it was OK . Those undefined addresses are indeed read as 0x00, as defined by the spec.

This leaves me with 0x300006 (CONFIG4L) that is read as 0xc4 when written as 0x81, and 0x300002 (CONFIG2L) that is read as 0x01 when written as 0x38). I now believe this is something specific to these registers and my specific PIC type, the 18F2553.

Maybe someone who has more PIC experience than me can explain why?
8
Pirate PIC programmer / Re: PIC programming adapter problem
[quote author="robots"]Looks much better :-) Should i wait till the fuse writing is working?
[/quote] Probably Yes, it will only be 1-2 more days, and currently the code adds no functionality beyond my previous patch, that already added code read/write ability for the 18F2553.

[quote author="robots"]http://ww1.microchip.com/downloads/en/DeviceDoc/39622L.pdf

Programming specification states that you should set all the TBLPRTx registers.
[/quote]
The link to the document is naturally the same one I'm looking at.
I don't think the document says I need to set all 3 TBLPRTx registers between writes.
I think the note on section 3.6 regarding setting the full address only relates to not using the 0xD command (write 2 bytes and post-increment).
I set all 3 TBLPRTx registers at the beginning, then for the next configuration writes, set only the new low address. I think this is consistent with their example as well. Even/Odd writes are separate, and they change only the lowest address register between writes.
In any case, if I will test this as well, just to be sure (this should be quick).
[quote author="robots"]So the fuse writing code would be like:
Code: [Select]
setup fuse write:
iface->PIC416Write(0x00, 0x8EA6); //setup PIC - BSF  EECON1, EEPGD
iface->PIC416Write(0x00, 0x8CA6); //setup PIC - BSF  EECON1, CFGS
// set table ptrs
iface->PIC416Write(0x00, 0x0e30); //movlw 0x30
iface->PIC416Write(0x00, 0x6ef8); //movwf TBLPTRU
iface->PIC416Write(0x00, 0x0e00); //movlw 0x00
iface->PIC416Write(0x00, 0x6ef7); //movwf TBLPTRH

cycle through fuses:
the same thing you have.
If this won't help, only analyzer will.

Page 10 suggest that you have only 8 (16bit config words), thats 16writes.[/quote]

I'm more worried about the write delay as set by the Bus Pirate. It is defined to be 1ms, which is what the spec says, with no safety margins.I'll take a look with the OLS to see what the actual delay is.
10
Pirate PIC programmer / Re: PIC programming adapter problem
[quote author="robots"]I have quickly looked at the patch, and there are quite few problems:

1. Static functions are static for a reason, and not to be exposed in *.h files.
[/quote]
You're right ofcourse. I moved those declarations to the beginning of pic18.c but that was on my laptop, and I forgot to sync it to my main machine.

[quote author="robots"]
2. Write_mem_table and read_mem_table use the same type, Why not have them typedef-ed ?  Why do you have array of function pointers? (functions are pointers), you would have no & in the array and calling function from array would look like write_mem(xx) instead of (*write_mem)(xxx).
[/quote]
typedefs are a good idea, I'll fix that later today.
As for arrays of functions - As far as I know, you can't have an array of functions in C, just array of function pointers.
http://c-faq.com/~scs/cclass/krnotes/sx8f.html
Quote
(The only possibilities that C doesn't support are functions returning arrays, and arrays of functions, and functions returning functions.)
I even tried that with GCC. The following code works:
Code: [Select]
#include "stdio.h"

void a(void) { printf("an");};
void b(void) { printf("bn");};
void c(void) { printf("cn");};
void d(void) { printf("dn");};

void (*arr[])(void) = {&a, &b, &c, &d};

int main(int argc, char *argv[])
{
int i;

  for (i = 0; i < sizeof(arr)/sizeof(arr[0]); i++) {
    (*arr[i])();
  }
  return 0;
}
The code below, however, doesn't work, producing the error:
Quote
b.c:8: error: declaration of 'arr' as array of functions
Code: [Select]
#include "stdio.h"

void a(void) { printf("an");};
void b(void) { printf("bn");};
void c(void) { printf("cn");};
void d(void) { printf("dn");};

void (arr[])(void) = {a, b, c, d};

int main(int argc, char *argv[])
{
int i;

  for (i = 0; i < sizeof(arr)/sizeof(arr[0]); i++) {
    (arr[i])();
  }
  return 0;
}
[quote author="robots"]3. Functions PIC18_Write and PIC18_Read are too generic. I think we should go with my proposal 1. Have this generic function in pic.c and call different PICxx_writeEeprom from the selected protocol.
[/quote]
I think this is a matter of personal style. The function in pic.c is iterating over the linked list of memory elements, calling the family-specific write function, which in turn decodes the memory address to decide what type of memory it is, and call the corresponding write function within that family. This was you isolate the fact that PIC18 has 3 different types of memory writes from the main program.
[quote author="robots"]
4. There is something wrong with the for-cycle in Write_fuse. 3/4 of the code are the same. :-)
[/quote]I assume you are bothered by the main loop in PIC18_Write_Fuse. Do you like this loop better?
Code: [Select]
	for(ctr = 0; ctr < length; ctr ++) {
if ((ctr & 1) == 0)
DataByte = (((uint8_t *)Data)[ctr + 1] << 8) + ((uint8_t *)Data)[ctr];
iface->PIC416Write(0x00, 0x0E00 | ctr);
iface->PIC416Write(0x00, 0x6EF6);
iface->PIC416Write(0x0F, DataByte);
iface->PIC416Write(0x40, 0x0000); // see PIC18_Write_Flash below
iface->flush();
}
[quote author="robots"]
These are of course non-functional bugs, just to keep the program in maintainable state.[/quote]
Generally speaking, when I contribute code to an existing project, I adapt to that project's coding style. Some of the choices I made were clearly no my personal coding style (The 3 line DataByte calculation, uppercase in variables, etc.).
Personally, for example, I would have avoided gcc extensions such as this:
Quote
   char tmp[21] = { [0 ... 20] = 0x00 };
11
Pirate PIC programmer / Re: PIC programming adapter problem
Here is my first take at writing configuration bits for the 18F2553 (And probably other 18Fxxx devices).
It is still not working 100%, but I want to give it an early review by others, who may spot the remaining bugs.

At the moment it seems to write only SOME of the configuration words, or perhaps some of these are write only and can't be read back (I haven't read the whole configuration registers descriptions yet). The first two bytes and the last 6 always seems to be OK, but the middle 6 always seems to be partially corrupted (only 1-2 bytes are OK, and one of the values is in the wrong address).
My test file was the diolan bootrom from the USB IR Toy repository, which I hand-edited to use a 8MHz xtal instead of the original 20Mhz (0x300000: 0x24 -> 0x21, and fixed the checksum).

I also removed some unused functions from pic24.c and pic16.c (ReadFlash and WriteFlash) because I removed those fields from proto_ops_t. (Dead code can always be resurrected from version control - that's what its there for).

I will probably end hooking up my Open Logic Sniffer to see what's really coming out of the Bus Pirate (now we only need to code an ICSP mode to the OLS software).

comments are welcomed!
12
Pirate PIC programmer / Re: PIC programming adapter problem
I took a look at your latest commit.

I'm all for what you refer to as solution 2.
I don't think you should add special functions for EEPROM and flash. I think that the main code should keep calling the generic Read/Write functions, and let the device/family-specific code handle the different memory types.
After all, as far as the HEX file is concerned, configuration writes is simply data at 0x300000. There is no reason to expose all the memory types at the generic layers.

For example, the 18F read/Write code should detect that writes to 0x300000 are configuration writes and treat them as such.

Since the current API calls for transferring a pointer and a length for the memory to be read/written, then either the family/device-specific code needs to handle that (i.e. if you get a 32 byte write request to configuration space, you need to break it into byte writes yourself), or the Read/Write function will return the actual number of bytes read/written , and the calling code will need to adjust.

You can have separate read/write routines for EEPROM/flash/config/whatever, but I think they should be kept static, and be called from the main read/write functions according to the tblptr.
13
Pirate PIC programmer / Re: PIC programming adapter problem
[quote author="tayken"][quote author="udif"]Am I reading pic18.c correct , and writing configuration bits for 18Fxxx is not supported yet?[/quote]
I was able to flash a PIC18f without any problems but that I have to check. Config bits should be there, that was the problem with the major haul. Are you looking the pic18.c file inside software folder? The ones inside software folder are the ones most up to date.[/quote]

Yes, I was looking into the one under 'software'.
I'm basing my conclusions on http://http://ww1.microchip.com/downloads/en/DeviceDoc/39622L.pdf

The reading part is OK, since reading configuration registers is identical to reading flash memory.
Quoting section 4.1 from the document above:
Quote
This technique will work to read any memory in the 000000h to 3FFFFFh address space, so it also applies to the reading of the ID and Configuration registers.

The writing part in pic.c treats flash memory the same way as configuration bits:
Code: [Select]
int PIC_WriteMemory(struct picprog_t *p, struct memory_t *mem)
{
        struct pic_chip_t *pic = PIC_GetChip(p->chip_idx);
        struct pic_family_t *fam = PIC_GetFamily(pic->family);
        struct proto_ops_t *proto = PIC_GetProtoOps(p->chip_idx);

        struct mem_page_t * page;

        proto->EnterICSP(p, fam->icsp_type);

        page = MEM_GetFirstPage(mem);
        while (page != NULL) {
                printf("Writing page %04lx... n", (unsigned long)page->base);

                // TODO: check address against pic memory map! EEPROM and Fuses might need separate handling
                proto->Write(p, page->base, page->data, page->size);
                page = MEM_GetNextPage(page);
        }

        proto->ExitICSP(p, fam->icsp_type);

}
As you can see, this code doesn'r care if the current page is flash memory or configuration registers.
However, configuration memory is written differently than flash memory.
Flash memory writing procedure is documented in section 3.2 of the spec above, while configuration register writing procedure is described in section 3.6
The differences are minor (a slightly different setup for the config registers, and each byte is written separately).
I plan adding it this week, since I have a blank PIC, and the bus pirate is my only PIC programmer.

There are two lines in the current code (pic18.c) that simply doesn't appear in the 2550 programming document (Table 3.5):
Lines 201-202:
Code: [Select]
        iface->PIC416Write(0x00, 0x6AA6);
        iface->PIC416Write(0x00, 0x88A6);
Line180:
Code: [Select]
        iface->PIC416Write(0x00, 0x84A6); //enable page writes

Are these really required? perhaps they were left here out of trial and error and never removed?