void _ltc3350_init_i2c(void) { unlock_config(); // Disable I2C4 Module I2C4CONbits.ON = 0; // SDA4 TRISGbits.TRISG7 = OUTPUT; LATGbits.LATG7 = 0; TRISGbits.TRISG7 = INPUT; TRISGbits.TRISG8 = OUTPUT; LATGbits.LATG8 = 0; TRISGbits.TRISG8 = INPUT; //ANSELGbits.ANSG7 = DIG_INPUT; CNPUGbits.CNPUG7 = 1; // SCL4 //TRISGbits.TRISG8 = OUTPUT; CNPUGbits.CNPUG8 = 1; // Disable interrupts IEC5CLR = _IEC5_I2C4MIE_MASK; IEC5CLR = _IEC5_I2C4SIE_MASK; IEC5CLR = _IEC5_I2C4BIE_MASK; IFS5CLR = _IFS5_I2C4MIF_MASK; IFS5CLR = _IFS5_I2C4SIF_MASK; IFS5CLR = _IFS5_I2C4BIF_MASK; /** * Baud rate (400kHz desired) * * I2CxBRG = (F_FBCLK2 * ((1 / (2 * F_SCL)) - T_PGD)) - 2 * I2CxBRG = (100Mhz * ((1.25 uS - 104nS)) - 2 * I2CxBRG = 112 */ //I2C4BRG = 0x70; 400 //I2C4BRG = 0x1E8; 100 I2C4BRG = 0x9B8; // 20 I2C4ADD = PIC_DEV_ADDR; // I2C4CON I2C4CONbits.A10M = 0; // 7-bit Slave Address I2C4CONbits.SMEN = 1; // Compliant with SMBus Spec // Enable I2C4 Module I2C4CONbits.ON = 1; lock_config(); }
void init_spi() { unlock_config(); // Initialize SDI1/SDO1 PPS pins CFGCONbits.IOLOCK = 0; TRISBbits.TRISB9 = INPUT; SDI1Rbits.SDI1R = 0b0101; // RPB9 TRISBbits.TRISB10 = OUTPUT; RPB10Rbits.RPB10R = 0b0101; // SDO1 CFGCONbits.IOLOCK = 1; // Disable interrupts IEC3bits.SPI1EIE = 0; IEC3bits.SPI1RXIE = 0; IEC3bits.SPI1TXIE = 0; // Disable SPI1 module SPI1CONbits.ON = 0; // Clear receive buffer SPI1BUF = 0; // Use standard buffer mode SPI1CONbits.ENHBUF = 0; /** * F_SCK = F_PBCLK2 / (2 * (SPI1BRG + 1)) * F_SCK = 100Mhz / (2 * (4 + 1)) * F_SCK = 10Mhz */ // Set the baud rate (see above equation) SPI1BRG = 4; SPI1STATbits.SPIROV = 0; SPI1CONbits.MCLKSEL = 0; // Master Clock Enable bit (PBCLK2 is used by the Baud Rate Generator) SPI1CONbits.SIDL = 0; // Stop in Idle Mode bit (Continue operation in Idle mode) SPI1CONbits.MODE32 = 0; // 32/16-Bit Communication Select bits (16-bit) SPI1CONbits.MODE16 = 1; // 32/16-Bit Communication Select bits (16-bit) SPI1CONbits.MSTEN = 1; // Master Mode Enable bit (Master mode) SPI1CONbits.CKE = 1; // SPI Clock Edge Select bit (Serial output data changes on transition from active clock state to idle clock state) // Enable SPI1 module SPI1CONbits.ON = 1; lock_config(); }
void init_general(void) { unlock_config(); // PRECON PRECONbits.PFMSECEN = 0; // Flash SEC Interrupt Enable (Do not generate an interrupt when the PFMSEC bit is set) PRECONbits.PREFEN = 0b11; // Predictive Prefetch Enable (Enable predictive prefetch for any address) PRECONbits.PFMWS = 0b010; // PFM Access Time Defined in Terms of SYSCLK Wait States (Two wait states) // CFGCON CFGCONbits.DMAPRI = 0; // DMA Read and DMA Write Arbitration Priority to SRAM (DMA uses Least Recently Serviced Arbitration) CFGCONbits.CPUPRI = 0; // CPU Arbitration Priority to SRAM When Servicing an Interrupt (CPU uses Least Recently Serviced Arbitration) CFGCONbits.ICACLK = 0; // Input Capture Alternate Clock Selection (All Input Capture modules use Timer2/3 as their timebase clock) CFGCONbits.OCACLK = 0; // Output Compare Alternate Clock Selection (All Output Compare modules use Timer2/3 as their timebase clock) CFGCONbits.IOLOCK = 1; // Peripheral Pin Select Lock (Peripheral Pin Select is locked. Writes to PPS registers are not allowed) CFGCONbits.PMDLOCK = 1; // Peripheral Module Disable (Peripheral module is locked. Writes to PMD registers are not allowed) CFGCONbits.PGLOCK = 1; // Permission Group Lock (Permission Group registers are locked. Writes to PG registers are not allowed) CFGCONbits.USBSSEN = 1; // USB Suspend Sleep Enable (USB PHY clock is shut down when Sleep mode is active) CFGCONbits.IOANCPN = 0; // I/O Analog Charge Pump Enable (Charge pump disabled) CFGCONbits.ECCCON = 0b10; // Flash ECC Configuration (ECC and dynamic ECC are disabled (ECCCON<1:0> bits are locked)) CFGCONbits.JTAGEN = 0; // JTAG Port Enable (Disable the JTAG port) CFGCONbits.TROEN = 0; // Trace Output Enable (Disable trace outputs and stop trace clock) CFGCONbits.TDOEN = 1; // TDO Enable for 2-Wire JTAG (2-wire JTAG protocol uses TDO) // CFGPG CFGPGbits.CRYPTPG = 0; // Crypto Engine Permission Group (Initiator is assigned to Permission Group 0) CFGPGbits.FCPG = 0; // Flash Control Permission Group (Initiator is assigned to Permission Group 0) CFGPGbits.SQI1PG = 0; // SQI Module Permission Group (Initiator is assigned to Permission Group 0) CFGPGbits.ETHPG = 0; // Ethernet Module Permission Group (Initiator is assigned to Permission Group 0) CFGPGbits.CAN2PG = 0; // CAN2 Module Permission Group (Initiator is assigned to Permission Group 0) CFGPGbits.CAN1PG = 0; // CAN1 Module Permission Group (Initiator is assigned to Permission Group 0) CFGPGbits.USBPG = 0; // USB Module Permission Group (Initiator is assigned to Permission Group 0) CFGPGbits.DMAPG = 0; // DMA Module Permission Group (Initiator is assigned to Permission Group 0) CFGPGbits.CPUPG = 0; // CPU Permission Group (Initiator is assigned to Permission Group 0) lock_config(); }
void init_timer1(void) { unlock_config(); // Disable TMR1 T1CONbits.ON = 0; // Timer On (Timer is disabled) // T1CON T1CONbits.TCS = 0; // Timer Clock Source Select (Internal peripheral clock) T1CONbits.SIDL = 0; // Stop in Idle Mode (Continue operation even in Idle mode) T1CONbits.TWDIS = 1; // Asynchronous Timer Write Disable (Writes to TMR1 are ignored until pending write operation completes) T1CONbits.TGATE = 0; // Timer Gated Time Accumulation Enable (Gated time accumulation is disabled) T1CONbits.TCKPS = 0b10; // Timer Input Clock Prescale Select (1:64 prescale value) // TMR1 TMR1 = 0; // TMR1 Count Register (0) /** * The clock source is PBCLK3, which is configured to run at SYSCLOCK / 50. * Currently, this gives a speed of 4Mhz. TMR1 uses a 1:64 prescale, meaning * 1 second should be equal to 4000000 / 64 == 62500 TMR1 cycles. */ // PR1 PR1 = 0xF424; // PR1 Period Register (62500) // Set up TMR1 Interrupt IFS0bits.T1IF = 0; // TMR1 Interrupt Flag Status (No interrupt request has occured) IPC1bits.T1IP = 7; // TMR1 Interrupt Priority (Interrupt priority is 7) IPC1bits.T1IS = 3; // TMR1 Interrupt Subpriority (Interrupt subpriority is 3) IEC0bits.T1IE = 1; // TMR1 Interrupt Enable Control (Interrupt is enabled) // Enable TMR1 T1CONbits.ON = 1; // Timer On (Timer is enabled) lock_config(); }
/* ioctl routine */ int vinumioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td) { unsigned int objno; int error = 0; struct sd *sd; struct plex *plex; struct volume *vol; unsigned int index; /* for transferring config info */ unsigned int sdno; /* for transferring config info */ int fe; /* free list element number */ struct _ioctl_reply *ioctl_reply = (struct _ioctl_reply *) data; /* struct to return */ /* First, decide what we're looking at */ switch (DEVTYPE(dev)) { case VINUM_SUPERDEV_TYPE: /* ordinary super device */ ioctl_reply = (struct _ioctl_reply *) data; /* save the address to reply to */ switch (cmd) { #ifdef VINUMDEBUG case VINUM_DEBUG: if (((struct debuginfo *) data)->changeit) /* change debug settings */ debug = (((struct debuginfo *) data)->param); else { if (debug & DEBUG_REMOTEGDB) boothowto |= RB_GDB; /* serial debug line */ else boothowto &= ~RB_GDB; /* local ddb */ Debugger("vinum debug"); } ioctl_reply = (struct _ioctl_reply *) data; /* reinstate the address to reply to */ ioctl_reply->error = 0; return 0; #endif case VINUM_CREATE: /* create a vinum object */ error = lock_config(); /* get the config for us alone */ if (error) /* can't do it, */ return error; /* give up */ error = setjmp(command_fail); /* come back here on error */ if (error == 0) /* first time, */ ioctl_reply->error = parse_user_config((char *) data, /* update the config */ &keyword_set); else if (ioctl_reply->error == 0) { /* longjmp, but no error status */ ioctl_reply->error = EINVAL; /* note that something's up */ ioctl_reply->msg[0] = '\0'; /* no message? */ } unlock_config(); return 0; /* must be 0 to return the real error info */ case VINUM_GETCONFIG: /* get the configuration information */ bcopy(&vinum_conf, data, sizeof(vinum_conf)); return 0; /* start configuring the subsystem */ case VINUM_STARTCONFIG: return start_config(*(int *) data); /* just lock it. Parameter is 'force' */ /* * Move the individual parts of the config to user space. * * Specify the index of the object in the first word of data, * and return the object there */ case VINUM_DRIVECONFIG: index = *(int *) data; /* get the index */ if (index >= (unsigned) vinum_conf.drives_allocated) /* can't do it */ return ENXIO; /* bang */ bcopy(&DRIVE[index], data, sizeof(struct _drive)); /* copy the config item out */ return 0; case VINUM_SDCONFIG: index = *(int *) data; /* get the index */ if (index >= (unsigned) vinum_conf.subdisks_allocated) /* can't do it */ return ENXIO; /* bang */ bcopy(&SD[index], data, sizeof(struct _sd)); /* copy the config item out */ return 0; case VINUM_PLEXCONFIG: index = *(int *) data; /* get the index */ if (index >= (unsigned) vinum_conf.plexes_allocated) /* can't do it */ return ENXIO; /* bang */ bcopy(&PLEX[index], data, sizeof(struct _plex)); /* copy the config item out */ return 0; case VINUM_VOLCONFIG: index = *(int *) data; /* get the index */ if (index >= (unsigned) vinum_conf.volumes_allocated) /* can't do it */ return ENXIO; /* bang */ bcopy(&VOL[index], data, sizeof(struct _volume)); /* copy the config item out */ return 0; case VINUM_PLEXSDCONFIG: index = *(int *) data; /* get the plex index */ sdno = ((int *) data)[1]; /* and the sd index */ if ((index >= (unsigned) vinum_conf.plexes_allocated) /* plex doesn't exist */ ||(sdno >= PLEX[index].subdisks)) /* or it doesn't have this many subdisks */ return ENXIO; /* bang */ bcopy(&SD[PLEX[index].sdnos[sdno]], /* copy the config item out */ data, sizeof(struct _sd)); return 0; /* * We get called in two places: one from the * userland config routines, which call us * to complete the config and save it. This * call supplies the value 0 as a parameter. * * The other place is from the user "saveconfig" * routine, which can only work if we're *not* * configuring. In this case, supply parameter 1. */ case VINUM_SAVECONFIG: if (VFLAGS & VF_CONFIGURING) { /* must be us, the others are asleep */ if (*(int *) data == 0) /* finish config */ finish_config(1); /* finish the configuration and update it */ else return EBUSY; /* can't do it now */ } save_config(); /* save configuration to disk */ return 0; case VINUM_RELEASECONFIG: /* release the config */ if (VFLAGS & VF_CONFIGURING) { /* must be us, the others are asleep */ finish_config(0); /* finish the configuration, don't change it */ save_config(); /* save configuration to disk */ } else error = EINVAL; /* release what config? */ return error; case VINUM_INIT: ioctl_reply = (struct _ioctl_reply *) data; /* reinstate the address to reply to */ ioctl_reply->error = 0; return 0; case VINUM_RESETCONFIG: if (vinum_inactive(0)) { /* if the volumes are not active */ /* * Note the open count. We may be called from v, so we'll be open. * Keep the count so we don't underflow */ free_vinum(1); /* clean up everything */ log(LOG_NOTICE, "vinum: CONFIGURATION OBLITERATED\n"); ioctl_reply = (struct _ioctl_reply *) data; /* reinstate the address to reply to */ ioctl_reply->error = 0; return 0; } return EBUSY; case VINUM_SETSTATE: setstate((struct vinum_ioctl_msg *) data); /* set an object state */ return 0; /* * Set state by force, without changing * anything else. */ case VINUM_SETSTATE_FORCE: setstate_by_force((struct vinum_ioctl_msg *) data); /* set an object state */ return 0; #ifdef VINUMDEBUG case VINUM_MEMINFO: vinum_meminfo(data); return 0; case VINUM_MALLOCINFO: return vinum_mallocinfo(data); case VINUM_RQINFO: return vinum_rqinfo(data); #endif case VINUM_LABEL: /* label a volume */ ioctl_reply->error = write_volume_label(*(int *) data); /* index of the volume to label */ ioctl_reply->msg[0] = '\0'; /* no message */ return 0; case VINUM_REMOVE: remove((struct vinum_ioctl_msg *) data); /* remove an object */ return 0; case VINUM_GETFREELIST: /* get a drive free list element */ index = *(int *) data; /* get the drive index */ fe = ((int *) data)[1]; /* and the free list element */ if ((index >= (unsigned) vinum_conf.drives_allocated) /* plex doesn't exist */ ||(DRIVE[index].state == drive_unallocated)) return ENODEV; if (fe >= DRIVE[index].freelist_entries) /* no such entry */ return ENOENT; bcopy(&DRIVE[index].freelist[fe], data, sizeof(struct drive_freelist)); return 0; case VINUM_RESETSTATS: resetstats((struct vinum_ioctl_msg *) data); /* reset object stats */ return 0; /* attach an object to a superordinate object */ case VINUM_ATTACH: attachobject((struct vinum_ioctl_msg *) data); return 0; /* detach an object from a superordinate object */ case VINUM_DETACH: detachobject((struct vinum_ioctl_msg *) data); return 0; /* rename an object */ case VINUM_RENAME: renameobject((struct vinum_rename_msg *) data); return 0; /* replace an object */ case VINUM_REPLACE: replaceobject((struct vinum_ioctl_msg *) data); return 0; case VINUM_DAEMON: vinum_daemon(); /* perform the daemon */ return 0; case VINUM_FINDDAEMON: /* check for presence of daemon */ return vinum_finddaemon(); return 0; case VINUM_SETDAEMON: /* set daemon flags */ return vinum_setdaemonopts(*(int *) data); case VINUM_GETDAEMON: /* get daemon flags */ *(int *) data = daemon_options; return 0; case VINUM_PARITYOP: /* check/rebuild RAID-4/5 parity */ parityops((struct vinum_ioctl_msg *) data); return 0; /* move an object */ case VINUM_MOVE: moveobject((struct vinum_ioctl_msg *) data); return 0; default: /* FALLTHROUGH */ break; } case VINUM_DRIVE_TYPE: default: log(LOG_WARNING, "vinumioctl: invalid ioctl from process %d (%s): %lx\n", curthread->td_proc->p_pid, curthread->td_proc->p_comm, cmd); return EINVAL; case VINUM_SD_TYPE: case VINUM_RAWSD_TYPE: objno = Sdno(dev); sd = &SD[objno]; switch (cmd) { case DIOCGDINFO: /* get disk label */ get_volume_label(sd->name, 1, sd->sectors, (struct disklabel *) data); break; /* * We don't have this stuff on hardware, * so just pretend to do it so that * utilities don't get upset. */ case DIOCWDINFO: /* write partition info */ case DIOCSDINFO: /* set partition info */ return 0; /* not a titty */ default: return ENOTTY; /* not my kind of ioctl */ } return 0; /* pretend we did it */ case VINUM_RAWPLEX_TYPE: case VINUM_PLEX_TYPE: objno = Plexno(dev); plex = &PLEX[objno]; switch (cmd) { case DIOCGDINFO: /* get disk label */ get_volume_label(plex->name, 1, plex->length, (struct disklabel *) data); break; /* * We don't have this stuff on hardware, * so just pretend to do it so that * utilities don't get upset. */ case DIOCWDINFO: /* write partition info */ case DIOCSDINFO: /* set partition info */ return 0; /* not a titty */ default: return ENOTTY; /* not my kind of ioctl */ } return 0; /* pretend we did it */ case VINUM_VOLUME_TYPE: objno = Volno(dev); if ((unsigned) objno >= (unsigned) vinum_conf.volumes_allocated) /* not a valid volume */ return ENXIO; vol = &VOL[objno]; if (vol->state != volume_up) /* not up, */ return EIO; /* I/O error */ switch (cmd) { case DIOCGMEDIASIZE: *(off_t *)data = vol->size << DEV_BSHIFT; break; case DIOCGSECTORSIZE: *(u_int *)data = DEV_BSIZE; break; /* * We don't have this stuff on hardware, * so just pretend to do it so that * utilities don't get upset. */ case DIOCWDINFO: /* write partition info */ case DIOCSDINFO: /* set partition info */ return 0; /* not a titty */ case DIOCWLABEL: /* set or reset label writeable */ if ((flag & FWRITE) == 0) /* not writeable? */ return EACCES; /* no, die */ if (*(int *) data != 0) /* set it? */ vol->flags |= VF_WLABEL; /* yes */ else vol->flags &= ~VF_WLABEL; /* no, reset */ break; default: return ENOTTY; /* not my kind of ioctl */ } break; } return 0; /* XXX */ }
void init_oscillator(void) { unlock_config(); // OSCCON OSCCONbits.FRCDIV = 0b000; // Internal Fast RC (FRC) Oscillator Clock Divider (FRC divided by 1) OSCCONbits.DRMEN = 0; // Dream Mode Enable (Dream mode is disabled) OSCCONbits.SLP2SPD = 0; // Sleep 2-speed Startup Control (Use the selected clock directly) OSCCONbits.CLKLOCK = 0; // Clock Selection Lock Enable (Clock and PLL selections are not locked and may be modified) OSCCONbits.SLPEN = 0; // Sleep Mode Enable (Device will enter Idle mode when a WAIT instruction is executed) OSCCONbits.SOSCEN = 0; // Secondary Oscillator (SOSC) Enable (Disable Secondary Oscillator) // OSCTUN OSCTUNbits.TUN = 0b00000; // FRC Oscillator Tuning (Center frequency. Oscillator runs at calibrated frequency (8 MHz)) // PB1DIV while(!PB1DIVbits.PBDIVRDY); PB1DIVbits.PBDIV = 0b0000001; // Peripheral Bus 1 Clock Divisor Control (PBCLK1 is SYSCLK divided by 2) // PB2DIV PB2DIVbits.ON = 1; // Peripheral Bus 2 Output Clock Enable (Output clock is enabled) while(!PB2DIVbits.PBDIVRDY); PB2DIVbits.PBDIV = 0b0000001; // Peripheral Bus 2 Clock Divisor Control (PBCLK2 is SYSCLK divided by 2) // PB3DIV PB3DIVbits.ON = 1; // Peripheral Bus 3 Output Clock Enable (Output clock is enabled) while(!PB3DIVbits.PBDIVRDY); PB3DIVbits.PBDIV = 0b0110010; // Peripheral Bus 3 Clock Divisor Control (PBCLK3 is SYSCLK divided by 50) // PB4DIV PB4DIVbits.ON = 1; // Peripheral Bus 4 Output Clock Enable (Output clock is enabled) while(!PB4DIVbits.PBDIVRDY); PB4DIVbits.PBDIV = 0b0000001; // Peripheral Bus 4 Clock Divisor Control (PBCLK4 is SYSCLK divided by 2) // PB5DIV PB5DIVbits.ON = 1; // Peripheral Bus 5 Output Clock Enable (Output clock is enabled) while(!PB5DIVbits.PBDIVRDY); PB5DIVbits.PBDIV = 0b0000001; // Peripheral Bus 5 Clock Divisor Control (PBCLK5 is SYSCLK divided by 2) // PB7DIV PB7DIVbits.ON = 1; // Peripheral Bus 7 Output Clock Enable (Output clock is enabled) while(!PB7DIVbits.PBDIVRDY); PB7DIVbits.PBDIV = 0b0000000; // Peripheral Bus 7 Clock Divisor Control (PBCLK7 is SYSCLK divided by 1) // PB8DIV PB8DIVbits.ON = 1; // Peripheral Bus 8 Output Clock Enable (Output clock is enabled) while(!PB8DIVbits.PBDIVRDY); PB8DIVbits.PBDIV = 0b0000001; // Peripheral Bus 8 Clock Divisor Control (PBCLK8 is SYSCLK divided by 2) /** * REFO1CLK == (PBCLK1 / (2 * (RODIV + (ROTRIM / 512)))) == * (100Mhz / (2 * (2 + (256/512)))) == (100Mhz / 5) == 20Mhz * * In other words, REFO1CLK is set up to output at (SYSCLK / 10). */ // Initialize REFCLKO1 PPS pin CFGCONbits.IOLOCK = 0; TRISFbits.TRISF0 = OUTPUT; RPF0R = 0b1111; // Assign REFCLKO1 to RF0 CFGCONbits.IOLOCK = 1; // REFO1CON REFO1CONbits.ACTIVE = 0; // Reference Clock Request Status (Reference clock request is not active) REFO1CONbits.ON = 0; // Output Enable (Reference Oscillator Module disabled) REFO1CONbits.ROSEL = 0b0001; // Reference Clock Source Select (PBCLK1) REFO1CONbits.SIDL = 1; // Peripheral Stop in Idle Mode (Discontinue module operation when device enters Idle mode) REFO1CONbits.OE = 1; // Reference Clock Output Enable (Reference clock is driven out on REFCLKO1 pin) REFO1CONbits.DIVSWEN = 1; // Divider Switch Enable (Divider switch is in progress) REFO1CONbits.RODIV = 0b000000000000010; // Reference Clock Divider (Divide by 2) REFO1CONbits.DIVSWEN = 0; // Divider Switch Enable (Divider switch is complete) // REFO1TRIM REFO1TRIMbits.ROTRIM = 0b100000000; // Reference Oscillator Trim (256/512 divisor added to RODIV value) // Enable REFCLKO1 REFO1CONbits.ACTIVE = 1; // Reference Clock Request Status (Reference clock request is active) REFO1CONbits.ON = 1; // Output Enable (Reference Oscillator Module enabled) // REF02CON REFO2CONbits.ACTIVE = 0; // Reference Clock Request Status (Reference clock request is not active) REFO2CONbits.ON = 0; // Output Enable (Reference Oscillator Module disabled) REFO2CONbits.OE = 0; // Reference Clock Output Enable (Reference clock is not driven out on REFCLKO2 pin) // REF03CON REFO3CONbits.ACTIVE = 0; // Reference Clock Request Status (Reference clock request is not active) REFO3CONbits.ON = 0; // Output Enable (Reference Oscillator Module disabled) REFO3CONbits.OE = 0; // Reference Clock Output Enable (Reference clock is not driven out on REFCLKO3 pin) // REF04CON REFO4CONbits.ACTIVE = 0; // Reference Clock Request Status (Reference clock request is not active) REFO4CONbits.ON = 0; // Output Enable (Reference Oscillator Module disabled) REFO4CONbits.OE = 0; // Reference Clock Output Enable (Reference clock is not driven out on REFCLKO4 pin) lock_config(); }
void init_peripheral_modules(void) { unlock_config(); CFGCONbits.PMDLOCK = 0; /** * To disable a module, first set its ON bit (or equivalent) to 0 and then set * the appropriate PMD bit to 1 (disabled). */ // ADC //TODO: ADC ON bit //PMD1bits.ADCMD = 1; // Comparator Voltage Reference CVRCONbits.ON = 0; PMD1bits.CVRMD = 1; // Comparator 1 CM1CONbits.ON = 0; PMD2bits.CMP1MD = 1; // Comparator 2 CM2CONbits.ON = 0; PMD2bits.CMP2MD = 1; // Input Capture 1 IC1CONbits.ON = 0; PMD3bits.IC1MD = 1; // Input Capture 2 IC2CONbits.ON = 0; PMD3bits.IC2MD = 1; // Input Capture 3 IC3CONbits.ON = 0; PMD3bits.IC3MD = 1; // Input Capture 4 IC4CONbits.ON = 0; PMD3bits.IC4MD = 1; // Input Capture 5 IC5CONbits.ON = 0; PMD3bits.IC5MD = 1; // Input Capture 6 IC6CONbits.ON = 0; PMD3bits.IC6MD = 1; // Input Capture 7 IC7CONbits.ON = 0; PMD3bits.IC7MD = 1; // Input Capture 8 IC8CONbits.ON = 0; PMD3bits.IC8MD = 1; // Input Capture 9 IC9CONbits.ON = 0; PMD3bits.IC9MD = 1; // Output Compare 1 OC1CONbits.ON = 0; PMD3bits.OC1MD = 1; // Output Compare 2 OC2CONbits.ON = 0; PMD3bits.OC2MD = 1; // Output Compare 3 OC3CONbits.ON = 0; PMD3bits.OC3MD = 1; // Output Compare 4 OC4CONbits.ON = 0; PMD3bits.OC4MD = 1; // Output Compare 5 OC5CONbits.ON = 0; PMD3bits.OC5MD = 1; // Output Compare 6 OC6CONbits.ON = 0; PMD3bits.OC6MD = 1; // Output Compare 7 OC7CONbits.ON = 0; PMD3bits.OC7MD = 1; // Output Compare 8 OC8CONbits.ON = 0; PMD3bits.OC8MD = 1; // Output Compare 9 OC9CONbits.ON = 0; PMD3bits.OC9MD = 1; // Timer1 //T1CONbits.ON = 0; //PMD4bits.T1MD = 1; // Timer2 T2CONbits.ON = 0; PMD4bits.T2MD = 1; // Timer3 T3CONbits.ON = 0; PMD4bits.T3MD = 1; // Timer4 T4CONbits.ON = 0; PMD4bits.T4MD = 1; // Timer5 T5CONbits.ON = 0; PMD4bits.T5MD = 1; // Timer6 T6CONbits.ON = 0; PMD4bits.T6MD = 1; // Timer7 T7CONbits.ON = 0; PMD4bits.T7MD = 1; // Timer8 T8CONbits.ON = 0; PMD4bits.T8MD = 1; // Timer9 T9CONbits.ON = 0; PMD4bits.T9MD = 1; // UART1 U1MODEbits.ON = 0; PMD5bits.U1MD = 1; // UART2 U2MODEbits.ON = 0; PMD5bits.U2MD = 1; // UART3 U3MODEbits.ON = 0; PMD5bits.U3MD = 1; // UART4 U4MODEbits.ON = 0; PMD5bits.U4MD = 1; // UART5 U5MODEbits.ON = 0; PMD5bits.U5MD = 1; // UART6 U6MODEbits.ON = 0; PMD5bits.U6MD = 1; // SPI1 //SPI1CONbits.ON = 0; //PMD5bits.SPI1MD = 1; // SPI2 SPI2CONbits.ON = 0; PMD5bits.SPI2MD = 1; // SPI3 SPI3CONbits.ON = 0; PMD5bits.SPI3MD = 1; // SPI4 SPI4CONbits.ON = 0; PMD5bits.SPI4MD = 1; // SPI5 SPI5CONbits.ON = 0; PMD5bits.SPI5MD = 1; // SPI6 SPI6CONbits.ON = 0; PMD5bits.SPI6MD = 1; // I2C1 I2C1CONbits.ON = 0; PMD5bits.I2C1MD = 1; // I2C3 I2C3CONbits.ON = 0; PMD5bits.I2C3MD = 1; // I2C4 I2C4CONbits.ON = 0; PMD5bits.I2C4MD = 1; // I2C5 I2C5CONbits.ON = 0; PMD5bits.I2C5MD = 1; // USB //TODO: USB ON bit //PMD5bits.USBMD = 1; // CAN 1 //C1CONbits.ON = 0; //PMD5bits.CAN1MD = 1; // CAN 2 C2CONbits.ON = 0; PMD5bits.CAN2MD = 1; // RTCC RTCCONbits.ON = 0; PMD6bits.RTCCMD = 1; /** * Note: Reference clock outputs are not disabled due to an error condition * noted in the revision A1 errata. */ // Reference Clock Output 1 //REFO1CONbits.ON = 0; //PMD6bits.REFO1MD = 1; // Reference Clock Output 2 //REFO2CONbits.ON = 0; //PMD6bits.REFO2MD = 1; // Reference Clock Output 3 //REFO3CONbits.ON = 0; //PMD6bits.REFO3MD = 1; // Reference Clock Output 4 //REFO4CONbits.ON = 0; //PMD6bits.REFO4MD = 1; // PMP PMCONbits.ON = 0; PMD6bits.PMPMD = 1; // SQI 1 SQI1CFGbits.SQIEN = 0; PMD6bits.SQI1MD = 1; // Ethernet ETHCON1bits.ON = 0; PMD6bits.ETHMD = 1; // DMA DMACONbits.ON = 0; PMD7bits.DMAMD = 1; // Random Number Generator RNGCONbits.PRNGEN = 0; RNGCONbits.TRNGEN = 0; PMD7bits.RNGMD = 1; // Crypto CECONbits.DMAEN = 0; PMD7bits.CRYPTMD = 1; CFGCONbits.PMDLOCK = 1; lock_config(); }
/* ioctl routine */ int vinumioctl(struct dev_ioctl_args *ap) { cdev_t dev = ap->a_head.a_dev; u_long cmd = ap->a_cmd; caddr_t data = ap->a_data; int error; unsigned int index; /* for transferring config info */ unsigned int sdno; /* for transferring config info */ unsigned int objno; struct volume *vol; struct partinfo *dpart; int fe; /* free list element number */ struct _ioctl_reply *ioctl_reply; /* struct to return */ error = 0; /* First, decide what we're looking at */ switch (DEVTYPE(dev)) { case VINUM_SUPERDEV_TYPE: /* ordinary super device */ ioctl_reply = (struct _ioctl_reply *) data; /* save the address to reply to */ switch (cmd) { #ifdef VINUMDEBUG case VINUM_DEBUG: if (((struct debuginfo *) data)->changeit) /* change debug settings */ debug = (((struct debuginfo *) data)->param); else { if (debug & DEBUG_REMOTEGDB) boothowto |= RB_GDB; /* serial debug line */ else boothowto &= ~RB_GDB; /* local ddb */ Debugger("vinum debug"); } ioctl_reply = (struct _ioctl_reply *) data; /* reinstate the address to reply to */ ioctl_reply->error = 0; break; #endif case VINUM_CREATE: /* create a vinum object */ error = lock_config(); /* get the config for us alone */ if (error) /* can't do it, */ break; error = setjmp(command_fail); /* come back here on error */ if (error == 0) /* first time, */ ioctl_reply->error = parse_user_config((char *) data, /* update the config */ &keyword_set); else if (ioctl_reply->error == 0) { /* longjmp, but no error status */ error = 0; ioctl_reply->error = EINVAL; /* note that something's up */ ioctl_reply->msg[0] = '\0'; /* no message? */ } unlock_config(); break; case VINUM_GETCONFIG: /* get the configuration information */ bcopy(&vinum_conf, data, sizeof(vinum_conf)); break; /* start configuring the subsystem */ case VINUM_STARTCONFIG: error = start_config(*(int *) data); /* just lock it. Parameter is 'force' */ break; case VINUM_DRIVECONFIG: /* * Move the individual parts of the config to user space. * * Specify the index of the object in the first word of data, * and return the object there */ index = *(int *) data; if (index >= (unsigned)vinum_conf.drives_allocated) { error = ENXIO; } else { bcopy(&DRIVE[index], data, sizeof(struct drive)); } break; case VINUM_SDCONFIG: index = *(int *) data; if (index >= (unsigned) vinum_conf.subdisks_allocated) { error = ENXIO; } else { bcopy(&SD[index], data, sizeof(struct sd)); } break; case VINUM_PLEXCONFIG: index = *(int *) data; if (index >= (unsigned) vinum_conf.plexes_allocated) { error = ENXIO; } else { bcopy(&PLEX[index], data, sizeof(struct plex)); } break; case VINUM_VOLCONFIG: index = *(int *) data; if (index >= (unsigned) vinum_conf.volumes_allocated) { error = ENXIO; } else { bcopy(&VOL[index], data, sizeof(struct volume)); } break; case VINUM_PLEXSDCONFIG: index = ((int *)data)[0]; /* get the plex index */ sdno = ((int *)data)[1]; /* and the sd index */ if ((index >= (unsigned) vinum_conf.plexes_allocated) ||(sdno >= PLEX[index].subdisks)) { error = ENXIO; } else { bcopy(&SD[PLEX[index].sdnos[sdno]], data, sizeof(struct sd)); } break; case VINUM_SAVECONFIG: /* * We get called in two places: one from the * userland config routines, which call us * to complete the config and save it. This * call supplies the value 0 as a parameter. * * The other place is from the user "saveconfig" * routine, which can only work if we're *not* * configuring. In this case, supply parameter 1. */ if (VFLAGS & VF_CONFIGURING) { /* must be us, the others are asleep */ if (*(int *) data == 0) /* finish config */ finish_config(1); /* finish the configuration and update it */ else error = EBUSY; } if (error == 0) save_config(); /* save configuration to disk */ break; case VINUM_RELEASECONFIG: /* release the config */ if (VFLAGS & VF_CONFIGURING) { /* must be us, the others are asleep */ finish_config(0); /* finish the configuration, don't change it */ save_config(); /* save configuration to disk */ } else { error = EINVAL; /* release what config? */ } break; case VINUM_INIT: ioctl_reply = (struct _ioctl_reply *) data; /* reinstate the address to reply to */ ioctl_reply->error = 0; break; case VINUM_RESETCONFIG: if (vinum_inactive(0)) { /* if the volumes are not active */ /* * Note the open count. We may be called from v, so we'll be open. * Keep the count so we don't underflow */ free_vinum(1); /* clean up everything */ log(LOG_NOTICE, "vinum: CONFIGURATION OBLITERATED\n"); ioctl_reply = (struct _ioctl_reply *) data; /* reinstate the address to reply to */ ioctl_reply->error = 0; } else { error = EBUSY; } case VINUM_SETSTATE: setstate((struct vinum_ioctl_msg *) data); /* set an object state */ break; /* * Set state by force, without changing * anything else. */ case VINUM_SETSTATE_FORCE: setstate_by_force((struct vinum_ioctl_msg *) data); /* set an object state */ break; #ifdef VINUMDEBUG case VINUM_MEMINFO: vinum_meminfo(data); break; case VINUM_MALLOCINFO: error = vinum_mallocinfo(data); break; case VINUM_RQINFO: error = vinum_rqinfo(data); break; #endif case VINUM_REMOVE: remove((struct vinum_ioctl_msg *) data); /* remove an object */ break; case VINUM_GETFREELIST: /* get a drive free list element */ index = *(int *) data; /* get the drive index */ fe = ((int *) data)[1]; /* and the free list element */ if ((index >= (unsigned) vinum_conf.drives_allocated) /* plex doesn't exist */ ||(DRIVE[index].state == drive_unallocated)) { error = ENODEV; } else if (fe >= DRIVE[index].freelist_entries) { error = ENOENT; } else { bcopy(&DRIVE[index].freelist[fe], data, sizeof(struct drive_freelist)); } break; case VINUM_RESETSTATS: resetstats((struct vinum_ioctl_msg *) data); /* reset object stats */ break; /* attach an object to a superordinate object */ case VINUM_ATTACH: attachobject((struct vinum_ioctl_msg *) data); break; /* detach an object from a superordinate object */ case VINUM_DETACH: detachobject((struct vinum_ioctl_msg *) data); break; /* rename an object */ case VINUM_RENAME: renameobject((struct vinum_rename_msg *) data); break; /* replace an object */ case VINUM_REPLACE: replaceobject((struct vinum_ioctl_msg *) data); break; case VINUM_DAEMON: vinum_daemon(); /* perform the daemon */ break; case VINUM_FINDDAEMON: /* check for presence of daemon */ error = vinum_finddaemon(); break; case VINUM_SETDAEMON: /* set daemon flags */ error = vinum_setdaemonopts(*(int *) data); break; case VINUM_GETDAEMON: /* get daemon flags */ *(int *) data = daemon_options; break; case VINUM_PARITYOP: /* check/rebuild RAID-4/5 parity */ parityops((struct vinum_ioctl_msg *) data); break; /* move an object */ case VINUM_MOVE: moveobject((struct vinum_ioctl_msg *) data); break; default: error = EINVAL; break; } break; case VINUM_LABEL: case VINUM_DRIVE_TYPE: case VINUM_SD_TYPE: case VINUM_RAWSD_TYPE: case VINUM_RAWPLEX_TYPE: case VINUM_PLEX_TYPE: error = EINVAL; break; case VINUM_VOLUME_TYPE: objno = Volno(dev); if ((unsigned)objno >= (unsigned)vinum_conf.volumes_allocated) { error = ENXIO; break; } vol = &VOL[objno]; if (vol->state != volume_up) { error = EIO; break; } switch(cmd) { case DIOCGPART: dpart = (void *)data; bzero(dpart, sizeof(*dpart)); dpart->media_offset = 0; dpart->media_size = (u_int64_t)vol->size * DEV_BSIZE; dpart->media_blocks = vol->size; dpart->media_blksize = DEV_BSIZE; dpart->fstype = FS_BSDFFS; break; default: error = EINVAL; } break; default: error = EINVAL; break; } if (error) { log(LOG_WARNING, "vinumioctl: invalid ioctl from process %d (%s): %lx\n", curproc->p_pid, curproc->p_comm, cmd); } return error; }