static int select_card(int card_no) { mutex_lock(&mmc_mutex); led(true); last_disk_activity = current_tick; mmc_enable_int_flash_clock(card_no == 0); if (!card_info[card_no].initialized) { setup_sci1(7); /* Initial rate: 375 kbps (need <= 400 per mmc specs) */ write_transfer(dummy, 10); /* allow the card to synchronize */ while (!(SSR1 & SCI_TEND)); } if (card_no == 0) /* internal */ and_b(~0x04, &PADRH); /* assert CS */ else /* external */ and_b(~0x02, &PADRH); /* assert CS */ if (card_info[card_no].initialized) { setup_sci1(card_info[card_no].bitrate_register); return 0; } else { return initialize_card(card_no); } }
void power_off(void) { disable_irq(); and_b(~0x08, &PADRH); or_b(0x08, &PAIORH); while(1); }
void ide_power_enable(bool on) { bool touched = false; if(on) { or_b(0x10, &PBDRL); touched = true; } #ifdef HAVE_ATA_POWER_OFF if(!on) { and_b(~0x10, &PBDRL); touched = true; } #endif /* HAVE_ATA_POWER_OFF */ /* late port preparation, else problems with read/modify/write of other bits on same port, while input and floating high */ if (touched) { or_b(0x10, &PBIORL); /* PB4 is an output */ PBCR2 &= ~0x0300; /* GPIO for PB4 */ } }
void usb_enable(bool on) { if(on) and_b(~0x04, &PADRH); else or_b(0x04, &PADRH); }
// define for what the timer should be used right now void timer_set_mode(int mode) { // I guess we should stop the timer first... (FPB) // and_b(~0x10, &TSTR); TCNT4 = 0; // start counting at 0 gTimer.mode = mode; // store the mode if (mode == TM_RX_TIMEOUT) { GRA4 = gTimer.gra_timeout; TCR4 = 0x00; // no clear at GRA match, sysclock/1 IPRD = (IPRD & 0xFF0F) | 0x00B0; // interrupt priority 11 or_b(0x10, &TSTR); // start timer 4 } else if (mode == TM_TRANSMIT) { GRA4 = gTimer.gra_transmit; TCR4 = 0x20; // clear at GRA match, sysclock/1 //IPRD = (IPRD & 0xFF0F) | 0x0020; // interrupt priority 14 IPRD = (IPRD & 0xFF0F) | 0x00F0; // interrupt priority 14 or_b(0x10, &TSTR); // start timer 4 } else { and_b(~0x10, &TSTR); // stop the timer 4 IPRD = (IPRD & 0xFF0F); // disable interrupt } }
/****************** implementation ******************/ void timer_init(unsigned hz, unsigned to) { memset(&gTimer, 0, sizeof(gTimer)); and_b(~0x10, &TSTR); // Stop the timer 4 and_b(~0x10, &TSNC); // No synchronization and_b(~0x10, &TMDR); // Operate normally IMIA4 = (unsigned long)timer4_isr; // install ISR gTimer.gra_transmit = FREQ / hz - 1; // time for bit transitions gTimer.gra_timeout = FREQ / to - 1; // time for receive timeout TSR4 &= ~0x01; TIER4 = 0xF9; // Enable GRA match interrupt }
void mmc_enable_int_flash_clock(bool on) { /* Internal flash clock is enabled by setting PA12 high with the new * clock circuit, and by setting it low with the old clock circuit */ if (on ^ new_mmc_circuit) and_b(~0x10, &PADRH); /* clear clock gate PA12 */ else or_b(0x10, &PADRH); /* set clock gate PA12 */ }
void usb_enable(bool on) { if(HW_MASK & USB_ACTIVE_HIGH) on = !on; if(on) and_b(~0x04, &PADRH); /* enable USB */ else or_b(0x04, &PADRH); }
// 2nd level ISR for I-Bus transmission void transmit_isr(void) { bool exit = false; TSR4 &= ~0x01; // clear the interrupt switch(gSendIRQ.step++) { case -3: // We are at the beggining of transmission // we need to make sure the line is free for 1.5 bits long and_b(~TXMASK, &PBIORH); // float PB10/PB11 (input); /* case -8: case -7: case -6: case -5: case -4: case -3: */ case -2: case -1: if ((PBDR & PB10) == 0) gSendIRQ.collision = true; break; case 0: // we are at the beggining of a new bit // Let's see what we need to send if(gSendIRQ.bitmask == 0x001) { // we need to send a startbit = 0 gSendIRQ.bit = false; } else if(gSendIRQ.bitmask == 0x200 ) { // we need to send the parity bit if(gSendIRQ.parity) gSendIRQ.bit = compute_even(gSendIRQ.byte); else // we don't need to send a parity bit after all... gSendIRQ.bitmask <<= 1; // Let's shift to the stopbit instead } if(gSendIRQ.bitmask == 0x400) { // stopbit is always one ('high') gSendIRQ.bit = true; } // This is where we really send the bits... if (gSendIRQ.bit) {// sending "one"? and_b(~TXMASK, &PBIORH); // float PB10/PB11 (input); } else { and_b(~TXMASK, &PBDRH); // low on PB10/PB11 or_b(TXMASK, &PBIORH); // drive PB10/PB11 low (output) } break; // case 1: // case 2: // case 3: // case 4: // case 5: // case 6: // case 7: // case 8: // if (gSendIRQ.bit && ((PBDR & PB10) == 0)) // gSendIRQ.collision = true; // break; default: if (gSendIRQ.bit && ((PBDR & PB10) == 0)) gSendIRQ.collision = true; // prepare next round gSendIRQ.step = 0; gSendIRQ.bitmask <<= 1; if (gSendIRQ.bitmask > 0x001 && gSendIRQ.bitmask < 0x200) { // new bit of the current byte gSendIRQ.bit = (gSendIRQ.byte & (gSendIRQ.bitmask>>1)); } else if(gSendIRQ.bitmask == 0x800)