diff --git a/src/core0_audio.rs b/src/core0_audio.rs index 140da49..1de67b2 100644 --- a/src/core0_audio.rs +++ b/src/core0_audio.rs @@ -67,7 +67,7 @@ pub fn audio_task( i2c_config: I2CConfig, clock_freq: u32, timer: &mut Timer, - pins: Core1Pins, + // pins: Core1Pins, gpio0: rp2040_hal::gpio::Pin< rp2040_hal::gpio::bank0::Gpio0, rp2040_hal::gpio::FunctionNull, @@ -85,66 +85,28 @@ pub fn audio_task( FunctionSio, PullDown, >, + + device_config: DeviceConfig, + flash_storage: &mut OnboardFlash, + pi_spi: &mut ExtSpiTransfers, ) -> ! { watchdog.feed(); let core = unsafe { pac::CorePeripherals::steal() }; let mut peripherals: Peripherals = unsafe { Peripherals::steal() }; - let sio = Sio::new(peripherals.SIO); let dma_channels = peripherals.DMA.split(&mut peripherals.RESETS); - // init flash - let mut flash_page_buf = [0xffu8; 4 + 2048 + 128]; - let mut flash_page_buf_2 = [0xffu8; 4 + 2048 + 128]; - let flash_page_buf = unsafe { extend_lifetime_generic_mut(&mut flash_page_buf) }; - let flash_page_buf_2 = unsafe { extend_lifetime_generic_mut(&mut flash_page_buf_2) }; - - let mut flash_storage = OnboardFlash::new( - pins.fs_cs, - pins.fs_mosi, - pins.fs_clk, - pins.fs_miso, - flash_page_buf, - flash_page_buf_2, - dma_channels.ch1, - dma_channels.ch2, - true, - None, - ); - - let mut payload_buf = [0x42u8; 2066]; - let payload_buf = unsafe { extend_lifetime_generic_mut(&mut payload_buf) }; - let mut crc_buf = [0x42u8; 32 + 104]; - let crc_buf = unsafe { extend_lifetime_generic_mut(&mut crc_buf) }; - let (pio0, sm0, _, _, _) = peripherals.PIO0.split(&mut peripherals.RESETS); - let mut pi_spi = ExtSpiTransfers::new( - pins.pi_mosi, - pins.pi_cs, - pins.pi_clk, - pins.pi_miso, - pins.pi_ping, - dma_channels.ch0, - payload_buf, - crc_buf, - pio0, - sm0, - ); let mut peripherals = unsafe { Peripherals::steal() }; watchdog.feed(); - flash_storage.take_spi(peripherals.SPI1, &mut peripherals.RESETS, clock_freq.Hz()); - flash_storage.init(); - - let mut device_config = - DeviceConfig::load_existing_config_from_flash(&mut flash_storage).unwrap(); let (pio1, _, sm1, _, _) = peripherals.PIO1.split(&mut peripherals.RESETS); let mut delay = Delay::new(core.SYST, clock_freq); let mut shared_i2c = SharedI2C::new(i2c_config, unlocked_pin, &mut delay); let mut synced_date_time = SyncedDateTime::default(); - let mut event_logger: EventLogger = EventLogger::new(&mut flash_storage); + let mut event_logger: EventLogger = EventLogger::new(flash_storage); match shared_i2c.get_datetime(&mut delay) { Ok(now) => { @@ -154,7 +116,7 @@ pub fn audio_task( //cant get time so use 0 and add a time when tc2-agent uploads event_logger.log_event( LoggerEvent::new(LoggerEventKind::RtcCommError, 0), - &mut flash_storage, + flash_storage, ); panic!("Unable to get DateTime from RTC {}", e) } @@ -166,7 +128,7 @@ pub fn audio_task( LoggerEventKind::Rp2040WokenByAlarm, synced_date_time.get_timestamp_micros(&timer), ), - &mut flash_storage, + flash_storage, ); } @@ -204,61 +166,61 @@ pub fn audio_task( let mut alarm_date_time: Option = None; //do this so tc2-agent knows whats going on - let (new_config, device_config_was_updated) = - get_existing_device_config_or_config_from_pi_on_initial_handshake( - &mut flash_storage, - &mut pi_spi, - &mut peripherals.RESETS, - &mut peripherals.DMA, - clock_freq.Hz(), - 2u32, //need to get radiometry and leton serial - 1, - true, - timer, - Some(device_config), - ); - device_config = new_config.unwrap(); - - if device_config_was_updated { - event_logger.log_event( - LoggerEvent::new( - LoggerEventKind::SavedNewConfig, - synced_date_time.get_timestamp_micros(&timer), - ), - &mut flash_storage, - ); - } + // let (new_config, device_config_was_updated) = + // get_existing_device_config_or_config_from_pi_on_initial_handshake( + // flash_storage, + // pi_spi, + // &mut peripherals.RESETS, + // &mut peripherals.DMA, + // clock_freq.Hz(), + // 2u32, //need to get radiometry and leton serial + // 1, + // true, + // timer, + // Some(device_config), + // ); + // device_config = new_config.unwrap(); + + // if device_config_was_updated { + // event_logger.log_event( + // LoggerEvent::new( + // LoggerEventKind::SavedNewConfig, + // synced_date_time.get_timestamp_micros(&timer), + // ), + // flash_storage, + // ); + // } if !user_recording_requested { - if device_config_was_updated { - let reboot; - - if device_config.config().is_audio_device() && !thermal_requested_audio { - if let AudioMode::AudioOnly = device_config.config().audio_mode { - reboot = false; - } else { - let in_window = device_config - .time_is_in_recording_window(&synced_date_time.date_time_utc, &None); - reboot = in_window; - } - } else { - reboot = !device_config.config().is_audio_device() - } - - if reboot { - let _ = shared_i2c.disable_alarm(&mut delay); - clear_audio_alarm(&mut flash_storage); - info!("Restarting as should be in thermal mode"); - restart(watchdog); - } - } + // if device_config_was_updated { + // let reboot; + + // if device_config.config().is_audio_device() && !thermal_requested_audio { + // if let AudioMode::AudioOnly = device_config.config().audio_mode { + // reboot = false; + // } else { + // let in_window = device_config + // .time_is_in_recording_window(&synced_date_time.date_time_utc, &None); + // reboot = in_window; + // } + // } else { + // reboot = !device_config.config().is_audio_device() + // } + + // if reboot { + // let _ = shared_i2c.disable_alarm(&mut delay); + // clear_audio_alarm(flash_storage); + // info!("Restarting as should be in thermal mode"); + // restart(watchdog); + // } + // } //this isn't reliable so use alarm stored in flash // let mut alarm_hours = shared_i2c.get_alarm_hours(); // let mut alarm_minutes = shared_i2c.get_alarm_minutes(); let mut scheduled: bool = false; - let (_, flash_alarm) = get_audio_alarm(&mut flash_storage); + let (_, flash_alarm) = get_audio_alarm(flash_storage); if let Some(alarm) = flash_alarm { scheduled = true; info!( @@ -269,20 +231,20 @@ pub fn audio_task( alarm.hour(), alarm.minute(), ); - if device_config_was_updated { - if check_alarm_still_valid( - &alarm, - &synced_date_time.get_adjusted_dt(timer), - &device_config, - ) { - alarm_date_time = Some(alarm); - } else { - //if window time changed and alarm is after rec window start - clear_audio_alarm(&mut flash_storage); - scheduled = false; - info!("Rescehduling as alarm is after window start"); - } - } + // if device_config_was_updated { + // if check_alarm_still_valid( + // &alarm, + // &synced_date_time.get_adjusted_dt(timer), + // &device_config, + // ) { + // alarm_date_time = Some(alarm); + // } else { + // //if window time changed and alarm is after rec window start + // clear_audio_alarm(flash_storage); + // scheduled = false; + // info!("Rescehduling as alarm is after window start"); + // } + // } } else { error!("Not scheduled"); } @@ -292,7 +254,7 @@ pub fn audio_task( LoggerEventKind::AudioMode, synced_date_time.get_timestamp_micros(&timer), ), - &mut flash_storage, + flash_storage, ); // Unset the is_recording flag on attiny on startup if let Ok(is_recording) = shared_i2c.get_is_recording(&mut delay) { @@ -302,7 +264,7 @@ pub fn audio_task( LoggerEventKind::RecordingNotFinished, synced_date_time.get_timestamp_micros(&timer), ), - &mut flash_storage, + flash_storage, ); } } @@ -330,7 +292,7 @@ pub fn audio_task( LoggerEventKind::ToldRpiToWake(WakeReason::AudioThermalEnded), synced_date_time.get_timestamp_micros(&timer), ), - &mut flash_storage, + flash_storage, ); } } @@ -339,7 +301,7 @@ pub fn audio_task( } if !should_wake { should_wake = should_offload_audio_recordings( - &mut flash_storage, + flash_storage, &mut event_logger, &mut delay, &mut shared_i2c, @@ -351,7 +313,7 @@ pub fn audio_task( LoggerEventKind::ToldRpiToWake(WakeReason::AudioShouldOffload), synced_date_time.get_timestamp_micros(&timer), ), - &mut flash_storage, + flash_storage, ); } }; @@ -359,8 +321,8 @@ pub fn audio_task( match offload( &mut shared_i2c, clock_freq, - &mut flash_storage, - &mut pi_spi, + flash_storage, + pi_spi, timer, &mut event_logger, should_wake, @@ -400,7 +362,7 @@ pub fn audio_task( LoggerEventKind::Rp2040MissedAudioAlarm(alarm.timestamp_micros() as u64), synced_date_time.get_timestamp_micros(&timer), ), - &mut flash_storage, + flash_storage, ); recording_type = Some(RecordingType::ScheduledRecording); } @@ -431,7 +393,7 @@ pub fn audio_task( LoggerEventKind::StartedAudioRecording, synced_date_time.get_timestamp_micros(&timer), ), - &mut flash_storage, + flash_storage, ); let recorded = microphone.record_for_n_seconds( @@ -441,7 +403,7 @@ pub fn audio_task( timer, &mut peripherals.RESETS, peripherals.SPI1, - &mut flash_storage, + flash_storage, timestamp, watchdog, &synced_date_time, @@ -456,7 +418,7 @@ pub fn audio_task( LoggerEventKind::AudioRecordingFailed, synced_date_time.get_timestamp_micros(&timer), ), - &mut flash_storage, + flash_storage, ); info!("Recording failed restarting and will try again"); restart(watchdog); @@ -466,7 +428,7 @@ pub fn audio_task( LoggerEventKind::EndedRecording, synced_date_time.get_timestamp_micros(&timer), ), - &mut flash_storage, + flash_storage, ); match recording_type.as_mut().unwrap() { RecordingType::LongRecording | RecordingType::TestRecording => { @@ -493,8 +455,8 @@ pub fn audio_task( let mut peripherals: Peripherals = unsafe { Peripherals::steal() }; offload_flash_storage_and_events( - &mut flash_storage, - &mut pi_spi, + flash_storage, + pi_spi, &mut peripherals.RESETS, &mut peripherals.DMA, clock_freq, @@ -512,7 +474,7 @@ pub fn audio_task( _ => { shared_i2c.clear_alarm(&mut delay); reschedule = true; - clear_audio_alarm(&mut flash_storage); + clear_audio_alarm(flash_storage); if thermal_requested_audio { //if audio requested from thermal, the alarm will be re scheduled there let _ = shared_i2c.tc2_agent_clear_and_set_flag( @@ -539,7 +501,7 @@ pub fn audio_task( &mut delay, &synced_date_time, &mut shared_i2c, - &mut flash_storage, + flash_storage, timer, &mut event_logger, &device_config, @@ -547,7 +509,7 @@ pub fn audio_task( alarm_date_time = Some(scheduled_time); } else { error!("Couldn't schedule alarm will restart"); - clear_audio_alarm(&mut flash_storage); + clear_audio_alarm(flash_storage); restart(watchdog); } } @@ -575,7 +537,7 @@ pub fn audio_task( LoggerEventKind::ToldRpiToSleep, synced_date_time.get_timestamp_micros(&timer), ), - &mut flash_storage, + flash_storage, ); logged_power_down = true; } @@ -604,7 +566,7 @@ pub fn audio_task( LoggerEventKind::Rp2040Sleep, synced_date_time.get_timestamp_micros(&timer), ), - &mut flash_storage, + flash_storage, ); if let Ok(_) = shared_i2c.tell_attiny_to_power_down_rp2040(&mut delay) { @@ -619,8 +581,8 @@ pub fn audio_task( match offload( &mut shared_i2c, clock_freq, - &mut flash_storage, - &mut pi_spi, + flash_storage, + pi_spi, timer, &mut event_logger, false, diff --git a/src/core1_task.rs b/src/core1_task.rs index 3ad9557..f832afa 100644 --- a/src/core1_task.rs +++ b/src/core1_task.rs @@ -231,17 +231,25 @@ impl SyncedDateTime { } pub fn core_1_task( + mut pi_spi: ExtSpiTransfers, + mut flash_storage: OnboardFlash, frame_buffer_local: &'static Mutex>>, frame_buffer_local_2: &'static Mutex>>, clock_freq: u32, - pins: Core1Pins, + // pins: Core1Pins, i2c_config: I2CConfig, unlocked_pin: Pin, PullDown>, lepton_serial: Option, lepton_firmware_version: Option<((u8, u8, u8), (u8, u8, u8))>, woken_by_alarm: bool, mut timer: Timer, + device_config: DeviceConfig, ) { + info!( + "core1 address is {:#x}", + *pi_spi.payload_buffer.as_mut().unwrap() as *const _ as usize + ); + let dev_mode = false; info!("=== Core 1 start ==="); if dev_mode { @@ -249,61 +257,24 @@ pub fn core_1_task( } else { warn!("FIELD MODE"); } + let another_v = false; + info!( + "dev mode address is {:#x} {:#x}", + &dev_mode as *const _ as usize, &another_v as *const _ as usize + ); let mut synced_date_time = SyncedDateTime::default(); - let mut crc_buf = [0x42u8; 32 + 104]; - let mut payload_buf = [0x42u8; 2066]; - let mut flash_page_buf = [0xffu8; 4 + 2048 + 128]; - let mut flash_page_buf_2 = [0xffu8; 4 + 2048 + 128]; - let crc_buf = unsafe { extend_lifetime_generic_mut(&mut crc_buf) }; - let payload_buf = unsafe { extend_lifetime_generic_mut(&mut payload_buf) }; - let flash_page_buf = unsafe { extend_lifetime_generic_mut(&mut flash_page_buf) }; - let flash_page_buf_2 = unsafe { extend_lifetime_generic_mut(&mut flash_page_buf_2) }; - let mut peripherals = unsafe { Peripherals::steal() }; - let dma_channels = peripherals.DMA.split(&mut peripherals.RESETS); let mut peripherals = unsafe { Peripherals::steal() }; let core = unsafe { pac::CorePeripherals::steal() }; let mut delay = Delay::new(core.SYST, clock_freq); let mut sio = Sio::new(peripherals.SIO); let mut shared_i2c = SharedI2C::new(i2c_config, unlocked_pin, &mut delay); - let (pio0, sm0, _, _, _) = peripherals.PIO0.split(&mut peripherals.RESETS); + // let (pio0, sm0, _, _, _) = peripherals.PIO0.split(&mut peripherals.RESETS); let should_record_to_flash = true; - let mut pi_spi = ExtSpiTransfers::new( - pins.pi_mosi, - pins.pi_cs, - pins.pi_clk, - pins.pi_miso, - pins.pi_ping, - dma_channels.ch0, - payload_buf, - crc_buf, - pio0, - sm0, - ); - - let mut spi_peripheral = Some(peripherals.SPI1); - let mut flash_storage = OnboardFlash::new( - pins.fs_cs, - pins.fs_mosi, - pins.fs_clk, - pins.fs_miso, - flash_page_buf, - flash_page_buf_2, - dma_channels.ch1, - dma_channels.ch2, - should_record_to_flash, - None, - ); { - flash_storage.take_spi( - spi_peripheral.take().unwrap(), - &mut peripherals.RESETS, - clock_freq.Hz(), - ); - flash_storage.init(); if flash_storage.has_files_to_offload() { info!("Finished scan, has files to offload"); } @@ -375,28 +346,28 @@ pub fn core_1_task( let radiometry_enabled = sio.fifo.read_blocking(); info!("Core 1 got radiometry enabled: {}", radiometry_enabled == 2); let lepton_version = if radiometry_enabled == 2 { 35 } else { 3 }; - let existing_config = DeviceConfig::load_existing_config_from_flash(&mut flash_storage); - - if let Some(existing_config) = &existing_config { - info!("Existing config {:#?}", existing_config.config()); - } - if existing_config.is_none() { - // We need to wake up the rpi and get a config - wake_raspberry_pi(&mut shared_i2c, &mut delay); - } - let (device_config, device_config_was_updated) = - get_existing_device_config_or_config_from_pi_on_initial_handshake( - &mut flash_storage, - &mut pi_spi, - &mut peripherals.RESETS, - &mut peripherals.DMA, - clock_freq.Hz(), - radiometry_enabled, - lepton_serial.unwrap_or(0), - false, - &mut timer, - existing_config, - ); + // let existing_config = DeviceConfig::load_existing_config_from_flash(&mut flash_storage); + + // if let Some(existing_config) = &existing_config { + // info!("Existing config {:#?}", existing_config.config()); + // } + // if existing_config.is_none() { + // // We need to wake up the rpi and get a config + // wake_raspberry_pi(&mut shared_i2c, &mut delay); + // } + // let (device_config, device_config_was_updated) = + // get_existing_device_config_or_config_from_pi_on_initial_handshake( + // &mut flash_storage, + // &mut pi_spi, + // &mut peripherals.RESETS, + // &mut peripherals.DMA, + // clock_freq.Hz(), + // radiometry_enabled, + // lepton_serial.unwrap_or(0), + // false, + // &mut timer, + // existing_config, + // ); if woken_by_alarm { event_logger.log_event( @@ -407,30 +378,31 @@ pub fn core_1_task( &mut flash_storage, ); } - if device_config_was_updated { - event_logger.log_event( - LoggerEvent::new( - LoggerEventKind::SavedNewConfig, - synced_date_time.get_timestamp_micros(&timer), - ), - &mut flash_storage, - ); - //changing from no audio to audio mode and then clicking test rec quickly - match shared_i2c.tc2_agent_requested_audio_recording(&mut delay) { - Ok(test_rec) => { - if test_rec.is_some() { - sio.fifo.write_blocking(Core1Task::RequestReset.into()); - loop { - // Wait to be reset - nop(); - } - } - } - Err(e) => error!("Error getting tc2 agent state: {}", e), - } - } - let device_config = device_config.unwrap_or(DeviceConfig::default()); + // if device_config_was_updated { + // event_logger.log_event( + // LoggerEvent::new( + // LoggerEventKind::SavedNewConfig, + // synced_date_time.get_timestamp_micros(&timer), + // ), + // &mut flash_storage, + // ); + // //changing from no audio to audio mode and then clicking test rec quickly + // match shared_i2c.tc2_agent_requested_audio_recording(&mut delay) { + // Ok(test_rec) => { + // if test_rec.is_some() { + // sio.fifo.write_blocking(Core1Task::RequestReset.into()); + // loop { + // // Wait to be reset + // nop(); + // } + // } + // } + // Err(e) => error!("Error getting tc2 agent state: {}", e), + // } + // } + + // let device_config = device_config.unwrap_or(DeviceConfig::default()); if let AudioMode::AudioOnly = device_config.config().audio_mode { let _ = shared_i2c.disable_alarm(&mut delay); info!("Is audio device restarting"); @@ -1071,13 +1043,23 @@ pub fn core_1_task( &crc_table, making_status_recording, ); + info!("STREAM NEW"); cptv_streamer.init_gzip_stream(&mut flash_storage, false); + info!("STREAM INIT"); + let new_v = true; + info!( + "core1 address is {:#x} another {:#x}", + *pi_spi.payload_buffer.as_mut().unwrap() as *const _ as usize, + &new_v as *const _ as usize + ); cptv_streamer.push_frame( &prev_frame, &mut prev_frame_2, // This should be zeroed out before starting a new clip. &prev_frame_telemetry.as_ref().unwrap(), &mut flash_storage, ); + info!("STREAM PUSH"); + frames_written += 1; event_logger.log_event( diff --git a/src/cptv_encoder/streaming_cptv.rs b/src/cptv_encoder/streaming_cptv.rs index 4b94c59..748ae2d 100644 --- a/src/cptv_encoder/streaming_cptv.rs +++ b/src/cptv_encoder/streaming_cptv.rs @@ -496,7 +496,9 @@ impl<'a> CptvStream<'a> { frame_telemetry: &Telemetry, flash_storage: &mut OnboardFlash, ) { + info!("PUSHING"); let (bit_width, min_value, max_value) = delta_encode_frame_data(prev_frame, current_frame); + info!("ENCODED"); let frame_size = 4 + ((FRAME_HEIGHT * FRAME_WIDTH) - 1) as u32 * (bit_width as u32 / 8); let frame_header = CptvFrameHeader { time_on: frame_telemetry.msec_on, @@ -506,19 +508,22 @@ impl<'a> CptvStream<'a> { last_ffc_temp_c: frame_telemetry.fpa_temp_c_at_last_ffc, frame_temp_c: frame_telemetry.fpa_temp_c, }; + info!("HEADER"); let frame_header_iter = frame_header_iter(&frame_header); let delta_encoded = unsafe { &u16_slice_to_u8(&prev_frame)[0..frame_size as usize] }; self.cptv_header.min_value = self.cptv_header.min_value.min(min_value); self.cptv_header.max_value = self.cptv_header.max_value.max(max_value); self.cptv_header.total_frame_count += 1; - + info!("DONE DELTA"); if self.cptv_header.total_frame_count % 10 == 0 { info!( "Write frame #{}, {}", self.cptv_header.total_frame_count, frame_telemetry.frame_num ); } + for byte in frame_header_iter.chain(delta_encoded.iter().map(|&x| x)) { + info!("CHAIN"); self.total_uncompressed += 1; self.crc_val = self.crc_val ^ 0xffffffff; self.crc_val = self.crc_table[((self.crc_val ^ byte as u32) & 0xff) as usize] @@ -526,6 +531,7 @@ impl<'a> CptvStream<'a> { self.crc_val = self.crc_val ^ 0xffffffff; let entry = &self.huffman_table[byte as usize]; self.cursor.write_bits(entry.code as u32, entry.bits as u32); + info!("WRITING BYTES"); if let Some((to_flush, num_bytes)) = self.cursor.should_flush() { _ = flash_storage.append_file_bytes(to_flush, num_bytes, false, None, None); self.cursor.flush_residual_bits(); diff --git a/src/event_logger.rs b/src/event_logger.rs index 7d294fd..5a39444 100644 --- a/src/event_logger.rs +++ b/src/event_logger.rs @@ -151,7 +151,8 @@ impl LoggerEvent { NaiveDateTime::from_timestamp_micros(self.timestamp as i64) } } -pub const MAX_EVENTS_IN_LOGGER: usize = 1024 - 4 * 64; //leave last page for config stuff +pub const MAX_EVENTS_IN_LOGGER: usize = 1024; +//- 4 * 64; //leave last page for config stuff const EVENT_CODE_LENGTH: usize = 2; const EVENT_TIMESTAMP_LENGTH: usize = 8; @@ -159,7 +160,7 @@ const EVENT_PAYLOAD_LENGTH: usize = 8; const EVENT_LENGTH: usize = EVENT_CODE_LENGTH + EVENT_TIMESTAMP_LENGTH; const FLASH_STORAGE_EVENT_LOG_START_BLOCK_INDEX: isize = 2048 - 4; -const FLASH_STORAGE_EVENT_LOG_END_BLOCK_INDEX: isize = 2047; +const FLASH_STORAGE_EVENT_LOG_END_BLOCK_INDEX: isize = 2048; pub struct EventLogger { next_event_index: Option, } diff --git a/src/ext_spi_transfers.rs b/src/ext_spi_transfers.rs index 582c1a7..5dd245e 100644 --- a/src/ext_spi_transfers.rs +++ b/src/ext_spi_transfers.rs @@ -90,7 +90,7 @@ pub struct ExtSpiTransfers { ping: Option, PullDown>>, dma_channel_0: Option>, - payload_buffer: Option<&'static mut [u8; 2066]>, + pub payload_buffer: Option<&'static mut [u8; 2066]>, return_payload_buffer: Option<&'static mut [u8; 32 + 104]>, return_payload_offset: Option, pio: PIO, diff --git a/src/main.rs b/src/main.rs index bf1b0fc..354b6e1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,7 +25,7 @@ mod utils; use crate::attiny_rtc_i2c::SharedI2C; use crate::core0_audio::audio_task; pub use crate::core0_task::frame_acquisition_loop; -use crate::core1_task::{core_1_task, Core1Pins, Core1Task}; +use crate::core1_task::{core_1_task, wake_raspberry_pi, Core1Pins, Core1Task}; use crate::cptv_encoder::FRAME_WIDTH; use crate::lepton::{init_lepton_module, LeptonPins}; use crate::onboard_flash::extend_lifetime_generic; @@ -110,14 +110,35 @@ impl FrameBuffer { } } +use crate::core1_sub_tasks::{ + get_existing_device_config_or_config_from_pi_on_initial_handshake, + offload_flash_storage_and_events, +}; +use crate::ext_spi_transfers::ExtSpiTransfers; use crate::onboard_flash::OnboardFlash; use rp2040_hal::dma::DMAExt; +use rp2040_hal::pio::PIOExt; #[entry] fn main() -> ! { info!("Startup tc2-firmware {}", FIRMWARE_VERSION); // TODO: Check wake_en and sleep_en registers to make sure we're not enabling any clocks we don't need. let mut peripherals: Peripherals = Peripherals::take().unwrap(); + + let (clocks, rosc) = clock_utils::setup_rosc_as_system_clock( + peripherals.CLOCKS, + peripherals.XOSC, + peripherals.ROSC, + ROSC_TARGET_CLOCK_FREQ_HZ.Hz(), + ); + let clocks: &'static ClocksManager = unsafe { extend_lifetime_generic(&clocks) }; + + let system_clock_freq = clocks.system_clock.freq().to_Hz(); + + info!( + "System clock speed {}MHz", + clocks.system_clock.freq().to_MHz() + ); let sio = Sio::new(peripherals.SIO); let dma_channels = peripherals.DMA.split(&mut peripherals.RESETS); let pins = rp2040_hal::gpio::Pins::new( @@ -159,52 +180,48 @@ fn main() -> ! { None, ); - let (clocks, rosc) = clock_utils::setup_rosc_as_system_clock( - peripherals.CLOCKS, - peripherals.XOSC, - peripherals.ROSC, - ROSC_TARGET_CLOCK_FREQ_HZ.Hz(), + let mut payload_buf = [0x42u8; 2066]; + let payload_buf = unsafe { extend_lifetime_generic_mut(&mut payload_buf) }; + let mut crc_buf = [0x42u8; 32 + 104]; + let crc_buf = unsafe { extend_lifetime_generic_mut(&mut crc_buf) }; + let (pio0, sm0, _, _, _) = peripherals.PIO0.split(&mut peripherals.RESETS); + + let mut pi_spi = ExtSpiTransfers::new( + core1.pi_mosi, + core1.pi_cs, + core1.pi_clk, + core1.pi_miso, + core1.pi_ping, + dma_channels.ch0, + payload_buf, + crc_buf, + pio0, + sm0, ); - let clocks: &'static ClocksManager = unsafe { extend_lifetime_generic(&clocks) }; - - let system_clock_freq = clocks.system_clock.freq().to_Hz(); - + let arra = pi_spi.payload_buffer.as_mut().unwrap(); info!( - "System clock speed {}MHz", - clocks.system_clock.freq().to_MHz() + "payload address is {:#x}", + *pi_spi.payload_buffer.as_mut().unwrap() as *const _ as usize ); - flash_storage.take_spi( peripherals.SPI1, &mut peripherals.RESETS, system_clock_freq.Hz(), ); + flash_storage.erase_all_blocks(); flash_storage.init(); - let mut config = DeviceConfig::load_existing_inner_config_from_flash(&mut flash_storage); - let mut is_audio: bool = config.is_some() && config.as_mut().unwrap().0.is_audio_device(); - - // Watchdog ticks are required to run the timer peripheral, since they're shared between both. - - let mut watchdog = bsp::hal::Watchdog::new(peripherals.WATCHDOG); - watchdog.enable_tick_generation((system_clock_freq / 1_000_000) as u8); - - watchdog.pause_on_debug(true); - watchdog.start(8388607.micros()); + let mut config: Option = + DeviceConfig::load_existing_config_from_flash(&mut flash_storage); + //do all the get config crap here - info!("Enabled watchdog timer"); - let timer = bsp::hal::Timer::new(peripherals.TIMER, &mut peripherals.RESETS, clocks); + if let Some(config) = &config { + info!("Existing config {:#?}", config.config()); + } let core = pac::CorePeripherals::take().unwrap(); let mut delay = Delay::new(core.SYST, system_clock_freq); - // let pins = rp2040_hal::gpio::Pins::new( - // peripherals.IO_BANK0, - // peripherals.PADS_BANK0, - // sio.gpio_bank0, - // &mut peripherals.RESETS, - // ); - // Attiny + RTC comms let sda_pin = pins.gpio6.into_function::(); let scl_pin = pins.gpio7.into_function::(); @@ -226,12 +243,51 @@ fn main() -> ! { let mut shared_i2c = SharedI2C::new(i2c1, unlocked_pin, &mut delay); info!("Got shared i2c"); + + // Watchdog ticks are required to run the timer peripheral, since they're shared between both. + + let mut watchdog = bsp::hal::Watchdog::new(peripherals.WATCHDOG); + watchdog.enable_tick_generation((system_clock_freq / 1_000_000) as u8); + + watchdog.pause_on_debug(true); + watchdog.start(8388607.micros()); + + info!("Enabled watchdog timer"); + + if config.is_none() { + info!("Waking pi to get config"); + // We need to wake up the rpi and get a config + wake_raspberry_pi(&mut shared_i2c, &mut delay); + } + + let mut timer: rp2040_hal::Timer = + bsp::hal::Timer::new(peripherals.TIMER, &mut peripherals.RESETS, clocks); + + let mut peripherals: Peripherals = unsafe { Peripherals::steal() }; + + let (device_config, device_config_was_updated) = + get_existing_device_config_or_config_from_pi_on_initial_handshake( + &mut flash_storage, + &mut pi_spi, + &mut peripherals.RESETS, + &mut peripherals.DMA, + system_clock_freq.Hz(), + 2u32, + 0, + false, + &mut timer, + config, + ); + let config = device_config.unwrap(); + let alarm_woke_us = shared_i2c.alarm_triggered(&mut delay); info!("Woken by RTC alarm? {}", alarm_woke_us); if alarm_woke_us { shared_i2c.clear_alarm(&mut delay); } + let mut is_audio: bool = config.config().is_audio_device(); + if let Ok(audio_only) = shared_i2c.is_audio_device(&mut delay) { info!("EEPROM audio device: {}", audio_only); is_audio = is_audio || audio_only; @@ -254,8 +310,7 @@ fn main() -> ! { } if is_audio { - let config = config.unwrap().0; - match config.audio_mode { + match config.config().audio_mode { AudioMode::AudioAndThermal | AudioMode::AudioOrThermal => { if let Ok(state) = shared_i2c.tc2_agent_state(&mut delay) { if (state & (tc2_agent_state::THERMAL_MODE)) > 0 { @@ -288,30 +343,20 @@ fn main() -> ! { if is_audio { let gpio0 = pins.gpio0; let gpio1 = pins.gpio1; - let pins = Core1Pins { - pi_ping: pins.gpio5.into_pull_down_input(), - - pi_miso: pins.gpio15.into_floating_disabled(), - pi_mosi: pins.gpio12.into_floating_disabled(), - pi_cs: pins.gpio13.into_floating_disabled(), - pi_clk: pins.gpio14.into_floating_disabled(), - - fs_cs: pins.gpio9.into_push_pull_output(), - fs_miso: pins.gpio8.into_pull_down_disabled().into_pull_type(), - fs_mosi: pins.gpio11.into_pull_down_disabled().into_pull_type(), - fs_clk: pins.gpio10.into_pull_down_disabled().into_pull_type(), - }; audio_branch( i2c1, system_clock_freq, timer, - pins, + // core1, gpio0, gpio1, watchdog, alarm_woke_us, unlocked_pin, + config, + &mut flash_storage, + &mut pi_spi, ); } else { let lepton_pins = LeptonPins { @@ -331,23 +376,12 @@ fn main() -> ! { clk_disable: pins.gpio27.into_push_pull_output(), master_clk: pins.gpio26.into_floating_input(), }; - let pins = Core1Pins { - pi_ping: pins.gpio5.into_pull_down_input(), - - pi_miso: pins.gpio15.into_floating_disabled(), - pi_mosi: pins.gpio12.into_floating_disabled(), - pi_cs: pins.gpio13.into_floating_disabled(), - pi_clk: pins.gpio14.into_floating_disabled(), - - fs_cs: pins.gpio9.into_push_pull_output(), - fs_miso: pins.gpio8.into_pull_down_disabled().into_pull_type(), - fs_mosi: pins.gpio11.into_pull_down_disabled().into_pull_type(), - fs_clk: pins.gpio10.into_pull_down_disabled().into_pull_type(), - }; thermal_code( + pi_spi, + flash_storage, lepton_pins, - pins, + // core1, watchdog, system_clock_freq, delay, @@ -357,6 +391,7 @@ fn main() -> ! { rosc, alarm_woke_us, unlocked_pin, + config, ); } } @@ -366,7 +401,7 @@ pub fn audio_branch( i2c_config: I2CConfig, clock_freq: u32, mut timer: bsp::hal::Timer, - pins: Core1Pins, + // pins: Core1Pins, gpio0: rp2040_hal::gpio::Pin< rp2040_hal::gpio::bank0::Gpio0, rp2040_hal::gpio::FunctionNull, @@ -384,22 +419,30 @@ pub fn audio_branch( FunctionSio, PullDown, >, + config: DeviceConfig, + flash_storage: &mut OnboardFlash, + pi_spi: &mut ExtSpiTransfers, ) -> ! { audio_task( i2c_config, clock_freq, &mut timer, - pins, + // pins, gpio0, gpio1, &mut watchdog, alarm_triggered, unlocked_pin, + config, + flash_storage, + pi_spi, ); } pub fn thermal_code( + pi_spi: ExtSpiTransfers, + onboard_flash: OnboardFlash, lepton_pins: LeptonPins, - pins: Core1Pins, + // pins: Core1Pins, mut watchdog: Watchdog, system_clock_freq: u32, mut delay: Delay, @@ -413,6 +456,7 @@ pub fn thermal_code( FunctionSio, PullDown, >, + config: DeviceConfig, ) -> ! { let mut peripherals = unsafe { Peripherals::steal() }; let mut sio = Sio::new(peripherals.SIO); @@ -445,7 +489,10 @@ pub fn thermal_code( let mut fb0 = FrameBuffer::new(); let mut fb1 = FrameBuffer::new(); - let mut core1_stack: Stack<44900> = Stack::new(); + + let mut core1_stack: Stack<40000> = Stack::new(); + let mem = unsafe { extend_lifetime_generic_mut_2(&mut core1_stack.mem) }; + let frame_buffer = Mutex::new(RefCell::new(Some(unsafe { extend_lifetime_generic_mut(&mut fb0) }))); @@ -460,26 +507,29 @@ pub fn thermal_code( unsafe { extend_lifetime_generic(&frame_buffer_2) }; watchdog.feed(); watchdog.disable(); - let peripheral_clock_freq = clocks.peripheral_clock.freq(); { - let _ = core1.spawn( - unsafe { extend_lifetime_generic_mut_2(&mut core1_stack.mem) }, - move || { - core_1_task( - frame_buffer_local, - frame_buffer_local_2, - system_clock_freq, - pins, - i2c1, - unlocked_pin, - lepton_serial, - lepton_firmware_version, - alarm_woke_us, - timer, - ) - }, - ); + let _ = core1.spawn(mem, move || { + core_1_task( + pi_spi, + onboard_flash, + frame_buffer_local, + frame_buffer_local_2, + system_clock_freq, + // pins, + i2c1, + unlocked_pin, + lepton_serial, + lepton_firmware_version, + alarm_woke_us, + timer, + config, + ) + }); + } + loop { + info!("DONE {} {} ", fb0.0[0], fb1.0[0]); + nop(); } let result = sio.fifo.read_blocking(); crate::assert_eq!(result, Core1Task::Ready.into()); diff --git a/src/onboard_flash.rs b/src/onboard_flash.rs index 0afe0d9..ce9618a 100644 --- a/src/onboard_flash.rs +++ b/src/onboard_flash.rs @@ -375,6 +375,7 @@ impl OnboardFlash { self.reset(); self.scan(); self.unlock_blocks(); + self.set_config_block(); } pub fn set_config_block(&mut self) { @@ -406,7 +407,7 @@ impl OnboardFlash { panic!("Config block has not been initialized, call flash_storage.init()"); } let config_block = self.config_block.unwrap(); - self.erase_block(config_block); + let _ = self.erase_block(config_block); // let mut payload = [0xffu8; 2115]; let mut start = 0; let mut page = 0; @@ -414,20 +415,35 @@ impl OnboardFlash { while !is_last { let mut end = start + 2048; - if start + 2048 > device_bytes.len() { + if end > device_bytes.len() { end = device_bytes.len(); } - let mut payload = [0xffu8; 2115]; - let is_last = end == device_bytes.len(); + let mut payload = [0xffu8; 2116]; + is_last = end == device_bytes.len(); + info!( + "Is last?? {} start {} end {} len {}", + is_last, + start, + end, + device_bytes.len() + ); let device_chunk = &mut device_bytes[start..end]; - self.write_config_bytes( - device_chunk, + info!("DEvice chunk is {}", device_chunk.len()); + payload[4..4 + device_chunk.len()].copy_from_slice(&device_chunk); + info!("Writing {}", payload); + start += 2048; + let _ = self.write_config_bytes( + &mut payload, device_chunk.len(), is_last, config_block, page, ); page += 1; + if page >= 64 { + panic!("Trying to write too many pages for config"); + } + info!("Is last {}", is_last); } } @@ -504,6 +520,7 @@ impl OnboardFlash { if self.config_block.is_none() { panic!("Config block has not been initialized, call flash_storage.init()"); } + info!("Reading config from {}", self.config_block); //guess this is the size of the config at the moment let mut config_bytes = [0u8; 2400 + 105]; @@ -514,13 +531,15 @@ impl OnboardFlash { while !is_last { self.read_page(block_i as isize, page_i).unwrap(); - self.read_page_metadata(block_i as isize); + self.read_page_from_cache(block_i as isize); self.wait_for_all_ready(); + info!("Reading {} {} ", block_i, page_i); if !self.current_page.page_is_used() { return Err("Config block empty"); // return Err(&format!("Config block {} page {} empty", block,_i page_i)); } let length = self.current_page.page_bytes_used(); + cursor.write_bytes(&self.current_page.user_data()[..length]); is_last = self.current_page.is_last_page_for_file(); page_i += 1;