Uart and Peripheral Pin Select

General discussion on mikroBasic PRO for dsPIC30/33 and PIC24.
Post Reply
Author
Message
peterverkaik
Posts: 174
Joined: 31 Aug 2009 22:44

Uart and Peripheral Pin Select

#1 Post by peterverkaik » 05 Jan 2010 14:33

Here is a test program to use Uart1 module to create 4 uart channels.
The mcu used is dsPIC33FJ128GP802/804

Code: Select all

program Uart_test

const
  RP0 = 0
  RP1 = 1
  RP2 = 2
  RP3 = 3
  RP4 = 4
  RP5 = 5
  RP6 = 6
  RP7 = 7

const Uart1TxPins as word[4] = (RP0,RP2,RP4,RP6)
const Uart1RxPins as word[4] = (RP1,RP3,RP5,RP7)
const Uart1Baud as word[4] = (9600,1200,19200,4800)

dim Uart1rxBuf as byte[256]
dim Uart1rxHead, Uart1rxTail as byte

dim hwUartChannel as word 'ch0=RP0,RP1 ch1=RP2,RP3 ch2=RP4,RP5 ch3=RP6,RP7

sub procedure Uart1rxInt org IVT_ADDR_U1RXINTERRUPT
  Uart1rxBuf[Uart1rxHead] = Uart1_Read()  'put char in buf
  Uart1rxHead = Uart1rxHead + 1           'increment head pointer
  IFS0.U1RXIF = 0                         'clear U1RXIF
end sub

sub procedure Uart1_Stop()
  IEC0.U1RXIE = 0 'disable U1RX interrupt
  U1MODE.UARTEN = 0 'disable uart1 module
end sub

main:
  ADPCFG = $FFFF  'In order to use PORTB pins for digital I/O, the corresponding bits in
                  'the ADPCFG register must be set to ‘1’, even if A/D module is turned off.

  'goal is to use uart1 module to support 4 uart channels
  'by remapping uart1 module to different pins in a roundrobin scheme
  while true
    LATB = LATB OR $00FF 'set latches to uart idle level
    TRISB = (TRISB AND $FF55) OR $0055 'make RP0,RP2,RP4,RP6 output, RP1,RP3,RP5,RP7 input
    for hwUartChannel = 0 to 3
      Unlock_IOLOCK()
      PPS_Mapping(Uart1RxPins[hwUartChannel],_INPUT,_U1RX)
      PPS_Mapping(Uart1TxPins[hwUartChannel],_OUTPUT,_U1TX)
      Lock_IOLOCK()
      Uart1rxHead = 0
      Uart1rxTail = 0
      Uart1_Init(Uart1Baud[hwUartChannel])
      Uart_Set_Active(@UART1_Read, @UART1_Write, @UART1_Data_Ready, @UART1_Tx_Idle)
      IPC2.U1RXIP_0 = 0 'U1RX interrupt priority 4
      IPC2.U1RXIP_1 = 0
      IPC2.U1RXIP_2 = 1
      IEC0.U1RXIE = 1 'enable U1RX interrupt
      'Send command
      Uart1_Write(0x41 + hwUartChannel) 'send 'A', 'B', 'C' or 'D'
      'Wait for response
      while Uart1rxTail = Uart1rxHead
      wend
      'Get response and echo
      Uart1_write(Uart1rxBuf[Uart1rxTail]) 'echo received bytes
      Uart1rxTail = Uart1rxTail + 1
      'Wait for transmission complete
      while Uart1_Tx_Idle = 0
      wend
      Uart1_Stop() 'disable uart1 module
      Delay_ms(2000) 'wait 2 seconds
    next hwUartChannel
  wend
end.
As the Uart library does not provide a Stop function, I declared
one myself.
Questions:

Do I take the right steps regarding unlock and lock functions?

Do I need to remap pins to _NULL before switching to next channel?
(I want a stopped channel to have its output pin at idle level)

Why is there no _NULL function for input pins?
(If I remap _U1RX it may be _U1RX is mapped to multiple pins)

regards peter

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

#2 Post by jpc » 05 Jan 2010 16:07

Peter,

peripheral inputs can be connected to only 1 pin at a time , however you can connect as many output-pins to a peripheral output as you want simultaneously e.g you could have the uart output connected to a number of pins and these will all behave identical.
Your mapping sequence seems ok btw, if you want to remap make sure the IOKOCK_Enable is cleared in the configuration settings.
If you want 4 uarts you better use one of the chips with 4 uarts ( e.g. p24FJ256GB110 family) instead of the multiplexing as you try to do, this will not work any better than simply using a rs485 buswhich has the advantage of allowing many nodes.
Au royaume des aveugles, les borgnes sont rois.

peterverkaik
Posts: 174
Joined: 31 Aug 2009 22:44

#3 Post by peterverkaik » 06 Jan 2010 16:04

peripheral inputs can be connected to only 1 pin at a time
Does this mean if I remap U1RX from RP1 to RP3, that RP1 comes
under control of LAT, TRIS and PORT automatically?
however you can connect as many output-pins to a peripheral output as you want simultaneously e.g you could have the uart output connected to a number of pins and these will all behave identical.
If I remap U1TX from RP0 to RP2 then I want RP0 to stay at idle
level, that's why I set LAT to 1 prior to using remapping. I assume
I must remap RP0 to NULL and then remap U1TX to RP2.

Thanks for the tip on IOLOCK_enable.
If this multiplexing works I may want to multiplex 8 uarts.
Also. the 802 comes in a relative small dip package.

regards peter

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

#4 Post by jpc » 06 Jan 2010 16:37

yes, you will have to disconnect the TX and yes, if you remap the RX the input's you mapped it to before should be released( allthough i must admit i never tested this)
I still think you waste energy on this multiplexing thing, this will never perform like 8 uarts, actually not even like 2. Well designed uart ISR's will capture any character as long as the buffers can hold it, multiplexing will introduce uart-errors allmost for sure unless you go for a master-slave protocol but this could be done with less effort on aRS485 bus which was designed for the purpose.

regards jpc
Au royaume des aveugles, les borgnes sont rois.

Post Reply

Return to “mikroBasic PRO for dsPIC30/33 and PIC24 General”