// // @(#) Use salvo to create a test program // @(#) $Header: /opt/x2k/timersalvo/RCS/main.c,v 1.6 2002/09/16 03:00:52 skia Exp skia $ // #include #include #include #define TASK_COUNT_P OSTCBP(1) // task #1 #define TASK_SHOW_P OSTCBP(2) // "" #2 #define TASK_BLINK_P OSTCBP(3) // "" #3 #define TASK_SERIAL_P OSTCBP(4) // "" #4 #define TASK_WAVE_P OSTCBP(5) // "" #5 #define PRIO_COUNT 12 // task priorities #define PRIO_SHOW 10 // "" #define PRIO_BLINK 2 // "" #define PRIO_OTHER 11 // "" // #define MSG_UPDATE_PORT_P OSECBP(1) // semaphore #1 #define MSG_GET_SERIAL OSECBP(2) // semaphore #2 #define SEM_USART_TX_READY OSECBP(3) // semaphore #3 #define bitGIE GIE #define bitTXIE TXIE // // Function prototypes // void Init(void); void OSIdlingHook( void ); int Nputch(unsigned char); void TaskCount(void); void TaskShow(void); void TaskBlink(void); void TaskGetSerial(void); //void TaskWave( void ); #define NPUTCH_M(c) while( Nputch(c) ) OSSched() #define NPUTCH_T(c, t) while( Nputch(c) ) OS_Yield(t) #define SYSPROMPT_M for( i=0; i < 5; i++ ) { NPUTCH_M( sysprompt[i] ); } #define SYSPROMPT_T(t) for( i=0; i < 5; i++ ) { NPUTCH_T( sysprompt[i], t ); } _OSLabel(TaskCount1) _OSLabel(TaskShow1) _OSLabel(TaskBlink1) _OSLabel(TaskBlink2) _OSLabel(TaskGetSerial1) _OSLabel(TaskGetSerial2) _OSLabel(TaskGetSerial3) _OSLabel(TaskWave1) // // global variables // char CODE_B = 'B'; char CODE_C = 'C'; // char SERIAL_GET = '1'; char SERIAL_CHAR; extern const char Banner[]; extern const char sysprompt[]; unsigned int counter; #define RX_BUFF_SIZE 80 unsigned char rxCount; unsigned char rxInPtr, rxOutPtr; unsigned char rxBuff[RX_BUFF_SIZE]; #define TX_BUFF_SIZE 80 unsigned char txCount; unsigned char txInPtr, txOutPtr; unsigned char txBuff[TX_BUFF_SIZE]; // // start the system // void main( void ) { int i; // // Make sure that these values are correct // CODE_B = 'B'; CODE_C = 'C'; SERIAL_GET = '1'; OSInit(); OSCreateTask(TaskCount, TASK_COUNT_P, PRIO_COUNT); OSCreateTask(TaskShow, TASK_SHOW_P, PRIO_SHOW); OSCreateTask(TaskBlink, TASK_BLINK_P, PRIO_BLINK); OSCreateTask(TaskGetSerial, TASK_SERIAL_P, PRIO_OTHER); //OSCreateTask(TaskWave, TASK_WAVE_P, PRIO_OTHER); OSCreateMsg(MSG_UPDATE_PORT_P, (OStypeMsgP) 0); OSCreateMsg(MSG_GET_SERIAL, (OStypeMsgP) 0); //OSCreateBinSem(SEM_USART_TX_READY, 0); // // Initialize the hardware and enable interrupts // Init(); // send the banner for( i=0; i< strlen(Banner); i++ ) { NPUTCH_M( Banner[i] ); } SYSPROMPT_M; // // Run the OS // for(;;) { OSSched(); } } void Init(void) { // T0CON - Timer 0 Configuration // 0 1 0 0 - 1 1 1 0 // // 1 - Start timer // 0 - 16 bit timer // 0 - Internal instruction cycle clock // 0 - Increment on low to high // // 0 - Timer0 Prescaler is assigned // 110 - 1:128 prescale value // 001 - 1:4 prescale value T0CON=0b10000000; // INTCON:2 (TMR0IF) = 0. TMR0 Register did NOT overflow. Clear overflow flag. TMR0IF=0; // INTCON:5 (TMR0IE) = 1. Enable TIMER0 interrupts. TMR0IE=1; // // At 40e6 Mhz. This value will give you 1ms tick. TMR0=60534; // // Enable interrupts // GIEH=1; GIEL=1; // Serial port communications // TXSTA - Transmit Enabled TXSTA=0b10100100; // RCSTA - Serial port enable RCSTA=0b10010000; // SPBRG - Baud rate. 19200, 40E6 Clock speed. SPBRG=129; // PORTC RC7=1(input) RX pin. RC6=0(output) TX pin. PORTC |= 0x40; // Set high to avoid bad chars 0100 0000 TRISC=0x80; // 1000 0000 // PIE1 - USART Transmit Interrupt Enable/Disable (1/0) TXIE=0; // If we have no chars, don't enable // RCIE - USART Receive Interrupt Enable/Disable (1/0) RCIE=1; // reset Tx ring buffer pointers txCount = 0; txInPtr = 0; txOutPtr = 0; // reset Rx ring buffer pointers rxCount = 0; rxInPtr = 0; rxOutPtr = 0; // PORTB is output port. Clear it initially. TRISB=0x00; PORTB=0x00; // PORTD is output port. Clear it initially. TRISD=0x00; PORTD=0x00; } int Nputch(unsigned char c) { // if ( txCount < TX_BUFF_SIZE ) { // insert char into Tx buffer and // wrap pointer if necessary. txBuff[txInPtr++] = (unsigned) c; if (txInPtr > TX_BUFF_SIZE-1) txInPtr = 0; // must protect txCount from ISR, // don't re-enable ints if they're // already disabled. if ( bitGIE ) { OSDi(); bitTXIE = 1; txCount++; OSEi(); } else { bitTXIE = 1; txCount++; } return 0; } else { // // Tell him that we coundn't send the char // return 1; } } #pragma interrupt_level 0 void interrupt low_priority ISRLOW(void) { ; } #pragma interrupt_level 0 void interrupt ISR(void) { if( (RCIE) && (RCIF) ) { // receive interrupt routine SERIAL_CHAR = RCREG; OSSignalMsg(MSG_GET_SERIAL, (OStypeMsgP) &SERIAL_GET); } if( (TXIE) && (TXIF) ) { // transmit interrupt routine // // If there is nothing in the Tx buffer, // Then Shut down the transmitter if ( txCount == 0 ) bitTXIE = 0; else { // Send the next char TXREG = txBuff[txOutPtr++]; // Wrap aroung if we reached the end if (txOutPtr > TX_BUFF_SIZE-1) txOutPtr = 0; txCount--; } } if( (TMR0IF) && (TMR0IE) ) { TMR0IF=0; TMR0=60534; PORTD ^= 0x01; #ifdef OSUSE_INLINE_OSTIMER #include "timer.c" #else OSTimer(); #endif } // // Useless code that satisfies the pic18 // call graph requirements. // //if( 0 ) // OSCreateMsg(MSG_UPDATE_PORT_P, (OStypeMsgP) 0); if( 0 ) OSSignalMsg(MSG_UPDATE_PORT_P, (OStypeMsgP) &CODE_B); if( 0 ) OSCreateBinSem(SEM_USART_TX_READY, 0); if( 0 ) OSSignalBinSem(SEM_USART_TX_READY); } void OSIdlingHook( void ) { ; } void TaskCount( void ) { counter = 0; for (;;) { counter++; if ( !(counter & 0x01FF) ) { OSProtect(); OSSignalMsg(MSG_UPDATE_PORT_P, (OStypeMsgP) &CODE_C); OSUnprotect(); } OS_Yield(TaskCount1); } } void TaskShow( void ) { OStypeMsgP msgP; for (;;) { OS_WaitMsg(MSG_UPDATE_PORT_P, &msgP, OSNO_TIMEOUT, TaskShow1); if ( *(char *)msgP == CODE_C ) { PORTB &= ~0xFE; PORTB |= ( counter >> 8 ) & 0xFE; } else PORTB ^= 0x01; } } void TaskBlink( void ) { OStypeErr err; for (;;) { OS_Delay(50, TaskBlink1); OSProtect(); err = OSSignalMsg(MSG_UPDATE_PORT_P, (OStypeMsgP) &CODE_B); OSUnprotect(); if ( err == OSERR_EVENT_FULL ) { OS_SetPrio(PRIO_SHOW+1, TaskBlink2); OSProtect(); OSSignalMsg(MSG_UPDATE_PORT_P, (OStypeMsgP) &CODE_B); OSUnprotect(); OSSetPrio(PRIO_BLINK); } } } //void TaskWave( void ) //{ // OS_Delay(1, TaskWave1); //} void TaskGetSerial( void ) { OStypeMsgP msgP; char lchar; for(;;) { OS_WaitMsg(MSG_GET_SERIAL, &msgP, OSNO_TIMEOUT, TaskGetSerial1); // localize the serial character lchar=SERIAL_CHAR; rxBuff[rxInPtr++] = lchar; if( rxInPtr > RX_BUFF_SIZE-1 ) rxInPtr=0; // // echo char back to sender NPUTCH_T(lchar, TaskGetSerial2); if( lchar == '\r' ) { NPUTCH_T('\n', TaskGetSerial3); } } }