00001
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 #include "gpio.h"
00069
00070
00071
00072 #include "FreeRTOS.h"
00073 #include "task.h"
00074
00075
00076 #include <avr32/io.h>
00077 #include <intrinsics.h>
00078
00079 #if configDBG
00080 #include "usart.h"
00081 #endif
00082
00083 #if( configTICK_USE_TC==1 )
00084 #include "tc.h"
00085 #endif
00086
00087
00088
00089 #define portINITIAL_SR ( ( portSTACK_TYPE ) 0x00400000 )
00090 #define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 0 )
00091
00092
00093 #define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
00094 volatile unsigned portLONG ulCriticalNesting = 9999UL;
00095
00096 #if( configTICK_USE_TC==0 )
00097 static void prvClearCcInt( void );
00098 #else
00099 static void prvClearTcInt( void );
00100 #endif
00101
00102
00103 static void prvSetupTimerInterrupt( void );
00104
00105
00106
00107
00108
00109
00110
00111 int __low_level_init(void)
00112 {
00113 #if configHEAP_INIT
00114 #pragma segment = "HEAP"
00115 portBASE_TYPE *pxMem;
00116 #endif
00117
00118
00119 ENABLE_ALL_EXCEPTIONS();
00120
00121
00122 INTC_init_interrupts();
00123
00124 #if configHEAP_INIT
00125 {
00126
00127 for( pxMem = __segment_begin( "HEAP" ); pxMem < ( portBASE_TYPE * ) __segment_end( "HEAP" ); )
00128 {
00129 *pxMem++ = 0xA5A5A5A5;
00130 }
00131 }
00132 #endif
00133
00134
00135 #if configDBG
00136 {
00137 static const gpio_map_t DBG_USART_GPIO_MAP =
00138 {
00139 { configDBG_USART_RX_PIN, configDBG_USART_RX_FUNCTION },
00140 { configDBG_USART_TX_PIN, configDBG_USART_TX_FUNCTION }
00141 };
00142
00143 static const usart_options_t DBG_USART_OPTIONS =
00144 {
00145 .baudrate = configDBG_USART_BAUDRATE,
00146 .charlength = 8,
00147 .paritytype = USART_NO_PARITY,
00148 .stopbits = USART_1_STOPBIT,
00149 .channelmode = USART_NORMAL_CHMODE
00150 };
00151
00152
00153 extern volatile avr32_usart_t *volatile stdio_usart_base;
00154 stdio_usart_base = configDBG_USART;
00155 gpio_enable_module( DBG_USART_GPIO_MAP,
00156 sizeof( DBG_USART_GPIO_MAP ) / sizeof( DBG_USART_GPIO_MAP[0] ) );
00157 usart_init_rs232(configDBG_USART, &DBG_USART_OPTIONS, configPBA_CLOCK_HZ);
00158 }
00159 #endif
00160
00161
00162 return 1;
00163 }
00164
00165
00166
00167 void *pvPortRealloc( void *pv, size_t xWantedSize )
00168 {
00169 void *pvReturn;
00170
00171 vTaskSuspendAll();
00172 {
00173 pvReturn = realloc( pv, xWantedSize );
00174 }
00175 xTaskResumeAll();
00176
00177 return pvReturn;
00178 }
00179
00180
00181
00182
00183
00184
00185 #pragma shadow_registers = full // Naked.
00186 static void vTick( void )
00187 {
00188
00189 portSAVE_CONTEXT_OS_INT();
00190
00191 #if( configTICK_USE_TC==1 )
00192
00193 prvClearTcInt();
00194 #else
00195
00196 prvClearCcInt();
00197 #endif
00198
00199
00200
00201 portENTER_CRITICAL();
00202 vTaskIncrementTick();
00203 portEXIT_CRITICAL();
00204
00205
00206 portRESTORE_CONTEXT_OS_INT();
00207 }
00208
00209
00210 #pragma shadow_registers = full // Naked.
00211 void SCALLYield( void )
00212 {
00213
00214 portSAVE_CONTEXT_SCALL();
00215 vTaskSwitchContext();
00216 portRESTORE_CONTEXT_SCALL();
00217 }
00218
00219
00220
00221
00222
00223
00224 #pragma optimize = no_inline
00225 void vPortEnterCritical( void )
00226 {
00227
00228 portDISABLE_INTERRUPTS();
00229
00230
00231
00232
00233 ulCriticalNesting++;
00234 }
00235
00236
00237 #pragma optimize = no_inline
00238 void vPortExitCritical( void )
00239 {
00240 if(ulCriticalNesting > portNO_CRITICAL_NESTING)
00241 {
00242 ulCriticalNesting--;
00243 if( ulCriticalNesting == portNO_CRITICAL_NESTING )
00244 {
00245
00246 portENABLE_INTERRUPTS();
00247 }
00248 }
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258 portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
00259 {
00260
00261
00262
00263
00264 pxTopOfStack--;
00265 *pxTopOfStack-- = ( portSTACK_TYPE ) 0x08080808;
00266 *pxTopOfStack-- = ( portSTACK_TYPE ) 0x09090909;
00267 *pxTopOfStack-- = ( portSTACK_TYPE ) 0x0A0A0A0A;
00268 *pxTopOfStack-- = ( portSTACK_TYPE ) 0x0B0B0B0B;
00269 *pxTopOfStack-- = ( portSTACK_TYPE ) pvParameters;
00270 *pxTopOfStack-- = ( portSTACK_TYPE ) 0xDEADBEEF;
00271 *pxTopOfStack-- = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
00272 *pxTopOfStack-- = ( portSTACK_TYPE ) portINITIAL_SR;
00273 *pxTopOfStack-- = ( portSTACK_TYPE ) 0xFF0000FF;
00274 *pxTopOfStack-- = ( portSTACK_TYPE ) 0x01010101;
00275 *pxTopOfStack-- = ( portSTACK_TYPE ) 0x02020202;
00276 *pxTopOfStack-- = ( portSTACK_TYPE ) 0x03030303;
00277 *pxTopOfStack-- = ( portSTACK_TYPE ) 0x04040404;
00278 *pxTopOfStack-- = ( portSTACK_TYPE ) 0x05050505;
00279 *pxTopOfStack-- = ( portSTACK_TYPE ) 0x06060606;
00280 *pxTopOfStack-- = ( portSTACK_TYPE ) 0x07070707;
00281 *pxTopOfStack = ( portSTACK_TYPE ) portNO_CRITICAL_NESTING;
00282
00283 return pxTopOfStack;
00284 }
00285
00286
00287 portBASE_TYPE xPortStartScheduler( void )
00288 {
00289
00290
00291 prvSetupTimerInterrupt();
00292
00293
00294 portRESTORE_CONTEXT();
00295
00296
00297 return 0;
00298 }
00299
00300
00301 void vPortEndScheduler( void )
00302 {
00303
00304
00305 }
00306
00307
00308
00309
00310 #if( configTICK_USE_TC==0 )
00311 static void prvScheduleFirstTick(void)
00312 {
00313 Set_system_register(AVR32_COMPARE, configCPU_CLOCK_HZ/configTICK_RATE_HZ);
00314 Set_system_register(AVR32_COUNT, 0);
00315 }
00316
00317 #pragma optimize = no_inline
00318 static void prvClearCcInt(void)
00319 {
00320 Set_system_register(AVR32_COMPARE, Get_system_register(AVR32_COMPARE));
00321 }
00322 #else
00323 #pragma optimize = no_inline
00324 static void prvClearTcInt(void)
00325 {
00326 AVR32_TC.channel[configTICK_TC_CHANNEL].sr;
00327 }
00328 #endif
00329
00330
00331
00332 static void prvSetupTimerInterrupt(void)
00333 {
00334 #if( configTICK_USE_TC==1 )
00335
00336 volatile avr32_tc_t *tc = &AVR32_TC;
00337
00338
00339 tc_waveform_opt_t waveform_opt =
00340 {
00341 .channel = configTICK_TC_CHANNEL,
00342
00343 .bswtrg = TC_EVT_EFFECT_NOOP,
00344 .beevt = TC_EVT_EFFECT_NOOP,
00345 .bcpc = TC_EVT_EFFECT_NOOP,
00346 .bcpb = TC_EVT_EFFECT_NOOP,
00347
00348 .aswtrg = TC_EVT_EFFECT_NOOP,
00349 .aeevt = TC_EVT_EFFECT_NOOP,
00350 .acpc = TC_EVT_EFFECT_NOOP,
00351 .acpa = TC_EVT_EFFECT_NOOP,
00352
00353 .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,
00354 .enetrg = FALSE,
00355 .eevt = 0,
00356 .eevtedg = TC_SEL_NO_EDGE,
00357 .cpcdis = FALSE,
00358 .cpcstop = FALSE,
00359
00360 .burst = FALSE,
00361 .clki = FALSE,
00362 .tcclks = TC_CLOCK_SOURCE_TC3
00363 };
00364
00365 tc_interrupt_t tc_interrupt =
00366 {
00367 .etrgs=0,
00368 .ldrbs=0,
00369 .ldras=0,
00370 .cpcs =1,
00371 .cpbs =0,
00372 .cpas =0,
00373 .lovrs=0,
00374 .covfs=0,
00375 };
00376
00377 #endif
00378
00379
00380 portDISABLE_INTERRUPTS();
00381
00382
00383
00384
00385 #if( configTICK_USE_TC==1 )
00386 {
00387 INTC_register_interrupt((__int_handler)&vTick, configTICK_TC_IRQ, AVR32_INTC_INT0);
00388
00389
00390 tc_init_waveform(tc, &waveform_opt);
00391
00392
00393
00394
00395
00396 tc_write_rc( tc, configTICK_TC_CHANNEL, ( configPBA_CLOCK_HZ + 4 * configTICK_RATE_HZ ) /
00397 ( 8 * configTICK_RATE_HZ ) );
00398
00399 tc_configure_interrupts( tc, configTICK_TC_CHANNEL, &tc_interrupt );
00400
00401
00402 tc_start(tc, configTICK_TC_CHANNEL);
00403 }
00404 #else
00405 {
00406 INTC_register_interrupt((__int_handler)&vTick, AVR32_CORE_COMPARE_IRQ, AVR32_INTC_INT0);
00407 prvScheduleFirstTick();
00408 }
00409 #endif
00410 }