65Org16.x Dev. Board V1.0 using a Spartan 6 XC6LX9-3TQG144
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
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
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.
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
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
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:
I came up with this code:
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.
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
Last edited by ElEctric_EyE on Mon Oct 24, 2011 3:35 pm, edited 2 times in total.
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
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
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.
... 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.
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
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
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
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...
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.
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Quote:
Isn't I2C meant to be over large distances?
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
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...
...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
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA