[r1]: / trunk / legacy / Libraries / SPI_PiFaceCaD.library.md  Maximize  Restore  History

Download this file

528 lines (457 with data), 9.6 kB

<?xml version="1.0" encoding="utf-8"?>---

FUNCTION_BLOCK PiFaceCaD EXTENDS spi
VAR_OUTPUT
    bySwitches: BYTE;
END_VAR
VAR
    _byHardwareAddress: BYTE;
    _byCurDisplayControl: BYTE;
    _byCurEntryMode: BYTE;
    _byCurAddress: BYTE;
END_VAR
VAR_TEMP
    i: INT;
    k: INT;
END_VAR
SUPER^();

CASE _iState OF
0:
    IF SUPER^.init() THEN
        _iState := 1;
    END_IF  
1:
    write8(_byHardwareAddress, IOCON, 8); //enable hardware addressing



    // Set GPIO Port A as inputs (switches)
    write8(_byHardwareAddress, IODIRA, 255); 

    write8(_byHardwareAddress, GPPUA, 255); 

    // Set GPIO Port B as outputs (connected to HD44780)
    write8(_byHardwareAddress, IODIRB, 0); 

    // enable interrupts
    write8(_byHardwareAddress, GPINTENA, 255); 

    sleep_ns(DELAY_SETUP_0_NS);
    write8(_byHardwareAddress, LCD_PORT, 3); 
    LCDPulseEnable();

    sleep_ns(DELAY_SETUP_1_NS);
    write8(_byHardwareAddress, LCD_PORT, 3); 
    LCDPulseEnable();

    sleep_ns(DELAY_SETUP_2_NS);
    write8(_byHardwareAddress, LCD_PORT, 3); 
    LCDPulseEnable();

    write8(_byHardwareAddress, LCD_PORT, 2); 
    LCDPulseEnable();

    LCDSendCommand(LCD_FUNCTIONSET OR LCD_4BITMODE OR LCD_2LINE OR LCD_5X8DOTS);

    LCDSendCommand(LCD_DISPLAYCONTROL OR LCD_DISPLAYOFF OR LCD_CURSOROFF OR LCD_BLINKOFF);

    Clear();

    _byCurEntryMode := LCD_ENTRYLEFT OR LCD_ENTRYSHIFTDECREMENT;
    LCDSendCommand(LCD_ENTRYMODESET OR _byCurEntryMode);

    _byCurDisplayControl := LCD_DISPLAYON OR LCD_CURSORON OR LCD_BLINKON;
    LCDSendCommand(LCD_DISPLAYCONTROL OR _byCurDisplayControl);

    SetText('CODESYS ON', 'RASPBERRY PI');

    _iState := 10;  
END_CASE

METHOD Initialize: UDINT
VAR_INPUT
    wModuleType: UINT;
    dwInstance: UDINT;
    pConnector: pointer;
END_VAR
VAR
    pParam: pointer;
    udiResult: UDINT;
END_VAR
SUPER^.Initialize(wModuleType, dwInstance, pConnector);

(*pParam := ConfigGetParameter(_pConnector, 1);
IF pParam &lt;&gt; 0 THEN
    _byHardwareAddress := IoStandard.ConfigGetParameterValueByte(pParam, ADR(udiResult));
END_IF*)

METHOD BeforeWriteOutputs: INT
VAR
    i: USINT;
END_VAR
SUPER^.BeforeWriteOutputs();

METHOD AfterReadInputs: INT
VAR
    aby: ARRAY [..] OF ;
END_VAR
SUPER^.AfterReadInputs();

IF _iState = 10 THEN
    bySwitches := NOT read8(_byHardwareAddress, SWITCH_PORT);
END_IF

METHOD read8: BYTE
VAR_INPUT
    byHardwareAddress: subrangeSigned;
    byPort: BYTE;
END_VAR
VAR
    abyTxBuffer: ARRAY [..] OF ;
    abyRxBuffer: ARRAY [..] OF ;
END_VAR
abyTxBuffer[0] := 16#40 + SHL(byHardwareAddress, 1) + 1; //SPI_READ_CMD;
abyTxBuffer[1] := byPort;
abyTxBuffer[2] := 16#FF;

IF transfer(pabyTxBuffer:=ADR(abyTxBuffer) , pabyRxBuffer:=ADR(abyRxBuffer) , udiLen:=3 , uiDelayus:=5 ) THEN
    read8 := abyRxBuffer[2];
ELSE
    _iState := 1000;
END_IF

METHOD write8: BOOL
VAR_INPUT
    byHardwareAddress: subrangeSigned;
    byPort: BYTE;
    byValue: BYTE;
