Q68 I2C addresses.

The Thor, Aurora, Q40, Q60 & Q68 etc. are discussed here.
martyn_hill
Aurora
Posts: 909
Joined: Sat Oct 25, 2014 9:53 am

Re: Q68 I2C addresses.

Post by martyn_hill »

Hi Peter
Peter wrote:My hope was that bitbanging I2C is simple enough, so people could live without me providing example code. It seems not so - and I stille have providing I2C example code on my to-do-list.
Perhaps we can help here, with just a teensy-bit of guidance from your (busy) self!

a) Could the Minerva MkII I2C primitives be used as a framework within Q68, once the port addresses are replaced? If so, M_ii_drive_asm should be a sufficient starting point for those of us with more cycles to spare than you :-)

b) Can you confirm that the 'keys_q68' include definitions file currently available in the SMSQ source is incorrect, as it has the following:

[src_keys_q68, lines 115..116]
i2c_scl equ $1c00c ; ?
i2c_sda equ $1c00e ; ?

Regards - and thank you again for Q68!


User avatar
Pr0f
QL Wafer Drive
Posts: 1298
Joined: Thu Oct 12, 2017 9:54 am

Re: Q68 I2C addresses.

Post by Pr0f »

Not 68K, but probably not too difficult to transpose to 68K c or assembler:

https://calcium3000.wordpress.com/2016/ ... al-part-i/


User avatar
Whopper
Over Heated PSU
Posts: 126
Joined: Tue Oct 24, 2017 4:04 pm

Re: Q68 I2C addresses.

Post by Whopper »

Peter wrote:The Q68 manual is correct regarding i2C addresses. Note that the clock register is output only, nothing you can read there.
Peter,

Thank you for this. Now I need to check the actual pins and their levels, but I would have needed to do that anyway.

If the CLK ($1C1C0) is un readable, how do you check for contention? Or do you just 'go for it'?

You are, of course, right BitBanging I2C is fairly simple and should present no problems to anyone serious enough to have a go at it.


Thanks,


Whopper


You woke me for THAT!!!
Derek_Stewart
Font of All Knowledge
Posts: 3929
Joined: Mon Dec 20, 2010 11:40 am
Location: Sunny Runcorn, Cheshire, UK

Re: Q68 I2C addresses.

Post by Derek_Stewart »

martyn_hill wrote: b) Can you confirm that the 'keys_q68' include definitions file currently available in the SMSQ source is incorrect, as it has the following:

[src_keys_q68, lines 115..116]
i2c_scl equ $1c00c ; ?
i2c_sda equ $1c00e ; ?
Hi Martin,

I had a look at the SMSQ/E Q68 key file, the drginition of; i2c_scl and i2c_sda is incorrect.

I will ask Wolfgang to change the equates.

But on saying this the I2C or IIC is not programmed within SMSQ/E, which why we have to absolute addresses rather than Traps or Vectors.

The Minerva MKIi drive_asm file defines access to the I2C interface, which is a little more complicated than the Q68.


Regards,

Derek
User avatar
Peter
QL Wafer Drive
Posts: 1953
Joined: Sat Jan 22, 2011 8:47 am

Re: Q68 I2C addresses.

Post by Peter »

martyn_hill wrote:Can you confirm that the 'keys_q68' include definitions file currently available in the SMSQ source is incorrect, as it has the following:

[src_keys_q68, lines 115..116]
i2c_scl equ $1c00c ; ?
i2c_sda equ $1c00e ; ?
Yes incorrect. It has historical reasons. The hardware was changed toward longword alignment after the initial SMSQ/E port was already done.
Thank YOU for the QL network driver!


User avatar
Peter
QL Wafer Drive
Posts: 1953
Joined: Sat Jan 22, 2011 8:47 am

Re: Q68 I2C addresses.

Post by Peter »

To get you going, here's a quick hack for the TF Services Analogue interface.
The wait(500000) in main() should of course be replaced by a non-polling delay.

Code: Select all

#include <stdio.h>

#define TIME_CPU (* (volatile unsigned long*) 0x1C060)

#define I2C_SCL (* (volatile unsigned char*) 0x1C1C0)
#define I2C_SDA (* (volatile unsigned char*) 0x1C1C4)

