PIC32 UART in 8-bit mode?

General discussion on mikroPascal PRO for PIC32.
Post Reply
Author
Message
javor.pas
Posts: 98
Joined: 16 Mar 2007 11:25
Contact:

PIC32 UART in 8-bit mode?

#1 Post by javor.pas » 06 Mar 2014 08:07

I finally laid my hands on a PIC32 MCU and tried mP PIC32 (in demo mode). My current MCU is PIC32MX220F032D :)
So far, so good. Took a brief look @ mE UART functions and :shock: as they work with WORDs instead of BYTEs.
Nothing to be afraid of, I though. Configured Peripheral Pins, configured UARTs (both), created Interrupts for UART1 and made my main loop to send through UART2 whatever I got on U1 interrupt. Here's my code:

Code: Select all

program Test_UART;

{ Declarations section }

procedure Setup;
begin
  ANSELA:=$00; //all pins Digital
  ANSELB:=$00; //all pins Digital
  ANSELC:=$00; //all pins Digital

  TRISA:=%01000010000;
  TRISB:=%0000010111000111;
  TRISC:=%0101110000;

  IC1CON:=0;
  IC2CON:=0;
  IC3CON:=0;
  IC4CON:=0;
  IC5CON:=0;

  INTCON.INT0EP:=0; //interrupt on falling edge
  INTCON.INT1EP:=0; //interrupt on falling edge
  INTCON.INT2EP:=0; //interrupt on falling edge
  INTCON.INT3EP:=0; //interrupt on falling edge
  INTCON.INT4EP:=0; //interrupt on falling edge

  Delay_10ms;

  Unlock_IOLOCK;
//
  PPS_Mapping_NoLock(_RPA4, _INPUT, _U1RX);
  PPS_Mapping_NoLock(_RPB4, _OUTPUT, _U1TX);
  PPS_Mapping_NoLock(_RPB8, _INPUT, _U2RX);   
  PPS_Mapping_NoLock(_RPB9, _OUTPUT, _U2TX);  
//
  PPS_Mapping_NoLock(_RPA8, _OUTPUT, _SDO1);   //SPI1 mapping - Data In (SI)
  PPS_Mapping_NoLock(_RPA9, _INPUT, _SDI1);   //SPI1 mapping - Data Out (SO)

  PPS_Mapping_NoLock(_RPB13, _INPUT, _SDI2);   //SPI1 mapping - Data In (SI)
  PPS_Mapping_NoLock(_RPB5, _OUTPUT, _SDO2);   //SPI1 mapping - Data Out (SO)
  Lock_IOLOCK;

  Delay_10ms;

  UART1_Init(115200);
  UART2_Init(115200);

  buf_counter:=0;

  U1RXIE_bit:=0;
  U1TXIE_bit:=0;
  U1RXIF_bit:=0;
  U1TXIF_bit:=0;
  U1IP0_bit := 1; // Set UART1 interrupt
  U1IP1_bit := 0; // Set interrupt priorities
  U1IP2_bit := 1; // Set UART1 interrupt to level 5

  U2RXIE_bit:=0;
  U2TXIE_bit:=0;
  U2RXIF_bit:=0;
  U2TXIF_bit:=0;
  U2IP0_bit := 1; // Set UART2 interrupt
  U2IP1_bit := 1; // Set interrupt priorities
  U2IP2_bit := 1; // Set UART2 interrupt to level 7

  Delay_10ms;

  URXISEL0_bit:=0; //generate interrupt on EVERY char instead of 3/4 or full buffer
  URXISEL1_bit:=0; //generate interrupt on EVERY char instead of 3/4 or full buffer
  U1RXIE_bit:=1;
//  U2RXIE_bit:=1;

  EnableInterrupts;
end;

procedure interrupt_UART1_Receive; iv IVT_UART_1; ilevel 5; ics ICS_AUTO;
var b2_, b3_: boolean;
    w: word;
begin
  U1RXIF_bit:=0;
  
 if (U1STA.OERR <> 0) or (U1STA.FERR <> 0) or (U1STA.PERR <> 0) then
   begin
     OERR_bit:=0;
   end
 else
// if RIDLE_bit <> 0 then
   begin
    w:=UART1_Read;
    buf_rcv[buf_counter]:=Lo(w); //UART1_Read;
    Inc(buf_counter);
   if buf_counter = 26 then
     begin
	   b2_:=buf_rcv[0] = packet_StartByte;
	   b3_:=buf_rcv[buf_counter - 1] = packet_EndByte;

	 if (b2_) and   //packet_StartByte available?
		(b3_) then  //packet_EndByte avavilable?
	   begin
		 T1IE_bit:=0;
		 UART1_Ready:=tcpsOK;
	   end
	 else
	   begin
		 T1IE_bit:=0;
		 UART1_Ready:=tcpsInvalidRequest;
	   end;
     end;
  end;
end;

