Created Fri, 30 Dec 2011 22:31:05 +0000 by hybridnz
Fri, 30 Dec 2011 22:31:05 +0000
Hey guys,
I am working on a project which one of my UARTS require 9600,e,8,1 communication not 9600,n,8,1 (which is hard coded)
Over at the Arduino forum and doing some research the current Arduino serial libary doesnt support switching of stop bits, odd/even, parity. Only baud rate switching is availible.
They seem to be getting around this problem by low level switching the chip registers EG:
Serial.begin(9600);
UCSR0C = ( UCSR0C & ~_BV(UPM00) | _BV(UPM01) );
Is their a way to do this on the PIC/MAX32 board ?
thanks Josh
Mon, 02 Jan 2012 18:48:31 +0000
Josh
Sure, you can bypass the abstraction layer just the same as your Atmel example.
The register would be U1MODE
I am going to see about adding a routine to set the data bits, stop bits and parity
I think this would be a good addition to MPIDE and to Arduino. This question has come up before on the Arduino forum.
Mark
Tue, 03 Jan 2012 02:31:46 +0000
Thanks for your reply.
This would be really helpfull if it could be added the serial lib.
thanks again :)
Thu, 12 Jan 2012 02:48:37 +0000
Hi Mark/team
Do you know where I can find any more information on the registers and the code to use for setting Serial1 to 9600,e,8,1
Im pretty beginner to all this and dont have a lot of background in micros .. am a fast/willing learner however :)
Cheers in advance :)
Thu, 12 Jan 2012 07:03:23 +0000
Well, there's the microchip documentation.
You ought to be able to put a
#include <plib.h>
at the top of your source to get the microchip peripheral library defines, and then do:
void setup()
{
Serial.begin(9600);
UARTSetLineControl(UART1, UART_DATA_SIZE_8_BITS|UART_PARITY_EVEN|UART_STOP_BITS_1);
But this seems to result in an error:
ASCIITable.cpp: In function 'void setup()':
ASCIITable.cpp:32:109: error: invalid conversion from 'int' to 'UART_LINE_CONTROL_MODE'
ASCIITable.cpp:32:109: error: initializing argument 2 of 'void UARTSetLineControl(UART_MODULE, UART_LINE_CONTROL_MODE)'
It looks to me like the various bitmasks are set up as a single enum, and C++ objects to ORing enums together (actually, to making the result back into an enum.) As it should, I think.
Seriously, Microchip?
It looks like casting it might work (don't forget the parens!):
UARTSetLineControl(UART1, (UART_LINE_CONTROL_MODE)(UART_DATA_SIZE_8_BITS|UART_PARITY_EVEN|UART_STOP_BITS_1));
I should note that I'm not sure if Serial1 maps to UART1...
Thu, 12 Jan 2012 22:19:31 +0000
After a bit of research with a friends help we came up with the same as above
#include <plib.h>
UARTSetLineControl(UART2, UART_DATA_SIZE_8_BITS | UART_PARITY_EVEN | UART_STOP_BITS_1);
I have set it to UART2 just incase I kill comms to UART1 / Serial. I will just use UART2 / Serial3. to start with. I assume UART1 = Serial. and Serial1. and UART2 = Serial2. and Serial3.
however errors are the following while running the code above.
sketch_jan12a.cpp:5:19: error: expected constructor, destructor, or type conversion before '(' token
sketch_jan12a.cpp: In function 'void setup()':
sketch_jan12a.cpp:66:33: error: no matching function for call to 'HardwareSerial::read(int&)'
C:\Program Files\MPIDE\hardware\pic32\cores\pic32/HardwareSerial.h:104:16: note: candidate is: virtual int HardwareSerial::read()
sketch_jan12a.cpp:68:36: error: expected '}' at end of input
Fri, 13 Jan 2012 03:54:03 +0000
You do have the call to UARTSetLineControl() inside your setup() function, right? And the #include statement outside? I get this error when I move the call outside of functions. Calls to functions MUST be inside of "code blocks" (usually: other functions.)
Fri, 13 Jan 2012 06:46:23 +0000
You do have the call to UARTSetLineControl() inside your setup() function, right? And the #include statement outside? I get this error when I move the call outside of functions. Calls to functions MUST be inside of "code blocks" (usually: other functions.)
I have
#include <plib.h>
at the top and put
UARTSetLineControl(UART2, (UART_LINE_CONTROL_MODE)(UART_DATA_SIZE_8_BITS|UART_PARITY_EVEN|UART_STOP_BITS_1));
inside
void setup()
I get
sketch_jan12a.cpp: In function 'void setup()':
sketch_jan12a.cpp:67:33: error: no matching function for call to 'HardwareSerial::read(int&)'
C:\Program Files\MPIDE\hardware\pic32\cores\pic32/HardwareSerial.h:104:16: note: candidate is: virtual int HardwareSerial::read()
sketch_jan12a.cpp:69:36: error: expected '}' at end of input
Im running this on MPIDE 0023
again thank you for your help on this :)
Fri, 13 Jan 2012 08:28:53 +0000
I dunno. It worked (compiled) for me (Uno32), starting with the ASCIITable example sketch. You could try fiddling with that till you have a better idea what's going on. Is your sketch short enough that you can post the whole thing?
Fri, 13 Jan 2012 08:36:26 +0000
no worries, will keep bashing away at it. Im running this on a MAX32
More that some of the content is sensitive .. the unit im talking to has taken me a long time to reverse engineer.
Thanks for the help anyways Ive been doing quite a bit of poking around in the librarys because of this.
Tue, 14 Feb 2012 01:02:15 +0000
Hello All,
I would recommend changing the UxMODE (where x is the number of the UART you are using) register directly, it will give you more control over the functionality of the UART. For example if you wish to set the UART1 to 8 data bits, even parity and 1 stop bits you would use:
U1MODE = 0;
U1MODESET = (1 << 15) | (1 << 1); //15 is the on bit and 1 is the 8-data + even parity bit.
This is detailed in the PIC32MX datasheet located
UART Specific:
http://ww1.microchip.com/downloads/en/DeviceDoc/61107F.pdf
Full PIC32MX
http://ww1.microchip.com/downloads/en/DeviceDoc/PIC32MX_Datasheet_v2_61143B.pdf
Best Regards,
Ryan
Fri, 02 Mar 2012 20:41:36 +0000
Thanks for that! :) Will give it a wurl as the other ways are just not working for me
Sat, 03 Mar 2012 01:09:32 +0000
Oh whoops I almost forgot you probably have to add #include <plib.h>
Mon, 12 Mar 2012 10:48:48 +0000
Software UART written in C language for atmega8? i want to increase serial port of atmega8 (which have 1 serial port,where i need 3 serial port) by using software uart .plz help me.
keyword research ~ keyword tool ~ keyword tracking ~ affiliate elite
Sun, 29 Apr 2012 01:17:47 +0000
Hi guys,
I have dedicated my weekend to working this out .. I have successfully managed to make this work on the Ardiuno Mega 2560 without any issue however when I use any of the code about its just not switching it to even parity.
I am running a 'sniffer' on the line and its still transmitting 9600,n,8,1 not 9600,e,8,1
Again the sniffer confirms the Ardiuno Mega 2560 is infact running 9600,e,8,1 however not the Max32 with the below code or any other in this thread.
here is what I have
#include <plib.h>
void setup() {
// Setup serial monitor coms
Serial.begin(9600);
Serial3.begin(9600);
U4MODE = 0;
U4MODESET = (1 << 15) | (1 << 1); //15 is the on bit and 1 is the 8-data + even parity bit.
}
Note i'm trying to send out and recieve commands on the last UART or RX3/TX3
Sun, 29 Apr 2012 03:33:24 +0000
Reading some of the spec.
bit 2-1 PDSEL<1:0>: Parity and Data Selection bits
11 = 9-bit data, no parity
10 = 8-bit data, odd parity
01 = 8-bit data, even parity
00 = 8-bit data, no parity
The synatax is still confusing me a little with the U4MODESET command.
Doing a lot of searching on this there doesnt seem to be a lot of info on this with examples :(
Does the 4 in U4MODESET = the last UART (serial3 in MPIDE)? Does setting Bit1 to 1 actually set it to binary '01' in U4MODESET = (1 << 15) | (1 << 1); ?
Mon, 30 Apr 2012 07:14:42 +0000
Persistance paid off.
This is the code that works for RX3/TX3 (Serial3) pins on Chipkit Max32
#include <plib.h>
void setup() {
// Setup serial monitor coms
Serial3.begin(9600);
// Switch UxMODE register - 15 is the on bit and 1 is the 8-data + even parity bit.
U5MODESET = (1 << 15) | (1 << 1);
}
Thanks to all that helped out and I hope this helps some one else out in their travels :)
Sun, 06 May 2012 00:58:46 +0000
Hmmm so it turns out with a lot of testing that unfortunately Im only half way there.
The above code works and allows the Max32 to transmit in 9600,e,8,1 however there is nothing on the recieve buffer at all.
I have tested with very back to basics code but all that I can get back is nothing.
The my send command is defanitely coming out of the Max32 in even parity. I have tested this with a sniffer on the line and the device im sending the command too is replying back correctly.
The Max32/pic32 just isnt recieveing.
I a friend and I have tested the hardware chain and voltages and they are all working 100%
Again we have tested the same code with a Ardiuno Mega 2560 and it works 100%
I have even attempted some more register 'SET' commands based on the UART documentation to force things like TX/RX on etc but with no luck there either. Im still using the SerialX.begin(9600) command (which I assume covers off a lot of the register setting in one command) and over lay the UxMODESET commands over the top.
I have also used a second Max32 and tested the code to make sure i hadn't blown the RX part of the silicon on mine. Same results with this one too.
Kind of at a real loss of what to try next :(
Any expert help would be much appriecated. I'm really keen on using the PIC32 for its out right grunt but I may have to change platforms to get on with this project.
Sun, 06 May 2012 21:23:26 +0000
Having enabled parity , what about parity error interrupts ,
INTERRUPTS The UART can generate interrupts reflecting the events that occur during the data communication. The following interrupts can be generated: • Receiver-data-available interrupt, signalled by UxRXIF. This event occurs based on the URXISEL<1:0> control bits (UxSTA<7:6>). Refer to 21.6.3 “Receive Interrupt†for details. • Transmitter buffer-empty interrupt, signalled by UxTXIF. This event occurs based on the UTXISEL<1:0> control bits (UxSTA<15:14>). Refer to 21.5.2 “Transmit Interrupt†for details. • UART-error interrupt, signalled by UxEIF.
Can you see errors when reading UxSTA . can you loopback tx--Rx .
Not an expert...... :(
Mon, 07 May 2012 03:59:31 +0000
I'll look at the other stuff you've posted tonight ...
Can you see errors when reading UxSTA . can you loopback tx--Rx .
I have run up my code in a loop back (serial1->serial3)
The strange thing is, when I display it in the serial monitor .. with Even parity turned on for serial1 the byte array dump to the serial monitor (serial.print) display without being garbled .. which is very strange. I would execpt it to be inputting rubbish however it comes through as normal.
Here is the code with some random bytes sent
NOTE: I have not set the recieve port to even parity delibrately (its remmed out) you can enable it by unremarking U5MODESET command.
#include <plib.h>
byte inByte[4];
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
Serial3.begin(9600);
U4MODESET = (1 << 15) | (1 << 1); //(Serial1) 15 is the on bit and 1 is the '8-data + even parity bit' (See PIC32 UART Datasheet for more detail).
// U5MODESET = (1 << 15) | (1 << 1); //(Serial3) 15 is the on bit and 1 is the '8-data + even parity bit' (See PIC32 UART Datasheet for more detail).
}
void loop() {
byte SendByte[] = {char(1), char(2), char(3), char(4)};
// Send message
int i;
for (i=0;i<4;i++){
Serial1.print(SendByte[i]);
}
// Recieve response
if (Serial3.available()){
int r;
for (r=0;r<4;r++){
inByte[r] = Serial3.read();
// Display in Serial Monitor
Serial.print(inByte[r], HEX);
}
}
// Line feed and Delay
Serial.println("");
delay(1000);
}
Mon, 07 May 2012 12:44:35 +0000
I would hope the handler for serialx looks at errors before moving the buyte to the rx buffer , my documents seem to suggest the uartx has shared interrupts. I will see what a UNO32 makes of it..........
(its raining and my project is on a soak test....:) Les.
Edit... As uno has only 2 serial ports I tried 9600,e,8,1 on serial1 and looped Rx<->Tx, then serial.print the Rx all was OK with the 1234.
are parity errors being ignored on your example..
Edit 2... using monitor SEND and input to Serial1 at even parity , then sent it back to monitor !!! first(single) byte was OK second was wrong as you would expect,,, UNO seems to do even parity OK , not seen UxSTA errors what ever i do..
Mon, 07 May 2012 23:10:48 +0000
Thanks for you time on this! :)
I have pretty much found the same thing ..
Max32 TX1_9600,e,8,1 -> logic converter -> device accepts and replies back with correct data-> (sniffer (with correct isolated electronics) tapped off the line) -> logic converter -> Max32 RX3_9600,n,8,1 / or Max32 TX3_9600,n,8,1 (doesnt matter) and I get nothing.
Same chain and code works on ATMEL/Ardiuno mega so I dont think its my mosfet logic converter?
To be sure also I have removed the sniffer in case it was causing a voltage drop and the PIC32 just didnt like it.
In loop back mode and bridging UART 1 and 3 together with hookup wire I can send the command and recieve it but if I try change the even on the TX side theRX can read it either way. One thing I think my friend and I have confirmed is that the RX just automatically recognises the N,E or O parity regardless? because it will just work.
This is so weird! and I cant work out if I have multiple things going wrong or not.
I think im just going to have to get hold of an oscilloscope and check the signals and voltages to be sure.
Wed, 09 May 2012 03:50:58 +0000
Hello,
Okay if I understand your problem correctly, it has to do with detecting parity errors?
Let me start with the way MPIDE does UART communication. Whenever data is placed into the receive FIFO it generates an interrupt which pulls the data from the FIFO into an internal buffer. This is the buffer that Serial.available() checks to see if there is anything in it.
Okay the way the PIC32MX works with detecting parity errors is that it sets the 3rd bit in the UxSTA register when the data at the top of the receive FIFO violates the parity rules set in the UxMODE register. But looking at the loop back example you have posted below using Serial1 and Serial3, you will most likely never see the parity error by placing code in the sketch since the interrupt will have already cleared the FIFO. You'll need to place the check in the interrupt itself before the read in HardwareSerial.cpp in the doSerialInt() member function.
As for you having the receive UART with no parity and with the transmit UART with even parity you aren't going to get parity errors on the receiving side. You'll get framing errors (indicated by 2nd bit in the UxSTA) whenever the parity from the transmit would be low because the receive UART expects a stop bit there instead.
For Les, each UART has separate interrupts.
If you have any questions let me know.
Best Regards, Ryan K Digilent
Wed, 09 May 2012 06:53:41 +0000
Hi Ryan,
The issue is not so much with being able to read the parity error register but with the fact that the PIC32mx wont read the incoming line (RX3) (atleast to the buffer) there is 0 data. Parity or no Parity it just doesnt seem to want to work
This is confirmed again last night with some more testing. The Arduino is having no problem with the circuit. We are just starting to think that its a tollerance thing with the PIC32mx oppose the atmel chip.
I'm looking at replacing my circuit with a transciever IC instead of using mosfets to convert the logic level from 12volt to 3.3volt.
Wed, 09 May 2012 13:17:26 +0000
Hello again...
When I typed " shared ^ Interrupts " above post I missed the word Error ^, in the UNO's 32MX320 UART errors : parity, frame , over-run, raise the same interrupt request flag so call the same routine , as any parity method is not supported in makes sense that the sw should / will / may disregard the byte as it is an error and loose it... That is assuming UART errors are enabled for interrupts and are catered for ?
This could be different for 32MAX.... Iv'e not looked.
Extract from data sheet DS61143G-page 90 91 IRQ V# flags U1E – UART1 Error 26 24 IFS0<26> IEC0<26> IPC6<4:2> IPC6<1:0> U2E – UART2 Error 40 32 IFS1<8> IEC1<8> IPC8<4:2> IPC8<1:0>