Unable to get synchronization between SPI communication and general purpose I/O

Hello everyone,

I am trying to program Arduino DUE board using Atmel Studio 6.1. So far I have been able to program general purpose I/O for blinking LEDs and PWM for fading LEDs. I have now come to the task where I have to use SPI for my LCD (DOGS 102). I have done all these things using Arduino IDE and everything was working perfectly as I wanted. However, now that I am programming using Atmel Studio I have run into some trouble and can’t seem to get the general purpose I/O pin to work synchronously with SPI communication. a little info about why I need the GP I/O and what is its purpose; Since the LCD needs to know whether the incoming byte is a data byte to display or a command byte to set the column and row addresses, therefore I need and extra pin to let the LCD know about this. But the problem that I am having at this point is that this GP I/O is not working as it is programmed in sequence with SPI write and thus the LCD displays nothing due to the fact that GP I/O changes state between data and command.

I have attached the code from both Arduino IDE and Atmel Studio 6.1. Moreover, as I am analyzing the signals using an oscilloscope I have attached a snap shot to clarify the situation.

  // Code from Arduino IDE

void DOGS_LCD_init (unsigned char CS)
{
  unsigned char  i, temp_byte;
  
   SPI.begin(CS);
   SPI.setBitOrder(CS,MSBFIRST);
   SPI.setDataMode(CS,SPI_MODE3);
   SPI.setClockDivider(CS,128);
  
   digitalWrite(CD,LOW);  
  
  for (i = 0; i < 13; i++)
  {	
    temp_byte = DOGS_init[i];    
    SPI.transfer(CS, temp_byte);	
  } // end for
  
  SPI.end(CS);  
  digitalWrite(CD,HIGH);
}

/*! \brief Write one ASCII character to DOGS graphic display at position Col and Row
 *	 
 *  \param Row           Value for the ASCII row [0..7]
 *  \param Col           Value for the DOGS col [0..16]
 *  \param ASCIIchar     ASCII and special character to display [0..127]
 */
void Dpc (unsigned char Row, unsigned char Col, unsigned char ASCIIchar, unsigned char CS)
{
  // Local vars
  unsigned char lauf, DOGSrow, DOGScol, DOGScol_l, DOGScol_h, DOGSchar;
 
  SPI.begin(CS);
  
  for (lauf = 0; lauf < 6; lauf++)
  {
    // Send 6 bytes to DOGS LCD
    digitalWrite(CD,LOW);
    // Compute row address
    DOGSrow =  0b10110000 | (Row & 0b00000111); // ROW = [0..7]    
    SPI.transfer(CS,DOGSrow);	
    // Compute col address
    if (Col > 17) Col = 17;
    DOGScol = (Col * 6) + lauf; // Col = [0..16]
    // Compute high col address
    DOGScol_h = 0b00010000 | (DOGScol >> 4);    
    SPI.transfer(CS,DOGScol_h);	
    // Compute low col address
    DOGScol_l = 0b00000000 | (DOGScol & 0b00001111);    
    SPI.transfer(CS,DOGScol_l);	
    // Compute data byte    
    digitalWrite(CD,HIGH);
    DOGSchar = ASCII_array[ASCIIchar & 0b01111111][lauf];   
    SPI.transfer(CS,DOGSchar);    
  }// end for
   
  SPI.end(CS);
}
  // Code from Atmel Studio 6.1

void DOGS_LCD_init ()
{
  unsigned char  i, temp_byte;
  // Define GP I/O pin for command or data control on LCD
  uint32_t CD = (1u << 21);  // shifted to the left 21 bits since PIN 9 on DUE corresponds to PC21
  REG_PIOC_OER = CD;

  spi_enable(SPI_MASTER_BASE);   
  REG_PIOC_CODR = CD;
  
  for (i = 0; i < 13; i++)
  {	
    temp_byte = DOGS_init[i];
    spi_write(SPI_MASTER_BASE, temp_byte, 0, 0);
    while ((spi_read_status(SPI_MASTER_BASE) & SPI_SR_RDRF) == 0);	
  } // end for
  
  spi_disable(SPI_MASTER_BASE);
  
  REG_PIOC_SODR = CD;
}

