65Org16.x Dev. Board V1.0 using a Spartan 6 XC6LX9-3TQG144

Topics relating to PALs, CPLDs, FPGAs, and other PLDs used for the support or creation of 65-family processors, both hardware and HDL.
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Post by ElEctric_EyE »

Next step is to ...
Last edited by ElEctric_EyE on Mon Oct 24, 2011 3:32 pm, edited 2 times in total.
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Post by ElEctric_EyE »

Working on the Sim and trying to get the I2C core to wake up. At least now, during synthesis, the SCL and SDA lines are not being optimized out. I have pullups on the lines and have written some simple code to send it the proper bits to activate the core, and send a byte of data, but nothing yet.
For the wishbone interface on the I2C core, I have the CYC and STB lines tied together for the active high CS. In ISim I can see the address decoding is correct and the core is getting the correct data at the correct time. I think I will pursue looking at some internal signals within the core.

On another unrelated note, looking at all my synthesis warnings, I found there was a problem with my ORs module. My registers were only 1 bit wide. I fixed that below.

Code: Select all

   module ORs( 
              clk, 
              WE, 
              CS1, 
              CS2, 
              CS3, 
              CS4, 
              INA, 
              INB, 
              INC, 
              IND, 
              INE, 
              INF, 
              ING, 
              DO 
              ); 
              
      input clk;         //cpu phase 2 
      input WE;         //cpu WE 
      input CS1;         //I2C active high enable 
      input CS2;         //PS2 active high enable 
      input CS3;         //SPI active high enable 
      input CS4;         //UART active high enable 
      input [15:0] INA;   //from 4Kx16 Zero Page RAMDO 
      input [15:0] INB;   //from 4Kx16 Stack RAMDO 
      input [15:0] INC;   //from 4Kx16 ROMDO 
      input [7:0] IND;   //from I2CDO 
      input [7:0] INE;   //from PS2DO 
      input [7:0] INF;   //from SPIDO 
      input [7:0] ING;   //from UART2BUSDO 
     output [15:0] DO;   //to CPUDI 
     
     reg [7:0] INDHOLD; 
     reg [7:0] INEHOLD; 
     reg [7:0] INFHOLD; 
     reg [7:0] INGHOLD; 
     
// when 8-bit cores are not selected, outputs are zero. 

   always @(posedge clk) 
   begin 
      if (!WE && CS1 == 1)    
      INDHOLD [7:0] <= IND [7:0]; 
      else INDHOLD [7:0] <= 0; 
       
      if (!WE && CS2 == 1) 
      INEHOLD [7:0] <= INE [7:0]; 
      else INEHOLD [7:0] <= 0; 
       
      if (!WE && CS3 == 1) 
      INFHOLD [7:0] <= INF [7:0]; 
      else INFHOLD [7:0] <= 0; 
       
      if (!WE && CS4 == 1) 
      INGHOLD [7:0] <= ING [7:0]; 
      else INGHOLD [7:0] <= 0; 
       
   end 
  
  assign DO = INA | INB | INC | INDHOLD | INEHOLD | INFHOLD | INGHOLD; 
  
endmodule
Last edited by ElEctric_EyE on Mon Oct 24, 2011 3:33 pm, edited 2 times in total.
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Post by ElEctric_EyE »

I see a bit of code related to the clock in the master_bit_ctrl, that is commented out, with a comment stating that it is for simulation purposes. When I uncomment it, it gives an error, so I'll have to skip the sim and dive right into the hardware. Hopefully I'll see a nice clock on SCL when I try to send a byte!
Last edited by ElEctric_EyE on Mon Oct 24, 2011 3:33 pm, edited 2 times in total.
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Post by ElEctric_EyE »

I can tell this is going to be a SOB...
According to the specs on page 13 example 1, program example of how to send a byte:

Code: Select all

I2C Sequence: 
1) generate start command 
2) write slave address + write bit 
3) receive acknowledge from slave 
4) write data 
5) receive acknowledge from slave 
6) generate stop command 
Commands: 
1) write 0xA2 (address + write bit) to Transmit Register, set STA bit, set WR bit. 
-- wait for interrupt or TIP flag to negate -- 
2) read RxACK bit from Status Register, should be ‘0’. 
write 0xAC to Transmit register, set STO bit, set WR bit. 
-- wait for interrupt or TIP flag to negate -- 
3) read RxACK bit from Status Register, should be ‘0’.

I came up with this code:

Code: Select all

START:   LDA #%00010111 
      STA $FFFF0000 
      LDA #$0000 
      STA $FFFF0001      ;set prescale register (12MHz/(5x100kHz))-1=23 
      LDA #%10000000    
      STA $FFFF0002      ;enable I2C core, disable interrupt 
      LDA #%10110000 
      STA $FFFF0003      ;put slave address, set write bit in transmit register 
      LDA #%10010000 
      STA $FFFF0004      ;generate repeated start condition and set write bit 
      JSR TIP         ;wait for transfer to complete 
      LDA #$0008 
      STA $FFFF0003      ;send Access DAC command 
      JSR TIP 
      LDA #$00FF 
      STA $FFFF0003      ;send LSB DAC data 
      JSR TIP 
      LDA #$C0 
      STA $FFFF0003      ;send MSB DAC data 
      JSR TIP 
      LDA #%01010000 
      STA $FFFF0004      ;generate stop condition 

DONE:      JMP DONE 
       
TIP:      LDA $FFFF0004 
      AND #%0000000000000010 
      BNE TIP         ;1=transferring data, 0=tranfer complete 
NACK      LDA $FFFF0004 
      AND #%0000000010000000 
      BNE NACK         ;1=no ack from slave, 0=ack from slave 
      RTS 