END_VAR
VAR
    abyTxBuffer: ARRAY [..] OF ;
    abyRxBuffer: ARRAY [..] OF ;
END_VAR
abyTxBuffer[0] := 16#40 + SHL(byHardwareAddress, 1); //SPI_WRITE_CMD;
abyTxBuffer[1] := byPort;
abyTxBuffer[2] := byValue;

write8 := transfer(pabyTxBuffer:=ADR(abyTxBuffer) , pabyRxBuffer:=ADR(abyRxBuffer) , udiLen:=3 , uiDelayus:=5 );

IF NOT write8 THEN
    _iState := 1000;
END_IF

METHOD LCDPulseEnable: 
LCDSetEnable(TRUE);
sleep_ns(DELAY_PULSE_NS);

LCDSetEnable(FALSE);
sleep_ns(DELAY_PULSE_NS);

METHOD LCDSendCommand: 
VAR_INPUT
    usiCommand: USINT;
END_VAR
LCDSetRs(FALSE);
LCDSendByte(usiCommand);
sleep_ns(DELAY_SETTLE_NS);

METHOD LCDSendByte: 
VAR_INPUT
    usi: USINT;
END_VAR
VAR
    usiCurrentState: USINT;
    usiNew: USINT;
END_VAR
// get current lcd port state and clear the data bits
usiCurrentState := read8(_byHardwareAddress, LCD_PORT) AND 16#F0;

// send first nibble (0bXXXX0000)
usiNew := usiCurrentState OR SHR(usi, 4);
write8(_byHardwareAddress, LCD_PORT, usiNew);
LCDPulseEnable();

