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