(command: u16, command_version: u8, data: &[u8])
| 243 | } |
| 244 | |
| 245 | pub fn send_command(command: u16, command_version: u8, data: &[u8]) -> EcResult<Vec<u8>> { |
| 246 | if !init() { |
| 247 | return Err(EcError::DeviceError("Failed to initialize".to_string())); |
| 248 | } |
| 249 | let request = EcHostRequest { |
| 250 | struct_version: EC_HOST_REQUEST_VERSION, |
| 251 | checksum: 0, |
| 252 | command, |
| 253 | // TODO: Has optional dev_index that we could consider |
| 254 | // rq.command = cec_command->cmd_code |(uint16_t) EC_CMD_PASSTHRU_OFFSET(cec_command->cmd_dev_index); |
| 255 | command_version, |
| 256 | reserved: 0, |
| 257 | data_len: data.len().try_into().unwrap(), |
| 258 | }; |
| 259 | let request_buffer = pack_request(request, data); |
| 260 | |
| 261 | // Transfer data first, once ready |
| 262 | if log_enabled!(Level::Trace) { |
| 263 | println!("Waiting to be ready"); |
| 264 | } |
| 265 | wait_for_ready(); |
| 266 | if log_enabled!(Level::Trace) { |
| 267 | print!("Ready, transferring request buffer: "); |
| 268 | } |
| 269 | if log_enabled!(Level::Trace) { |
| 270 | util::print_buffer(&request_buffer); |
| 271 | } |
| 272 | transfer_write(&request_buffer); |
| 273 | |
| 274 | // Set the command version |
| 275 | Pio::<u8>::new(EC_LPC_ADDR_HOST_CMD).write(EC_COMMAND_PROTOCOL_3); |
| 276 | wait_for_ready(); |
| 277 | let res = Pio::<u8>::new(EC_LPC_ADDR_HOST_DATA).read(); |
| 278 | match FromPrimitive::from_u8(res) { |
| 279 | None => return Err(EcError::UnknownResponseCode(res as u32)), |
| 280 | Some(EcResponseStatus::Success) => {} |
| 281 | Some(status) => return Err(EcError::Response(status)), |
| 282 | } |
| 283 | |
| 284 | // Read response |
| 285 | let resp_hdr_buffer = transfer_read( |
| 286 | EC_LPC_ADDR_HOST_ARGS, |
| 287 | 0, |
| 288 | std::mem::size_of::<EcHostResponse>() as u16, |
| 289 | ); |
| 290 | let resp_header = unpack_response_header(&resp_hdr_buffer); |
| 291 | // TODO: I think we're already covered by checking res above |
| 292 | // But this seems also to be the EC reponse code, so make sure it's 0 (Success) |
| 293 | assert_eq!( |
| 294 | FromPrimitive::from_u16(resp_header.result), |
| 295 | Some(EcResponseStatus::Success) |
| 296 | ); |
| 297 | |
| 298 | if resp_header.struct_version != EC_HOST_RESPONSE_VERSION { |
| 299 | return Err(EcError::DeviceError(format!( |
| 300 | "Struct version invalid. Should be {:#X}, is {:#X}", |
| 301 | EC_HOST_RESPONSE_VERSION, resp_header.struct_version |
| 302 | ))); |
no test coverage detected