static void prvFixedDelayCoRoutine( xCoRoutineHandle xHandle, unsigned short usIndex ) { /* The usIndex parameter of the co-routine function is used as an index into the xFlashRates array to obtain the delay period to use. */ static const portTickType xFlashRates[ ledNUM_OF_LED_CO_ROUTINES ] = { 150 / portTICK_RATE_MS, 300 / portTICK_RATE_MS, 450 / portTICK_RATE_MS, 600 / portTICK_RATE_MS, 750 / portTICK_RATE_MS, 900 / portTICK_RATE_MS, 1050 / portTICK_RATE_MS }; /* Co-routines MUST start with a call to crSTART. */ crSTART( xHandle ); for( ;; ) { /* Toggle the LED. An offset of 8 is used to skip over the segments of the left side display which use the low numbers. */ vParTestToggleLED( usIndex + 8 ); /* Delay until it is time to toggle the segment that this co-routine is controlling again. */ crDELAY( xHandle, xFlashRates[ usIndex ] ); } /* Co-routines MUST end with a call to crEND. */ crEND(); }
static void vSerialTxCoRoutine( CoRoutineHandle_t xHandle, unsigned portBASE_TYPE uxIndex ) { TickType_t xDelayPeriod; static unsigned long *pulRandomBytes = mainFIRST_PROGRAM_BYTES; /* Co-routine MUST start with a call to crSTART. */ crSTART( xHandle ); for(;;) { /* Was the previously transmitted string received correctly? */ if( uxErrorStatus != pdPASS ) { /* An error was encountered so set the error LED. */ vSetErrorLED(); } /* The next character to Tx is the first in the string. */ cNextChar = mainFIRST_TX_CHAR; UARTIntDisable( UART0_BASE, UART_INT_TX ); { /* Send the first character. */ if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) ) { HWREG( UART0_BASE + UART_O_DR ) = cNextChar; } /* Move the variable to the char to Tx on so the ISR transmits the next character in the string once this one has completed. */ cNextChar++; } UARTIntEnable(UART0_BASE, UART_INT_TX); /* Toggle the LED to show a new string is being transmitted. */ vParTestToggleLED( mainCOMMS_TX_LED ); /* Delay before we start the string off again. A pseudo-random delay is used as this will provide a better test. */ xDelayPeriod = xTaskGetTickCount() + ( *pulRandomBytes ); pulRandomBytes++; if( pulRandomBytes > mainTOTAL_PROGRAM_MEMORY ) { pulRandomBytes = mainFIRST_PROGRAM_BYTES; } /* Make sure we don't wait too long... */ xDelayPeriod &= mainMAX_TX_DELAY; /* ...but we do want to wait. */ if( xDelayPeriod < mainMIN_TX_DELAY ) { xDelayPeriod = mainMIN_TX_DELAY; } /* Block for the random(ish) time. */ crDELAY( xHandle, xDelayPeriod ); } /* Co-routine MUST end with a call to crEND. */ crEND(); }
static void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex ) { portBASE_TYPE xResult, xNothing; crSTART( xHandle ); for( ;; ) { /* Wait for start of next round. */ crQUEUE_RECEIVE( xHandle, xDelayQueue, &xNothing, portMAX_DELAY, &xResult ); /* Wait until it is this co-routines turn to flash. */ crDELAY( xHandle, uxDelay * uxIndex ); /* Turn on the LED for a fixed period. */ vParTestSetLED( uxIndex, pdTRUE ); crDELAY( xHandle, uxDelay ); vParTestSetLED( uxIndex, pdFALSE ); /* Go back and wait for the next round. */ } crEND(); }
static void prvADCCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex ) { static unsigned long ulADCValue; static char cMessageBuffer[ mainMAX_ADC_STRING_LEN ]; static char *pcMessage; static xLCDMessage xMessageToSend; /* Co-routines MUST start with a call to crSTART(). */ crSTART( xHandle ); for( ;; ) { /* Start an ADC conversion. */ ADCProcessorTrigger( ADC_BASE, 0 ); /* Simply delay - when we unblock the result should be available */ crDELAY( xHandle, mainADC_DELAY ); /* Get the ADC result. */ ADCSequenceDataGet( ADC_BASE, 0, &ulADCValue ); /* Create a string with the result. */ sprintf( cMessageBuffer, "ADC = %d ", ulADCValue ); pcMessage = cMessageBuffer; /* Configure the message we are going to send for display. */ xMessageToSend.ppcMessageToDisplay = ( char** ) &pcMessage; xMessageToSend.xRow = mainBOTTOM_ROW; /* Send the string to the LCD task for display. We are sending on a task queue so do not have the option to block. */ if( !xQueueSend( xLCDQueue, ( void * ) &xMessageToSend, 0 ) ) { uxErrorStatus = pdFAIL; } } /* Co-routines MUST end with a call to crEND(). */ crEND(); }
static void vI2CCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex ) { portTickType xADCResult; static portBASE_TYPE xResult = 0, xMilliSecs, xLED; crSTART( xHandle ); for( ;; ) { /* Start the I2C off to read the ADC. */ uxState = mainI2C_READ_1; I2CMasterSlaveAddrSet( I2C_MASTER_BASE, mainI2CAddress, pdTRUE ); I2CMasterControl( I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START ); /* Wait to receive the conversion result. */ crQUEUE_RECEIVE( xHandle, xADCQueue, &xADCResult, portMAX_DELAY, &xResult ); /* Scale the result to give a useful range of values for a visual demo. */ xADCResult >>= 2; xMilliSecs = xADCResult / portTICK_RATE_MS; /* The delay is split between the four co-routines so they remain in synch. */ uxDelay = xMilliSecs / ( mainNUM_LEDs + 1 ); /* Trigger each of the flash co-routines. */ for( xLED = 0; xLED < mainNUM_LEDs; xLED++ ) { crQUEUE_SEND( xHandle, xDelayQueue, &xLED, 0, &xResult ); } /* Wait for the full delay time then start again. This delay is long enough to ensure the flash co-routines have done their thing and gone back to sleep. */ crDELAY( xHandle, xMilliSecs ); } crEND(); }
static void prvFixedDelayCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex ) { /* Even though this is a co-routine the xResult variable does not need to be static as we do not need it to maintain its state between blocks. */ signed portBASE_TYPE xResult; /* The uxIndex parameter of the co-routine function is used as an index into the xFlashRates array to obtain the delay period to use. */ static const portTickType xFlashRates[ crfMAX_FLASH_TASKS ] = { 150 / portTICK_RATE_MS, 200 / portTICK_RATE_MS, 250 / portTICK_RATE_MS, 300 / portTICK_RATE_MS, 350 / portTICK_RATE_MS, 400 / portTICK_RATE_MS, 450 / portTICK_RATE_MS, 500 / portTICK_RATE_MS }; /* Co-routines MUST start with a call to crSTART. */ crSTART( xHandle ); for( ;; ) { /* Post our uxIndex value onto the queue. This is used as the LED to flash. */ crQUEUE_SEND( xHandle, xFlashQueue, ( void * ) &uxIndex, crfPOSTING_BLOCK_TIME, &xResult ); if( xResult != pdPASS ) { /* For the reasons stated at the top of the file we should always find that we can post to the queue. If we could not then an error has occurred. */ xCoRoutineFlashStatus = pdFAIL; } crDELAY( xHandle, xFlashRates[ uxIndex ] ); } /* Co-routines MUST end with a call to crEND. */ crEND(); }
void taskWatchdog( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex ) { crSTART( xHandle ); // Task loop for ( ;; ) { if ( g_wdLeft > 0 ) // Count down g_wdLeft--; else { // Turn all motors off pst->pwm1 = 0; pst->pwm2 = 0; MOTORS_PORT &= ~( MOTORS_EN | SERVO_EN | MOTORS_MASK | SERVO_MASK ); // To begin new count down. resetWatchdog(); } crDELAY( xHandle, 100 ); } crEND(); }
void crI2c( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex ) { static uint8_t i; crSTART( xHandle ); for ( ;; ) { static uint8_t init = 0; if ( init == 0 ) { i2cSetEn( 0, 1 ); uint8_t data[1]; data[0] = 77; i2cIo( 0, 0, 1, 1, data ); i2cConfig( 0, 0, 123, 10000 ); init = 1; } TI2C * idc = i2c( uxIndex ); // Commands loop. if ( idc->master ) { if ( ( idc->sendCnt ) || ( idc->receiveCnt ) ) { idc->status = I2C_BUSY; // wait for BUSY bit to get cleared. idc->elapsed = 0; while ( I2C_GetFlagStatus( idc->i2c, I2C_FLAG_BUSY ) ) { if ( idc->elapsed++ > idc->timeout ) { idc->status = I2C_ERROR_BUSY; goto i2c_end; } crDELAY( xHandle, 1 ); idc = i2c( uxIndex ); } if ( idc->sendCnt ) { // Generate START condition on a bus. I2C_GenerateSTART( idc->i2c, ENABLE ); idc->status = I2C_MMS; // Wait for SB to be set idc->elapsed = 0; while ( !I2C_CheckEvent( idc->i2c, I2C_EVENT_MASTER_MODE_SELECT ) ) { if ( idc->elapsed++ > idc->timeout ) { idc->status = I2C_ERROR_MMS; I2C_GenerateSTOP( idc->i2c, ENABLE ); goto i2c_end; } crDELAY( xHandle, 1 ); idc = i2c( uxIndex ); } // Transmit the slave address with write operation enabled. I2C_Send7bitAddress( idc->i2c, idc->address, I2C_Direction_Transmitter ); idc->status = I2C_TMS; // Test on ADDR flag. idc->elapsed = 0; while ( !I2C_CheckEvent( idc->i2c, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) ) { if ( idc->elapsed++ > idc->timeout ) { idc->status = I2C_ERROR_TMS; I2C_GenerateSTOP( idc->i2c, ENABLE ); goto i2c_end; } crDELAY( xHandle, 1 ); idc = i2c( uxIndex ); } // Read data from send queue. for ( i=0; i<idc->sendCnt; i++ ) { idc = i2c( uxIndex ); // Transmit data. uint8_t data = idc->sendQueue[ i ]; I2C_SendData( idc->i2c, data ); // Test for TXE flag (data sent). idc->status = I2C_MBT; idc->elapsed = 0; while ( !I2C_CheckEvent( idc->i2c, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) ) { if ( idc->elapsed++ > idc->timeout ) { idc->status = I2C_ERROR_MBT; I2C_GenerateSTOP( idc->i2c, ENABLE ); goto i2c_end; } crDELAY( xHandle, 1 ); idc = i2c( uxIndex ); } idc->bytesWritten = i+1; } // Wait untill BTF flag is set before generating STOP. idc->status = I2C_BTF; idc->elapsed = 0; while ( !I2C_GetFlagStatus( idc->i2c, I2C_FLAG_BTF ) ) { if ( idc->elapsed++ > idc->timeout ) { idc->status = I2C_ERROR_BTF; I2C_GenerateSTOP( idc->i2c, ENABLE ); goto i2c_end; } crDELAY( xHandle, 1 ); idc = i2c( uxIndex ); } } // Receiving data if necessary. if ( idc->receiveCnt ) { I2C_AcknowledgeConfig( idc->i2c, ENABLE ); // Generate START condition if there was at least one byte written. I2C_GenerateSTART( idc->i2c, ENABLE ); idc->status = I2C_MMS_R; // Wait for SB to be set idc->elapsed = 0; while ( !I2C_CheckEvent( idc->i2c, I2C_EVENT_MASTER_MODE_SELECT ) ) { if ( idc->elapsed++ > idc->timeout ) { idc->status = I2C_ERROR_MMS_R; I2C_GenerateSTOP( idc->i2c, ENABLE ); goto i2c_end; } crDELAY( xHandle, 1 ); idc = i2c( uxIndex ); } I2C_Send7bitAddress( idc->i2c, idc->address, I2C_Direction_Receiver ); // Test on ADDR Flag idc->status = I2C_RMS; idc->elapsed = 0; while ( !I2C_CheckEvent( idc->i2c, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ) ) { if ( idc->elapsed++ > idc->timeout ) { idc->status = I2C_ERROR_RMS; I2C_GenerateSTOP( idc->i2c, ENABLE ); goto i2c_end; } crDELAY( xHandle, 1 ); idc = i2c( uxIndex ); } // Receiving a number of bytes from slave. for ( i=0; i<idc->receiveCnt; i++ ) { // Turn acknowledge off when reading the last byte. if ( i == (idc->receiveCnt-1) ) I2C_AcknowledgeConfig( idc->i2c, DISABLE ); // Wait for data available. idc->status = I2C_MBR; idc->elapsed = 0; while ( !I2C_CheckEvent( idc->i2c, I2C_EVENT_MASTER_BYTE_RECEIVED ) ) { if ( idc->elapsed++ > idc->timeout ) { idc->status = I2C_ERROR_MBR; I2C_GenerateSTOP( idc->i2c, ENABLE ); goto i2c_end; } crDELAY( xHandle, 1 ); idc = i2c( uxIndex ); } // Read the data. uint8_t data = I2C_ReceiveData( idc->i2c ); idc->receiveQueue[i] = data; idc->bytesRead = i+1; } } // Generating STOP. I2C_GenerateSTOP( idc->i2c, ENABLE ); // Idle status when finished in regular way. idc->status = I2C_IDLE; } } else // master. { // slave mode IO. //...... implementation..... // Idle status when finished in regular way. //idc->status = I2C_IDLE; crDELAY( xHandle, 1 ); } i2c_end: // To prevent cyclic writes of zero data. idc->sendCnt = 0; idc->receiveCnt = 0; // Give other coroutines time for running. crDELAY( xHandle, 1 ); } crEND(); }
void crUsbIo( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex ) { static uint8_t data; static portBASE_TYPE rcTo; static uint8_t state = STATE_CMD; static uint8_t size = 0; static uint8_t bufferIndex = 0; static uint32_t stateResetTimeout = 0; crSTART( xHandle ); for ( ;; ) { if ( !g_usbInitialized ) { initUsbIo(); // USB setup. Set_USBClock(); USB_Interrupts_Config(); USB_Init(); g_usbInitialized = 1; } /*if ( !g_usbInitialized ) { // Data for gpioEn. data = 0; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); data = 1; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); data = 1; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); data = 0; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); data = 1; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); data = 1; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); // Call gpioConfig. data = 1; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); data = 2; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); // Data for gpioConfig data = 0; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); data = 1; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); data = 1; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); data = 0; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); data = 2; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); data = 255; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); data = 255; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); data = 0; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); data = 1; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); data = 0x48; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); // Call gpioConfig. data = 1; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); data = 3; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); // Data for gpio. data = 0; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); data = 1; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); data = 1; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); // Call gpioConfig. data = 1; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); data = 5; crQUEUE_SEND( xHandle, g_toMcu, &data, 0, &rcTo ); g_usbInitialized = 1; }*/ // Receive data from USB and place to an execution buffer. crQUEUE_RECEIVE( xHandle, g_toMcu, &data, 0, &rcTo ); if ( rcTo == pdPASS ) { // Analyze data and put it into execution buffer. switch ( state ) { case STATE_CMD: //setRed( 1 ); //setGreen( 0 ); // Reset timer. stateResetTimeout = STATE_RESET_TIMEOUT; if ( data == CMD_DATA ) { state = STATE_SIZE; } else if ( data == CMD_FUNC ) { state = STATE_FUNC; } break; case STATE_SIZE: size = data; state = STATE_DATA; break; case STATE_DATA: g_buffer[ bufferIndex++ ] = data; size--; if ( size == 0 ) state = STATE_CMD; break; case STATE_FUNC: //setRed( 0 ); //setGreen( 1 ); // Function invocation. invokeFunc( data ); // And state back to STATE_CMD state = STATE_CMD; bufferIndex = 0; break; } } else { if ( stateResetTimeout > 0 ) stateResetTimeout--; else { state = STATE_CMD; bufferIndex = 0; } } crDELAY( xHandle, 1 ); // Debugging. //static uint8_t a = 'a'; //crQUEUE_SEND( xHandle, g_fromMcu, &a, 0, &rcFrom ); //if ( rcFrom == pdPASS ) // setRed( ( red() ) ? 0 : 1 ); /*a = 'b'; crQUEUE_SEND( xHandle, g_fromMcu, &a, 0, &rcFrom ); if ( rcFrom == pdPASS ) setRed( ( red() ) ? 0 : 1 );*/ //a = '\r'; //crQUEUE_SEND( xHandle, g_fromMcu, &a, 0, &rcFrom ); //if ( rcFrom == pdPASS ) // setRed( ( red() ) ? 0 : 1 ); //a = '\n'; //crQUEUE_SEND( xHandle, g_fromMcu, &a, 0, &rcFrom ); //if ( rcFrom == pdPASS ) // setRed( ( red() ) ? 0 : 1 ); /*taskENTER_CRITICAL(); USB_Send_Data( 'a' ); USB_Send_Data( '\r' ); USB_Send_Data( '\n' ); taskEXIT_CRITICAL();*/ //crDELAY( xHandle, 20 ); } crEND(); }