April 27, 2024, 06:01:53 PM

News:

Got VSA?  Want to use your Prop-SX?  Now you can!  See the VSA section of the Library forum for Prop-SX code that works with VSA.


Prop-SX Programming Template

Started by JonnyMac, February 12, 2007, 08:45:53 PM

Previous topic - Next topic

JonnyMac

February 12, 2007, 08:45:53 PM Last Edit: January 09, 2009, 10:19:11 AM by JonnyMac
This full-featured Prop-SX programming template is written completely in BASIC (SX/B).  When it is compiled it will run at the speed of the selected oscillator.

Code updated: 09 JAN 2009

' =========================================================================
'
'   File...... TEMPLATE.SXB
'   Purpose...
'   Author.... EFX-TEK
'              Copyright (c) 2006-2009 EFX-TEK
'              Some Rights Reserved
'              -- see http://creativecommons.org/licenses/by/3.0/
'   E-mail.... team@efx-tek.com
'   Started...
'   Updated...
'
' =========================================================================


' -------------------------------------------------------------------------
' Program Description
' -------------------------------------------------------------------------


' -------------------------------------------------------------------------
' Conditional Compilation Symbols
' -------------------------------------------------------------------------


' -------------------------------------------------------------------------
' Device Settings
' -------------------------------------------------------------------------

ID              "PROP-SX"

DEVICE          SX28, OSCHS2, TURBO, STACKX, OPTIONX, BOR42
FREQ            50_000_000


' -------------------------------------------------------------------------
' I/O Pins
' -------------------------------------------------------------------------

Sio             PIN     RC.7 INPUT              ' No ULN, SETUP = UP
Trigger3        PIN     RC.6 INPUT              ' SETUP = DN
Trigger2        PIN     RC.5 INPUT              ' SETUP = DN
Trigger1        PIN     RC.4 INPUT              ' SETUP = DN

TX              PIN     RA.3 OUTPUT             ' to PC
RX              PIN     RA.2 INPUT              ' from PC
SCL             PIN     RA.1                    ' EE clock line (I2C)
SDA             PIN     RA.0                    ' EE data line (I2C)


' -------------------------------------------------------------------------
' Constants
' -------------------------------------------------------------------------

PcBaud          CON     "T115200"               ' for PC comms
Baud            CON     "OT38400"               ' for RC-4, DC-16, AP-8

IsOn            CON     1
IsOff           CON     0

SlaveWr         CON     $A0                     ' for 24FC256
SlaveRd         CON     $A1
Ack             CON     0
Nak             CON     1

LF              CON     10
FF              CON     12                      ' use as CLS
CR              CON     13


' -------------------------------------------------------------------------
' Variables
' -------------------------------------------------------------------------

flags           VAR     Byte
ackNak         VAR     flags.0                 ' for I2C routines
i2cMulti       VAR     flags.1

addr            VAR     Word
dbOut           VAR     Byte
dbIn            VAR     Byte

tmpB1           VAR     Byte                    ' work variables
tmpB2           VAR     Byte
tmpB3           VAR     Byte
tmpW1           VAR     Word


' =========================================================================
' Subroutine / Function Declarations
' =========================================================================

DELAY_MS        SUB     1, 2                    ' delay in milliseconds
DELAY_US        SUB     1, 2                    ' delay in microseconds

TX_BYTE         SUB     1                       ' transmit byte on Sio
TX_STR          SUB     2                       ' transmit string on Sio
RX_BYTE         FUNC    1, 0                    ' receive byte on Sio

PC_TX_BYTE      SUB     1                       ' transmit byte on TX
PC_TX_STR       SUB     2                       ' transmit string on TX
PC_RX_BYTE      FUNC    1, 0                    ' receive byte on RX

PUT_EE          SUB     3, 4                    ' write byte(s) to EEPROM
GET_EE          FUNC    1, 2                    ' read byte from EEPROM
GET_EE2         FUNC    2, 2                    ' read word from EEPROM


' I2C routines used by subs/funcs above

I2C_START       SUB     0                       ' generate I2C Start
I2C_STOP        SUB     0                       ' generate I2C Stop
I2C_OUT         SUB     1, 1                    ' write byte to SDA
I2C_IN          FUNC    1, 1                    ' read byte from SDA


' =========================================================================
  PROGRAM Start
' =========================================================================

Start:
  TX = 1                                        ' set to idle
  DELAY_MS 5

  ' other setup items here

Main:

  ' core code

  GOTO Main


' -------------------------------------------------------------------------
' Subroutine / Function Code
' -------------------------------------------------------------------------

' Use: DELAY_MS duration
' -- shell for PAUSE

SUB DELAY_MS
  mSecs         VAR     __WPARAM12

  \ SB  __PARAMCNT.1
  \ CLR mSecs_MSB
  PAUSE mSecs
  ENDSUB

' -------------------------------------------------------------------------

' Use: DELAY_US duration
' -- shell for PAUSEUS

SUB DELAY_US
  uSecs         VAR     __WPARAM12

  \ SB  __PARAMCNT.1
  \ CLR uSecs_MSB
  PAUSEUS uSecs
  ENDSUB

' -------------------------------------------------------------------------

' Use: TX_BYTE byteVal
' -- transmits 'byteVal' on Sio at Baud

SUB TX_BYTE
  SEROUT Sio, Baud, __PARAM1                    ' tx the byte to device
  ENDSUB

' -------------------------------------------------------------------------

' Use: TX_STR [string | label]
' -- transmits embedded string or z-string (at label) on Sio at Baud

