Загрузка данных


bool axi_iic_bus::send(i2c_address_type i2c_addr, size_t size, const uint8_t* data)
{
     register_value_type  interrupt_status;
     register_value_type  control;

     write_register(Register::TxFifo, (i2c_addr << 1) | 0);

     interrupt_status  = read_register(Register::InterruptStatus);
     interrupt_status &= InterruptStatusBit::TransmitComplete |
                         InterruptStatusBit::TransmitError |
                         InterruptStatusBit::ArbitrationLost;

     write_register(Register::InterruptStatus, interrupt_status);

     control = ControlBit::TransmitModeSelect |
               ControlBit::MasterModeSelect |
               ControlBit::Enable;

     write_register(Register::Control, control);

     if (!wait_busy())
     {
          reset();
          return false;
     }

     interrupt_status  = read_register(Register::InterruptStatus);
     interrupt_status &= InterruptStatusBit::BusNotBusy;

     write_register(Register::InterruptStatus, interrupt_status);

     while (size--)
     {
          do
          {
               interrupt_status  = read_register(Register::InterruptStatus);
               interrupt_status &= InterruptStatusBit::BusNotBusy |
                                   InterruptStatusBit::TransmitComplete |
                                   InterruptStatusBit::TransmitError |
                                   InterruptStatusBit::ArbitrationLost;
          } while (!interrupt_status);

          if (interrupt_status & ~InterruptStatusBit::TransmitComplete)
          {
               reset();
               return false;
          }

          if (!size)
          {
               control  = read_register(Register::Control);
               control &= ~ControlBit::MasterModeSelect;

               write_register(Register::Control, control);
          }

          write_register(Register::TxFifo, *data++);

          write_register(Register::InterruptStatus, interrupt_status);
     }

     do
     {
          interrupt_status  = read_register(Register::InterruptStatus);
          interrupt_status &= InterruptStatusBit::BusNotBusy |
                              InterruptStatusBit::TransmitError |
                              InterruptStatusBit::ArbitrationLost;
     } while (!interrupt_status);

     if (interrupt_status & ~InterruptStatusBit::BusNotBusy)
     {
          reset();
          return false;
     }

     return true;
}