DMP_INLINE(void) set_pins(int dev, int SCL, int SDA) { unsigned char mask = ~(0x03 << (dev*2 + 4)); unsigned char dir = 0; unsigned char val = (unsigned char)((SDA<<1) + SCL) << (dev*2 + 4); if (SCL == 0) dir = dir | (0x01 << (dev*2 + 4)); // set the SCL to output 0 if (SDA == 0) dir = dir | (0x02 << (dev*2 + 4)); // set the SDA to output 0 io_outpb(GPIO3_DIR, (io_inpb(GPIO3_DIR) & mask) | dir); //set GPIO direction = out io_outpb(GPIO3_DATA, (io_inpb(GPIO3_DATA) & mask) | val); }
RBAPI(bool) i2c_InitSW2(unsigned devs, int i2c0mode, unsigned long i2c0clkdelay, int i2c1mode, unsigned long i2c1clkdelay) { int i; if (I2C_ioSection != -1) { err_SetMsg(ERROR_I2C_INUSE, "I2C lib was already opened"); return false; } if ((I2C_ioSection = io_Init()) == -1) return false; #ifdef ROBOIO switch (roboio_GetRBVer()) { case RB_100b1: case RB_100b2: case RB_100b3: case RB_100: case RB_100RD: case RB_110: case RB_050: devs = devs & I2C_USEMODULE0; break; default: devs = 0; break; } #endif I2C_swMode[0] = i2c0mode; I2CSW_delay[0] = i2c0clkdelay; I2C_swMode[1] = i2c1mode; I2CSW_delay[1] = i2c1clkdelay; I2C_action[0] = I2C_action[1] = I2CACT_DISABLE; for (i=0; i<2; i++) { if ((i == 0) && ((devs & I2C_USEMODULE0) == 0)) continue; if ((i == 1) && ((devs & I2C_USEMODULE1) == 0)) continue; I2C_action[i] = I2CACT_IDLE; // switch GPIO/I2C pins into GPIO pins OLD_I2CGPIO3FLAG[i] = read_sb_reg(SB_IPFCTRL3_REG) & OLD_I2CGPIO3MASK[i]; // backup GPIO/I2C switch flag write_sb_reg(SB_IPFCTRL3_REG, read_sb_reg(SB_IPFCTRL3_REG) & (~OLD_I2CGPIO3MASK[i])); OLD_I2CGPIO3DIR[i] = io_inpb(GPIO3_DIR) & (0x03 << (i*2+4)); // backup GPIO3 DIR OLD_I2CGPIO3VAL[i] = io_inpb(GPIO3_DATA) & (0x03 << (i*2+4)); // backup GPIO3 VAL // set GPIO pins as INPUT state (equiv. to OUT 1 of I2C lines) io_outpb(GPIO3_DIR, io_inpb(GPIO3_DIR) & ~(0x03 << (i*2+4))); } return true; }
DMPAPI(void) uart_Close(void *vport) { unsigned char lcr; SerialPort *port = (SerialPort *)vport; if (port == NULL) { err_print((char*)"%s: port is null.\n", __FUNCTION__); return; } if (port->InUse != 0) { // restore old IER & MCR uart_IntDisable(vport); io_DisableINT(); { io_outpb(port->MCR, port->old_mcr); } io_RestoreINT(); irq_Close(); // restore old LSB & MSB #ifdef _VORTEX86EXC_UART_WORKAROUND /* To avoid Vortex86EX(D) write sync. issue. */ io_DisableINT(); { lcr = io_inpb(port->LCR); io_outpb(port->LCR, 0x80); do { io_outpb(port->DLLSB, port->old_lsb); } while (io_inpb(port->DLLSB) != port->old_lsb); do { io_outpb(port->DLMSB, port->old_msb); } while (io_inpb(port->DLMSB) != port->old_msb); io_inpb(0x80); // do IO delay io_outpb(port->LCR, lcr); } io_RestoreINT(); #else _16550_DLAB_Out(port, port->DLLSB, port->old_lsb); _16550_DLAB_Out(port, port->DLMSB, port->old_msb); #endif // restore old LCR & timeout uart_SetFormat(vport, port->old_lcr); uart_SetTimeOut(vport, port->old_TimeOut); vx86_uart_Close(port->com); if (io_Close() == false) err_print((char*)"Close IO lib error!!\n"); } uart_Free(port); }
DMPAPI(void) wdt_enable(unsigned long nTime) { // us unit unsigned char val; if(wdt1_init_f == true) return; // restore current WDT1 register WDT_t.ctrl_reg = io_inpb(0xA8); WDT_t.sigsel_reg = io_inpb(0xA9); WDT_t.count0_reg = io_inpb(0xAA); WDT_t.count1_reg = io_inpb(0xAB); WDT_t.count2_reg = io_inpb(0xAC); WDT_t.stat_reg = io_inpb(0xAD); WDT_t.reload_reg = io_inpb(0xAE); io_outpb(0xad, 0x80); // clear timeout event bit // set reset system mode io_outpb(0xa9, 0x0D << 4); // set time period wdt1_timer_watchdog(nTime); // start WDT1. val = io_inpb(0xa8); io_outpb(0xa8, val | 0x40); // set bit 6 to enable WDT1 wdt1_init_f = true; }
static int _recv_poll(SerialPort *port, unsigned char* buf, int bsize) { int cur = 0; while (cur < bsize) { if (io_inpb(port->LSR) & 0x01) { buf[cur] = io_inpb(port->RXDB); } else { break; } } return cur; }
// // only for DLLSB, DLMSB DMP_INLINE(unsigned char) _16550_DLAB_In(SerialPort *port, unsigned short addr) { unsigned char data, lcr; io_DisableINT(); { lcr = io_inpb(port->LCR); io_outpb(port->LCR, 0x80); data = io_inpb(addr); io_outpb(port->LCR, lcr); } io_RestoreINT(); return data; }
RBAPI(bool) com_FlushWFIFO(int com) { #if defined(RB_MSVC_WIN32) || defined(RB_MSVC_WINCE) if (FlushFileBuffers(COM_info[com].fp) == FALSE) { err_SetMsg(ERROR_COM_FAIL, "FlushFileBuffers() fails"); return false; } #elif defined(RB_LINUX) if (COM_duplex[com] != COM_HDUPLEX_RTS) { if (tcdrain(COM_info[com].fp) < 0) { err_SetMsg(ERROR_COM_FAIL, "tcdrain() fails"); return false; } } else // tcdrain() is too slow in the purpose of switching RTS to read servos in readtime { //use "ioctl(fd, FIONWRITE, &nBytes)" to wait write-FIFO empty... } #endif if (COM_duplex[com] == COM_HDUPLEX_RTS) // ensure that all bytes in 16550 FIFO have been sent while((io_inpb(COM_baseaddr[com] + 5) & 0x60) != 0x60); return true; }
DMP_INLINE(bool) uart_IsOK(SerialPort *port) { unsigned char temp; if (port == NULL) { err_print((char*)"%s: port is null.\n", __FUNCTION__); return false; } if ((io_inpb(port->IIR) & 0x30) != 0x00) return false; temp = io_inpb(port->SCR); io_outpb(port->SCR, 0x55); if (io_inpb(port->SCR) != 0x55) return false; io_outpb(port->SCR, 0xaa); if (io_inpb(port->SCR) != 0xaa) return false; io_outpb(port->SCR, temp); return true; }
static void set_pin_out(char port, char pin) { io_outpdw(gpio_config_addr + 0x00, io_inpdw(gpio_config_addr + 0x00) | 0x01L << port); // set data address if ((usb_on_off_data = io_inpw(gpio_config_addr + (4 + 4*port))) == 0x0000) io_outpw(gpio_config_addr + (4 + 4*port), (usb_on_off_data = (GPIO_BASE_ADDR + port))); // set direction address if ((usb_on_off_dir = io_inpw(gpio_config_addr + (6 + 4*port))) == 0x0000) io_outpw(gpio_config_addr + (6 + 4*port), (usb_on_off_dir = (GPIO_BASE_ADDR + port + 10))); // set USB-ONOFF pin -> OUT io_outpb(usb_on_off_dir, io_inpb(usb_on_off_dir) | (1 << pin)); io_outpb(usb_on_off_data, io_inpb(usb_on_off_data) | (1 << pin)); usb_on_off_pin = pin; }
void SPIClass::begin() { if (!initialized) { void *pciDev = NULL; // Get SPI device base address pciDev = pci_Alloc(0x00, 0x10, 0x01); // PCI SPI configuration space if(pciDev == NULL) {printf("SPI device don't exist\n"); return;} SPI_IOaddr = (unsigned)(pci_In16(pciDev, 0x10) & 0xFFFFFFF0L); // get SPI base address #if defined DEBUG_MODE printf("SPI base address = %04X\n", SPI_IOaddr); #endif pci_Free(pciDev); WriteCTRR(FULLDUPEX + SPI_MODE0 + RESET); io_outpb(SPI_IOaddr + 7, FULLDUPEX); // full-dupex io_outpb(SPI_IOaddr + 7, io_inpb(SPI_IOaddr + 7) & 0xF1 | SPI_MODE0); // set mode io_outpb(SPI_IOaddr + 0x0b, 0x08); // delay clk between two transfers //SOURCE clock/(2 * SPI_CLOCK_DIV) setClockDivider(13); // 100/(2*13) ~= 4MHz useFIFO(); detachInterrupt(); io_outpb(SPI_IOaddr + 4, 0x01); // set CS = high // Set SS to high so a connected chip will be "deselected" by default pinMode(SS, OUTPUT); digitalWrite(SS, HIGH); } initialized++; // reference count }
DMP_INLINE(unsigned char) inpb_cmos(unsigned char reg) { unsigned char tmp; io_DisableINT(); io_outpb(0x70, 0x80 | reg); // disable NMI (by setting the 0x80 bit) and assign a RTC register address tmp = io_inpb(0x71); io_RestoreINT(); return tmp; }
RBAPI(void) spi_CloseSW(void) { if (spi_InUse() == false) return; if (SPISW_active == false) return; if (OLD_SPIGPIO3FLAG != 0xffffffffL) write_sb_reg(SB_MULTIFUNC_REG, (read_sb_reg(SB_MULTIFUNC_REG) & 0xfffffffeL) + OLD_SPIGPIO3FLAG); // restore GPIO3[3:0] io_outpb(GPIO3_DIR, (io_inpb(GPIO3_DIR) & 0xf0) + OLD_SPIGPIODIR); io_outpb(GPIO3_DATA, (io_inpb(GPIO3_DATA) & 0xf0) + OLD_SPIGPIODATA); io_Close(SPI_ioSection); SPI_ioSection = -1; OLD_SPIGPIO3FLAG = 0xffffffffL; SPISW_active = false; }
/* #define SPI_CLOCK_DIV4 0x00 : 4MHz #define SPI_CLOCK_DIV16 0x01 : 1MHz #define SPI_CLOCK_DIV64 0x02 : 250kHz #define SPI_CLOCK_DIV128 0x03 : 125kHz #define SPI_CLOCK_DIV2 0x04 : 8MHz #define SPI_CLOCK_DIV8 0x05 : 2MHz #define SPI_CLOCK_DIV32 0x06 : 500MHz it's result is 16MHz/above value, so that the lowest speed is 0.125MHz #define SPI_CLOCK_DIV25 (25) : 4MHz #define SPI_CLOCK_DIV100 (100) : 1MHz #define SPI_CLOCK_DIV400 (400) : 250kHz #define SPI_CLOCK_DIV800 (800) : 125kHz #define SPI_CLOCK_DIV13 (13) : 8MHz (it is 12.5) #define SPI_CLOCK_DIV50 (50) : 2MHz #define SPI_CLOCK_DIV200 (200) : 500kHz */ void SPIClass::setClockDivider(uint16_t rate) { if(rate == 0 || rate > 4095) return; if(SPI_IOaddr == 0) return; if(rate > 15) io_outpb(SPI_IOaddr + 6, (rate&0x0ff0)>>4); io_outpb(SPI_IOaddr + 2, (io_inpb(SPI_IOaddr + 2) & 0xF0) | (rate%16)); }
DMPAPI(bool) i2c_Reset(int dev) { unsigned long nowtime; io_outpb(I2C_EXCTRL_REG(dev), io_inpb(I2C_EXCTRL_REG(dev)) | 0x80); nowtime = timer_nowtime(); while (((io_inpb(I2C_EXCTRL_REG(dev)) & 0x80) != 0) && ((timer_nowtime() - nowtime) < I2C_TIMEOUT)); if ((io_inpb(I2C_EXCTRL_REG(dev)) & 0x80) != 0) { err_SetMsg(ERROR_I2CFAIL, "fail to reset I2C module %d", dev); return false; } //Remarks: due to Vortex86DX's poor I2C design, RESET bit may become 0 when dummy clocks are still being output delay_ms(20L); //lazy trick to tackle the above issue return true; }
/* #define SPI_CLOCK_DIV4 0x00 : 4MHz #define SPI_CLOCK_DIV16 0x01 : 1MHz #define SPI_CLOCK_DIV64 0x02 : 250kHz #define SPI_CLOCK_DIV128 0x03 : 125kHz #define SPI_CLOCK_DIV2 0x04 : 8MHz #define SPI_CLOCK_DIV8 0x05 : 2MHz #define SPI_CLOCK_DIV32 0x06 : 500MHz it's result is 16MHz/above value, so that the lowest speed is 1.25MHz #define WIFI_SPI_CLOCK_DIV25 (25) : 4MHz #define WIFI_SPI_CLOCK_DIV100 (100) : 1MHz #define WIFI_SPI_CLOCK_DIV400 (400) : 250kHz #define WIFI_SPI_CLOCK_DIV800 (800) : 125kHz #define WIFI_SPI_CLOCK_DIV13 (13) : 8MHz (it is 12.5) #define WIFI_SPI_CLOCK_DIV50 (50) : 2MHz #define WIFI_SPI_CLOCK_DIV200 (200) : 500kHz */ void WIFI_SPIClass::setClockDivider(uint16_t rate) { if(rate == 0 && rate > 4095) return; if(rate > 255) { io_outpb(WIFI_SPI_IOaddr + 6, rate/256); } io_outpb(WIFI_SPI_IOaddr + 2, (io_inpb(WIFI_SPI_IOaddr + 2) & 0xF0) | (rate%256)); }
RBAPI(void) i2c_Close(void) { int i; if (I2C_ioSection == -1) return; for (i=0; i<2; i++) //restore GPIO3/I2C switch setting { if (I2C_action[i] == I2CACT_DISABLE) continue; io_outpb(GPIO3_DIR, (io_inpb(GPIO3_DIR) & (~(0x03 << (i*2+4)))) | OLD_I2CGPIO3DIR[i]); //restore GPIO3 DIR io_outpb(GPIO3_DATA, (io_inpb(GPIO3_DATA) & (~(0x03 << (i*2+4)))) | OLD_I2CGPIO3VAL[i]); //restore GPIO3 VAL write_sb_reg(SB_IPFCTRL3_REG, (read_sb_reg(SB_IPFCTRL3_REG) & (~OLD_I2CGPIO3MASK[i])) | OLD_I2CGPIO3FLAG[i]); //restore GPIO/I2C switch flag I2C_action[i] = I2CACT_DISABLE; } io_Close(I2C_ioSection); I2C_ioSection = -1; }
static int _recv_int(SerialPort *port, unsigned char* buf, int bsize) { int i; unsigned long pretime; for (i = 0; i < bsize; i++) { if (port->RxTimeOut < 0) { while (QueueEmpty(port->rcvd)); } else { pretime = timer_NowTime(); while (QueueEmpty(port->rcvd) && (timer_NowTime() - pretime) < port->RxTimeOut); if (QueueEmpty(port->rcvd)) { if (UART_TIMEOUT_DEBUG) err_print((char*)"%s: COM%d receive timeout.\n", __FUNCTION__, port->com + 1); break; } } io_DisableINT(); { buf[i] = PopQueue(port->rcvd); switch (port->control) { case NO_CONTROL: break; case RTS_CTS: { if (QueueSize(port->rcvd) < (RX_QUEUE_SIZE - NEAR_FULL_SIZE) && port->rts == 0) { io_outpb(port->MCR, io_inpb(port->MCR) | 0x02); port->rts = 1; } } break; case XON_XOFF: { if (QueueSize(port->rcvd) < (RX_QUEUE_SIZE - NEAR_FULL_SIZE) && port->xonxoff_xmit != XON_XMIT) { port->xon = 1; io_outpb(port->IER, port->ier |= 0x02); } } break; default: break; }; } io_RestoreINT(); } return i; }
// // only for DLLSB, DLMSB, FCR DMP_INLINE(void) _16550_DLAB_Out(SerialPort *port, unsigned short addr, unsigned char data) { unsigned char lcr; io_DisableINT(); { lcr = io_inpb(port->LCR); io_outpb(port->LCR, 0x80); io_outpb(addr, data); io_outpb(port->LCR, lcr); } io_RestoreINT(); }
DMPAPI(void) usb_Close(void *vusb) { USB_Device *usb = (USB_Device *)vusb; if (usb == NULL) { err_print((char*)"%s: USB device is null.\n", __FUNCTION__); return; } if (usb->InUse != 0) { io_DisableINT(); { io_outpb(usb->CFR, io_inpb(usb->CFR) & 0xFE); irq_UninstallISR(usb->nIRQ, (void *)usb); } io_RestoreINT(); irq_Close(); io_outpb(usb->CFR, 0x02); // Soft reset while (io_inpb(usb->CFR) & 0x02); #if defined DMP_DOS_DJGPP if (dma_Free(dma_handle) == false) err_print((char*)"%s: Free DMA buffer fail!!\n", __FUNCTION__); #endif ker_Mfree(usb->EP[0].SetupBuf); ker_Mfree(usb->EP[0].InBuf); ker_Mfree(usb->EP[0].OutBuf); ker_Mfree(usb->EP[1].InBuf); ker_Mfree(usb->EP[2].InBuf); ker_Mfree(usb->EP[2].OutBuf); if (io_Close() == false) err_print((char*)"%s: Close IO lib error!!\n", __FUNCTION__); usb->state = USB_DEV_POWERED; usb->InUse = 0; USB_Disconnect(); } DestoryQueue(usb->rcvd); DestoryQueue(usb->xmit); ker_Mfree((void *)usb); }
static int _send_poll(SerialPort *port, unsigned char* buf, int bsize) { int cur = 0; while (cur < bsize) { if ((io_inpb(port->LSR) & 0x60) == 0x60) { io_outpb(port->TXDB, buf[cur]); cur++; } } return cur; }
void WIFI_SPIClass::begin() { void *pciDev = NULL; if(io_Init() == false) return; // Get SPI device base address pciDev = pci_Alloc(0x00, 0x10, 0x01); // PCI SPI configuration space if(pciDev == NULL) {printf("WiFi-SPI device don't exist\n"); return;} WIFI_SPI_IOaddr = (unsigned)(pci_In16(pciDev, 0x10) & 0xFFFFFFF0L); // get SPI base address #if defined WIFI_DEBUG_MODE printf("WiFi-SPI base address = %04X\n", WIFI_SPI_IOaddr); #endif pci_Free(pciDev); WIFI_WriteCTRR(WIFI_FULLDUPEX + WIFI_SPI_MODE0 + WIFI_RESET); io_outpb(WIFI_SPI_IOaddr + 7, WIFI_FULLDUPEX); // full-dupex io_outpb(WIFI_SPI_IOaddr + 7, io_inpb(WIFI_SPI_IOaddr + 7) & 0xF1 | WIFI_SPI_MODE0); // set mode io_outpb(WIFI_SPI_IOaddr + 0x0b, 0x08); // delay clk between two transfers //SOURCE clock/(2 * SPI_CLOCK_DIV) setClockDivider(WIFI_SPI_CLOCK_DIV800); // 125k Hz WIFI_useFIFO(); detachInterrupt(); io_outpb(WIFI_SPI_IOaddr + 4, 0x01); // set CS = high // Set SS to high so a connected chip will be "deselected" by default digitalWrite(SS, HIGH); // When the SS pin is set as OUTPUT, it can be used as // a general purpose output port (it doesn't influence // SPI operations). //pinMode(SS, OUTPUT); // Warning: if the SS pin ever becomes a LOW INPUT then SPI // automatically switches to Slave, so the data direction of // the SS pin MUST be kept as OUTPUT. //SPCR |= _BV(MSTR); //SPCR |= _BV(SPE); // Set direction register for SCK and MOSI pin. // MISO pin automatically overrides to INPUT. // By doing this AFTER enabling SPI, we avoid accidentally // clocking in a single bit since the lines go directly // from "input" to SPI control. // http://code.google.com/p/arduino/issues/detail?id=888 //pinMode(SCK, OUTPUT); //pinMode(MOSI, OUTPUT); }
RBAPI(bool) spi_InitSW(int mode, unsigned long clkdelay) { if(spi_InUse() == true) { err_SetMsg(ERROR_SPI_INUSE, "SPI was already opened"); return false; } if ((SPI_ioSection = io_Init()) == -1) return false; SPISW_mode = mode; SPISW_delay = clkdelay; // set the initial state of SPI GPIO pins OLD_SPIGPIODIR = io_inpb(GPIO3_DIR); OLD_SPIGPIODATA = io_inpb(GPIO3_DATA); io_outpb(GPIO3_DIR, (OLD_SPIGPIODIR & 0xf0) | 0x07); if ((SPISW_mode & SPIMODE_CPOL1) != 0) io_outpb(GPIO3_DATA, (OLD_SPIGPIODATA & 0xf0) + 0x03); // SPI_CLK = 1, SPI_CS = 1 else io_outpb(GPIO3_DATA, (OLD_SPIGPIODATA & 0xf0) + 0x01); // SPI_CLK = 0, SPI_CS = 1 OLD_SPIGPIODIR = OLD_SPIGPIODIR & 0x0f; OLD_SPIGPIODATA = OLD_SPIGPIODATA & 0x0f; // switch to GPIO interface OLD_SPIGPIO3FLAG = read_sb_reg(SB_MULTIFUNC_REG); write_sb_reg(SB_MULTIFUNC_REG, OLD_SPIGPIO3FLAG & 0xfffffffeL); OLD_SPIGPIO3FLAG = OLD_SPIGPIO3FLAG & 1L; SPISW_active = true; return true; }
static void set_rx_led(char port, char pin) { io_outpdw(gpio_config_addr + 0x00, io_inpdw(gpio_config_addr + 0x00) | 0x01L << port); // set data address if ((rx_led_data = io_inpw(gpio_config_addr + (4 + 4*port))) == 0x0000) io_outpw(gpio_config_addr + (4 + 4*port), (rx_led_data = (GPIO_BASE_ADDR + port))); // set direction address if ((rx_led_dir = io_inpw(gpio_config_addr + (6 + 4*port))) == 0x0000) io_outpw(gpio_config_addr + (6 + 4*port), (rx_led_dir = (GPIO_BASE_ADDR + port + 10))); // set RX LED pin -> OUT io_outpb(rx_led_dir, io_inpb(rx_led_dir) | (1 << pin)); rx_led_pin = pin; }
static void set_pin_in(char port, char pin) { io_outpdw(gpio_config_addr + 0x00, io_inpdw(gpio_config_addr + 0x00) | 0x01L << port); // set data address if ((usb_detect_data = io_inpw(gpio_config_addr + (4 + 4*port))) == 0x0000) io_outpw(gpio_config_addr + (4 + 4*port), (usb_detect_data = (GPIO_BASE_ADDR + port))); // set direction address if ((usb_detect_dir = io_inpw(gpio_config_addr + (6 + 4*port))) == 0x0000) io_outpw(gpio_config_addr + (6 + 4*port), (usb_detect_dir = (GPIO_BASE_ADDR + port + 10))); // set USB-Detect pin -> IN io_outpb(usb_detect_dir, io_inpb(usb_detect_dir) & ~(1 << pin)); usb_detect_pin = pin; }
DMPAPI(void) wdt_disable(void) { unsigned char val; if(wdt1_init_f == true) { val = io_inpb(0xa8); io_outpb(0xa8, val & (~0x40)); // reset bit 6 to disable WDT1 io_outpb(0xA8, WDT_t.ctrl_reg); io_outpb(0xA9, WDT_t.sigsel_reg); io_outpb(0xAA, WDT_t.count0_reg); io_outpb(0xAB, WDT_t.count1_reg); io_outpb(0xAC, WDT_t.count2_reg); io_outpb(0xAD, WDT_t.stat_reg); io_outpb(0xAE, WDT_t.reload_reg); wdt1_init_f = false; } }
// transmit or receive one bit for SPI software simulatived mode _RB_INLINE void sw_dataout(unsigned char val) { io_outpb(GPIO3_DATA, (io_inpb(GPIO3_DATA) & 0xf1) + val); }
RBAPI(void) i2c_ClearResetPin(void) { // clear the Reset pin on I2C connector of RB-110 & RB-050 to 0 if ((roboio_GetRBVer() != RB_110) && (roboio_GetRBVer() != RB_050)) return; io_outpb(GPIO2_DIR, io_inpb(GPIO2_DIR) | 0x80); io_outpb(GPIO2_DATA, io_inpb(GPIO2_DATA) & 0x7f); }
RBAPI(bool) i2c_Init2(unsigned baseaddr, unsigned devs, int i2c0irq, int i2c1irq) { int i; if (I2C_ioSection != -1) { err_SetMsg(ERROR_I2C_INUSE, "I2C lib was already opened"); return false; } if ((I2C_ioSection = io_Init()) == -1) return false; //NOTE: base address should be selected carefully to avoid conflicts with other devices! if (baseaddr != 0xffff) i2c_SetBaseAddress(baseaddr); else { if (i2c_SetDefaultBaseAddress() == 0x0000) i2c_SetBaseAddress(0xfb00); } #ifdef ROBOIO switch (roboio_GetRBVer()) { case RB_100b1: case RB_100b2: case RB_100b3: case RB_100: case RB_100RD: case RB_110: case RB_050: devs = devs & I2C_USEMODULE0; i2c1irq = I2CIRQ_DISABLE; break; default: devs = 0; i2c0irq = i2c1irq = I2CIRQ_DISABLE; break; } #endif i2c_SetIRQ(i2c0irq, i2c1irq); I2C_swMode[0] = I2C_swMode[1] = I2CSW_DISABLE; I2C_action[0] = I2C_action[1] = I2CACT_DISABLE; for (i=0; i<2; i++) { if ((i == 0) && ((devs & I2C_USEMODULE0) == 0)) continue; if ((i == 1) && ((devs & I2C_USEMODULE1) == 0)) continue; I2C_action[i] = I2CACT_IDLE; //switch GPIO/I2C pins into GPIO pins OLD_I2CGPIO3FLAG[i] = read_sb_reg(SB_IPFCTRL3_REG) & OLD_I2CGPIO3MASK[i]; //backup GPIO/I2C switch flag write_sb_reg(SB_IPFCTRL3_REG, read_sb_reg(SB_IPFCTRL3_REG) & (~OLD_I2CGPIO3MASK[i])); //send START & STOP signal to reset I2C devices OLD_I2CGPIO3DIR[i] = io_inpb(GPIO3_DIR) & (0x03 << (i*2+4)); //backup GPIO3 DIR OLD_I2CGPIO3VAL[i] = io_inpb(GPIO3_DATA) & (0x03 << (i*2+4)); //backup GPIO3 VAL //set_pins(i, 1, 1); delay_ms(1); //SCL = 1, SDA = 1; START //set_pins(i, 1, 0); delay_ms(1); //SCL = 1, SDA = 0 //set_pins(i, 0, 0); delay_ms(1); //SCL = 0, SDA = 0 //Note: if we send the above START, some I2C sensors, such as ADI ADXL345, may fail to respond //set_pins(i, 0, 0); delay_ms(1); //SCL = 0, SDA = 0; STOP //Note: if we perform the line above, some I2C sensors, such as MEMSIC MXC6202, may fail to respond //set_pins(i, 1, 0); delay_ms(1); //SCL = 1, SDA = 0 //set_pins(i, 1, 1); delay_ms(1); //SCL = 1, SDA = 1 //Note: the above lines work for all sensors we tested, but we disable them to avoid unexpected sensor behaviors if (i2c_Reset(i) == false) // assume the status of GPIO/I2C pins are GPIO "IN" or "OUT 1" { i2c_Close(); err_SetMsg(ERROR_I2C_INITFAIL, "can't reset the I2C modules"); return false; } i2c_DisableINT(i, I2CINT_ALL); i2c_ClearSTAT(i, I2CSTAT_ALL); //Remarks: for DX ver.2, we must disable the noise filter to ensure that 3.3Mbps works in high-speed mode i2c_DisableNoiseFilter(i); //i2c_EnableNoiseFilter(i); i2c_DisableStandardHSM(i); //SCL open-drain in high-speed mode //i2c_EnableStandardHSM(i); i2c_SetSpeed(i, I2CMODE_AUTO, 100000L); //default 100Kbps i2cslave_SetAddr(i, 0x7f); //set slave address 0x7F by default (change this if it collide with external I2C devices) i2cslave_EnableACK(i); //switch GPIO pins into I2C SCL,SDA pins //Remarks: Vortex86DX's H/W I2C has an issue here; if you call i2c_Reset() in case GPIO/SCL pin = GPIO out 0, // then, whenever you switch GPIO/SCL pin to SCL pin, the SCL pin always first send the 10 reset dummy clocks write_sb_reg(SB_IPFCTRL3_REG, read_sb_reg(SB_IPFCTRL3_REG) | OLD_I2CGPIO3MASK[i]); } return true; }
void WIFI_WriteCTRR(uint8_t data) { io_outpb(WIFI_SPI_IOaddr + 7, io_inpb(WIFI_SPI_IOaddr + 7) | data); }
void WIFI_Reset(void) { io_outpb(WIFI_SPI_IOaddr + 7, 0x01); while((io_inpb(WIFI_SPI_IOaddr + 7)&0x01) != 0); // wait SPI reset for complete }