SUB TX_STR
  tmpW1 = __WPARAM12                            ' get string address

  DO
    READINC tmpW1, __PARAM1                     ' read a character
    IF __PARAM1 = 0 THEN EXIT                   ' if 0, string complete
    TX_BYTE __PARAM1                            ' tx the byte
  LOOP
  ENDSUB

' -------------------------------------------------------------------------

' Use: byteVal = RX_BYTE
' -- receives 'byteVal' on Sio at Baud

FUNC RX_BYTE
  SERIN Sio, Baud, __PARAM1                     ' rx the byte from Sio
  ENDFUNC

' -------------------------------------------------------------------------

' Use: PC_TX_BYTE byteVal
' -- transmits 'byteVal' on TX at PcBaud

SUB PC_TX_BYTE
  SEROUT TX, PcBaud, __PARAM1                   ' tx the byte to PC
  ENDSUB

' -------------------------------------------------------------------------

' Use: PC_TX_STR [string | label]
' -- transmits constant string or z-string (at label) on TX at PcBaud

SUB PC_TX_STR
  tmpW1 = __WPARAM12                            ' get string address
  DO
    READINC tmpW1, __PARAM1                     ' read a character
    IF __PARAM1 = 0 THEN EXIT                   ' if 0, string complete
    PC_TX_BYTE __PARAM1                         ' send character
  LOOP
  ENDSUB

' -------------------------------------------------------------------------

' Use: byteVal = PC_RX_BYTE
' -- receives 'byteVal' on RX at PcBaud

FUNC PC_RX_BYTE
  SERIN RX, PcBaud, __PARAM1
  ENDFUNC

' -------------------------------------------------------------------------

' Use: PUT_EE address, byteVal1 {, byteVal2 }
' -- writes 'byteVal1' to 'address'
' -- writes [optional] 'byteVal2' to 'address'+1
' -- 'address' is a word (0 to 65535)

SUB PUT_EE
  IF __PARAMCNT = 3 THEN                        ' write one byte
    tmpW1 = __WPARAM12
    tmpB1 = __PARAM3
    i2cMulti = 0
  ELSE
    tmpW1 = __WPARAM12
    tmpB1 = __PARAM3
    tmpB2 = __PARAM4
    i2cMulti = 1
  ENDIF

  I2C_START
  I2C_OUT SlaveWr                               ' send slave ID
  I2C_OUT tmpW1_MSB                             ' send address, high byte
  I2C_OUT tmpW1_LSB                             ' send address, low byte
  I2C_OUT tmpB1                                 ' send data byte
  IF i2cMulti = 1 THEN
    I2C_OUT tmpB2                               ' send second data byte
  ENDIF
  I2C_STOP                                      ' finish

  '{$IFNDEF NOEEWAIT}
  DO                                            ' let write cycle finish
    I2C_START
    I2C_OUT SlaveWr
  LOOP UNTIL ackNak = Ack
  '{$ENDIF}

  ENDSUB

' -------------------------------------------------------------------------

' Use: byteVal = GET_EE address
' -- reads 'byteVal' from EEPROM location 'address'
' -- 'address' is a word (0 to 65535)

FUNC GET_EE
  tmpW1 = __WPARAM12

  I2C_START
  I2C_OUT SlaveWr                               ' send slave ID
  I2C_OUT tmpW1_MSB                             ' send address, high byte
  I2C_OUT tmpW1_LSB                             ' send address, low byte
  I2C_START
  I2C_OUT SlaveRd
  tmpB1 = I2C_IN Nak
  I2C_STOP
  RETURN tmpB1
  ENDFUNC

' -------------------------------------------------------------------------

' Use: wordVal = GET_EE2 address
' -- reads [little-Endian] 'wordVal' from EEPROM location 'address'
' -- 'address' is a word (0 to 65535)

FUNC GET_EE2
  tmpW1 = __WPARAM12

  I2C_START
  I2C_OUT SlaveWr                               ' send slave ID
  I2C_OUT tmpW1_MSB                             ' send address, high byte
  I2C_OUT tmpW1_LSB                             ' send address, low byte
  I2C_START
  I2C_OUT SlaveRd
  tmpW1_LSB = I2C_IN Ack
  tmpW1_MSB = I2C_IN Nak
  I2C_STOP
  RETURN tmpW1
  ENDFUNC

' -------------------------------------------------------------------------

' Use: I2C_START
' -- generates I2C start condition on SDA/SCL pins

SUB I2C_START
  I2CSTART SDA
  ENDSUB

' -------------------------------------------------------------------------

' Use: I2C_STOP
' -- generates I2C stop condition on SDA/SCL pins

SUB I2C_STOP
  I2CSTOP SDA
  ENDSUB

' -------------------------------------------------------------------------

' Use: I2C_OUT byteVal
' -- writes 'byteVal' to SDA pin
' -- affects global var "ackNak"
' -- EE address pointer must be preset before call

SUB I2C_OUT
  I2CSEND SDA, __PARAM1, ackNak
  ENDSUB

' -------------------------------------------------------------------------

' Use: byteVal = I2C_IN AckBit
' -- reads 'byteVal' from SDA pin
' -- EE address pointer must be preset before call
' -- use of __PARAM3 okay at 20 and 50 MHz

FUNC I2C_IN
  ackNak = __PARAM1.0
  I2CRECV SDA, __PARAM1, ackNak
  ENDFUNC


' =========================================================================
' User Data
' =========================================================================

Jon McPhalen
EFX-TEK Hollywood Office