Jump to content
sdujolo

Program Stopp Woring When Useing Serial Port!

Recommended Posts

I am testing Novo and the program is working but when I activate serial port it stop working.

 

rcsta.SPEN = 1; //If I comment out this line everything works.

Share this post


Link to post
Share on other sites

Not many clues to go on here.

 

Do you have an interrupt that is not being serviced, like the tx interrupt. If an interrupt flag remains uncleared then it could be hogging all the processor time jumping in and out of the interrupt function but the flags are not being cleared or stopped from being set when you don't want them.

 

Cheers

 

Reynard

Share this post


Link to post
Share on other sites

Below is a sample code that will appear in the next SourceBoost release. It shows how Novo can handle serial port. Please use it as a reference.

 

Don't forget to add -swcs to linker command line

 

 

Regards,

Pavel

 

/********************************************************************
BoostC/BoostC++ sample code for
Microchip "PICDEM HPC Explorer Board" 
Part Number: DM183022

Asynchronous UART and Novo RTOS

This code uses Novo RTOS and shows how to use interrupts
to receive and transmit serial data and how to safely share
this data with tasks. 

Two tasks are implemented:
- one task runs every second and updates
  port D connected to 8 LEDs
- another task waits for data from UART, than transforms
  it and sends back

Receive buffer uses counting semaphore to indicate data
availability so that tasks waiting for data will yield
if data is not available.

BoostC/BoostC++ compilers are available from www.sourceboost.com

Author(s) Pavel Baranov
Copyright(C) 2009 Pavel Baranov

This code can be used free of charge in both commercial and 
non-commercial projects as long as this copyright notice and 
this entire statement is left unchanged. This software is provided
"as is", without warranty of any kind.

********************************************************************/

//System headers
#include <system.h>
#include <novocfg_pic18t3e5ts1.h>
#include <novo.h>

//Target PIC18F8722 configuration word
#pragma DATA _CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L & _STVREN_OFF_4L & _XINST_OFF_4L
#pragma DATA _CONFIG2H, _WDT_OFF_2H & _WDTPS_128_2H
#pragma DATA _CONFIG2L, _PWRT_OFF_2L & _BOREN_OFF_2L
#pragma DATA _CONFIG1H, _FCMEN_OFF_1H & _OSC_HS_1H

//Set clock frequency
#pragma CLOCK_FREQ	10000000

//Novo tasks
#define hTask0 0
#define hTask1 1

//Novo semaphores
#define hRxSem 0

//LED counter
static unsigned char led = 0;

//UART Tx and Rx data
#define TX_BUFFER_SIZE	8
#define RX_BUFFER_SIZE	16

static unsigned char TxBuffer[TX_BUFFER_SIZE], txHead, txTail;
static unsigned char RxBuffer[RX_BUFFER_SIZE], rxHead, rxTail;

//Port settings

#define USE_PORT_0

#if defined USE_PORT_0
#define TX_IRQ_FLAG		 pir1.TX1IF
#define RX_IRQ_FLAG		 pir1.RC1IF
#define TX_IRQ_ENABLE	   pie1.TX1IE
#define RX_IRQ_ENABLE	   pie1.RC1IE
#define TX_IRQ_PRIO		 ipr1.TXIP
#define RX_IRQ_PRIO		 ipr1.RCIP
#define TX_ENABLE		   txsta.TXEN
#define RX_ENABLE		   rcsta.CREN
#define UART_TX_END		 txsta.TRMT
#define UART_ENABLE		 rcsta.SPEN
#define UART_EVERFLOW_ERR   rcsta.OERR
#define UART_FRAME_ERR	  rcsta.FERR
#define UART_BRG_HIGH_SPEED txsta.BRGH
#define UART_BRG			spbrg
#define UART_TX_REG		 txreg1
#define UART_RX_REG		 rcreg1
#elif defined USE_PORT_1
#define TX_IRQ_FLAG		 pir3.TX2IF
#define RX_IRQ_FLAG		 pir3.RC2IF
#define TX_IRQ_ENABLE	   pie3.TX2IE
#define RX_IRQ_ENABLE	   pie3.RC2IE
#define TX_IRQ_PRIO		 ipr3.TXIP
#define RX_IRQ_PRIO		 ipr3.RCIP
#define TX_ENABLE		   txsta2.TXEN
#define RX_ENABLE		   rcsta2.CREN
#define UART_TX_END		 txsta2.TRMT
#define UART_ENABLE		 rcsta2.SPEN
#define UART_EVERFLOW_ERR   rcsta2.OERR
#define UART_FRAME_ERR	  rcsta2.FERR
#define UART_BRG_HIGH_SPEED txsta2.BRGH
#define UART_BRG			spbrg2
#define UART_TX_REG		 txreg2
#define UART_RX_REG		 rcreg2
#else
#error "Error: unsupported port selected"
#endif

