uint8_t read_i2c_address(void){ uint32_t config = MUX_GPIO | PULL_UP; uint8_t addr = 0; ADDR_BIT0_CTRL = config; ADDR_BIT1_CTRL = config; ADDR_BIT2_CTRL = config; ADDR_BIT3_CTRL = config; ADDR_BIT0_PORT(DDR) &= ~ADDR_BIT0_BIT; ADDR_BIT1_PORT(DDR) &= ~ADDR_BIT1_BIT; ADDR_BIT2_PORT(DDR) &= ~ADDR_BIT2_BIT; ADDR_BIT3_PORT(DDR) &= ~ADDR_BIT3_BIT; delay_microseconds(1); // Probably not needed, but wait for things to stabilize addr |= (ADDR_BIT0_PORT(DIR) & ADDR_BIT0_BIT) ? 0 : 1; addr |= (ADDR_BIT1_PORT(DIR) & ADDR_BIT1_BIT) ? 0 : 2; addr |= (ADDR_BIT2_PORT(DIR) & ADDR_BIT2_BIT) ? 0 : 4; addr |= (ADDR_BIT3_PORT(DIR) & ADDR_BIT3_BIT) ? 0 : 8; config = MUX_GPIO | PULL_NONE; ADDR_BIT0_CTRL = config; ADDR_BIT1_CTRL = config; ADDR_BIT2_CTRL = config; ADDR_BIT3_CTRL = config; return addr; }
void ow_write_bit(unsigned char bit) { if (!bit) { ow_drive_low(); delay_microseconds(OW_C); ow_release(); delay_microseconds(OW_D); } else { ow_drive_low(); delay_microseconds(OW_A); ow_release(); delay_microseconds(OW_B); } }
unsigned char ow_read_bit() { unsigned char bit; ow_drive_low(); delay_microseconds(OW_A); ow_release(); delay_microseconds(OW_E); if (ONEWIRE_PORTIN & ONEWIRE_PINMASK){ bit = 1; } else { bit = 0; } delay_microseconds(OW_F); return(bit); }
void ow_write_byte(unsigned char data) { unsigned char bitcount; for(bitcount=8; bitcount>0; bitcount--) { if (data & 0x01) { ow_drive_low(); delay_microseconds(OW_A); ow_release(); delay_microseconds(OW_B); } else { ow_drive_low(); delay_microseconds(OW_C); ow_release(); delay_microseconds(OW_D); } data = data >> 1; } }
int ow_reset() { int presence; delay_microseconds( OW_G ); ow_drive_low(); delay_microseconds( OW_H ); ow_release(); delay_microseconds( OW_I ); if(ONEWIRE_PORTIN & ONEWIRE_PINMASK ) { presence = 0; // bus is high, slave did not pull it down } else { presence = 1; // bus is being pulled down, presence detected } delay_microseconds( OW_J ); return ( presence ); // return the sampled presence pulse result }
unsigned char ow_read_byte() { unsigned char data=0; unsigned char bitcount, bit; for ( bitcount=8; bitcount>0; bitcount-- ) { ow_drive_low(); delay_microseconds(OW_A); ow_release(); delay_microseconds(OW_E); if (ONEWIRE_PORTIN & ONEWIRE_PINMASK){ bit = 1; } else { bit = 0; } delay_microseconds(OW_F); //on 1-wire bus data is sent starting with least significant bit. We need to inert bits from the left and shift. data = data >> 1; data |= (bit << 7); } return(data); }
HD44780_Result hd44780_init(HD44780 *display, HD44780_Mode mode, const HD44780_Config *config, uint8_t cols, uint8_t lines, uint8_t charsize) { HD44780_RETURN_ASSERT(display != NULL, HD44780_RESULT_ERROR); HD44780_RETURN_ASSERT(config != NULL, HD44780_RESULT_ERROR); HD44780_RETURN_ASSERT(config->gpios != NULL, HD44780_RESULT_ERROR); HD44780_RETURN_ASSERT(config->gpios->write != NULL, HD44780_RESULT_ERROR); HD44780_RETURN_ASSERT(config->delay_microseconds != NULL, HD44780_RESULT_ERROR); HD44780_RETURN_ASSERT(cols > 0, HD44780_RESULT_ERROR); HD44780_RETURN_ASSERT(lines > 0, HD44780_RESULT_ERROR); display->cfg = *config; HD44780_GPIO_Interface *const gpios = display->cfg.gpios; HD44780_DelayMicrosecondsFn delay_microseconds = display->cfg.delay_microseconds; if (gpios->configure != NULL) { HD44780_RETURN_IF_ERROR(gpios->configure(gpios, HD44780_PIN_RS, HD44780_PINMODE_OUTPUT)); HD44780_RETURN_IF_ERROR(gpios->configure(gpios, HD44780_PIN_ENABLE, HD44780_PINMODE_OUTPUT)); if (display->cfg.options & HD44780_OPT_USE_RW) HD44780_RETURN_IF_ERROR(gpios->configure(gpios, HD44780_PIN_RW, HD44780_PINMODE_OUTPUT)); if (display->cfg.options & HD44780_OPT_USE_BACKLIGHT) HD44780_RETURN_IF_ERROR(gpios->configure(gpios, HD44780_PIN_BACKLIGHT, HD44780_PINMODE_OUTPUT)); } if (display->cfg.options & HD44780_OPT_USE_BACKLIGHT) HD44780_RETURN_IF_ERROR(gpios->write(gpios, HD44780_PIN_BACKLIGHT, HD44780_PINSTATE_LOW)); if (mode == HD44780_MODE_4BIT) { display->displayfunction = HD44780_FLAG_4BITMODE | HD44780_FLAG_1LINE | HD44780_FLAG_5x8DOTS; display->dp_first = HD44780_PIN_DP4; display->dp_amount = 4; } else { display->displayfunction = HD44780_FLAG_8BITMODE | HD44780_FLAG_1LINE | HD44780_FLAG_5x8DOTS; display->dp_first = HD44780_PIN_DP0; display->dp_amount = 8; } /* For some 1 line displays you can select a 10 pixel high font */ if ((charsize != 0) && (lines == 1)) display->displayfunction |= HD44780_FLAG_5x10DOTS; if (lines > 1) display->displayfunction |= HD44780_FLAG_2LINE; display->columns_amount = cols; display->lines_amount = lines; display->currline = 0; if (hd44780_config(display) != HD44780_RESULT_OK) return HD44780_RESULT_ERROR; /* Put the LCD into 4 bit or 8 bit mode */ if (! (display->displayfunction & HD44780_FLAG_8BITMODE)) { /* This is according to the hitachi HD44780 datasheet figure 24, pg 46 */ /* We start in 8bit mode, try to set 4 bit mode */ HD44780_RETURN_IF_ERROR(hd44780_write_bits(display, 0x03)); delay_microseconds(4500); // wait min 4.1ms /* Second try */ HD44780_RETURN_IF_ERROR(hd44780_write_bits(display, 0x03)); delay_microseconds(4500); // wait min 4.1ms /* Third go! */ HD44780_RETURN_IF_ERROR(hd44780_write_bits(display, 0x03)); delay_microseconds(150); /* Finally, set to 4-bit interface */ HD44780_RETURN_IF_ERROR(hd44780_write_bits(display, 0x02)); } else { /* This is according to the hitachi HD44780 datasheet page 45 figure 23 */ /* Send function set command sequence */ HD44780_RETURN_IF_ERROR(hd44780_command(display, HD44780_CMD_FUNCTIONSET | display->displayfunction)); delay_microseconds(4500); // wait more than 4.1ms /* Second try */ HD44780_RETURN_IF_ERROR(hd44780_command(display, HD44780_CMD_FUNCTIONSET | display->displayfunction)); delay_microseconds(150); /* Third go */ HD44780_RETURN_IF_ERROR(hd44780_command(display, HD44780_CMD_FUNCTIONSET | display->displayfunction)); } /* Finally, set # lines, font size, etc. */ HD44780_RETURN_IF_ERROR(hd44780_command(display, HD44780_CMD_FUNCTIONSET | display->displayfunction)); /* Turn the display on with no cursor or blinking default */ display->displaycontrol = HD44780_FLAG_DISPLAYON | HD44780_FLAG_CURSOROFF | HD44780_FLAG_BLINKOFF; HD44780_RETURN_IF_ERROR(hd44780_display_on(display)); /* Clear it off */ HD44780_RETURN_IF_ERROR(hd44780_clear(display)); /* Initialize to default text direction (for romance languages) */ display->displaymode = HD44780_FLAG_ENTRYLEFT | HD44780_FLAG_ENTRYSHIFTDECREMENT; /* Set the entry mode */ HD44780_RETURN_IF_ERROR(hd44780_command(display, HD44780_CMD_ENTRYMODESET | display->displaymode)); return HD44780_RESULT_OK;
void reset() { phy_reset(); // device reset - the RST bit is self-clearing ioreg(reg::CTRL, ioreg(reg::CTRL) | CTRL_RST); for (int timeout = 0; ; ++timeout) { REQUIRE(timeout < 1000 && "Failed to reset i825x device"); delay_microseconds(2); // Need to delay at least 1us before reading status after a reset if (!(ioreg(reg::CTRL) & CTRL_RST)) { break; } } // LRST->0 enables auto-negotiation, clear ILOS and disable VLAN Mode Enable ioreg(reg::CTRL, (ioreg(reg::CTRL) & ~(CTRL_LRST | CTRL_ILOS | CTRL_VME)) | CTRL_ASDE | CTRL_SLU); // TODO: Reset flow control // TODO: Clear statistics counters // Program the Receive Address Register ioreg(reg::RAL0, (mac_addr_[0]) | (mac_addr_[1] << 8) | (mac_addr_[2] << 16) | (mac_addr_[3] << 24)); ioreg(reg::RAH0, (mac_addr_[4]) | (mac_addr_[5] << 8) | RAH_AV); // Initialize the MTA (Multicast Table Array) to 0 for (int i = 0; i < 128; i++) { ioreg(static_cast<reg>(static_cast<uint32_t>(reg::MTA) + i * 4), 0); } // Program the Interrupt Mask Set/Read (IMS) register ioreg(reg::IMC, ~0U); // Inhibit interrupts ioreg(reg::ICR, ~0U); // Clear pending interrupts ioreg(reg::IMS, ICR_TXDW | ICR_LSC | ICR_RXDMT0 | ICR_RXT0); // Enable interrupts // Program the Receive Descriptor Base Address const uint64_t rx_desc_phys = virt_to_phys((const void*)&rx_desc_[0]); ioreg(reg::RDBAL0, static_cast<uint32_t>(rx_desc_phys)); ioreg(reg::RDBAH0, static_cast<uint32_t>(rx_desc_phys>>32)); // Set the Receive Descriptor Length (RDLEN) register to the size (in bytes) of the descriptor ring. ioreg(reg::RDLEN0, sizeof(rx_desc_)); // Initialize Receive Descriptor Head and Tail registers ioreg(reg::RDH0, 0); ioreg(reg::RDT0, num_rx_descriptors-1); memset((void*)rx_desc_, 0, sizeof(rx_desc_)); for (uint32_t i = 0; i < num_rx_descriptors; ++i) { rx_desc_[i].buffer_addr = virt_to_phys(rx_buffer_[i]); rx_desc_[i].status = 0; } // Enable RX ioreg(reg::RCTL, RCTL_EN | RCTL_SBP // recieve everyting | RCTL_UPE // even | RCTL_MPE // bad packets | RCTL_BAM // and multicast.. | RCTL_SZ_2048); rx_head_ = 0; // Enable TX memset((void*)tx_desc_, 0, sizeof(tx_desc_)); const uint64_t tx_desc_phys = virt_to_phys((const void*)&tx_desc_[0]); REQUIRE((tx_desc_phys & 15) == 0); ioreg(reg::TDBAL0, static_cast<uint32_t>(tx_desc_phys)); ioreg(reg::TDBAH0, static_cast<uint32_t>(tx_desc_phys>>32)); ioreg(reg::TDLEN0, sizeof(tx_desc_)); static_assert(sizeof(tx_desc_) % 128 == 0, ""); static_assert(sizeof(tx_desc_) >= 128, ""); // Set the transmit descriptor write-back policy ioreg(reg::TXDCTL0, (ioreg(reg::TXDCTL0) & TXDCTL_WTHRESH) | TXDCTL_FULL_TX_DESC_WB/* | TXDCTL_COUNT_DESC*/); ioreg(reg::TDH0, 0); ioreg(reg::TDT0, 0); ioreg(reg::TCTL, ioreg(reg::TCTL) | TCTL_EN | TCTL_PSP); tx_tail_ = 0; }
void phy_reset() { const auto orig = ioreg(reg::CTRL); ioreg(reg::CTRL, orig | CTRL_RST | CTRL_PHY_RST); delay_microseconds(4); // Should be held high for at least 3 us. NOTE: Should be held high for 10ms(!) for 82546GB ioreg(reg::CTRL, orig & ~CTRL_PHY_RST); }
void delay_miliseconds(unsigned int miliseconds){ for(;miliseconds>0;miliseconds--){ delay_microseconds(1000); } }