00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 #include <sys/thread.h>
00124 #include <sys/heap.h>
00125 #include <cfg/memory.h>
00126 #include <cfg/os.h>
00127 #include <cfg/arch/avr.h>
00128 #include <cfg/arch.h>
00129
00134
00135 #ifdef NUTXMEM_SIZE
00136
00139 #define NUTMEM_END (u_short)(NUTXMEM_START + (u_short)NUTXMEM_SIZE - 1U)
00140
00141 #else
00142
00148 #define NUTMEM_END (u_short)(NUTMEM_START + (u_short)NUTMEM_SIZE - 1U)
00149
00150 #endif
00151
00152 #ifdef NUTMEM_RESERVED
00153
00163 u_char nutmem_onchip[NUTMEM_RESERVED];
00164 #endif
00165
00166
00167 #if defined(__GNUC__) && defined(__AVR_ENHANCED__)
00168 u_char idle_sleep_mode = SLEEP_MODE_NONE;
00169
00170
00171 #if defined(SMCR)
00172 #define AVR_SLEEP_CTRL_REG SMCR
00173 #else
00174 #define AVR_SLEEP_CTRL_REG MCUCR
00175 #endif
00176
00177 #endif
00178
00179
00180
00181
00182
00183 #if defined(RTL_EESK_BIT) && defined(__GNUC__)
00184
00185 #ifndef RTL_BASE_ADDR
00186 #define RTL_BASE_ADDR 0x8300
00187 #endif
00188 #define NIC_CR _MMIO_BYTE(RTL_BASE_ADDR)
00189 #define NIC_EE _MMIO_BYTE(RTL_BASE_ADDR + 1)
00190
00191 #if (RTL_EEMU_AVRPORT == AVRPORTB)
00192 #define RTL_EEMU_PORT PORTB
00193 #define RTL_EEMU_DDR DDRB
00194
00195 #elif (RTL_EEMU_AVRPORT == AVRPORTD)
00196 #define RTL_EEMU_PORT PORTD
00197 #define RTL_EEMU_DDR DDRD
00198
00199 #elif (RTL_EEMU_AVRPORT == AVRPORTE)
00200 #define RTL_EEMU_PORT PORTE
00201 #define RTL_EEMU_DDR DDRE
00202
00203 #elif (RTL_EEMU_AVRPORT == AVRPORTF)
00204 #define RTL_EEMU_PORT PORTF
00205 #define RTL_EEMU_DDR DDRF
00206
00207 #else
00208 #define RTL_EE_MEMBUS
00209 #define RTL_EEMU_PORT PORTC
00210 #define RTL_EEMU_DDR DDRC
00211
00212 #endif
00213
00214 #if (RTL_EEDO_AVRPORT == AVRPORTB)
00215 #define RTL_EEDO_PORT PORTB
00216 #define RTL_EEDO_DDR DDRB
00217
00218 #elif (RTL_EEDO_AVRPORT == AVRPORTD)
00219 #define RTL_EEDO_PORT PORTD
00220 #define RTL_EEDO_DDR DDRD
00221
00222 #elif (RTL_EEDO_AVRPORT == AVRPORTE)
00223 #define RTL_EEDO_PORT PORTE
00224 #define RTL_EEDO_DDR DDRE
00225
00226 #elif (RTL_EEDO_AVRPORT == AVRPORTF)
00227 #define RTL_EEDO_PORT PORTF
00228 #define RTL_EEDO_DDR DDRF
00229
00230 #else
00231 #define RTL_EE_MEMBUS
00232 #define RTL_EEDO_PORT PORTC
00233 #define RTL_EEDO_DDR DDRC
00234
00235 #endif
00236
00237 #if (RTL_EESK_AVRPORT == AVRPORTB)
00238 #define RTL_EESK_PIN PINB
00239 #define RTL_EESK_DDR DDRB
00240
00241 #elif (RTL_EESK_AVRPORT == AVRPORTD)
00242 #define RTL_EESK_PIN PIND
00243 #define RTL_EESK_DDR DDRD
00244
00245 #elif (RTL_EESK_AVRPORT == AVRPORTE)
00246 #define RTL_EESK_PIN PINE
00247 #define RTL_EESK_DDR DDRE
00248
00249 #elif (RTL_EESK_AVRPORT == AVRPORTF)
00250 #define RTL_EESK_PIN PINF
00251 #define RTL_EESK_DDR DDRF
00252
00253 #else
00254 #define RTL_EE_MEMBUS
00255 #define RTL_EESK_PIN PINC
00256 #define RTL_EESK_DDR DDRC
00257
00258 #endif
00259 #endif
00260
00261 #ifdef __GNUC__
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 void NutInit(void) __attribute__ ((naked)) __attribute__ ((section(".init8")));
00284 extern void NutAppMain(void *arg) __attribute__ ((noreturn));
00285 #else
00286 extern void main(void *);
00287 #endif
00288
00289
00290
00291
00292 #if defined(__GNUC__) && defined(NUTXMEM_SIZE)
00293
00294
00295
00296
00297 static void NutInitXRAM(void) __attribute__ ((naked, section(".init1"), used));
00298 void NutInitXRAM(void)
00299 {
00300 #if defined(__AVR_AT90CAN128__) || defined(__AVR_ATmega2561__)
00301
00302
00303
00304
00305 #ifdef NUT_3WAITSTATES
00306 XMCRA = _BV(SRE) | _BV(SRL2) | _BV(SRW00) | _BV(SRW10) | _BV(SRW11);
00307 #else
00308 XMCRA = _BV(SRE) | _BV(SRW10);
00309 #endif
00310
00311 #elif defined(__AVR_ATmega128__)
00312
00313 MCUCR = _BV(SRE) | _BV(SRW10);
00314
00315
00316
00317
00318
00319 #ifdef NUT_3WAITSTATES
00320 XMCRA |= _BV(SRL2) | _BV(SRW00) | _BV(SRW11);
00321 XMCRB = 0;
00322 #endif
00323
00324 #else
00325 MCUCR = _BV(SRE) | _BV(SRW);
00326 #endif
00327 }
00328
00329 #endif
00330
00331
00332 #if defined(RTL_EESK_BIT) && defined(__GNUC__) && defined(NUTXMEM_SIZE)
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 static void FakeNicEeprom(void) __attribute__ ((naked, section(".init1"), used));
00345 void FakeNicEeprom(void)
00346 {
00347
00348
00349
00350
00351 #ifdef RTL_EEMU_BIT
00352 sbi(RTL_EEMU_PORT, RTL_EEMU_BIT);
00353 sbi(RTL_EEMU_DDR, RTL_EEMU_BIT);
00354 #endif
00355 sbi(RTL_EEDO_PORT, RTL_EEDO_BIT);
00356 sbi(RTL_EEDO_DDR, RTL_EEDO_BIT);
00357
00358
00359 NIC_CR = 0xE1;
00360 NIC_EE = 0x40;
00361
00362
00363 #ifdef RTL_EE_MEMBUS
00364 cbi(MCUCR, SRE);
00365 #endif
00366
00367
00368
00369
00370
00371
00372 __asm__ __volatile__("\n"
00373 "EmuLoop: " "\n"
00374 " ldi r24, 0 " "\n"
00375 " ldi r25, 0 " "\n"
00376 " sbis %0, %1 " "\n"
00377 " rjmp EmuClkClr " "\n"
00378 "EmuClkSet: " "\n"
00379 " adiw r24, 1 " "\n"
00380 " breq EmuDone " "\n"
00381 " sbis %0, %1 " "\n"
00382 " rjmp EmuLoop " "\n"
00383 " rjmp EmuClkSet " "\n"
00384 "EmuClkClr: " "\n"
00385 " adiw r24, 1 " "\n"
00386 " breq EmuDone " "\n"
00387 " sbic %0, %1 " "\n"
00388 " rjmp EmuLoop " "\n"
00389 " rjmp EmuClkClr " "\n"
00390 "EmuDone: \n\t"
00391 :
00392 :"I"(_SFR_IO_ADDR(RTL_EESK_PIN)),
00393 "I"(RTL_EESK_BIT)
00394 :"r24", "r25");
00395
00396
00397 #ifdef RTL_EE_MEMBUS
00398 sbi(MCUCR, SRE);
00399 #endif
00400
00401
00402 #ifdef RTL_EEMU_BIT
00403 cbi(RTL_EEMU_PORT, RTL_EEMU_BIT);
00404 cbi(RTL_EEMU_DDR, RTL_EEMU_BIT);
00405 #endif
00406 cbi(RTL_EEDO_PORT, RTL_EEDO_BIT);
00407 cbi(RTL_EEDO_DDR, RTL_EEDO_BIT);
00408 }
00409
00410 #endif
00411
00423 #if defined(__GNUC__) && defined(__AVR_ENHANCED__)
00424 u_char NutThreadSetSleepMode(u_char mode)
00425 {
00426 u_char old_mode = idle_sleep_mode;
00427 idle_sleep_mode = mode;
00428 return old_mode;
00429 }
00430 #endif
00431
00437 THREAD(NutIdle, arg)
00438 {
00439 #if defined(__GNUC__) && defined(__AVR_ENHANCED__)
00440 u_char sleep_mode;
00441 #endif
00442 #ifdef IDLE_HEARTBEAT_BIT
00443 u_char beat = 0;
00444 #endif
00445
00446
00447 NutTimerInit();
00448
00449
00450 NutThreadCreate("main", main, 0, NUT_THREAD_MAINSTACK);
00451
00452
00453
00454
00455
00456
00457 NutThreadSetPriority(254);
00458 for (;;) {
00459 NutThreadYield();
00460 NutThreadDestroy();
00461
00462 #ifdef IDLE_HEARTBEAT_BIT
00463 if ((beat = !beat) == 0) {
00464
00465 cbi(IDLE_HEARTBEAT_PORT, IDLE_HEARTBEAT_BIT);
00466 }
00467 else {
00468 sbi(IDLE_HEARTBEAT_PORT, IDLE_HEARTBEAT_BIT);
00469 }
00470 sbi(IDLE_HEARTBEAT_DDR, IDLE_HEARTBEAT_BIT);
00471 #endif
00472
00473 #if defined(__GNUC__) && defined(__AVR_ENHANCED__)
00474 if (idle_sleep_mode != SLEEP_MODE_NONE) {
00475 sleep_mode = AVR_SLEEP_CTRL_REG & _SLEEP_MODE_MASK;
00476 set_sleep_mode(idle_sleep_mode);
00477 #ifdef IDLE_THREAD_ADC_OFF
00478 u_char adc = bit_is_set(ADCSR, ADEN);
00479 cbi(ADCSR, ADEN);
00480 #endif
00481 #ifdef IDLE_THREAD_BUSKEEPER_OFF
00482 u_char bitkeeper = bit_is_set(XMCRB, XMBK);
00483 cbi(XMCRB, XMBK);
00484 #endif
00485
00486
00487 AVR_SLEEP_CTRL_REG |= _BV(SE);
00488 __asm__ __volatile__ ("sleep" "\n\t" :: );
00489 AVR_SLEEP_CTRL_REG &= ~_BV(SE);
00490 #ifdef IDLE_THREAD_ADC_OFF
00491 if (bitkeeper) {
00492 sbi(XMCRB, XMBK);
00493 }
00494 #endif
00495 #ifdef IDLE_THREAD_BUSKEEPER_OFF
00496 if (adc) {
00497 sbi(ADCSR, ADEN);
00498 }
00499 #endif
00500 set_sleep_mode(sleep_mode);
00501 }
00502 #endif
00503 }
00504 }
00505
00506 #if defined(__GNUC__)
00507 static void NutInitSP(void) __attribute__ ((naked, section (".init5"), used));
00508 void NutInitSP(void)
00509 {
00510 #if defined (__AVR_AT90CAN128__)
00511
00512 #else
00513
00514
00515
00516 SP = (u_short)(NUTMEM_END);
00517 #endif
00518 }
00519 #endif
00520
00521 #if defined(__GNUC__)
00522 static void NutInitHeap(void) __attribute__ ((naked, section (".init5"), used));
00523 #endif
00524 void NutInitHeap()
00525 {
00526 #if defined (NUTMEM_STACKHEAP)
00527 NutStackAdd((void *) NUTMEM_START, NUTMEM_STACKHEAP);
00528 #endif
00529
00530
00531
00532
00533
00534
00535 if ((u_short)NUTMEM_END - (u_short) (&__heap_start) > 384) {
00536 NutHeapAdd(&__heap_start, (u_short) NUTMEM_END - 256 - (u_short) (&__heap_start));
00537 }
00538 }
00539
00540 #if defined(__GNUC__)
00541 static void NutCustomInit(void) __attribute__ ((naked, section (".init1"), used));
00542 #endif
00543
00552 void NutCustomInit(void)
00553
00554
00555
00556 #if defined(MMNET02)
00557 {
00558 volatile u_char *breg = (u_char *)((size_t)-1 & ~0xFF);
00559
00560 *(breg + 1) = 0x01;
00561
00562
00563 outp(7, UBRR);
00564 outp(7, UBRR1L);
00565 }
00566
00567
00568
00569 #elif defined(ARTHERNET1)
00570 {
00571
00572
00573
00574
00575
00576 MCUCR = _BV(SRE);
00577 XMCRA |= _BV(SRL0) | _BV(SRW01) | _BV(SRW00);
00578 XMCRB = 0;
00579
00580 *((volatile u_char *)(ARTHERCPLDSTART)) = 0x10;
00581 *((volatile u_char *)(ARTHERCPLDSPI)) = 0xFF;
00582
00583
00584 outp(25, UBRR);
00585 outp(25, UBRR1L);
00586 }
00587
00588
00589
00590 #elif defined(XNUT_100) || defined(XNUT_105)
00591 {
00592 PORTB = 0x35;
00593 DDRB = 0x3F;
00594 PORTD = 0xE8;
00595 DDRD = 0xB0;
00596 PORTE = 0x0E;
00597 DDRE = 0x02;
00598 PORTF = 0xF0;
00599 DDRF = 0x0F;
00600 PORTG = 0x1F;
00601 DDRG = 0x07;
00602
00603 ACSR |= _BV(ACD);
00604
00605
00606 TWSR = 0;
00607 TWBR = (NUT_CPU_FREQ / 100000UL - 16) / 2;
00608
00609
00610 #if NUT_CPU_FREQ == 14745600
00611 UBRR0L = (NUT_CPU_FREQ / (16 * 9600UL)) - 1;
00612 UBRR1L = (NUT_CPU_FREQ / (16 * 9600UL)) - 1;
00613 #else
00614 sbi(UCSR0A, U2X0);
00615 sbi(UCSR1A, U2X1);
00616 UBRR0L = (NUT_CPU_FREQ / (8 * 9600UL)) - 1;
00617 UBRR1L = (NUT_CPU_FREQ / (8 * 9600UL)) - 1;
00618 #endif
00619 }
00620
00621
00622
00623 #else
00624 {
00625
00626 outp(7, UBRR);
00627 #ifdef __AVR_ENHANCED__
00628 outp(7, UBRR1L);
00629 #endif
00630 }
00631 #endif
00632
00665 void NutInit(void)
00666 {
00667
00668
00669
00670
00671 #ifdef NUTDEBUG
00672
00673 outp(BV(RXEN) | BV(TXEN), UCR);
00674 #endif
00675
00676 #ifndef __GNUC__
00677 NutCustomInit();
00678
00679
00680
00681
00682 SP = (u_short)(NUTMEM_END);
00683
00684
00685
00686 NutInitHeap();
00687 #endif
00688
00689
00690
00691
00692 if (NutLoadConfig()) {
00693 strcpy(confos.hostname, "ethernut");
00694 NutSaveConfig();
00695 }
00696
00697
00698
00699 NutThreadCreate("idle", NutIdle, 0, NUT_THREAD_IDLESTACK);
00700 }
00701