The only way to really test where this code is hanging up is with an output test port in which different bits are set depending on what part of the code it gets stuck at. 4 bits should be enough.
Last edited by ElEctric_EyE on Mon Oct 24, 2011 3:35 pm, edited 2 times in total.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8774
Joined: 30 Aug 2002
Location: Southern California
Contact:

Post by GARTHWILSON »

Learning any interface is a bit of a pain, but you just start making the tiny building blocks of code, test them if you want to, then build bigger ones with them, and so on. The only I²C thing I ever did that didn't work on first try was a 24256 EEPROM, and it was because the ST Microelectronics data sheet was missing a STOP condition after a busy poll in one of the situatlons. I found out by experimenting. They probably left it out because they didn't expect anyone to be doing a busy poll at that point, but although it was not necessary, I had it in one of my building blocks of code so I could use the same one for more things.
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Post by ElEctric_EyE »

GARTHWILSON wrote:
... The only I²C thing I ever did that didn't work on first try was a 24256 EEPROM...

Was that your first attempt at I2C as well? And what value were your Pullups, do you remember?

Got the 3-bit port working, now I have to insert the values of the port and see where it's sticking. I'm imagining it is stuck in the TIP (Transfer In Progress) loop. We'll see before tonight's end. I know at least it got far enough to set all 3 bits high.
Last edited by ElEctric_EyE on Mon Oct 24, 2011 3:35 pm, edited 2 times in total.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8774
Joined: 30 Aug 2002
Location: Southern California
Contact:

Post by GARTHWILSON »

I don't think it was my first I²C project. Pull-ups were 4.7K.
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Post by 8BIT »

While implementing the I2C EEPROM on the SBC-4P, I had read someones calculations (didn't keep the link) and he had calculated 1.8k for maximum speed. I'll try to find the link.

Daryl

EDIT ADD LINK

http://ww1.microchip.com/downloads/en/devicedoc/i2c.pdf

Page 9 has a table : 4.7K <100kHz : 2.2k for 100khz : 1k for 400 khz
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Post by ElEctric_EyE »

Garth & Daryl, thanks a mil for looking that up...
Cred to Bitwises' assembler again. Check my above code out. The assembler works, I've checked the .bin. It right justifies non-standard 16-bit values, so no need to type in all 16 bits, hex, binary. Doesn't matter. Nice!

Isn't I2C meant to be over large distances? I've not done alot of research on it, was too busy on the layout. One useful setting Xilinx FPGA's have are drive current choices per output pin, which I've experimented on the 6502SoC when I was driving a TFT. In that situation it seemed I could lower noise in the form of bad data to the display, by lowering the default 12mA output current to 4mA IIRC. I may be able to keep the 4.7K pull-ups in this present situation, and lower the drive current in the same manner, since the distances are very small. Then again maybe not. Your info will be at the back of my mind just in case...

I have found my endless loop at the NACK, the second part of the TIP loop in the software posted above. Reading from the DS1085 is not resulting in proper data to the CPU core which means my ORs module is still suspect since it is in between. I need to hook up the keyboard section next, since it is also always spitting data out (albeit zeros when not selected by address decoding), to prove the ORs module does work as expected, as I have a proof that this core has worked in the 6502SoC.
After this I'm done using a DMM to probe volts on the 3-bit port. Time for next phase of hooking up the TFT display to see high speed data transfer values shown in graphic bits...
Last edited by ElEctric_EyE on Mon Oct 24, 2011 3:35 pm, edited 2 times in total.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8774
Joined: 30 Aug 2002
Location: Southern California
Contact:

Post by GARTHWILSON »

Quote:
Isn't I2C meant to be over large distances?
It can go a long way (hundreds of meters) with special bus buffers; but normally the things on the bus will all be on the same PC board. The maximum bus capacitance is specified to be 400pF (without repeaters) which this overview says is about 20-30 devices or 10 feet of wire.

I missed what the 3 bits of your port were. I²C only has two lines, clock and data.

I've always bit-banged it, so getting the fastest rise times was not a concern. What I found when I experimented with the LM339 comparator however was that going below a few kilohms actually became counterproductive.
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Post by ElEctric_EyE »

GARTHWILSON wrote:
...I missed what the 3 bits of your port were. I²C only has two lines, clock and data...

The port was used as sort of a troubleshooting marker. In the beginning of the program above I set it to zero. The value I read was a steady 4 on the 'scope. I realized I needed to look at the signals on a scope not a DMM! I changed the program above to store a 4 in the beginning of the NACK BNE loop. Value 3 was at the beginning of the TIP BNE loop and it made it past that... So the 65Org16 core appears to be reading and outputting good data.

The DS1085 datasheet doesn't mention pull-up values for the I2C bus. The TSC2003 touchscreen controller shows 1.2K pullups. The CS4954 video IC shows 1.5K pullups, with 110ohm resistors in series (not gonna bother with those). So I am using 4.7K pullups, I am just abit concerned, but I don't think that is where my trouble lies. Will try more experimentation today...
Last edited by ElEctric_EyE on Mon Oct 24, 2011 3:36 pm, edited 2 times in total.
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Post by ElEctric_EyE »

..
Last edited by ElEctric_EyE on Thu Oct 20, 2011 5:48 pm, edited 1 time in total.
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Post by ElEctric_EyE »

..
Last edited by ElEctric_EyE on Thu Oct 20, 2011 5:48 pm, edited 1 time in total.
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

.

Post by ElEctric_EyE »

..
PontusO
Posts: 43
Joined: 22 Jul 2004
Location: Sweden
Contact:

Post by PontusO »

Hupp, what's happening here?
Post Reply