/*! \brief Write one ASCII character to DOGS graphic display at position Col and Row
 *	 
 *  \param Row           Value for the ASCII row [0..7]
 *  \param Col           Value for the DOGS col [0..16]
 *  \param ASCIIchar     ASCII and special character to display [0..127]
 */
void Dpc (unsigned char Row, unsigned char Col, unsigned char ASCIIchar)
{
  // Local vars
  unsigned char lauf, DOGSrow, DOGScol, DOGScol_l, DOGScol_h, DOGSchar;
  // Define GP I/O pin for command or data control on LCD
  uint32_t CD = (1u << 21);  // shifted to the left 21 bits since PIN 9 on DUE corresponds to PC21
  REG_PIOC_OER = CD;
  spi_enable(SPI_MASTER_BASE);
  
  for (lauf = 0; lauf < 6; lauf++)
  {
    // Send 6 bytes to DOGS LCD
    REG_PIOC_CODR = CD;

    // Compute row address
    DOGSrow =  0b10110000 | (Row & 0b00000111); // ROW = [0..7]
    spi_write(SPI_MASTER_BASE, DOGSrow, 0, 0);
    while ((spi_read_status(SPI_MASTER_BASE) & SPI_SR_RDRF) == 0);
    // Compute col address
    if (Col > 17) Col = 17;
    DOGScol = (Col * 6) + lauf; // Col = [0..16]
    // Compute high col address
    DOGScol_h = 0b00010000 | (DOGScol >> 4);
    spi_write(SPI_MASTER_BASE, DOGScol_h, 0, 0);
    while ((spi_read_status(SPI_MASTER_BASE) & SPI_SR_RDRF) == 0);
    // Compute low col address
    DOGScol_l = 0b00000000 | (DOGScol & 0b00001111);
    spi_write(SPI_MASTER_BASE, DOGScol_l, 0, 0);
    while ((spi_read_status(SPI_MASTER_BASE) & SPI_SR_RDRF) == 0);
    // Compute data byte
    REG_PIOC_SODR = CD;
    DOGSchar = ASCII_array[ASCIIchar & 0b01111111][lauf];
    spi_write(SPI_MASTER_BASE, DOGSchar, 0, 0);
    while ((spi_read_status(SPI_MASTER_BASE) & SPI_SR_RDRF) == 0);    
  }// end for
  
  spi_disable(SPI_MASTER_BASE);
}

In case of Atmel Studio here is the initialization of SPI in Master Mode

static void spi_master_initialize(void)
{
	/* Configure an SPI peripheral. */
	spi_enable_clock(SPI_MASTER_BASE);
	spi_disable(SPI_MASTER_BASE);
	spi_reset(SPI_MASTER_BASE);
	//spi_set_lastxfer(SPI_MASTER_BASE);	
	spi_set_master_mode(SPI_MASTER_BASE);
	spi_disable_mode_fault_detect(SPI_MASTER_BASE);
	//spi_set_fixed_peripheral_select(SPI_MASTER_BASE);
	spi_set_variable_peripheral_select(SPI_MASTER_BASE);
	//spi_enable_peripheral_select_decode(SPI_MASTER_BASE);
	//spi_disable_peripheral_select_decode(SPI_MASTER_BASE);
	spi_set_peripheral_chip_select_value(SPI_MASTER_BASE, SPI_CHIP_SEL);	
	spi_set_clock_polarity(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CLK_POLARITY);
	spi_set_clock_phase(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CLK_PHASE);
	spi_set_bits_per_transfer(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CSR_BITS_8_BIT);
	spi_set_baudrate_div(SPI_MASTER_BASE, SPI_CHIP_SEL, 128	);
	spi_set_transfer_delay(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_DLYBS, SPI_DLYBCT);
	//spi_enable(SPI_MASTER_BASE);
}

The Data sent is similar in both cases as well as the SCBR value which is set to 128. The difference is in case of Arduino IDE the LCD displays the data whereas in case of Atmel Studio nothing is displayed.

Hope someone could help me out.

Regards,

Owais.