Help - Search - Members - Calendar
Full Version: Program Stopp Woring When Useing Serial Port!
SourceBoost support forum > PIC and SX Embedded Programming > Novo RTOS Programming
sdujolo
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.
Reynard
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
Pavel
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

CODE
/********************************************************************
    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
sdujolo
Thanks it works now:)
babos
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
Pavel
QUOTE (babos @ Jun 15 2009, 08:58 PM) *
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
babos
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.
D.Cauby
In my opinion it is not logical
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2010 Invision Power Services, Inc.