// send second nibble (0b0000XXXX)
usiNew := usiCurrentState OR (usi AND 2#1111);
write8(_byHardwareAddress, LCD_PORT, usiNew);
LCDPulseEnable();

METHOD writeBit: BOOL
VAR_INPUT
    byHardwareAddress: subrangeSigned;
    byPort: BYTE;
    byBit: subrangeSigned;
    xValue: BOOL;
END_VAR
VAR
    byValue: BYTE;
END_VAR
byValue := read8(byHardwareAddress, byPort);
IF xValue THEN
    byValue := byValue OR SHL(USINT#1, byBit);
ELSE    
    byValue := byValue AND NOT SHL(USINT#1, byBit);
END_IF
writeBit := write8(byHardwareAddress, byPort, byValue);

METHOD LCDSetRs: 
VAR_INPUT
    x: BOOL;
END_VAR
writeBit(_byHardwareAddress, LCD_PORT, PIN_RS, x);

METHOD sleep_ns: 
VAR_INPUT
    udiNs: UDINT;
END_VAR
VAR
    udi1: ULINT;
    udi2: ULINT;
END_VAR
SysTimeGetNs(udi1);
REPEAT
    SysTimeGetNs(udi2);
UNTIL udi2-udi1 &gt;= udiNs
END_REPEAT

METHOD LCDSetEnable: 
VAR_INPUT
    x: BOOL;
END_VAR
writeBit(_byHardwareAddress, LCD_PORT, PIN_ENABLE, x);

METHOD Write: 
VAR_INPUT
    sText: string;
END_VAR
VAR
    i: INT;
    pby: pointer;
END_VAR
LCDSendCommand(LCD_SETDDRAMADDR OR _byCurAddress);
pby := ADR(sText);
FOR i:=0 TO len(sText)-1 DO
    IF pby[i] = 10 THEN
        SetCursor(0,1);
    ELSE
        LCDSendData(pby[i]);
        _byCurAddress := _byCurAddress + 1;
    END_IF
END_FOR 

METHOD Clear: 
LCDSendCommand(LCD_CLEARDISPLAY);
_byCurAddress := 0;
sleep_ns(DELAY_CLEAR_NS);   

METHOD Home: 
LCDSendCommand(LCD_RETURNHOME);
_byCurAddress := 0;
sleep_ns(DELAY_CLEAR_NS);

METHOD SetCursor: 
VAR_INPUT
    usiColumn: USINT;
    usiRow: USINT;
END_VAR
usiColumn := MAX(0, MIN(usiColumn, (LCD_RAM_WIDTH / 2) - 1));
usiRow := MAX(0, MIN(usiRow, LCD_MAX_LINES - 1));

_byCurAddress := (usiColumn + ROW_OFFSETS[usiRow]) MOD LCD_RAM_WIDTH;
LCDSendCommand(LCD_SETDDRAMADDR OR _byCurAddress);

METHOD LCDSendData: 
VAR_INPUT
    data: USINT;
END_VAR
LCDSetRs(TRUE);
LCDSendByte(data);
sleep_ns(DELAY_SETTLE_NS);

METHOD MoveLeft: 
LCDSendCommand(LCD_CURSORSHIFT OR LCD_DISPLAYMOVE OR LCD_MOVELEFT);

METHOD MoveRight: 
LCDSendCommand(LCD_CURSORSHIFT OR LCD_DISPLAYMOVE OR LCD_MOVERIGHT);

METHOD SetText: 
VAR_INPUT
    sLine1: string;
    sLine2: string;
END_VAR
SetCursor(0, 0);
Write(sLine1);

SetCursor(0, 1);
Write(sLine2);

METHOD WriteCustomBitmap: 
VAR_INPUT
    byLocation: subrangeSigned;
END_VAR
LCDSendCommand(LCD_SETDDRAMADDR OR _byCurAddress);
LCDSendData(byLocation);

_byCurAddress := _byCurAddress + 1;

METHOD DefineCustomBitmap: 
VAR_INPUT
    byLocation: subrangeSigned;
    abyBitmap: ARRAY [..] OF ;
END_VAR
VAR
    i: INT;
END_VAR
LCDSendCommand(LCD_SETCGRAMADDR OR SHL(byLocation, 3));
FOR i := 0 TO 7 DO
    LCDSendData(abyBitmap[i]);
END_FOR

VAR_GLOBAL
IODIRA: USINT;
IODIRB: USINT;
IPOLA: USINT;
IPOLB: USINT;
GPINTENA: USINT;
GPINTENB: USINT;
DEFVALA: USINT;
DEFVALB: USINT;
INTCONA: USINT;
INTCONB: USINT;
IOCON: USINT;
GPPUA: USINT;
GPPUB: USINT;
INTFA: USINT;
INTFB: USINT;
INTCAPA: USINT;
INTCAPB: USINT;
GPIOA: USINT;
GPIOB: USINT;
OLATA: USINT;
OLATB: USINT;
BANK_OFF: USINT;
BANK_ON: USINT;
INT_MIRROR_ON: USINT;
INT_MIRROR_OFF: USINT;
SEQOP_OFF: USINT;
SEQOP_ON: USINT;
DISSLW_ON: USINT;
DISSLW_OFF: USINT;
HAEN_ON: USINT;
HAEN_OFF: USINT;
ODR_ON: USINT;
ODR_OFF: USINT;
INTPOL_HIGH: USINT;
INTPOL_LOW: USINT;
DELAY_PULSE_NS: UDINT;
DELAY_SETTLE_NS: UDINT;
DELAY_CLEAR_NS: UDINT;
DELAY_SETUP_0_NS: UDINT;
DELAY_SETUP_1_NS: UDINT;
DELAY_SETUP_2_NS: UDINT;
PIN_D4: USINT;
PIN_D5: USINT;
PIN_D6: USINT;
PIN_D7: USINT;
PIN_ENABLE: USINT;
PIN_RW: USINT;
PIN_RS: USINT;
PIN_BACKLIGHT: USINT;
LCD_CLEARDISPLAY: USINT;
LCD_RETURNHOME: USINT;
LCD_ENTRYMODESET: USINT;
LCD_DISPLAYCONTROL: USINT;
LCD_CURSORSHIFT: USINT;
LCD_FUNCTIONSET: USINT;
LCD_SETCGRAMADDR: USINT;
LCD_SETDDRAMADDR: USINT;
LCD_NEWLINE: USINT;
LCD_ENTRYRIGHT: USINT;
LCD_ENTRYLEFT: USINT;
LCD_ENTRYSHIFTINCREMENT: USINT;
LCD_ENTRYSHIFTDECREMENT: USINT;
LCD_DISPLAYON: USINT;
LCD_DISPLAYOFF: USINT;
LCD_CURSORON: USINT;
LCD_CURSOROFF: USINT;
LCD_BLINKON: USINT;
LCD_BLINKOFF: USINT;
LCD_DISPLAYMOVE: USINT;
LCD_CURSORMOVE: USINT;
LCD_MOVERIGHT: USINT;
LCD_MOVELEFT: USINT;
LCD_8BITMODE: USINT;
LCD_4BITMODE: USINT;
LCD_2LINE: USINT;
LCD_1LINE: USINT;
LCD_5X10DOTS: USINT;
LCD_5X8DOTS: USINT;
LCD_MAX_LINES: USINT;
LCD_WIDTH: USINT;
LCD_RAM_WIDTH: USINT;
ROW_OFFSETS: ARRAY [..] OF ;
SWITCH_PORT: USINT;
LCD_PORT: USINT;
END_VAR