void wait(unsigned int usec)
{
  unsigned long start, diff;
  
  start = TIME_CPU;
  diff = 40*usec;
  while ((TIME_CPU-start) < diff);
}

void i2c_dly(void)
{
  wait(100); /* Not at maximum speed */
}

void i2c_start(void)
{
  I2C_SDA = 1; i2c_dly();
  I2C_SCL = 1; i2c_dly();
  I2C_SDA = 0; i2c_dly();
  I2C_SCL = 0; i2c_dly();
}

void i2c_stop(void)
{
  I2C_SDA = 0; i2c_dly();
  I2C_SCL = 1; i2c_dly();
  I2C_SDA = 1; i2c_dly();
}

unsigned char i2c_rx(char ack)
{
  unsigned char x, d=0;
  I2C_SDA = 1; i2c_dly();
  for(x=0; x<8; x++)
  {
    d <<= 1;
    I2C_SCL = 1; i2c_dly();
    if(I2C_SDA)
      d |= 1;
    I2C_SCL = 0; i2c_dly();
  } 
  if(ack)
    I2C_SDA = 0;
  else
    I2C_SDA = 1;
  i2c_dly();
  I2C_SCL = 1; i2c_dly();
  I2C_SCL = 0; i2c_dly();
  I2C_SDA = 1; i2c_dly();
  return d;
}

unsigned char i2c_tx(unsigned char d)
{
  char x;
  unsigned char ack;
  for(x=8; x; x--)
  {
    if(d & 0x80)
      I2C_SDA = 1;
    else
      I2C_SDA = 0;
    i2c_dly();
    d <<= 1;
    I2C_SCL = 1; i2c_dly();
    I2C_SCL = 0; i2c_dly();
  }
  I2C_SDA = 1; i2c_dly();
  I2C_SCL = 1; i2c_dly();
  ack = !I2C_SDA;
  I2C_SCL = 0; i2c_dly();
  return ack;
}

void PCF8591InitADC(unsigned char adr)
{
  unsigned char ack;
  i2c_start();
  /* 1 0 0 1 A2 A1 A0 R/W */
  ack = i2c_tx(0x90 | (adr<<1));
  if (!ack)
    printf("Missing Acknowledge after write address byte\n");
  /* Analogue output enabled, 4 single-ended inputs, auto-increment */
  /* Start with channel 1, so we are at channel 0 when reading */
  ack = i2c_tx(0x45|adr);
  if (!ack)
    printf("Missing Acknowledge after control byte\n");
  i2c_stop();
}

void PCF8591ReadADC(unsigned char adr, unsigned char data[])
{
  unsigned char ack;
  i2c_start();
  /* 1 0 0 1 A2 A1 A0 R/W */
  ack = i2c_tx(0x91 | (adr<<1));
  if (!ack)
    printf("Missing Acknowledge after read address byte\n");
  data[0] = i2c_rx(1);
  data[1] = i2c_rx(1);
  data[2] = i2c_rx(1);
  data[3] = i2c_rx(0);
  i2c_stop();
}

void main(void)
{
  static unsigned char data[4];
  
  PCF8591InitADC(0);
  do
  {
    PCF8591ReadADC(0, data);
    printf("PCF8591 analogue inputs: $%02X $%02X $%02X $%02X\n",
      (int)data[0], (int)data[1], (int)data[2], (int)data[3]);
    wait(500000);
  }
  while(1);
}


Derek_Stewart
Font of All Knowledge
Posts: 3929
Joined: Mon Dec 20, 2010 11:40 am
Location: Sunny Runcorn, Cheshire, UK

Re: Q68 I2C addresses.

Post by Derek_Stewart »

Hi,

In addition to Peter's Q68 I2C example code.

Here are some I2C Resources:

I2C Primer
https://www.i2c-bus.org/i2c-primer/

Sparkfun I2C Tutorial
https://learn.sparkfun.com/tutorials/i2c/

Wikipedia I2C Article
http://en.wikipedia.org/wiki/I%C2%B2C

I2C-bus specification and user manual
UM10204.pdf
I2C-bus specification and user manual
(1.33 MiB) Downloaded 164 times


Regards,

Derek
Post Reply