SDA20 and SCL21 on the slave? Then SDA1 and SCL1 on the master?
It's up to you, providing you add #define Wire Wire1 at the beginning of your sketch, just after the #include of libraries, as stated above. You could also use SDA1/SCL1 on both cards, and add pull ups of 2K2. It seems that this resistor value is OK.
You can test your code for I2C in Master and I2C in Slave modes with a DUE on a single DUE board, here is an example sketch using the builtin temperature sensor (hook a jumper between SDA/SDA1 and another one between SCL/SCL1):
/******************************************************************************/
/************ Master TWI0, Slave TWI1, temperature reading *************/
/******************************************************************************/
#define read 1
#define write 0
#define TemperatureAddress (0b1001000)
/********************* Init TWIn ************************/
void I2c_Init(Twi* pTWI, boolean Master) {
if (pTWI == TWI0) {
PMC->PMC_PCER0 |= PMC_PCER0_PID22; // TWI0 power ON
PIOA->PIO_PDR |= PIO_PDR_P17 // Enable peripheral control
| PIO_PDR_P18;
PIOA->PIO_ABSR &= ~(PIO_PA17A_TWD0 // TWD0 & TWCK0 Peripherals type A
| PIO_PA18A_TWCK0);
}
else {
PMC->PMC_PCER0 |= PMC_PCER0_PID23; // TWI1 power ON
PIOB->PIO_PDR |= PIO_PDR_P13 // Enable peripheral control
| PIO_PDR_P12;
PIOB->PIO_ABSR &= ~(PIO_PB12A_TWD1 // TWD1 & TWCK1 Peripherals type A
| PIO_PB13A_TWCK1);
}
// I2C lines are Open drain by hardware, no need to program PIO_MDER
pTWI->TWI_CR = TWI_CR_SWRST; // TWIn software reset
pTWI->TWI_RHR; // Flush reception buffer
pTWI->TWI_CR = TWI_CR_SVDIS | TWI_CR_MSDIS; // Disable Master and Slave modes
//Enable master mode
if (Master == true) {
//enter slave address
pTWI->TWI_MMR |= TWI_MMR_DADR(TemperatureAddress);
pTWI->TWI_CR = TWI_CR_MSEN; // Master mode enable
//clockwave from 100khz to 400khz
SetClock(pTWI, 400000); // from 100000 to 400000
}
else { // Enable Slave mode
pTWI->TWI_SMR = TWI_SMR_SADR(TemperatureAddress);
pTWI->TWI_CR = TWI_CR_SVEN; // Slave mode enable
}
}
/**************************** Start ****************************/
void I2c_Start(Twi* pTWI, uint8_t slave_address, uint8_t mread) { //read=1, write=0
//set slave address
pTWI->TWI_MMR = (pTWI->TWI_MMR & ~TWI_MMR_DADR_Msk)
| TWI_MMR_DADR(slave_address);
//set read/write direction
if (mread == write) { //write
pTWI->TWI_MMR &= ~TWI_MMR_MREAD;
}
else if (mread == read) { //read
pTWI->TWI_MMR |= TWI_MMR_MREAD;
}
//send start
pTWI->TWI_CR |= TWI_CR_START;
//wait for ack
while (!(pTWI->TWI_SR & TWI_SR_TXRDY));
}
/*************************** Stop ****************************/
void I2c_Stop(Twi* pTWI) {
pTWI->TWI_CR |= TWI_CR_STOP;
}
/********************** Read 1 byte **************************/
uint8_t I2c_ReadByte(Twi* pTWI) {
uint8_t receivedByte;
//If the stop bit in the control register is not set,
//Sam3x will automatically ACK after reading TWIn_RHR register
//RXRDY will be set when data arrives in TWIn_RHR register
while (!(pTWI->TWI_SR & TWI_SR_RXRDY));
//reading data will clear RXRDY bit in the status register
receivedByte = pTWI->TWI_RHR;
return receivedByte;
}
/***************** Read the last byte ***********************/
uint8_t I2c_ReadLastByte(Twi* pTWI) {
uint8_t receivedByte;
//Sam3x requires stop bit to be set before data is set on the TWIn_RHR
//when stop bit is set, Sam3x will send a NACK instead of an ACK automatically
I2c_Stop(pTWI);
//When data arrives in the TWIn_RHR register RXRDY is set in the Status Register
while (!(pTWI->TWI_SR & TWI_SR_RXRDY));
//reading data will clear RXRDY bit in the status register
receivedByte = pTWI->TWI_RHR;
while (!(pTWI->TWI_SR & TWI_SR_TXCOMP));
return receivedByte;
}
/************************ Write 1 byte *******************/
void I2c_WriteByte(Twi* pTWI, uint8_t data) {
pTWI->TWI_THR |= data;
//wait for ack
while (!(pTWI->TWI_SR & TWI_SR_TXRDY));
}
/*********************** Write last byte *******************/
void I2c_WriteLastByte(Twi* pTWI, uint8_t data) {
pTWI->TWI_THR |= data;
I2c_Stop(pTWI);
//wait for ack
while (!(pTWI->TWI_SR & TWI_SR_TXRDY));
while (!(pTWI->TWI_SR & TWI_SR_TXCOMP));
}
/***************** Set Interrupt Configuration *********************/
void I2c_Interrupt(Twi* pTWI, uint32_t InterrConfig) {
pTWI->TWI_IER = InterrConfig;
if (pTWI == TWI0) {
NVIC_EnableIRQ(TWI0_IRQn);
}
else {
NVIC_EnableIRQ(TWI1_IRQn);
}
}
/******************* TWI1 Handler ***********************/
void TWI1_Handler(void) {
uint32_t status = TWI1->TWI_SR;
if (status & TWI_SR_SVREAD) {
TWI1->TWI_RHR;
TWI1->TWI_THR = temperature();
}
}
/********************** Configure clock *********************/
void SetClock(Twi* pTWI , uint32_t frequency) {
uint32_t CLDIV = 0;
uint32_t CKDIV = 0;
uint8_t readyByte = 0;
while (!readyByte) {
CLDIV = ((VARIANT_MCK / (2 * frequency)) - 4) / (1 << CKDIV) ;
if ( CLDIV <= 255 ) {
readyByte = 1 ;
}
else {
CKDIV++ ;
}
}
pTWI->TWI_CWGR = (CKDIV << 16) | (CLDIV << 8) | CLDIV;
}
void setup() {
// Power OFF all peripherals
PMC->PMC_PCDR0 = 0xFFFFFFFF;
PMC->PMC_PCDR1 = 0xFFFFFFFF;
Serial.begin(250000);
PMC->PMC_PCER1 |= PMC_PCER1_PID37; // ADC power ON
ADC->ADC_ACR |= ADC_ACR_TSON; // Temperature sensor ON
I2c_Init(TWI0, true); // TWI0 Master
I2c_Init(TWI1, false); // TWI1 Slave
uint32_t InterruptConfig = TWI_IER_SVACC; // | TWI_IER_SVREAD
I2c_Interrupt(TWI1, InterruptConfig);
}
void loop() {
uint8_t ReceivedByte;
static uint32_t Oldmillis;
if ((millis() - Oldmillis) > 1000) {
Oldmillis = millis();
I2c_Start(TWI0, TemperatureAddress, 1);
ReceivedByte = I2c_ReadLastByte(TWI0);
printf("%d\xB0" "C\n", ReceivedByte );
}
}
/***************** Temperature function *******************/
uint8_t temperature() {
float trans = 3.3 / 4096;
float offset = 0.76;
float factor = 0.00265;
float fixtemp = 15;
uint32_t ulValue;
float treal;
uint8_t __treal;
ADC->ADC_CHER |= 1 << ADC_TEMPERATURE_SENSOR;
ADC->ADC_CR = ADC_CR_START;
while (!(ADC->ADC_ISR & ADC_ISR_DRDY));
ulValue = ADC->ADC_LCDR;
ADC->ADC_CHDR |= 1 << ADC_TEMPERATURE_SENSOR;
treal = fixtemp + (( trans * ulValue ) - offset ) / factor;
__treal = (uint8_t) treal;
return __treal;
}