Micheal,

I have started to encounter problems with the UART handling.  Test4 starts to 
add some program logic and construct debugging messages back through the UART 
functions.

The first problem is a corrupting of the system start message, although 
subsequent message output is fine?  This can be seen in the attached image.
Strangely, I have found by trial and error, that removing:

      GPIOOutputPin(TXDPinNumber);

from the UARTConfigure procedure (which is a line-for-line translation of the 
original GCC function) makes this issue go away!  I don't understand why this 
happens, nor if it is safe for me to leave out this line permanently from the 
procedure? 

Secondly, the run counter should be formatted by the string expression:

      MessageText := 'Run: '+IntToStr(RunCount)+#13#10;
      UARTSendString(MessageText);

All that is actually printed is the RunCount number.  This can also be seen in 
the screen shot.  I wonder if there is some aspect of the string handling that 
is still not being linked?  If so, would it be possible to fix this, as this 
sort of trivial text construction is a major benefit of Pascal over C.

I have also managed to get button input working and some initial success with 
using timer interrupts rather than the rather clumsy wait loops included in 
these tests.  At the moment this code still uses my old nRF51 header 
translation.  I will next work on converting these to use your header layout.  
I would be happy to post these here if anyone would like them?

After this I want to start looking at how to use the RF/Bluetooth softdevice, 
has anyone else tried this yet?

Thanks,

Paul 
 
Program test4;

Uses Strings, SysUtils, nRF51Utils;

Const
  RXDPIN = 11;
  TXDPIN = 9;
  CTSPIN = 10;
  RTSPIN = 8;

Const
  LED1 = 21;
  LED2 = 22;
  LED3 = 23;
  LED4 = 24;

Var
  LEDsList: Array [1..4] Of LongWord = (LED1, LED2, LED4, LED3);
  Index: Integer;

Var
  MessageText: String;
  RunCount: Integer;

