!
        @brief Flash a portion of a page.
        
        @exception FlashFailure The address or data length is not aligned to the minimum
            programming length specified in the flash algorithm.
        @exception FlashProgramFailure

def program_phrase(self, address, bytes):
        """!
        @brief Flash a portion of a page.
        
        @exception FlashFailure The address or data length is not aligned to the minimum
            programming length specified in the flash algorithm.
        @exception FlashProgramFailure
        """
        assert self._active_operation == self.Operation.PROGRAM

        # Get min programming length. If one was not specified, use the page size.
        if self.min_program_length:
            min_len = self.min_program_length
        else:
            min_len = self.get_page_info(address).size

        # Require write address and length to be aligned to min write size.
        if flashPtr % min_len:
            raise FlashFailure("unaligned flash write address")
        if len(bytes) % min_len:
            raise FlashFailure("phrase length is unaligned or too small")

        # prevent security settings from locking the device
        bytes = self.override_security_bits(address, bytes)

        # first transfer in RAM
        self.target.write_memory_block8(self.begin_data, bytes)

        # update core register to execute the program_page subroutine
        result = self._call_function_and_wait(self.flash_algo['pc_program_page'], address, len(bytes), self.begin_data)

        # check the return code
        if result != 0:
            raise FlashProgramFailure('program_phrase(0x%x) error: %i' % (address, result), address, result)