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 #include <mc1322x.h>
00037 #include <stdio.h>
00038
00039 #ifndef DEBUG_MACA
00040 #define DEBUG_MACA 0
00041 #endif
00042 #if (DEBUG_MACA == 0)
00043 #define PRINTF(...)
00044 #else
00045 #define PRINTF(...) printf(__VA_ARGS__)
00046 #endif
00047
00048 #ifndef MACA_BOUND_CHECK
00049 #define MACA_BOUND_CHECK 0
00050 #endif
00051 #if (MACA_BOUND_CHECK == 0)
00052 #define BOUND_CHECK(x)
00053 #else
00054 #define BOUND_CHECK(x) bound_check(x)
00055 #endif
00056
00057 #ifndef NUM_PACKETS
00058 #define NUM_PACKETS 32
00059 #endif
00060
00061
00062 #define MACA_CLOCK_DIV 95
00063
00064
00065 #define CLK_PER_BYTE 8
00066
00067 #ifndef RECV_SOFTIMEOUT
00068 #define RECV_SOFTIMEOUT (1024*128*CLK_PER_BYTE)
00069 #endif
00070
00071 #ifndef CPL_TIMEOUT
00072 #define CPL_TIMEOUT (2*128*CLK_PER_BYTE)
00073 #endif
00074
00075 #define reg(x) (*(volatile uint32_t *)(x))
00076
00077 int count_packets(void);
00078 void Print_Packets(char *s);
00079
00080 static volatile packet_t packet_pool[NUM_PACKETS];
00081 static volatile packet_t *free_head, *rx_end, *tx_end, *dma_tx, *dma_rx;
00082
00083
00084
00085
00086 volatile packet_t *rx_head, *tx_head;
00087
00088
00089
00090 static volatile packet_t dummy_ack;
00091
00092
00093
00094 volatile uint32_t maca_entry = 0;
00095
00096 enum posts {
00097 NO_POST = 0,
00098 TX_POST,
00099 RX_POST,
00100 MAX_POST,
00101 };
00102 static volatile uint8_t last_post = NO_POST;
00103
00104 volatile uint8_t fcs_mode = USE_FCS;
00105 volatile uint8_t prm_mode = PROMISC;
00106
00107
00108
00109
00110
00111
00112
00113
00114 void check_maca(void) {
00115 safe_irq_disable(MACA);
00116 static volatile uint32_t last_time;
00117 static volatile uint32_t last_entry;
00118 volatile uint32_t i;
00119 #if DEBUG_MACA
00120 volatile uint32_t count;
00121 #endif
00122
00123
00124
00125
00126
00127 for(i=0; (i < 1024) && (*MACA_CLK == last_time); i++) { continue; }
00128
00129 if(*MACA_CLK == last_time) {
00130 PRINTF("check maca: maca_clk stopped, restarting\n");
00131
00132 ResumeMACASync();
00133 *INTFRC = (1<<INT_NUM_MACA);
00134 } else {
00135 if((last_time > (*MACA_SFTCLK + RECV_SOFTIMEOUT)) &&
00136 (last_time > (*MACA_CPLCLK + CPL_TIMEOUT))) {
00137 PRINTF("check maca: complete clocks expired\n");
00138
00139
00140
00141 if(last_entry == maca_entry) {
00142 PRINTF("check maca: forcing isr\n");
00143 *INTFRC = (1<<INT_NUM_MACA);
00144 }
00145 }
00146 }
00147
00148 last_entry = maca_entry;
00149 last_time = *MACA_CLK;
00150
00151 #if DEBUG_MACA
00152 if((count = count_packets()) != NUM_PACKETS) {
00153 PRINTF("check maca: count_packets %d\n", (int)count);
00154 Print_Packets("check_maca");
00155 #if PACKET_STATS
00156 for(i=0; i<NUM_PACKETS; i++) {
00157 printf("packet 0x%lx seen %d post_tx %d get_free %d rxd %d\n",
00158 (uint32_t) &packet_pool[i],
00159 packet_pool[i].seen,
00160 packet_pool[i].post_tx,
00161 packet_pool[i].get_free,
00162 packet_pool[i].rxd);
00163 }
00164 #endif
00165 if(bit_is_set(*NIPEND, INT_NUM_MACA)) { *INTFRC = (1 << INT_NUM_MACA); }
00166 }
00167 #endif
00168 irq_restore();
00169 }
00170
00171 void maca_init(void) {
00172 reset_maca();
00173 radio_init();
00174 flyback_init();
00175 init_phy();
00176 free_head = 0; tx_head = 0; rx_head = 0; rx_end = 0; tx_end = 0; dma_tx = 0; dma_rx = 0;
00177 free_all_packets();
00178
00179 #if DEBUG_MACA
00180 Print_Packets("maca_init");
00181 #endif
00182
00183
00184
00185 *MACA_CONTROL =
00186 (prm_mode << PRM) |
00187 (NO_CCA << MACA_MODE);
00188
00189 enable_irq(MACA);
00190 *INTFRC = (1 << INT_NUM_MACA);
00191 }
00192
00193 #define print_packets(x) Print_Packets(x)
00194 void Print_Packets(char *s) {
00195 volatile packet_t *p;
00196
00197 printf("packet pool after %s:\n\r",s);
00198 p = free_head;
00199 printf("free_head: 0x%lx ", (uint32_t) free_head);
00200 while(p != 0) {
00201 p = p->left;
00202 printf("->0x%lx", (uint32_t) p);
00203 }
00204 printf("\n\r");
00205
00206 p = tx_head;
00207 printf("tx_head: 0x%lx ", (uint32_t) tx_head);
00208 while(p != 0) {
00209 p = p->left;
00210 printf("->0x%lx", (uint32_t) p);
00211 }
00212 printf("\n\r");
00213
00214 p = rx_head;
00215 printf("rx_head: 0x%lx ", (uint32_t) rx_head);
00216 while(p != 0) {
00217 p = p->left;
00218 printf("->0x%lx", (uint32_t) p);
00219 }
00220 printf("\n\r");
00221
00222 printf("dma_rx: 0x%lx\n", (uint32_t) dma_rx);
00223 printf("dma_tx: 0x%lx\n", (uint32_t) dma_tx);
00224
00225 }
00226
00227 inline void bad_packet_bounds(void) {
00228 PRINTF("bad packet bounds! Halting.\n");
00229 while(1) { continue; }
00230 }
00231
00232 int count_packets(void) {
00233 volatile int8_t total = -1;
00234
00235 #if PACKET_STATS
00236 volatile packet_t *pk;
00237 volatile uint8_t tx, rx, free;
00238 volatile int i;
00239
00240 for(i = 0; i < NUM_PACKETS; i++) {
00241 packet_pool[i].seen = 0;
00242 }
00243
00244 pk = tx_head; tx = 0;
00245 while( pk != 0 ) {
00246 if(pk->seen == 0) { tx++; }
00247 pk->seen++;
00248 pk = pk->left;
00249 }
00250 pk = rx_head; rx = 0;
00251 while( pk != 0 ) {
00252 if(pk->seen == 0) { rx++; }
00253 pk->seen++;
00254 pk = pk->left;
00255 }
00256 pk = free_head; free = 0;
00257 while( pk != 0 ) {
00258 if(pk->seen == 0) { free++; }
00259 pk->seen++;
00260 pk = pk->left;
00261 }
00262
00263 total = free + rx + tx;
00264 if(dma_rx && (dma_rx->seen == 0)) { dma_rx->seen++; total++; }
00265 if(dma_tx && (dma_tx->seen == 0)) { dma_tx->seen++; total++; }
00266 #endif
00267
00268 return total;
00269 }
00270
00271 void bound_check(volatile packet_t *p) {
00272 volatile int i;
00273
00274 if((p == 0) ||
00275 (p == &dummy_ack)) { return; }
00276 for(i=0; i < NUM_PACKETS; i++) {
00277 if(p == &packet_pool[i]) { return; }
00278 }
00279
00280 bad_packet_bounds();
00281 }
00282
00283
00284
00285
00286
00287 void free_packet(volatile packet_t *p) {
00288 safe_irq_disable(MACA);
00289
00290 BOUND_CHECK(p);
00291
00292 if(!p) { PRINTF("free_packet passed packet 0\n\r"); return; }
00293 if(p == &dummy_ack) { return; }
00294
00295 BOUND_CHECK(free_head);
00296
00297 p->length = 0; p->offset = 0;
00298 p->left = free_head; p->right = 0;
00299 #if PACKET_STATS
00300 p->seen = 0;
00301 p->post_tx = 0;
00302 p->get_free = 0;
00303 p->rxd = 0;
00304 #endif
00305
00306 free_head = p;
00307
00308 BOUND_CHECK(free_head);
00309
00310 irq_restore();
00311 if(bit_is_set(*NIPEND, INT_NUM_MACA)) { *INTFRC = (1 << INT_NUM_MACA); }
00312
00313 return;
00314 }
00315
00316 volatile packet_t* get_free_packet(void) {
00317 volatile packet_t *p;
00318
00319 safe_irq_disable(MACA);
00320
00321 BOUND_CHECK(free_head);
00322
00323 p = free_head;
00324 if( p != 0 ) {
00325 free_head = p->left;
00326 free_head->right = 0;
00327 }
00328
00329 BOUND_CHECK(free_head);
00330
00331 #if PACKET_STATS
00332 p->get_free++;
00333 #endif
00334
00335
00336 irq_restore();
00337 if(bit_is_set(*NIPEND, INT_NUM_MACA)) { *INTFRC = (1 << INT_NUM_MACA); }
00338
00339 return p;
00340 }
00341
00342 void post_receive(void) {
00343 last_post = RX_POST;
00344
00345
00346
00347 *MACA_TXLEN = (MAX_PACKET_SIZE << 16);
00348 if(dma_rx == 0) {
00349 dma_rx = get_free_packet();
00350 if (dma_rx == 0) {
00351 PRINTF("trying to fill MACA_DMARX in post_receieve but out of packet buffers\n\r");
00352
00353 *MACA_SFTCLK = *MACA_CLK + RECV_SOFTIMEOUT;
00354 *MACA_TMREN = (1 << maca_tmren_sft);
00355
00356 enable_irq(MACA);
00357 return;
00358 }
00359 }
00360 BOUND_CHECK(dma_rx);
00361 BOUND_CHECK(dma_tx);
00362 *MACA_DMARX = (uint32_t)&(dma_rx->data[0]);
00363
00364 *MACA_SFTCLK = *MACA_CLK + RECV_SOFTIMEOUT;
00365 *MACA_TMREN = (1 << maca_tmren_sft);
00366
00367 *MACA_CONTROL = ( (1 << maca_ctrl_asap) |
00368 ( 4 << PRECOUNT) |
00369 ( fcs_mode << NOFC ) |
00370 ( prm_mode << PRM) |
00371 #if 0 //dak says removing ctrl auto fixes the autoack checksum error --- doesn't cause a performance issue either
00372 (1 << maca_ctrl_auto) |
00373 #endif
00374 (maca_ctrl_seq_rx));
00375
00376
00377
00378 }
00379
00380
00381 volatile packet_t* rx_packet(void) {
00382 volatile packet_t *p;
00383 safe_irq_disable(MACA);
00384
00385 BOUND_CHECK(rx_head);
00386
00387 p = rx_head;
00388 if( p != 0 ) {
00389 rx_head = p->left;
00390 rx_head->right = 0;
00391 }
00392
00393 #if PACKET_STATS
00394 p->rxd++;
00395 #endif
00396
00397
00398 irq_restore();
00399 if(bit_is_set(*NIPEND, INT_NUM_MACA)) { *INTFRC = (1 << INT_NUM_MACA); }
00400
00401 return p;
00402 }
00403
00404 void post_tx(void) {
00405
00406
00407 disable_irq(MACA);
00408 last_post = TX_POST;
00409 dma_tx = tx_head;
00410 #if PACKET_STATS
00411 dma_tx->post_tx++;
00412 #endif
00413 *MACA_TXSEQNR = dma_tx->data[2];
00414 *MACA_TXLEN = (uint32_t)((dma_tx->length) + 2) | (3 << 16);
00415 *MACA_DMATX = (uint32_t)&(dma_tx->data[ 0 + dma_tx->offset]);
00416 if(dma_rx == 0) {
00417 dma_rx = get_free_packet();
00418 if (dma_rx == 0) {
00419 dma_rx = &dummy_ack;
00420 PRINTF("trying to fill MACA_DMARX on post_tx but out of packet buffers\n\r");
00421 }
00422
00423 }
00424 BOUND_CHECK(dma_rx);
00425 BOUND_CHECK(dma_tx);
00426 *MACA_DMARX = (uint32_t)&(dma_rx->data[0]);
00427
00428
00429 *MACA_TMRDIS = (1 << maca_tmren_sft) | ( 1<< maca_tmren_cpl) | ( 1 << maca_tmren_strt ) ;
00430
00431
00432
00433 *MACA_CPLCLK = *MACA_CLK + CPL_TIMEOUT;
00434
00435 *MACA_TMREN = (1 << maca_tmren_cpl);
00436
00437 enable_irq(MACA);
00438 *MACA_CONTROL = ( ( 4 << PRECOUNT) |
00439 ( prm_mode << PRM) |
00440 (maca_ctrl_mode_no_cca << maca_ctrl_mode) |
00441 (1 << maca_ctrl_asap) |
00442 (maca_ctrl_seq_tx));
00443
00444
00445
00446 }
00447
00448 void tx_packet(volatile packet_t *p) {
00449 safe_irq_disable(MACA);
00450
00451 BOUND_CHECK(p);
00452
00453 if(!p) { PRINTF("tx_packet passed packet 0\n\r"); return; }
00454 if(tx_head == 0) {
00455
00456 tx_end = p;
00457 tx_end->left = 0; tx_end->right = 0;
00458 tx_head = tx_end;
00459 } else {
00460
00461 tx_end->left = p;
00462 p->right = tx_end;
00463
00464 tx_end = p; tx_end->left = 0;
00465 }
00466
00467 irq_restore();
00468 if(bit_is_set(*NIPEND, INT_NUM_MACA)) { *INTFRC = (1 << INT_NUM_MACA); }
00469 if(last_post == NO_POST) { *INTFRC = (1<<INT_NUM_MACA); }
00470
00471 if(last_post == RX_POST) { *MACA_SFTCLK = *MACA_CLK + CLK_PER_BYTE; }
00472 return;
00473 }
00474
00475 void free_all_packets(void) {
00476 volatile int i;
00477 safe_irq_disable(MACA);
00478
00479 free_head = 0;
00480 for(i=0; i<NUM_PACKETS; i++) {
00481 free_packet((volatile packet_t *)&(packet_pool[i]));
00482 }
00483 rx_head = 0; rx_end = 0;
00484 tx_head = 0; tx_end = 0;
00485
00486 irq_restore();
00487 if(bit_is_set(*NIPEND, INT_NUM_MACA)) { *INTFRC = (1 << INT_NUM_MACA); }
00488
00489 return;
00490 }
00491
00492
00493
00494 void free_tx_head(void) {
00495 volatile packet_t *p;
00496 safe_irq_disable(MACA);
00497
00498 BOUND_CHECK(tx_head);
00499
00500 p = tx_head;
00501 tx_head = tx_head->left;
00502 if(tx_head == 0) { tx_end = 0; }
00503 free_packet(p);
00504
00505
00506 irq_restore();
00507 if(bit_is_set(*NIPEND, INT_NUM_MACA)) { *INTFRC = (1 << INT_NUM_MACA); }
00508
00509 return;
00510 }
00511
00512 void add_to_rx(volatile packet_t *p) {
00513 safe_irq_disable(MACA);
00514
00515 BOUND_CHECK(p);
00516
00517 if(!p) { PRINTF("add_to_rx passed packet 0\n\r"); return; }
00518 p->offset = 1;
00519 if(rx_head == 0) {
00520
00521 rx_end = p;
00522 rx_end->left = 0; rx_end->right = 0;
00523 rx_head = rx_end;
00524 } else {
00525 rx_end->left = p;
00526 p->right = rx_end;
00527 rx_end = p; rx_end->left = 0;
00528 }
00529
00530
00531 irq_restore();
00532 if(bit_is_set(*NIPEND, INT_NUM_MACA)) { *INTFRC = (1 << INT_NUM_MACA); }
00533
00534 return;
00535 }
00536
00537 void decode_status(void) {
00538 volatile uint32_t code;
00539
00540 code = get_field(*MACA_STATUS,CODE);
00541
00542
00543 switch(code)
00544 {
00545 case ABORTED:
00546 {
00547 PRINTF("maca: aborted\n\r");
00548 ResumeMACASync();
00549 break;
00550
00551 }
00552 case NOT_COMPLETED:
00553 {
00554 PRINTF("maca: not completed\n\r");
00555 ResumeMACASync();
00556 break;
00557
00558 }
00559 case CODE_TIMEOUT:
00560 {
00561 PRINTF("maca: timeout\n\r");
00562 ResumeMACASync();
00563 break;
00564
00565 }
00566 case NO_ACK:
00567 {
00568 PRINTF("maca: no ack\n\r");
00569 ResumeMACASync();
00570 break;
00571
00572 }
00573 case EXT_TIMEOUT:
00574 {
00575 PRINTF("maca: ext timeout\n\r");
00576 ResumeMACASync();
00577 break;
00578
00579 }
00580 case EXT_PND_TIMEOUT:
00581 {
00582 PRINTF("maca: ext pnd timeout\n\r");
00583 ResumeMACASync();
00584 break;
00585 }
00586 case SUCCESS:
00587 {
00588
00589 ResumeMACASync();
00590 break;
00591 }
00592 default:
00593 {
00594 PRINTF("status: %x", (unsigned int)*MACA_STATUS);
00595 ResumeMACASync();
00596
00597 }
00598 }
00599 }
00600
00601 void maca_isr(void) {
00602
00603
00604
00605 maca_entry++;
00606
00607 if (bit_is_set(*MACA_STATUS, maca_status_ovr))
00608 { PRINTF("maca overrun\n\r"); }
00609 if (bit_is_set(*MACA_STATUS, maca_status_busy))
00610 { PRINTF("maca busy\n\r"); }
00611 if (bit_is_set(*MACA_STATUS, maca_status_crc))
00612 { PRINTF("maca crc error\n\r"); }
00613 if (bit_is_set(*MACA_STATUS, maca_status_to))
00614 { PRINTF("maca timeout\n\r"); }
00615
00616 if (data_indication_irq()) {
00617 *MACA_CLRIRQ = (1 << maca_irq_di);
00618 dma_rx->length = *MACA_GETRXLVL - 2;
00619 dma_rx->lqi = get_lqi();
00620 dma_rx->rx_time = *MACA_TIMESTAMP;
00621
00622
00623 if(dma_rx->data[1] & 0x20) {
00624
00625 volatile uint32_t wait_clk;
00626 wait_clk = *MACA_CLK + 200;
00627 while(*MACA_CLK < wait_clk) { continue; }
00628 }
00629
00630 if(maca_rx_callback != 0) { maca_rx_callback(dma_rx); }
00631
00632 add_to_rx(dma_rx);
00633 dma_rx = 0;
00634 }
00635 if (filter_failed_irq()) {
00636 PRINTF("maca filter failed\n\r");
00637 ResumeMACASync();
00638 *MACA_CLRIRQ = (1 << maca_irq_flt);
00639 }
00640 if (checksum_failed_irq()) {
00641 PRINTF("maca checksum failed\n\r");
00642 ResumeMACASync();
00643 *MACA_CLRIRQ = (1 << maca_irq_crc);
00644 }
00645 if (softclock_irq()) {
00646 *MACA_CLRIRQ = (1 << maca_irq_sftclk);
00647 }
00648 if (poll_irq()) {
00649 *MACA_CLRIRQ = (1 << maca_irq_poll);
00650 }
00651 if(action_complete_irq()) {
00652
00653 if(last_post == TX_POST) {
00654 tx_head->status = get_field(*MACA_STATUS,CODE);
00655 if(maca_tx_callback != 0) { maca_tx_callback(tx_head); }
00656 dma_tx = 0;
00657 free_tx_head();
00658 last_post = NO_POST;
00659 }
00660 ResumeMACASync();
00661 *MACA_CLRIRQ = (1 << maca_irq_acpl);
00662 }
00663
00664 decode_status();
00665
00666 if (*MACA_IRQ != 0)
00667 { PRINTF("*MACA_IRQ %x\n\r", (unsigned int)*MACA_IRQ); }
00668
00669 if(tx_head != 0) {
00670 post_tx();
00671 } else {
00672 post_receive();
00673 }
00674 }
00675
00676
00677 static uint8_t ram_values[4];
00678
00679
00680 void init_phy(void)
00681 {
00682
00683 *MACA_CLKDIV = MACA_CLOCK_DIV;
00684 *MACA_WARMUP = 0x00180012;
00685 *MACA_EOFDELAY = 0x00000004;
00686 *MACA_CCADELAY = 0x001a0022;
00687 *MACA_TXCCADELAY = 0x00000025;
00688 *MACA_FRAMESYNC0 = 0x000000A7;
00689 *MACA_CLK = 0x00000008;
00690 *MACA_RXACKDELAY = 30;
00691 *MACA_RXEND = 180;
00692 *MACA_TXACKDELAY = 68;
00693 *MACA_MASKIRQ = ((1 << maca_irq_rst) |
00694 (1 << maca_irq_acpl) |
00695 (1 << maca_irq_cm) |
00696 (1 << maca_irq_flt) |
00697 (1 << maca_irq_crc) |
00698 (1 << maca_irq_di) |
00699 (1 << maca_irq_sftclk)
00700 );
00701 *MACA_SLOTOFFSET = 0x00350000;
00702 }
00703
00704 void reset_maca(void)
00705 {
00706 volatile uint32_t cnt;
00707
00708 *MACA_RESET = (1 << maca_reset_rst);
00709
00710 for(cnt = 0; cnt < 100; cnt++) {};
00711
00712 *MACA_RESET = (1 << maca_reset_clkon);
00713
00714 *MACA_CONTROL = maca_ctrl_seq_nop;
00715
00716 for(cnt = 0; cnt < 400000; cnt++) {};
00717
00718
00719 *MACA_CLRIRQ = 0xffff;
00720 }
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745 #define RF_BASE 0x80009a00
00746 void flyback_init(void) {
00747 uint32_t val8, or;
00748
00749 val8 = *(volatile uint32_t *)(RF_BASE+8);
00750 or = val8 | 0x0000f7df;
00751 *(volatile uint32_t *)(RF_BASE+8) = or;
00752 *(volatile uint32_t *)(RF_BASE+12) = 0x00ffffff;
00753 *(volatile uint32_t *)(RF_BASE+16) = (((uint32_t)0x00ffffff)>>12);
00754 *(volatile uint32_t *)(RF_BASE) = 16;
00755
00756 }
00757
00758 #define MAX_SEQ1 2
00759 const uint32_t addr_seq1[MAX_SEQ1] = {
00760 0x80003048,
00761 0x8000304c,
00762 };
00763
00764 const uint32_t data_seq1[MAX_SEQ1] = {
00765 0x00000f78,
00766 0x00607707,
00767 };
00768
00769
00770 #define MAX_SEQ2 2
00771 const uint32_t addr_seq2[MAX_SEQ2] = {
00772 0x8000a050,
00773 0x8000a054,
00774 };
00775
00776 const uint32_t data_seq2[MAX_SEQ2] = {
00777 0x0000047b,
00778 0x0000007b,
00779 };
00780
00781 #define MAX_CAL3_SEQ1 3
00782 const uint32_t addr_cal3_seq1[MAX_CAL3_SEQ1] = { 0x80009400,0x80009a04,0x80009a00, };
00783 const uint32_t data_cal3_seq1[MAX_CAL3_SEQ1] = {0x00020017,0x8185a0a4,0x8c900025, };
00784
00785 #define MAX_CAL3_SEQ2 2
00786 const uint32_t addr_cal3_seq2[MAX_CAL3_SEQ2] = { 0x80009a00,0x80009a00,};
00787 const uint32_t data_cal3_seq2[MAX_CAL3_SEQ2] = { 0x8c900021,0x8c900027,};
00788
00789 #define MAX_CAL3_SEQ3 1
00790 const uint32_t addr_cal3_seq3[MAX_CAL3_SEQ3] = { 0x80009a00 };
00791 const uint32_t data_cal3_seq3[MAX_CAL3_SEQ3] = { 0x8c900000 };
00792
00793 #define MAX_CAL5 4
00794 const uint32_t addr_cal5[MAX_CAL5] = {
00795 0x80009400,
00796 0x8000a050,
00797 0x8000a054,
00798 0x80003048,
00799 };
00800 const uint32_t data_cal5[MAX_CAL5] = {
00801 0x00000017,
00802 0x00000000,
00803 0x00000000,
00804 0x00000f00,
00805 };
00806
00807 #define MAX_DATA 43
00808 const uint32_t addr_reg_rep[MAX_DATA] = { 0x80004118,0x80009204,0x80009208,0x8000920c,0x80009210,0x80009300,0x80009304,0x80009308,0x8000930c,0x80009310,0x80009314,0x80009318,0x80009380,0x80009384,0x80009388,0x8000938c,0x80009390,0x80009394,0x8000a008,0x8000a018,0x8000a01c,0x80009424,0x80009434,0x80009438,0x8000943c,0x80009440,0x80009444,0x80009448,0x8000944c,0x80009450,0x80009460,0x80009464,0x8000947c,0x800094e0,0x800094e4,0x800094e8,0x800094ec,0x800094f0,0x800094f4,0x800094f8,0x80009470,0x8000981c,0x80009828 };
00809
00810 const uint32_t data_reg_rep[MAX_DATA] = { 0x00180012,0x00000605,0x00000504,0x00001111,0x0fc40000,0x20046000,0x4005580c,0x40075801,0x4005d801,0x5a45d800,0x4a45d800,0x40044000,0x00106000,0x00083806,0x00093807,0x0009b804,0x000db800,0x00093802,0x00000015,0x00000002,0x0000000f,0x0000aaa0,0x01002020,0x016800fe,0x8e578248,0x000000dd,0x00000946,0x0000035a,0x00100010,0x00000515,0x00397feb,0x00180358,0x00000455,0x00000001,0x00020003,0x00040014,0x00240034,0x00440144,0x02440344,0x04440544,0x0ee7fc00,0x00000082,0x0000002a };
00811
00812 void maca_off(void) {
00813 disable_irq(MACA);
00814
00815 reg(0x80003048) = 0x00000f00;
00816
00817 maca_reset = maca_reset_rst;
00818 }
00819
00820 void maca_on(void) {
00821
00822 reg(0x80003048) = 0x00000f78;
00823
00824 reset_maca();
00825 init_phy();
00826
00827 enable_irq(MACA);
00828 *INTFRC = (1 << INT_NUM_MACA);
00829 }
00830
00831
00832 uint8_t ctov[16] = {
00833 0x0b,
00834 0x0b,
00835 0x0b,
00836 0x0a,
00837 0x0d,
00838 0x0d,
00839 0x0c,
00840 0x0c,
00841 0x0f,
00842 0x0e,
00843 0x0e,
00844 0x0e,
00845 0x11,
00846 0x10,
00847 0x10,
00848 0x0f,
00849 };
00850
00851
00852
00853 #define _INIT_CTOV_WORD_1 0x00dfbe77
00854 #define _INIT_CTOV_WORD_2 0x023126e9
00855 uint8_t get_ctov( uint32_t r0, uint32_t r1 )
00856 {
00857
00858 r0 = r0 * _INIT_CTOV_WORD_1;
00859 r0 += ( r1 << 22 );
00860 r0 += _INIT_CTOV_WORD_2;
00861
00862 r0 = (uint32_t)(((int32_t)r0) >> 25);
00863
00864 return (uint8_t)r0;
00865 }
00866
00867
00868
00869 void radio_init(void) {
00870 volatile uint32_t i;
00871
00872 for(i=0; i<MAX_SEQ1; i++) {
00873 *(volatile uint32_t *)(addr_seq1[i]) = data_seq1[i];
00874 }
00875
00876 for(i=0; i<0x161a8; i++) { continue; }
00877
00878 for(i=0; i<MAX_SEQ2; i++) {
00879 *(volatile uint32_t *)(addr_seq2[i]) = data_seq2[i];
00880 }
00881
00882 *(volatile uint32_t *)0x80009000 = 0x80050100;
00883
00884 for(i=0; i<MAX_CAL3_SEQ1; i++) {
00885 *(volatile uint32_t *)(addr_cal3_seq1[i]) = data_cal3_seq1[i];
00886 }
00887
00888 for(i=0; i<0x11194; i++) { continue; }
00889
00890 for(i=0; i<MAX_CAL3_SEQ2; i++) {
00891 *(volatile uint32_t *)(addr_cal3_seq2[i]) = data_cal3_seq2[i];
00892 }
00893
00894 for(i=0; i<0x11194; i++) { continue; }
00895
00896 for(i=0; i<MAX_CAL3_SEQ3; i++) {
00897 *(volatile uint32_t *)(addr_cal3_seq3[i]) = data_cal3_seq3[i];
00898 }
00899
00900 for(i=0; i<MAX_CAL5; i++) {
00901 *(volatile uint32_t *)(addr_cal5[i]) = data_cal5[i];
00902 }
00903
00904 for(i=0; i<MAX_DATA; i++) {
00905 *(volatile uint32_t *)(addr_reg_rep[i]) = data_reg_rep[i];
00906 }
00907
00908 PRINTF("initfromflash\n\r");
00909
00910 *(volatile uint32_t *)(0x80003048) = 0x00000f04;
00911 for(i=0; i<0x161a8; i++) { continue; }
00912
00913 *(volatile uint32_t *)(0x80003048) = 0x00000fa4;
00914 for(i=0; i<0x161a8; i++) { continue; }
00915
00916 init_from_flash(0x1F000);
00917
00918 PRINTF("ram_values:\n\r");
00919 for(i=0; i<4; i++) {
00920 PRINTF(" 0x%02x\n\r",ram_values[i]);
00921 }
00922
00923 PRINTF("radio_init: ctov parameter 0x%02x\n\r",ram_values[3]);
00924 for(i=0; i<16; i++) {
00925 ctov[i] = get_ctov(i,ram_values[3]);
00926 PRINTF("radio_init: ctov[%d] = 0x%02x\n\r",(int)i,ctov[i]);
00927 }
00928
00929
00930 }
00931
00932 const uint32_t PSMVAL[19] = {
00933 0x0000080f,
00934 0x0000080f,
00935 0x0000080f,
00936 0x0000080f,
00937 0x0000081f,
00938 0x0000081f,
00939 0x0000081f,
00940 0x0000080f,
00941 0x0000080f,
00942 0x0000080f,
00943 0x0000001f,
00944 0x0000000f,
00945 0x0000000f,
00946 0x00000816,
00947 0x0000001b,
00948 0x0000000b,
00949 0x00000802,
00950 0x00000817,
00951 0x00000003,
00952 };
00953
00954 const uint32_t PAVAL[19] = {
00955 0x000022c0,
00956 0x000022c0,
00957 0x000022c0,
00958 0x00002280,
00959 0x00002303,
00960 0x000023c0,
00961 0x00002880,
00962 0x000029f0,
00963 0x000029f0,
00964 0x000029f0,
00965 0x000029c0,
00966 0x00002bf0,
00967 0x000029f0,
00968 0x000028a0,
00969 0x00002800,
00970 0x00002ac0,
00971 0x00002880,
00972 0x00002a00,
00973 0x00002b00,
00974 };
00975
00976 const uint32_t AIMVAL[19] = {
00977 0x000123a0,
00978 0x000163a0,
00979 0x0001a3a0,
00980 0x0001e3a0,
00981 0x000223a0,
00982 0x000263a0,
00983 0x0002a3a0,
00984 0x0002e3a0,
00985 0x000323a0,
00986 0x000363a0,
00987 0x0003a3a0,
00988 0x0003a3a0,
00989 0x0003e3a0,
00990 0x000423a0,
00991 0x000523a0,
00992 0x000423a0,
00993 0x0004e3a0,
00994 0x0004e3a0,
00995 0x0004e3a0,
00996 };
00997
00998 #define RF_REG 0x80009400
00999 void set_demodulator_type(uint8_t demod) {
01000 uint32_t val = reg(RF_REG);
01001 if(demod == DEMOD_NCD) {
01002 val = (val & ~1);
01003 } else {
01004 val = (val | 1);
01005 }
01006 reg(RF_REG) = val;
01007 }
01008
01009
01010 #define ADDR_POW1 0x8000a014
01011 #define ADDR_POW2 ADDR_POW1 + 12
01012 #define ADDR_POW3 ADDR_POW1 + 64
01013 void set_power(uint8_t power) {
01014 safe_irq_disable(MACA);
01015
01016 reg(ADDR_POW1) = PSMVAL[power];
01017
01018
01019
01020 #ifdef USE_PA
01021 reg(ADDR_POW2) = 0xffffdfff & PAVAL[power];
01022 #else
01023 reg(ADDR_POW2) = 0x00002000 | PAVAL[power];
01024 #endif
01025
01026 reg(ADDR_POW3) = AIMVAL[power];
01027
01028 irq_restore();
01029 if(bit_is_set(*NIPEND, INT_NUM_MACA)) { *INTFRC = (1 << INT_NUM_MACA); }
01030
01031 }
01032
01033 const uint8_t VCODivI[16] = {
01034 0x2f,
01035 0x2f,
01036 0x2f,
01037 0x2f,
01038 0x2f,
01039 0x2f,
01040 0x2f,
01041 0x2f,
01042 0x30,
01043 0x30,
01044 0x30,
01045 0x2f,
01046 0x30,
01047 0x30,
01048 0x30,
01049 0x30,
01050 };
01051
01052 const uint32_t VCODivF[16] = {
01053 0x00355555,
01054 0x006aaaaa,
01055 0x00a00000,
01056 0x00d55555,
01057 0x010aaaaa,
01058 0x01400000,
01059 0x01755555,
01060 0x01aaaaaa,
01061 0x01e00000,
01062 0x00155555,
01063 0x004aaaaa,
01064 0x00800000,
01065 0x00b55555,
01066 0x00eaaaaa,
01067 0x01200000,
01068 0x01555555,
01069 };
01070
01071
01072 #define ADDR_CHAN1 0x80009800
01073 #define ADDR_CHAN2 (ADDR_CHAN1+12)
01074 #define ADDR_CHAN3 (ADDR_CHAN1+16)
01075 #define ADDR_CHAN4 (ADDR_CHAN1+48)
01076 void set_channel(uint8_t chan) {
01077 volatile uint32_t tmp;
01078 safe_irq_disable(MACA);
01079
01080 tmp = reg(ADDR_CHAN1);
01081 tmp = tmp & 0xbfffffff;
01082 reg(ADDR_CHAN1) = tmp;
01083
01084 reg(ADDR_CHAN2) = VCODivI[chan];
01085 reg(ADDR_CHAN3) = VCODivF[chan];
01086
01087 tmp = reg(ADDR_CHAN4);
01088 tmp = tmp | 2;
01089 reg(ADDR_CHAN4) = tmp;
01090
01091 tmp = reg(ADDR_CHAN4);
01092 tmp = tmp | 4;
01093 reg(ADDR_CHAN4) = tmp;
01094
01095 tmp = tmp & 0xffffe0ff;
01096 tmp = tmp | (((ctov[chan])<<8)&0x1F00);
01097 reg(ADDR_CHAN4) = tmp;
01098
01099 irq_restore();
01100 if(bit_is_set(*NIPEND, INT_NUM_MACA)) { *INTFRC = (1 << INT_NUM_MACA); }
01101 }
01102
01103 uint8_t (*get_lqi)(void) = (void *) 0x0000e04d;
01104
01105 #define ROM_END 0x0013ffff
01106 #define ENTRY_EOF 0x00000e0f
01107
01108
01109 uint32_t exec_init_entry(volatile uint32_t *entries, uint8_t *valbuf)
01110 {
01111 volatile uint32_t i;
01112 if(entries[0] <= ROM_END) {
01113 if (entries[0] == 0) {
01114
01115 PRINTF("init_entry: delay 0x%08x\n\r", (unsigned int)entries[1]);
01116 for(i=0; i<entries[1]; i++) { continue; }
01117 return 2;
01118 } else if (entries[0] == 1) {
01119
01120 PRINTF("init_entry: bit set clear 0x%08x 0x%08x 0x%08x\n\r", (unsigned int)entries[1], (unsigned int)entries[2], (unsigned int)entries[3]);
01121 reg(entries[2]) = (reg(entries[2]) & ~entries[1]) | (entries[3] & entries[1]);
01122 return 4;
01123 } else if ((entries[0] >= 16) &&
01124 (entries[0] < 0xfff1)) {
01125
01126 PRINTF("init_entry: store in valbuf 0x%02x position %d\n\r",
01127 (unsigned int)entries[1],
01128 (unsigned int)(entries[0]>>4)-1);
01129 valbuf[(entries[0]>>4)-1] = entries[1];
01130 return 2;
01131 } else if (entries[0] == ENTRY_EOF) {
01132 PRINTF("init_entry: eof ");
01133 return 0;
01134 } else {
01135
01136 PRINTF("init_entry: invaild code 0x%08x\n\r",(unsigned int)entries[0]);
01137 return 0;
01138 }
01139 } else {
01140
01141 PRINTF("init_entry: address value pair - *0x%08x = 0x%08x\n\r",
01142 (unsigned int)entries[0],
01143 (unsigned int)entries[1]);
01144 reg(entries[0]) = entries[1];
01145 return 2;
01146 }
01147 }
01148
01149
01150 #define FLASH_INIT_MAGIC 0x00000abc
01151 uint32_t init_from_flash(uint32_t addr) {
01152 nvmType_t type=0;
01153 nvmErr_t err;
01154 volatile uint32_t buf[8];
01155 volatile uint32_t len;
01156 volatile uint32_t i=0,j;
01157
01158 err = nvm_detect(gNvmInternalInterface_c, &type);
01159 PRINTF("nvm_detect returned type 0x%08x err 0x%02x\n\r", type, err);
01160
01161 nvm_setsvar(0);
01162 err = nvm_read(gNvmInternalInterface_c, type, (uint8_t *)buf, addr, 8);
01163 i+=8;
01164 PRINTF("nvm_read returned: 0x%02x\n\r",err);
01165
01166 for(j=0; j<4; j++) {
01167 PRINTF("0x%08x\n\r",(unsigned int)buf[j]);
01168 }
01169
01170 if(buf[0] == FLASH_INIT_MAGIC) {
01171 len = buf[1] & 0x0000ffff;
01172 while(i < (len-4)) {
01173 err = nvm_read(gNvmInternalInterface_c, type, (uint8_t *)buf, addr+i, 32);
01174 i += 4*exec_init_entry(buf, ram_values);
01175 }
01176 return i;
01177 } else {
01178 return 0;
01179 }
01180
01181 }
01182
01183
01184
01185
01186
01187 void ResumeMACASync(void)
01188 {
01189 volatile uint32_t clk, TsmRxSteps, LastWarmupStep, LastWarmupData, LastWarmdownStep, LastWarmdownData;
01190
01191 volatile uint32_t i;
01192 safe_irq_disable(MACA);
01193
01194
01195
01196
01197
01198
01199
01200 TsmRxSteps = (*((volatile uint32_t *)(0x80009204)));
01201
01202
01203
01204 LastWarmupStep = (TsmRxSteps & 0x1f) << 2;
01205
01206 LastWarmupData = (*((volatile uint32_t *)(0x80009300 + LastWarmupStep)));
01207
01208
01209
01210
01211 LastWarmdownStep = ((TsmRxSteps & 0x1f00) >> 8) << 2;
01212
01213 LastWarmdownData = (*((volatile uint32_t *)(0x80009300 + LastWarmdownStep)));
01214 (*((volatile uint32_t *)(0x80009300 + LastWarmupStep))) = LastWarmdownData;
01215
01216
01217 MACA_WRITE(maca_control, 1);
01218
01219
01220 for (clk = maca_clk, i = 0; maca_clk - clk < 3 && i < 300; i++)
01221 ;
01222
01223
01224 MACA_WRITE(maca_control, 0);
01225
01226
01227 for (clk = maca_clk, i = 0; maca_clk - clk < 3 && i < 300; i++)
01228 ;
01229
01230
01231
01232 (*((volatile uint32_t *)(0x80009300 + LastWarmupStep))) = LastWarmupData;
01233
01234
01235
01236
01237 MACA_WRITE(maca_clrirq, 0xFFFF);
01238
01239
01240
01241
01242 irq_restore();
01243
01244 }