procedure Zero_UART1_Variables;
begin
  memset(@buf_snd[0], 0, buf_length);
  memset(@buf_rcv[0], 0, buf_length);
  UART1_Ready:=-1;
  buf_counter:=0;
end;

var I: Integer;
    w: word;

begin
  Setup;
  Zero_UART1_Variables;
 while True do
   begin
   if UART1_Ready <> -1 then
     begin
      for I:=0 to buf_counter - 1  do
        begin
          w:=buf_rcv[I] and $0F;
          U2TXREG:=w; 
		  //UART2_Write(buf_rcv[I]);
        end;
       
       UART1_Ready:=-1;
	   Zero_UART1_Variables;
     end;
   end;
end.
The test board is connected as following:
- UART1 is connected to PC hardware serial port, from which I send packet bytes
- UART2 is connected to another PC hardware serial port, from which I read the bytes, sent on UART1
What I want to point is that data, received from PIC's UART2 is WORD instead of bytes, i.e. every byte from packet has a MSB of 0x00 (in most cases, but sometimes MSB is different/random value). No breaks/errors are generated during reception, so I wouldn't blame UART baudrate for that. I tried to receive and send mE functions but they generate the same result. Read through PDFs and forums, nowhere is mentioned anything regarding my problem. Please, take a look and check if I'm missing anything :roll: , either in configuration or in sending/receiving procedures, although I used almost the same mechanism for PIC16 and PIC18 and had no problems there...
I sit and think, sit and think... and some time I notice I only sit :)

javor.pas
Posts: 98
Joined: 16 Mar 2007 11:25
Contact:

Re: PIC32 UART in 8-bit mode?

#2 Post by javor.pas » 06 Mar 2014 09:07

My bad. Error was in reception. For anyone's further needs let me share my experience toward this:
1) mE functions are awesome but they're mainly for POLLing mechanism and not interrupt driven UART;
2) if anyone wants to send data (in my example from UART2) and wants to use his own methods instead of mE functions, here's a piece of code, which works flawless:

Code: Select all

 for I:=0 to 255 {whatever value you need} do
   begin
    while (UTXBF_U2STA_bit <> 0) or (TRMT_U2STA_bit = 0) do ; //poll and check to see U2 TX is ready for next byte ;), else there will be a loss of data
     U2TXREG:=myBuffer[I];
   end;
3) while receiving inside an Interrupt, here's a working piece of code (in this example receiving on UART1), that ensures no trash/empty/dummy bytes are received:

Code: Select all

procedure interrupt_UART1_Receive; iv IVT_UART_1; ilevel 5; ics ICS_AUTO;
begin
  U1RXIF_bit:=0;
  
 if (U1STA.OERR <> 0) or (U1STA.FERR <> 0) or (U1STA.PERR <> 0) then
   begin
     OERR_bit:=0;
   end
 if TestBit(U1STA, 0) <> 0 then //very important to check whether we're ready to get actual data!!!
   begin
    myBuff[buf_counter]:=U1RXREG;
...
   end;
I was bitbanging my head for 1 1/2 days already, but gladly found a solution. Hope this info will be useful for everyone who needs interrupt driven UART.

P.S. Just a proposition: admins/mods can make a read-only pinned topic in every compiler forum and fill it frequently with such user pieces of useful code. That way many users will have the chance to take a look @ the topic, instead of re-inventing the wheel every time.
I sit and think, sit and think... and some time I notice I only sit :)

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

Re: PIC32 UART in 8-bit mode?

#3 Post by filip » 06 Mar 2014 11:09

Hi,
1) mE functions are awesome but they're mainly for POLLing mechanism and not interrupt driven UART;
You are right, the interrupt mechanism isn't enabled in any of the libraries included in the compiler,
the user must implement this on how own.

Please find the interrupt driven examples for PIC32 here :
http://www.libstock.com/projects/view/3 ... mx460f512l

Regards,
Filip.

jpc
Posts: 1986
Joined: 22 Apr 2005 17:40
Location: France 87

Re: PIC32 UART in 8-bit mode?

#4 Post by jpc » 06 Mar 2014 17:09

shame we have to reinvent the weel so often, a search on forum might have brought up http://www.mikroe.com/forum/viewtopic.p ... rt#p177982
Au royaume des aveugles, les borgnes sont rois.

javor.pas
Posts: 98
Joined: 16 Mar 2007 11:25
Contact:

Re: PIC32 UART in 8-bit mode?

#5 Post by javor.pas » 06 Mar 2014 17:43

Thanks, jpc,but!
Every example I've found was either for a fixed pin MCU, or very simple and limited use of the uart interrupt or both. My goal here was to help people with some more complex things like peripheral pin + interrupt and so on. Another thing to point is that my solution is very simple, fast and ready to work in no time. I don't intend to be some complex help or manual writer. So yes, I kinda reinvented the wheel for me at least ;)
What the shame is there are no pinned topics with important codes...
I sit and think, sit and think... and some time I notice I only sit :)

Post Reply

Return to “mikroPascal PRO for PIC32 General”