CH375 USB 2.0 host/device interface with FreeBASIC on LPT.

For issues with communication ports, protocols, etc.
Post Reply
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

CH375 USB 2.0 host/device interface with FreeBASIC on LPT.

Post by D.J.Peters »

For my home made CNC project i searched a USB host and device chip and found the CH375.
CH375 is really easy to use and works in parallel or serial mode.

Before I include this chip in my project I test it with the LPT port first.
Image

I got it from eBay
Image

download: FB_CH375.zip PDF's included.

Joshy

Code: Select all

#include once "ch375.bi"
' Address                     MSB                         LSB
'                       Bit:   7   6   5   4   3   2   1   0
'                             R/W R/W R/W R/W R/W R/W R/W R/W
' Base   (Data port)    Pin:   9   8   7   6   5   4   3   2
'                              I   I   I   I   I
' Base+1 (Status port)  Pin: ~11  10  12  13  15
'                                            I/O I/O I/O I/O
' Base+2 (Control port) Pin:                 ~17  16 ~14  ~1

' ~ = inverted
' _ = LO active

' CH375B USB HOST/DEVICE interface on LPT
' D7-0 dataport    R/W bit 7-0 pin 9-2
' _INT  stautsport R   bit 7   pin ~11
' _CS  controlport W   bit 0   pin ~ 1
' _RD  controlport W   bit 1   pin ~14
'  A0  controlport W   bit 2   pin  16
' _WR  controlport W   bit 3   pin ~17


' CS# WR# RD#  A0 D7-D0  Operation for CH375 
'  1   X   X   X   X/Z   Don’t choose CH375, no operation 
'  0   1   1   X   X/Z   Choose CH375, but no operation 
'  0   0  1/X  1   IN    Write command code to CH375’ s commandport 
'  0   0  1/X  0   IN    Write data to CH375’ s data port 
'  0   1   0   0   OUT   Read data from CH375’ s data port 
'  0   1   0   1   OUT   Read interrupt token from CH375B’ s command port, the bit7 is equal to INT# 

const as ushort BASE_PORT    = &H378
const as ushort STATUS_PORT  = BASE_PORT + 1
const as ushort CONTROL_PORT = BASE_PORT + 2

extern "Windows-MS" lib "inpout32"
  declare function PortRead  alias "Inp32" (PortAddress as ushort) as ushort
  declare sub      PortWrite alias "Out32" (PortAddress as ushort, Value as ushort)
end extern

dim shared as double tick
#define delay2us  tick = Timer() +  2e-6 : Do : Loop Until Timer() > tick
#define delay5us  tick = Timer() +  5e-6 : Do : Loop Until Timer() > tick
#define delay10us tick = Timer() + 10e-6 : Do : Loop Until Timer() > tick
#define delay20us tick = Timer() + 20e-6 : Do : Loop Until Timer() > tick
#define delay40us tick = Timer() + 40e-6 : Do : Loop Until Timer() > tick
#define delay50us tick = Timer() + 50e-6 : Do : Loop Until Timer() > tick

' write D0-D7 on LPT pins 2-9
sub write8(v8 as ubyte)
  PortWrite(BASE_PORT,v8)
end sub

' read D0-D7 from LPT pins 2-9
function read8 as ubyte
  dim as ushort v16 = PortRead(CONTROL_PORT)
  PortWrite(CONTROL_PORT,v16 or  &B00100000)
  dim as ubyte v8 = PortRead(BASE_PORT)
  PortWrite(CONTROL_PORT,v16 and &B11011111)
  return v8
end function

' CH375 _CH chip select low active LPT pin 1
sub CS_LO ' ~bit 0
  dim as ushort v16 = PortRead(CONTROL_PORT)
  PortWrite(CONTROL_PORT,v16 or  &B00000001)
end sub
sub CS_HI ' ~bit 0
  dim as ushort v16 = PortRead(CONTROL_PORT)
  PortWrite(CONTROL_PORT,v16 and &B11111110)
end sub

' CH375 _RD read mode low active LPT pin 14
sub RD_LO ' ~bit 1
  dim as ushort v16 = PortRead(CONTROL_PORT)
  PortWrite(CONTROL_PORT,v16 or  &B00000010)
end sub
sub RD_HI ' ~bit 1
  dim as ushort v16 = PortRead(CONTROL_PORT)
  PortWrite(CONTROL_PORT,v16 and &B11111101)
end sub

' CH375 data mode LPT pin 16
sub A0_LO ' bit 2
  dim as ushort v16 = PortRead(CONTROL_PORT)
  PortWrite(CONTROL_PORT,v16 and &B11111011)
end sub
' CH375 command mode 
sub A0_HI ' bit 2
  dim as ushort v16 = PortRead(CONTROL_PORT)
  PortWrite(CONTROL_PORT,v16 or  &B00000100)
end sub

' CH375 _WR write mode low active LPT pin 17
sub WR_LO ' ~bit 3
  dim as ushort v16 = PortRead(CONTROL_PORT)
  PortWrite(CONTROL_PORT,v16 or  &B00001000)
end sub
sub WR_HI ' ~bit 3
  dim as ushort v16 = PortRead(CONTROL_PORT)
  PortWrite(CONTROL_PORT,v16 and &B11110111)
end sub

' CH375 write command byte
' chip must be selected (_CS must be low)
sub CH375_WR_CMD(cmd as ubyte)
  A0_HI ' command mode 
  write8 cmd
  WR_LO
  WR_HI
