Problem setting registers bit

General discussion on mikroPascal PRO for ARM.
Post Reply
Author
Message
Dan_Rig
Posts: 15
Joined: 28 Oct 2013 16:36

Problem setting registers bit

#1 Post by Dan_Rig » 02 Sep 2016 18:37

Hello,
I have begun to play with my new "Clicker for Kinetis" card.
I have also bought the "mikroProg for Kinetis" and everything go well.
But I have lost a couple of hours about the setting of a register.
The idea was to use the UART0 with the interrupt.
Here is the code

Code: Select all

program Test;

var LD1 : sbit at PTA_PDOR.B5;
    LD2 : sbit at PTA_PDOR.B12;

procedure UART0_RX_TX_INT(); iv IVT_INT_UART0_RX_TX; ics ICS_AUTO;
var
 DataRX:byte;
begin        // UART0_RX_INT
 LD2:=not LD1;
 if UART0_Data_Ready()
  then
   begin
    DataRX := UART0_Read();
    UART0_Write(DataRX);
   end;
end;         // UART0_RX_INT

// main function
begin
 // Set PTA_PDOR pins 5 and 12 as digital output
 GPIO_Digital_Output(PTA_PDOR, _GPIO_PINMASK_5 or _GPIO_PINMASK_12);

 UART0_Init(9600);
 
 // enable interrupt vector
 NVIC_IntEnable(IVT_INT_UART0_RX_TX);

 // now I have to enable the interrupt of the receiver setting RIE_UART0_C2_bit
 // here is the problem --------------------------
 // I have tried:

 // UART0_C2.RIE_UART0_C2_bit:=1; // <-- This way the application hangs
 // UART0_C2.B5:=1;               // <-- Also this way tha application hangs  
 // RIE_UART0_C2_bit:=1;          // <-- And also this way the application hangs

 UART0_C2:=UART0_C2 or $20; // <-- This work!!!

 EnableInterrupts();

 UART0_Write_Text('Hello!');
  
 LD2:=0;
  
  while true do
   begin
    LD1:=not LD1;
    Delay_ms(500);
   end;

end.
Probably I did not understand how to set the registers properly.
Have you any suggestion?

Compiler used "mikroPascal PRO for ARM v 4.9.0" registered

Thank you,
Danilo

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: Problem setting registers bit

#2 Post by filip » 05 Sep 2016 15:59

Hi,

There is no need to poll UART0_Data_Ready() function in the interrupt, it is redundant,
as the code will enter UART interrupt routine as soon as new information is placed into the receiving buffer.

Please, have a look at the RS-485 example for Clicker 2 from the compiler, at the following path :
\mikroPascal PRO for ARM\Examples\NXP\Clicker 2 for Kinetis\RS485\RS485 Master

It utilizes UART interrupt and it will show you how to properly set this up.

Regards,
Filip.

Dan_Rig
Posts: 15
Joined: 28 Oct 2013 16:36

Re: Problem setting registers bit

#3 Post by Dan_Rig » 06 Sep 2016 10:33

Thank you! The RS-485 example for Clicker 2 is really interesting.
However let me understand.
I do not need to poll UART0_Data_Ready() because the only interrupt active
is the receiver (bit RIE of the register UART2_C2).
But if I activate also the interrupt of the transmission complete (for example)
bit TCIE of UART_C2 then I should do the poll of UART0_Data_Ready()
and UARTx_Tx_Idle() because the routine of interrupt service for the UART
is unique. Is it true?


However the nature of the question was different.
I see in the RS-485 example for Clicker 2 the notation to set the register
bit is C-like

Code: Select all

 UART2_C2 := UART2_C2 or (1 shl RIE);  // enable uart rx interrupt
Now the documentation of the compiler in the Accessing Individual Bits paragraph says:
To access this bit in your code by its name, you can write something like this:

// Clear GPIO_PORTA.0 Bit
GPIO_PORTA_DATA.GPIO_PORTA_DATA0 := 0;

etc...

Another way of accesing bits is by using the direct member selector (.) with a variable, followed by a primary expression. Primary expression can be variable, constant, function call or an expression enclosed by parentheses. For individual bit access there are predefined global constants B0, B1, … , B15, or 0, 1, … 15, with 15 being the most significant bit :

// predefined globals as bit designators
// Clear bit 0 in GPIO_PORTA_DATA register
GPIO_PORTA_DATA.B0 := 0;

// literal constant as bit designator
// Set bit 5 in GPIO_PORTA_DATA register
GPIO_PORTA_DATA.5 := 1;

// expression as bit designator
// Set bit 6 in GPIO_PORTA_DATA register
i := 5;
GPIO_PORTA_DATA.(i+1) := 1;

etc...

Also, you can access the desired bit by using its alias name :

// Set GPIO_PORTA.0 Bit
GPIO_PORTA_DATA0_bit := 1;

etc..
So to set the bit RIE of UART_C0 register I can write

UART0_C2 := UART0_C2 or (1 shl RIE); and in this case everything work

but if I write
RIE_UART0_C0_bit:=1; the processor hangs and the program does not work

Why? Both the two expressions are legit.

Also writing UART0_C2.B5:=1; does not work

Making a comparison between the generated code of the three versions

Code: Select all

 UART0_C2 := UART0_C2 or (1 shl RIE);
 RIE_UART0_C2_bit:=1;
 UART0_C2.B5:=1;
we obtain

Code: Select all

;clicker for Kinetis.mpas, 467 :: 		UART0_C2 := UART0_C2 or (1 shl RIE);
0x1BCE	0x4857    LDR	R0, [PC, #348]
0x1BD0	0x7800    LDRB	R0, [R0, #0]
0x1BD2	0xF4401100  ORR	R1, R0, #2097152
0x1BD6	0x4855    LDR	R0, [PC, #340]
0x1BD8	0x7001    STRB	R1, [R0, #0]
;clicker for Kinetis.mpas, 468 :: 		RIE_UART0_C2_bit:=1;
0x1BDA	0x2101    MOVS	R1, #1
0x1BDC	0x4854    LDR	R0, [PC, #336]
0x1BDE	0x6001    STR	R1, [R0, #0]
;clicker for Kinetis.mpas, 469 :: 		UART0_C2.B5:=1;
0x1BE0	0x4854    LDR	R0, [PC, #336]
0x1BE2	0x6001    STR	R1, [R0, #0]
The first, the working one, is really different from the other two
that do not work.
Strange, I would expect to see the same code for all three versions because
all the three lines of code do the same thing.

Thank you,
Dan.

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: Problem setting registers bit

#4 Post by filip » 07 Sep 2016 09:14

Hi,
But if I activate also the interrupt of the transmission complete (for example)
bit TCIE of UART_C2 then I should do the poll of UART0_Data_Ready()
and UARTx_Tx_Idle() because the routine of interrupt service for the UART
is unique. Is it true?
It appears that unique interrupt vector is dedicated to both Rx and Tx, so you should poll appropriate status bits (like TCIE) in the interrupt routine,
in order to be able to monitor receive/transmit actions.
UART0_C2 := UART0_C2 or (1 shl RIE); and in this case everything work
but if I write
RIE_UART0_C0_bit:=1; the processor hangs and the program does not work
I will check this out and let you know.

Regards,
Filip.

Post Reply

Return to “mikroPascal PRO for ARM General”