00001 /* 00002 * Femto OS v 0.91 - Copyright (C) 2008-2009 Ruud Vlaming 00003 * 00004 * This file is part of the Femto OS distribution. 00005 * 00006 * This program is free software: you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation, version 3 of the License. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 * 00018 * Please note that, due to the GPLv3 license, for application of this 00019 * work and/or combined work in embedded systems special obligations apply. 00020 * If these are not to you liking, please know the Femto OS is dual 00021 * licensed. A commercial license and support are available. 00022 * See http://www.femtoos.org/ for details. 00023 */ 00024 00025 00042 /* This this the only include needed in your code .*/ 00043 #include "femtoos_code.h" 00044 00045 /* For this application i choose for a decent, that is concurrency protected, way 00046 * to flip a ledbit. Inverting a bit cannot be compiled to an atomic instruction by gcc. */ 00047 static void invLed(Tuint08 lednr) 00048 { taskEnterSwitchCritical(); 00049 devLedPORT ^= (1 << lednr); 00050 taskExitSwitchCritical(); } 00051 00052 /* Writing a number to the display need such a protection too. By using a mask we can write 00053 * a number to a specific part of the display, leaving the rest as is. */ 00054 static void setNumber(Tuint08 mask,Tuint08 number) 00055 { taskEnterSwitchCritical(); 00056 devLedPORT = ~((~devLedPORT & (mask)) | (number)); 00057 taskExitSwitchCritical(); } 00058 00059 /* After the appBoot (which is not used in this example) the OS calls for each 00060 * task to be started the function appInit_[taskname]. Here, you can set task 00061 * specific hardware initialization. You can be sure that all initializers of 00062 * all tasks are called before any task is started. */ 00063 void appInit_WriteTask(void) 00064 { devLedDRR |= 0x0F; 00065 devLedPORT |= 0x0F; } 00066 00067 00068 /* The write task writes number into the queue in series of 8, as long as 00069 * space allows for. The numbers written are displayed. When the queue 00070 * cannot be obtained, a wait led starts flashing until a new attempt is 00071 * done. */ 00072 void appLoop_WriteTask(void) 00073 { Tuint08 count = 0; 00074 while (true) 00075 { if (taskQueuWriteRequestOnName(ThePipe,8,800)) 00076 { for (count=0; count<8; count++) 00077 { genQueuWriteOnName(ThePipe,count); 00078 setNumber(0xF0,count); 00079 taskDelayFromNow(600); } 00080 taskQueuReleaseOnName(ThePipe); } 00081 else 00082 { for (count=0; count<10; count++) 00083 { invLed(3); 00084 taskDelayFromNow(80); } } } } 00085 00086 00087 /* After the appBoot (which is not used in this example) the OS calls for each 00088 * task to be started the function appInit_[taskname]. Here, you can set task 00089 * specific hardware initialization. You can be sure that all initializers of 00090 * all tasks are called before any task is started. */ 00091 void appInit_ReadTask(void) 00092 { devLedDRR |= 0xF0; 00093 devLedPORT |= 0xF0; } 00094 00095 00096 /* The read task reads numbers from the queue in series of 6, as long as 00097 * numbers are available. The numbers read are displayed. When the queue 00098 * cannot be obtained, a wait led starts flashing until a new attempt is 00099 * done. */ 00100 void appLoop_ReadTask(void) 00101 { Tuint08 count = 0; 00102 Tuint08 Result; 00103 while (true) 00104 { if (taskQueuReadRequestOnName(ThePipe,6,800)) 00105 { for (count=0; count<6; count++) 00106 { Result = genQueuReadOnName(ThePipe); 00107 setNumber(0x0F,Result<<4); 00108 taskDelayFromNow(600); } 00109 taskQueuReleaseOnName(ThePipe); } 00110 else 00111 { for (count=0; count<10; count++) 00112 { invLed(7); 00113 taskDelayFromNow(80); } } } } 00114 00115 00116 #if (preTaskDefined(ResetTask)) 00117 00118 /* Special initialization for the reset task, we need the switches to be input. */ 00119 void appInit_ResetTask(void) 00120 { devSwitchDRR = 0x00; } 00121 00122 /* If you want you can reset the queue by pushing the button. 00123 * This task starts waiting until a lock on the queue is 00124 * obtained. When this is the case, the queue is reset. */ 00125 void appLoop_ResetTask(void) 00126 { Tuint08 button = devSwitchPIN & 01; 00127 Tuint08 lastbutton = button; 00128 while (true) 00129 { button = devSwitchPIN & 01; 00130 if (button != lastbutton) 00131 { setNumber(0x88,0x88); 00132 taskQueuReadRequestOnName(ThePipe,0,defDelayTimeMax); 00133 Tuint08 uiLedState = devLedPORT; 00134 devLedPORT = 0x00; 00135 genQueuClearOnName(ThePipe); 00136 taskDelayFromNow(80); 00137 devLedPORT = uiLedState; 00138 taskQueuReleaseOnName(ThePipe); } 00139 taskDelayFromNow(100); } } 00140 00141 #endif 00142