Begin
  UARTConfigure(UARTBaud38400, RTSPIN, TXDPIN, CTSPIN, RXDPIN, True);
  UARTSendString('System Started'#13#10);
  GPIOOutputPin(LED1);
  GPIOOutputPin(LED2);
  GPIOOutputPin(LED3);
  GPIOOutputPin(LED4);
  RunCount := 1;
  While True Do
    Begin
      For Index := 1 To 4 Do
        Begin
          GPIOTogglePin(LEDsList[Index]);
          GPIOTogglePin(LEDsList[1+(Index+1) Mod 4]);
          MillisecondsDelay(250);
        End;
      MessageText := 'Run: '+IntToStr(RunCount)+#13#10;
      UARTSendString(MessageText);
      Inc(RunCount);
    End;
End.
Unit nRF51Utils;

Interface

Type
  TGPIOPinPull = (NoPull := $00, PullDown := $01, PullUp := $03);

Function GPIOScanPin(PinNumber: LongWord): LongWord;
Procedure GPIOClearPin(PinNumber: LongWord);
Procedure GPIOInputPin(PinNumber: LongWord; PinPull: TGPIOPinPull);
Procedure GPIOOutputPin(PinNumber: LongWord);
Procedure GPIOSetPin(PinNumber: LongWord);
Procedure GPIOTogglePin(PinNumber: LongWord);
Procedure MicrosecondsDelay(Count: LongWord);
Procedure MillisecondsDelay(Count: LongWord);
Procedure UARTConfigure(BaudRate: LongWord; RTSPinNumber, TXDPinNumber, CTSPinNumber, RXDPinNumber: Byte; FlowControl: Boolean);
Procedure UARTSend(Value: Byte);
Procedure UARTSendChar(Value: Char);
Procedure UARTSendString(Const Text: String);
Procedure WaitForEvent;

Const
  UARTBaud1200 = $0004F000;
  UARTBaud2400 = $0009D000;
  UARTBaud4800 = $0013B000;
  UARTBaud9600 = $00275000;
  UARTBaud14400 = $003B0000;
  UARTBaud19200 = $004EA000;
  UARTBaud28800 = $0075F000;
  UARTBaud38400 = $009D5000;
  UARTBaud57600 = $00EBF000;
  UARTBaud76800 = $013A9000;
  UARTBaud115200 = $01D7E000;
  UARTBaud230400 = $03AFB000;
  UARTBaud250000 = $04000000;
  UARTBaud460800 = $075F7000;
  UARTBaud921600 = $0EBEDFA4;
  UARTBaud1M = $10000000;

Implementation

Type
  TLongWordArray = Packed Array[0..32] Of LongWord;
  TLongWordArrayPointer = ^TLongWordArray;

Function GPIOScanPin(PinNumber: LongWord): LongWord; Inline;
Var
  PinBit: LongWord;
Begin
  PinBit := LongWord(1) ShL PinNumber;
  If (GPIO.&IN And PinBit)=0 Then
    Result := 0
  Else
    Result := 1;
End;

Procedure GPIOClearPin(PinNumber: LongWord); Inline;
Var
  PinBit: LongWord;
Begin
  PinBit := LongWord(1) ShL PinNumber;
  GPIO.OUTCLR := PinBit;
End;

Procedure GPIOInputPin(PinNumber: LongWord; PinPull: TGPIOPinPull); Inline;
Var
  GPIO_PIN_CNF_bitsPointer: ^TGPIO_PIN_CNF_bits;
Begin
  GPIO_PIN_CNF_bitsPointer := Pointer(@TLongWordArrayPointer(@GPIO.PIN_CNF0)^[PinNumber]);
  With GPIO_PIN_CNF_bitsPointer^ Do
    Begin
      SENSE := 0;
      DRIVE := 0;
      PULL := TBits_2(PinPull);
      setINPUT;
      clearDIR;
    End;
End;

Procedure GPIOOutputPin(PinNumber: LongWord); Inline;
Var
  GPIO_PIN_CNF_bitsPointer: ^TGPIO_PIN_CNF_bits;
Begin
  GPIO_PIN_CNF_bitsPointer := Pointer(@TLongWordArrayPointer(@GPIO.PIN_CNF0)^[PinNumber]);
  With GPIO_PIN_CNF_bitsPointer^ Do
    Begin
      SENSE := 0;
      DRIVE := 0;
      PULL := 0;
      clearINPUT;
      setDIR;
    End;
End;

Procedure GPIOSetPin(PinNumber: LongWord); Inline;
Var
  PinBit: LongWord;
Begin
  PinBit := LongWord(1) ShL PinNumber;
  GPIO.OUTSET := PinBit;
End;

Procedure GPIOTogglePin(PinNumber: LongWord); Inline;
Var
  PinBit: LongWord;
Begin
  PinBit := LongWord(1) ShL PinNumber;
  If (GPIO.OUT And PinBit)=0 Then
    GPIO.OUTSET := PinBit
  Else
    GPIO.OUTCLR := PinBit;
End;

Procedure MicrosecondsDelay(Count: LongWord); Assembler; NoStackFrame; //Inline; - Not yet supported for assembler procedures!
Asm
.Loop:
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  sub r0,r0,#1
  cmp r0, #0
  bne .Loop
End;

Procedure MillisecondsDelay(Count: LongWord); Inline;
Begin
  While Count>0 Do
    Begin
      MicrosecondsDelay(999);
      Dec(Count);
    End;
End;

Procedure WaitForEvent; Assembler; NoStackFrame; //Inline; - Not yet supported for assembler procedures!
{ Permits the processor to enter a low-power state until an events occurs, first clearing any pending events. }
Asm
  wfe
  sev
  wfe
End;

{ Function for configuring UART to use 38400 baud rate. }
Procedure UARTConfigure(BaudRate: LongWord; RTSPinNumber, TXDPinNumber, CTSPinNumber, RXDPinNumber: Byte; FlowControl: Boolean);
Begin
//  GPIOOutputPin(TXDPinNumber);
  GPIOInputPin(RXDPinNumber, NoPull);
  UART0.PSELTXD := TXDPinNumber;
  UART0.PSELRXD := RXDPinNumber;
  If FlowControl Then
    Begin
      GPIOOutputPin(RTSPinNumber);
      GPIOInputPin(CTSPinNumber, NoPull);
      UART0.PSELCTS := CTSPinNumber;
      UART0.PSELRTS := RTSPinNumber;
      UART0.CONFIG_bits.HWFC := 1;
    End;
  UART0.BAUDRATE_bits.BAUDRATE := BaudRate;
  UART0.ENABLE_bits.ENABLE := $04;
  UART0.TASKS_STARTTX := 1;
  UART0.TASKS_STARTRX := 1;
  UART0.EVENTS_RXDRDY := 0;
End;

Procedure UARTSend(Value: Byte); Inline;
Begin
  UART0.TXD := Value;
  While UART0.EVENTS_TXDRDY<>1 Do
    Begin
      { Wait for TXD data to be sent. }
    End;
  UART0.EVENTS_TXDRDY := 0;
End;

Procedure UARTSendChar(Value: Char); Inline;
Begin
  UARTSend(Byte(Value));
End;

Procedure UARTSendString(Const Text: String);
Var
  Index, LastIndex: Integer;
Begin
  LastIndex := Length(Text);
  For Index := 1 To LastIndex Do
    UARTSendChar(Text[Index]);
End;

End.

_______________________________________________
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to