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