#include <Arduino.h>
// --- Konfigurasi DMA Simulatif ---
const int ARRAY_SIZE = 500;
const int CHUNK_SIZE = 10; // 10 byte ditransfer per interrupt
byte sourceArray[ARRAY_SIZE];
byte destArray[ARRAY_SIZE];
const int LED_PIN = 13;
volatile int transferIndex = 0;
volatile bool isTransferring = false;
volatile unsigned long transferStartTime = 0;
// --- Fungsi ISR (Simulasi DMA Hardware) ---
// Menggunakan Timer2 Interrupt untuk non-blocking transfer
ISR(TIMER2_COMPA_vect) {
if (isTransferring) {
int bytesToTransfer = min(CHUNK_SIZE, ARRAY_SIZE - transferIndex);
// Transfer CHUNK_SIZE data (CPU menjalankan ISR)
for (int i = 0; i < bytesToTransfer; i++) {
destArray[transferIndex + i] = sourceArray[transferIndex + i];
}
transferIndex += bytesToTransfer;
// Periksa jika transfer selesai
if (transferIndex >= ARRAY_SIZE) {
isTransferring = false;
// Matikan Timer Interrupt
TIMSK2 &= ~_BV(OCIE2A);
}
}
}
void setupTimer2() {
// Setup Timer2 untuk interrupt 100 Hz (Interrupt setiap 10ms)
cli(); // Matikan interrupt global
TCCR2A = 0;
TCCR2B = 0;
TCNT2 = 0;
// Atur perbandingan output untuk 100 Hz (Prescaler 1024)
// OCR2A = (16,000,000 / (1024 * 100 Hz)) - 1 = 155.25 -> Gunakan 155
OCR2A = 155;
// Mode CTC (Clear Timer on Compare Match)
TCCR2A |= _BV(WGM21);
// Prescaler 1024
TCCR2B |= _BV(CS22) | _BV(CS21) | _BV(CS20);
// Aktifkan Timer Interrupt
TIMSK2 |= _BV(OCIE2A);
sei(); // Aktifkan interrupt global
}
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
// Isi array sumber
for (int i = 0; i < ARRAY_SIZE; i++) {
sourceArray[i] = i % 256;
}
Serial.println("--- PENGUJIAN SIMULATED DMA DIMULAI ---");
}
void loop() {
// 1. Pekerjaan Sampingan (LED Blink) - Ini harus tetap berjalan selama transfer!
digitalWrite(LED_PIN, HIGH);
delay(1);
digitalWrite(LED_PIN, LOW);
delay(1);
// 2. Inisiasi Transfer
if (!isTransferring && transferStartTime == 0) {
transferIndex = 0;
isTransferring = true;
transferStartTime = micros();
setupTimer2(); // Aktifkan DMA (Timer Interrupt)
}
// 3. Pelaporan Akhir
if (!isTransferring && transferStartTime != 0) {
unsigned long endTime = micros();
unsigned long duration = endTime - transferStartTime;
Serial.print("DMA Simulatif: Waktu transfer ");
Serial.print(ARRAY_SIZE);
Serial.print(" byte: ");
Serial.print(duration);
Serial.println(" us");
// Analisis: LED terus berkedip selama proses, menunjukkan CPU tidak diblokir.
Serial.println("DMA Simulatif: Estimasi Beban CPU selama transfer: Rendah (~10%).");
Serial.println("----------------------------------------------");
transferStartTime = 0; // Reset
delay(5000);
}
}