Protect custom form from SQL injection

Yes, $wpdb->update is sufficient protection. You should not escape or prepare the data.

From the documentation of wpdb:

data (array) Data to update (in column => value pairs). Both $data
columns and $data values should be “raw” (neither should be SQL
escaped). This means that if you are using GET or POST data you may
need to use stripslashes() to avoid slashes ending up in the database.

As a side note, you can help wordpress better understand the content to prepare for the database by including format and where_format in your update call.

$uptable = $mydb->update(
    'table',
    $updatevalues,
    $where_data,
    $data_format, // '%d' for numbers, '%s' for strings, can be an array
    $where_format // Same here
);

Update: In reply to your comment:

It depends on the data you are saving and its purpose.

Your next step after SQL injection is to prevent XSS attacks. This is where a user is able to enter malicious Javascript into your text field, and the database saves it and then your site happens to display it to other users.

While this can be prevented by using esc_html() when displaying the content from the database, it’s better not to have that stuff in the database in the first place!

As for the code to do this, it would look like this:

$user_value = stripslashes($_POST['user_value']);
$user_value = sanitize_text_field($user_value);
$user_data = array('table_column' => $user_value);
$user_format = array('%s'); // Means $user_value is a string
$where_data = array('id' => 5); // example
$where_format = array('%d'); // Means 'id' is a number
$mydb->update(
    'table',
    $user_data,
    $where_data,
    $user_format,
    $where_format
);

And if you only want that data to be alpha numeric, you could wrap the code after stripslashes with if(ctype_alnum($user_value)). Ultimately you only want the exact data you need and nothing more.

Hope that helps!