end sub

' CH375 write data byte
' chip must be selected (_CS must be low)
sub CH375_WR_DATA(d as ubyte)
  A0_LO ' data mode
  write8 d
  WR_LO ' write lo active
  WR_HI
end sub 

' CH375 read data byte
' chip must be selected (_CS must be low)
function CH375_RD_DATA as ubyte
  A0_LO ' data mode
  RD_LO
  dim as ubyte d=read8()
  RD_HI
  return d
end function


' CH375 _INT interrupt pin low active ~bit 7 LPT pin 11
function CH375_RD_INT(byref v as ubyte) as integer
  delay2us
  dim as integer i=10
  while PortRead(STATUS_PORT) and &B10000000=0 andalso i>0
    i-=1
    if i=0 then
      print "CH375_RD_INT() timeout !"
      return 0
    end if
  wend
  ' get interrupt status
  CH375_WR_CMD(CMD_GET_STATUS)
  v=CH375_RD_DATA()
  return -1
end function

function CH375_DISK_READY(byref v as ubyte) as integer
  CH375_WR_CMD(CMD_DISK_READY)
  if not CH375_RD_INT(v) then
    print "CMD_DISK_READY failed no interrupt !"
    return 0
  end if 
  return -1
end function

function CH375_DISK_INIT(byref v as ubyte) as integer
  CH375_WR_CMD(CMD_DISK_INIT)
  if not CH375_RD_INT(v) then
    print "CMD_DISK_INIT failed no interrupt !"
    return 0
  end if 
  return -1
end function

function CH375_TEST_CONNECT(byref v as ubyte) as integer
  CH375_WR_CMD(CMD_TEST_CONNECT)
  delay20us
  v=CH375_RD_DATA()
  return (v<>0)
end function

function CH375_GET_IC_VERSION(byref v as ubyte) as integer
  CH375_WR_CMD(CMD_GET_IC_VER)
  v=CH375_RD_DATA()
  function = ((v and &B10100000)=&B10100000)
  v and=&B00011111
end function

function CH375_SET_USB_MODE(mode as ubyte) as integer
  CH375_WR_CMD(CMD_SET_USB_MODE)
  CH375_WR_DATA(mode)
  delay20us
  return (CH375_RD_DATA() = CMD_RET_SUCCESS)
end function

function CH375_RESET_ALL as integer
  CH375_WR_CMD(CMD_RESET_ALL)
  sleep 50,1
  CH375_WR_CMD(CMD_GET_STATUS)
  return (CH375_RD_DATA()=USB_INT_SUCCESS)
end function

function CH375_INIT(mode as ubyte=USB_VALID_HOST_SOF) as integer
  delay40uS
  CH375_WR_CMD(CMD_CHECK_EXIST)
  CH375_WR_DATA &H0f
  if CH375_RD_DATA()=&Hf0 then return -1
  dim as integer i=10
  while CH375_RD_DATA()<>&Hf0 andalso i>0
    CH375_RESET_ALL
    CH375_WR_CMD(CMD_CHECK_EXIST)
    CH375_WR_DATA &H0f
  wend
  if i<1 then 
    print "CMD_CHECK_EXIST failed !"
    return 0
  end if
  return CH375_SET_USB_MODE(mode)
end function

' module constructor
sub _init constructor
  CS_LO ' chip select
end sub

' module destructor
sub _exit destructor
  CS_HI ' chip deselect
end sub

'
' main
'
dim as ubyte v

if not CH375_INIT() then
  print "error: CH375_INIT() !"
  beep:sleep:end
end if

if not CH375_GET_IC_VERSION(v) then
  print "error: CH375_GET_IC_VERSION() !"
  beep:sleep:end
end if
print "CH375 version: " & v

print "wait for USB stick or disk ..."

v=USB_INT_DISCONNECT
while v=USB_INT_DISCONNECT andalso inkey=""
  if not CH375_TEST_CONNECT(v) then
    print "warning: CH375_TEST_CONNECT() timeout !"
    beep:sleep:end
  end if
  sleep 100
wend
if not CH375_DISK_INIT(v) then
  print "error: CH375_DISK_INIT() !"
  beep:sleep:end
end if
select case as const v
  case USB_INT_DISCONNECT : print "device not found"
  case USB_INT_CONNECT    : print "device found"
  case USB_INT_USB_READY  : print "device found and ready"
  case else               : print "device state &H" & hex(v,2) & " unknow !"
end select
 
sleep
Last edited by D.J.Peters on Oct 12, 2022 19:14, edited 1 time in total.
ike
Posts: 387
Joined: Jan 17, 2011 18:59

Re: CH375 USB 2.0 host/device interface with FreeBASIC on LP

Post by ike »

I look at PDFs and if I understood well In paralell interface mode you will have only 8 pins

To run 3 axes you need 3x2=6 pins. Each stepper motor need 2 pins: STEP and DIRECTION

and then you will have just 2 pins left for everything else:

Motor ON OFF, limit switches etc
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: CH375 USB 2.0 host/device interface with FreeBASIC on LP

Post by D.J.Peters »

ike I will use the STM32F103 to control the stepper drivers, spindel and some inputs.

USB-STMF32F103 <--switches, --> stepper drivers, --> spindel, --> dispaly, <-- touchpanel, <--> CH375-USB <--> USB-stick/hd.

Of course you can connect PC <--> STMF32F103 also.

Joshy
Post Reply