//////////////////////////////////////////////
// High priority interrupt handles
// handles system time
//////////////////////////////////////////////
void interrupt( void )
{
//Handle timer0 interrupt
if( intcon.T0IF )
{
	// update system time every 1s
	static unsigned char nDivider = 0;
	if( 39 == ++nDivider )
	{
		nDivider = 0;
		SysTimerUpdate();
	}
	clear_bit( intcon, T0IF ); //clear timer 0 interrupt bit
}
}

//////////////////////////////////////////////
// Low priority interrupt handles
// handles UART send and receive
//////////////////////////////////////////////
void interrupt_low( void )
{
//Handle UART transmit
if( TX_IRQ_FLAG )
{
	//Check if there is data in transmit buffer
	if( txHead != txTail )
	{
		UART_TX_REG = TxBuffer[txTail++];
		if( TX_BUFFER_SIZE == txTail )
			txTail = 0;
	}
	else
	{
		//Nothing to send, disable Tx irq
		//but only after the last bit from
		//prev transmission is out
		while( !UART_TX_END );
		TX_ENABLE = 0;
	}
}
//Handle UART receive
if( RX_IRQ_FLAG )
{
	//Test for errors first
	if( UART_EVERFLOW_ERR ) //overflow error
	{
		//read and discard incoming byte
		unsigned char discard = UART_RX_REG;
	}
	else if( UART_FRAME_ERR ) //frame error
	{
		//restart Rx to clear this error
		RX_ENABLE = 0;
		RX_ENABLE = 1;
	}
	else
	{
		//Check if there is free space in receive buffer
		BYTE cnt = SysReadSemaphore( hRxSem );
		if( cnt < RX_BUFFER_SIZE )
		{
			//Write incoming byte into the buffer and increment Rx semaphore
			RxBuffer[rxHead++] = UART_RX_REG;
			if( RX_BUFFER_SIZE == rxHead )
				rxHead = 0;
			SysSignalSemaphoreIsr( hRxSem );
		}
		else
		{
			//Buffer overflow, the incoming byte will be lost
			unsigned char discard = UART_RX_REG;
		}
	}
}
}

//////////////////////////////////////////////
//Receive one byte from serial port
//////////////////////////////////////////////
unsigned char Rx( void )
{
//Wait for serial data to come
Sys_WaitSemaphore( hRxSem, EVENT_NO_TIMEOUT );

//Read one byte from rx queue
SysCriticalSectionBegin();
unsigned char data = RxBuffer[rxTail++];
if( RX_BUFFER_SIZE == rxTail )
	rxTail = 0;
SysCriticalSectionEnd();

return data;
}

//////////////////////////////////////////////
//Send one byte into serial port
//////////////////////////////////////////////
void Tx( unsigned char data )
{
//Put data into the rx queue
SysCriticalSectionBegin();
TxBuffer[txHead++] = data;
if( TX_BUFFER_SIZE == txHead )
	txHead = 0;
TX_ENABLE = 1; //enable Tx
SysCriticalSectionEnd();
}

//////////////////////////////////////////////
//Send a string into serial port
//////////////////////////////////////////////
void Tx( char * text )
{
while( *text )
	Tx( *text++ );
}

//////////////////////////////////////////////
// Task that processes UART data
//////////////////////////////////////////////
void Task0()
{
//Send out hello string (string should fit into the tx buffer)
Tx( "Ready..." );

//This tack will receive data, transform it and send back
while( 1 )
{
	//Wait for serial data to come. This is a blocking
	//call that will yield if no data is available
	unsigned char data = Rx();

	//If this is lover case character convert it to capital
	if( data >= 'a' && data <= 'z' )
		data -= 'a' - 'A';

	//Send data back
	Tx( data );
}
}

