Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
It's in the Swordfish Library folder (or at least it should be).Searched but no SHIFT.bas
Popcorn, I notice that your image above states that the modules are in development. Any later news?
Mike.
Do we really need SHIFT.bas?
All I am doing to sequencely turn ON then OFF sixty blue LEDs one at a time
Then, do the same with 12 green LEDs.
include "shift.bas"
{
****************************************************************
* Name : Shift Module *
* Author : David John Barker *
* Notice : Copyright (c) 2006 Mecanique *
* : All Rights Reserved *
* Date : 10 JAN 2023 *
* Version : 1.7 10 JAN 2023 *
* : add default values for pShift param (SHIFT_MAX) *
* : allow SHIFT_CLOCK = 0 to 255, add to both hi/low *
* : add #option SHIFT_DATA_SETUP *
* : 1.6 19/08/2019 *
* : add PORT/LAT/TRIS offset for devices with *
* : different reg maps (K40, K42, Q10, etc) *
* Notes : 1.5 04/02/2006 *
* : *
****************************************************************
}
module Shift
// import modules...
include "utils.bas"
include "system.bas"
// shiftin modes...
public const
MSB_PRE = $00, // MSB first, sample before clock
MSB_POST = $02, // MSB first, sample after clock
LSB_PRE = $01, // LSB first, sample before clock
LSB_POST = $03 // LSB first, sample after clock
// shiftout modes...
public const
LSB_FIRST = $00, // LSB first
MSB_FIRST = $01 // MSB first
// a pin structure...
structure TPin
PortAddr as word // PORT addr (input), LAT addr (output)
TrisAddr as word // TRIS addr
Pin as byte
PinMask as byte
end structure
// local working variables...
dim
FDataIn as TPin,
FDataOut as TPin,
FClock as TPin
// maximum shift size can be 8, 16 or 32 bits
// using a smaller maximum shift size will reduce code overhead
// the default is 16 bits
#if IsOption(SHIFT_MAX) and not (SHIFT_MAX in (8, 16, 32))
#error SHIFT_MAX, "Invalid option. MAX must be 8, 16 or 32 bits."
#endif
#option SHIFT_MAX = 16
const DEFAULT_SHIFT as byte = SHIFT_MAX
#if (SHIFT_MAX = 8)
type TType = byte
#elseif (SHIFT_MAX = 16)
type TType = word
#else // SHIFT_MAX = 32
type TType = longword
#endif
// speed of shift clock, in usecs
#if IsOption(SHIFT_CLOCK) and (SHIFT_CLOCK > 255)
#error SHIFT_CLOCK, "Invalid option. SHIFT_CLOCK must be < 256"
#endif
#option SHIFT_CLOCK = 1
const SHIFT_CLOCK_US = SHIFT_CLOCK
// shift clock delay usage
// 0 = only call delay after first transition (previous versions)
// 1 = delay after both transitions (v1.7)
#option SHIFT_CLOCK_DELAY = 0
// optional data setup time (output data to clk, in usecs)
#option SHIFT_DATA_SETUP = 0
const SHIFT_DATA_SETUP_US = SHIFT_DATA_SETUP
{
****************************************************************************
* Name : ToggleClock (PRIVATE) *
* Purpose : Toggle the shift clock. *
* : The default minimum clock width will be 1us for frequencies *
* : above 4MHz. For 4Mhz and below, the minimum clock width will *
* : be 2us. Using #option SHIFT_CLOCK = 2 will force a minimum *
* : clock width of 2us for all frequencies. *
* : NOTE - These figures assume a perfect clock. A plus or minus *
* : variation of the clock width will be observed for all real *
* : world clock frequencies that deviate from the ideal *
****************************************************************************
}
inline sub ClockDelay()
#if (SHIFT_CLOCK = 0)
asm- // at least one nop between clock transitions
nop
end asm
#elseif (SHIFT_CLOCK > 2)
delayus(SHIFT_CLOCK_US)
#else // SHIFT_CLOCK = 1 or 2 (previous versions)
// force minimum 2us...
#if SHIFT_CLOCK = 2
#if _clock >= 8
delayus(1)
#endif
#endif
// burn 8...
#if _clock > 36
asm-
bra $ + 2
bra $ + 2
bra $ + 2
bra $ + 2
end asm
// burn 7...
#elseif _clock > 32
asm-
bra $ + 2
bra $ + 2
bra $ + 2
nop
end asm
// burn 6...
#elseif _clock > 28
asm-
bra $ + 2
bra $ + 2
bra $ + 2
end asm
// burn 5...
#elseif _clock > 24
asm-
bra $ + 2
bra $ + 2
nop
end asm
// burn 4...
#elseif _clock > 20
asm-
bra $ + 2
bra $ + 2
end asm
// burn 3...
#elseif _clock > 16
asm-
bra $ + 2
nop
end asm
// burn 2...
#elseif _clock > 12
asm-
bra $ + 2
end asm
// burn 1...
#elseif _clock > 8
asm-
nop
end asm
#endif
#endif
end sub
inline sub DataSetup()
#if (SHIFT_DATA_SETUP > 0)
delayus(SHIFT_DATA_SETUP_US)
#endif
end sub
inline sub ToggleClock()
// toggle clock...
INDF1 = INDF1 xor FClock.Pin
ClockDelay()
// toggle clock...
INDF1 = INDF1 xor FClock.Pin
#if (SHIFT_CLOCK_DELAY > 0) // added v1.7
ClockDelay()
#endif
end sub
{
****************************************************************************
* Name : MakeOutput(PRIVATE) *
* Purpose : Make the data pin an output *
****************************************************************************
}
inline sub MakeOutput()
FSR1 = FDataOut.TrisAddr
INDF1 = INDF1 and FDataOut.PinMask
end sub
{
****************************************************************************
* Name : MakeInput (PRIVATE) *
* Purpose : Make the data pin an input *
****************************************************************************
}
inline sub MakeInput()
FSR1 = FDataIn.TrisAddr
INDF1 = INDF1 or FDataIn.Pin
end sub
{
****************************************************************************
* Name : LoadDataInAndClockAddr (PRIVATE) *
* Purpose : Load the data and clock pin address into FSR(x) *
****************************************************************************
}
inline sub LoadDataInAndClockAddr()
FSR0 = FDataIn.PortAddr
FSR1 = FClock.PortAddr
end sub
{
****************************************************************************
* Name : LoadDataOutAndClockAddr (PRIVATE) *
* Purpose : Load the data and clock pin address into FSR(x) *
****************************************************************************
}
inline sub LoadDataOutAndClockAddr()
FSR0 = FDataOut.PortAddr
FSR1 = FClock.PortAddr
end sub
{
****************************************************************************
* Name : LAT_OFFSET/TRIS_OFFSET *
* Purpose : these macros load 'wresult' with the LAT and TRIS register *
* : offsets from PORT. they assume wresult is a 16-bit word *
* : located in the access bank (PROD is a good choice) *
****************************************************************************
}
macro LAT_OFFSET(wresult)
asm-
movlw low(LATA-PORTA)
movwf wresult
movlw high(LATA-PORTA)
movwf wresult+1
end asm
end macro
macro TRIS_OFFSET(wresult)
asm-
movlw low(TRISA-PORTA)
movwf wresult
movlw high(TRISA-PORTA)
movwf wresult+1
end asm
end macro
{
****************************************************************************
* Name : SetInput *
* Purpose : Sets the shift data in pin *
****************************************************************************
}
public sub SetInput(byref pDataPin as bit)
dim reg_offset as PROD // 16-bit reg (must be in access bank)
FDataIn.PortAddr = addressof(pDataPin) // point address to port
TRIS_OFFSET(reg_offset) // get TRIS offset
FDataIn.TrisAddr = FDataIn.PortAddr + reg_offset // TRIS addr
FDataIn.Pin = bitof(pDataPin)
FDataIn.PinMask = not FDataIn.Pin
end sub
{
****************************************************************************
* Name : SetOutput *
* Purpose : Sets the shift data out clock pin *
****************************************************************************
}
public sub SetOutput(byref pDataPin as bit)
dim reg_offset as PROD // 16-bit reg (must be in access bank)
FDataOut.PortAddr = addressof(pDataPin) // PORT addr
TRIS_OFFSET(reg_offset) // get TRIS offset
FDataOut.TrisAddr = FDataOut.PortAddr + reg_offset // TRIS addr
LAT_OFFSET(reg_offset) // get LAT offset
FDataOut.PortAddr = FDataOut.PortAddr + reg_offset // change PortAddr to LAT addr
FDataOut.Pin = bitof(pDataPin)
FDataOut.PinMask = not FDataOut.Pin
end sub
{
****************************************************************************
* Name : Set *
* Purpose : Sets the clock pins. An optional idle high determines if the *
* : clock pin idles high or low. The default is to idle low *
* : The clock address points to a port latch *
****************************************************************************
}
public sub SetClock(byref pClockPin as bit, pIdleHigh as boolean = false)
dim reg_offset as PROD // 16-bit reg (must be in access bank)
FClock.PortAddr = addressof(pClockPin) // PORT addr
TRIS_OFFSET(reg_offset) // get TRIS offset
FClock.TrisAddr = FClock.PortAddr + reg_offset // TRIS addr
LAT_OFFSET(reg_offset) // get LAT offset
FClock.PortAddr = FClock.PortAddr + reg_offset // change PortAddr to LAT addr
FClock.Pin = bitof(pClockPin)
FClock.PinMask = not FClock.Pin
// set clock idle state...
FSR1 = FClock.PortAddr
if pIdleHigh then
INDF1 = INDF1 or FClock.Pin
else
INDF1 = INDF1 and FClock.PinMask
endif
// make clock pin an output...
FSR1 = FClock.TrisAddr
INDF1 = INDF1 and FClock.PinMask
end sub
{
****************************************************************************
* Name : Out *
* Purpose : Shift out a value by pShift bits. Date values can be up to 32 *
* : bits in size. Mode can be either LSB_FIRST or MSB_FIRST *
****************************************************************************
}
public sub Out(pMode as byte, pData as TType, pShift as byte=DEFAULT_SHIFT)
// set data pin to output and load
// data and clock address...
MakeOutput()
LoadDataOutAndClockAddr()
// MSB first...
if pMode.0 = 1 then
pData = Reverse(pData, pShift)
endif
// shift out...
while (pShift > 0)
if pData.0 = 0 then
INDF0 = INDF0 and FDataOut.PinMask
else
INDF0 = INDF0 or FDataOut.Pin
endif
DataSetup()
ToggleClock()
pData = pData >> 1
dec(pShift)
wend
ClrWDT
end sub
{
****************************************************************************
* Name : In *
* Purpose : Shift in a value by pShift bits. Date values can be up to 32 *
* : bits in size. Mode can be MSB_PRE, MSB_POST, LSB_PRE or *
* : LSB_POST *
****************************************************************************
}
public function In(pMode as byte, pShift as byte=DEFAULT_SHIFT) as TType
dim Index as byte
// set data pin to input and load
// data and clock address...
MakeInput()
LoadDataInAndClockAddr()
// shift in...
Result = 0
Index = pShift
while (Index > 0)
Result = Result << 1
// sample before clock...
if pMode.1 = 0 then
if (INDF0 and FDataIn.Pin) = 0 then
Result.0 = 0
else
Result.0 = 1
endif
ToggleClock()
// sample after clock...
else
ToggleClock()
if (INDF0 and FDataIn.Pin) = 0 then
Result.0 = 0
else
Result.0 = 1
endif
endif
dec(Index)
wend
// LSB first...
if pMode.0 = 1 then
Result = Reverse(Result,pShift)
endif
ClrWDT
end function
end module
Sorry it's thereIt's usually located in C:\ProgramData\Mecanique\Swordfish\Library
Looking over post3 119, a question comes to mind.
2- 60 led rings? =(120 leds)
Big question?
post#105 has a schematic showing 2 transistors connected to outputs G & H
WHY?