//////////////////////////////////////////////
// Task that every second flashes a LED
//////////////////////////////////////////////
void Task1()
{
//Update LEDs connected to port D every second
while( 1 )
{
	latd = ++led;
	Sys_Sleep( 1 );
}
}

//////////////////////////////////////////////
// Program entry point
//////////////////////////////////////////////
void main( void )
{
//Disable watchdog
wdtcon.SWDTEN = 0;

//Configure port A
trisa = 0x00;
//Configure port B
trisb = 0x00;
//Configure port C
trisc = 0x00;
//Configure port D
trisd = 0x00;

//Initialize port A
porta = 0x00;
//Initialize port B
portb = 0x00;
//Initialize port C
portc = 0x00;
//Initialize port D
portd = 0x00;

//Set Timer0 mode
set_bit( t0con, TMR0ON ); //enable timer0
clear_bit( t0con, T0CS ); //configure timer0 as a timer
//Set Timer0 resolution
set_bit( t0con, T08BIT ); //set timer0 8 bit wide
//Set prescaler assignment
clear_bit( t0con, PSA ); //prescaler is assigned
//Set prescaler rate
set_bit( t0con, T0PS2 ); //prescaler rate 1:256
set_bit( t0con, T0PS1 );
set_bit( t0con, T0PS0 );
//Set timer0 source edge selection
set_bit( t0con, T0SE ); //increment on high-to-low transition on RA4/T0CKI pin

//Configure serial port
RX_IRQ_PRIO = TX_IRQ_PRIO = 0; //use low priority interrupt
UART_BRG_HIGH_SPEED = 1; //high speed
UART_BRG = 64;		//9600kbps/10Mhz
RX_IRQ_ENABLE = 1;	//enable Rx irq
TX_IRQ_ENABLE = 1;	//enable Tx irq
RX_ENABLE = 1; //enable continuous receive
UART_ENABLE = 1; //enable serial port

//Configure UART pins
#if defined USE_PORT_0
trisc.7 = 1;
trisc.6 = 0;
#elif defined USE_PORT_1
trisg.2 = 1;
trisg.1 = 0;
#endif

//Configure interrupts
rcon.IPEN = 1; //enable priority level interrupts
intcon.TMR0IE = 1; //enable timer 0 interrupt
intcon.GIEH = intcon.GIEL = 1; //Enable hign and low priority interruptr

//Initialize Novo RTOS
SysInit();

//Create Novo tasks
SysCreateTask( hTask0, 2, Task0 );
SysCreateTask( hTask1, 2, Task1 );

//Start Novo tasks
SysStartTask( hTask0 );
SysStartTask( hTask1 );


//Endless loop
while( 1 ) Sys_Yield();
}

// End of code

Share this post


Link to post
Share on other sites

Dear sir,

I try this code with MPlab then Simulate in Proteus 7.4 but, in the serial terminal only the first "R" of the string "Ready..." appear and the led are all Off forever.

Only if I comment the line TX("Ready...", the task of led start but nothing about serial port.

I try to debug and the program loop because TX_IRQ_FLAG is ever HIGH every irq occurs.

 

???

where I mistake

Thank's

Share this post


Link to post
Share on other sites
Dear sir,

I try this code with MPlab then Simulate in Proteus 7.4 but, in the serial terminal only the first "R" of the string "Ready..." appear and the led are all Off forever.

Only if I comment the line TX("Ready...", the task of led start but nothing about serial port.

I try to debug and the program loop because TX_IRQ_FLAG is ever HIGH every irq occurs.

 

???

where I mistake

Thank's

 

This code uses Novo RTOS and because of this needs -swcs linker command line argument. Please make sure you have it or you will see all kind of strange problems.

 

Regards,

Pavel

Share this post


Link to post
Share on other sites

It's all right sir,

the program work in MPLAB IDE Simulator right, but not in Labcenter Proteus 7.3 sp4 simulator.

thanks also if you have suggest something.

Share this post


Link to post
Share on other sites

Your content will need to be approved by a moderator

Guest
You are commenting as a guest. If you have an account, please sign in.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoticons maximum are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×