FTDI Community

Please login or register.

Login with username, password and session length.
Advanced Search  

News:

Welcome to the FTDI Community!

Please read our Welcome Note

Technical Support enquires
please contact the team
@ FTDI Support


New Bridgetek Community is now open

Please note that we have created the Bridgetek Community to discuss all Bridgetek products e.g. EVE, MCU.

Please follow this link and create a new user account to get started.

Bridgetek Community

Author Topic: Implement VNC2 as SPI Slave but receiving data which shifted one bit on MISO  (Read 807 times)

Yvonne

  • Newbie
  • *
  • Posts: 5
    • View Profile

Hello,

I am using C232HM-DDHSL-0 cable as SPI master sending data with FTD2XX, and I am using V2DIP1-32 board of VNC2 as SPI slave.

I modified the example code "SPI to USB Memory Sample Application ROM" to write the recieved data from SPI master into MISO (here I write two bytes of received data: 0x01, 0x02), and I see the received data all shifted one bit (the received data are: 0x00, 0x02, 0x04, 0x04, ..., 0x04) in the capture of logic analyzer as shown in attachment. Also, the first byte of the received data is 0x00, and then shift one bit in left direction for each received data (i.e., 0x01 -> 0x02, 0x02 -> 0x04) and repeat it until the end of MOSI data transaction.

I dont't really understand why the first received byte is 0x00, and why the other received data shifted one bit, is any configs of SPI slave mode that I made a mistake? or any idea will be grateful!

Thanks
Yvonne
Logged

FTDI Community

  • Administrator
  • Hero Member
  • *****
  • Posts: 800
    • View Profile

Hi Yvonne,

Does this happen when you use the example code unmodified?

What SPI mode are you using? Have a look at section 6.2 of the Vinculum-II Datasheet. This goes over the different SPI modes available and the following sections give timing diagrams.

Best Regards
FTDI Community 
Logged

Yvonne

  • Newbie
  • *
  • Posts: 5
    • View Profile

Hello,

The following is my code which modified the example code "SPI to USB Memory Sample Application ROM", I paste it as in the following.

In my code, I use SPI slave in unmanaged SPI mode. And the SPI master sends data in 1M Hz, however the MISO will receive data string with double bytes for each data byte as shown in the attachment figure.

I wonder is it because the interrupt frequency of "vos_dev_write" slower than the SPI master clock frequency (here in my code should be 1 MHz), therefore when the clock is drived, the Tx Shift Register has no new data byte can be transmitted, and VNC2 can send the last data byte in the Tx Shift Register again until the new data byte copied from ram to the rgister in the following clock.

Is there anay advice to increase the interrupt frequency of "vos_dev_write" on the condition that SPI master can keep in 1 MHz clock frequency, and by doing this way, the MISO can receive data bytes with no double? Or any suggestion are appreciated!

Thank you very much!
Yvonne

===========
/*
** Filename: SPI2DSC.c
**
** Automatically created by Application Wizard 1.4.2
**
** Part of solution Firmware in project SPI2DSC
**
** Comments:
**
** Important: Sections between markers "FTDI:S*" and "FTDI:E*" will be overwritten by
** the Application Wizard
*/

#include "SPI2DSC.h"

/* FTDI:STP Thread Prototypes */
vos_tcb_t *tcbSETUP;
vos_tcb_t *tcbSPISLAVE;
vos_tcb_t *tcbBOMS;

void setup();
void SPISlave();
/* FTDI:ETP */

/* FTDI:SDH Driver Handles */
VOS_HANDLE hUSBHOST_1; // USB Host Port 1
VOS_HANDLE hSPI_SLAVE_1; // SPISlave Port 1 Interface Driver
VOS_HANDLE hFAT_FILE_SYSTEM; // FAT File System for FAT32 and FAT16
/* FTDI:EDH */

vos_semaphore_t setupSem;
vos_semaphore_t dataSem;
vos_mutex_t mBufAccess;

FILE *file;
unsigned char leds;
unsigned char buf[40];
unsigned short pBuf = 0;
unsigned short index = 0;

#define V2EVALBOARD_V1
#ifdef V2EVALBOARD_V1
unsigned char led0 = 0x02;
unsigned char led1 = 0x04;
unsigned char led2 = 0x20;
unsigned char led3 = 0x40;
unsigned char led4 = 0x00;
#else
unsigned char led0 = 0x08;
unsigned char led1 = 0x10;
unsigned char led2 = 0x20;
unsigned char led3 = 0x40;
unsigned char led4 = 0x00;
#endif

/* Declaration for IOMUx setup function */
void iomux_setup(void);
void monError();

/* Main code - entry point to firmware */
void main(void)
{
   /* FTDI:SDD Driver Declarations */
   // SPI Slave 0 configuration context
   spislave_context_t spisContext0;
   // USB Host configuration context
   usbhost_context_t usbhostContext;
   /* FTDI:EDD */

   /* FTDI:SKI Kernel Initialisation */
   vos_init(50, VOS_TICK_INTERVAL, VOS_NUMBER_DEVICES);
   vos_set_clock_frequency(VOS_48MHZ_CLOCK_FREQUENCY);
   vos_set_idle_thread_tcb_size(256);
   /* FTDI:EKI */

   iomux_setup();

   /* FTDI:SDI Driver Initialisation */
   // Initialise SPI Slave 0
   spisContext0.buffer_size = VOS_BUFFER_SIZE_512_BYTES;
   spisContext0.slavenumber = SPI_SLAVE_0;
   spislave_init(VOS_DEV_SPI_SLAVE_1,&spisContext0);

   // Initialise FAT File System Driver
   fatdrv_init(VOS_DEV_FAT_FILE_SYSTEM);

   // Initialise USB Host
   usbhostContext.if_count = 8;
   usbhostContext.ep_count = 16;
   usbhostContext.xfer_count = 2;
   usbhostContext.iso_xfer_count = 2;
   usbhost_init(-1, VOS_DEV_USBHOST_1, &usbhostContext);
   /* FTDI:EDI */

   /* FTDI:SCT Thread Creation */
   vos_create_thread_ex(25, 1024, setup, "Setup", 0);
   vos_create_thread_ex(24, 1024, SPISlave, "Read", 0);
   /* FTDI:ECT */

   vos_init_semaphore(&setupSem, 0);
   vos_init_semaphore(&dataSem, 0);
   vos_init_mutex(&mBufAccess, VOS_MUTEX_UNLOCKED);

   vos_start_scheduler();
   
main_loop:
   goto main_loop;
}

/* FTDI:SSP Support Functions */

unsigned char usbhost_connect_state(VOS_HANDLE hUSB)
{
   unsigned char connectstate = PORT_STATE_DISCONNECTED;
   usbhost_ioctl_cb_t hc_iocb;

   if (hUSB)
   {
      hc_iocb.ioctl_code = VOS_IOCTL_USBHOST_GET_CONNECT_STATE;
      hc_iocb.get        = &connectstate;
      vos_dev_ioctl(hUSB, &hc_iocb);

      // repeat if connected to see if we move to enumerated
      if (connectstate == PORT_STATE_CONNECTED)
      {
         vos_dev_ioctl(hUSB, &hc_iocb);
      }
   }
   return connectstate;
}

/* FTDI:ESP */

void open_drivers(void)
{
        /* Code for opening and closing drivers - move to required places in Application Threads */
        /* FTDI:SDA Driver Open */
        hUSBHOST_1 = vos_dev_open(VOS_DEV_USBHOST_1);
        hSPI_SLAVE_1 = vos_dev_open(VOS_DEV_SPI_SLAVE_1);
        /* FTDI:EDA */
}

void monError()
{
   unsigned char leds;
   leds = led4;
   vos_gpio_write_port(GPIO_PORT_A, leds);
}

void setup()
{
   // Open a handle to all our devices...
   unsigned char status = 0;
   common_ioctl_cb_t spi_iocb;
   fat_context *fat_ctx = NULL;
   open_drivers();
   if (hUSBHOST_1 == NULL)
   {
      monError(); return;
   }

   // Set all pins to output.
   vos_gpio_set_port_mode(GPIO_PORT_A, 0xff);

   // SPI Slave setup...
   spi_iocb.ioctl_code = VOS_IOCTL_SPI_SLAVE_SCK_CPHA;
   spi_iocb.set.param = SPI_SLAVE_SCK_CPHA_0; // SPI_SLAVE_SCK_CPHA_0;
   vos_dev_ioctl(hSPI_SLAVE_1,&spi_iocb);

   spi_iocb.ioctl_code = VOS_IOCTL_SPI_SLAVE_SCK_CPOL;
   spi_iocb.set.param = SPI_SLAVE_SCK_CPOL_0; // SPI_SLAVE_SCK_CPOL_0;
   vos_dev_ioctl(hSPI_SLAVE_1,&spi_iocb);

   spi_iocb.ioctl_code = VOS_IOCTL_SPI_SLAVE_DATA_ORDER;
   spi_iocb.set.param = SPI_SLAVE_DATA_ORDER_MSB;
   vos_dev_ioctl(hSPI_SLAVE_1,&spi_iocb);

   spi_iocb.ioctl_code = VOS_IOCTL_SPI_SLAVE_SET_ADDRESS;
   spi_iocb.set.param = 0;
   vos_dev_ioctl(hSPI_SLAVE_1,&spi_iocb);

   spi_iocb.ioctl_code = VOS_IOCTL_SPI_SLAVE_SET_MODE;
   spi_iocb.set.param = SPI_SLAVE_MODE_UNMANAGED;
   vos_dev_ioctl(hSPI_SLAVE_1,&spi_iocb);

   vos_signal_semaphore(&setupSem);
}

void SPISlave()
{
   unsigned short numRead;
   common_ioctl_cb_t spi_iocb;
   unsigned short dataAvail = 0;
   unsigned char testdata;
   
   common_ioctl_cb_t spi_iocb2;
   unsigned short dataTx = 0;
   unsigned char report_buffer[15];
   unsigned short num_xfer;
   
   common_ioctl_cb_t uart_iocb;

   vos_wait_semaphore(&setupSem);
   vos_memset(report_buffer, 0, 15);

   while(1)
   {
         report_buffer[0] = 0x10;
         report_buffer[1] = 0x20;
         report_buffer[2] = 0x30;
         report_buffer[3] = 0x40;
         report_buffer[4] = 0x50;
         report_buffer[5] = 0x60;
         report_buffer[6] = 0x70;
         report_buffer[7] = 0x80;
         report_buffer[8] = 0x90;
         report_buffer[9] = 0xA0;
         report_buffer[10] = 0xB0;
         report_buffer[11] = 0xC0;
         report_buffer[12] = 0xD0;
         report_buffer[13] = 0xE0;
         report_buffer[14] = 0xF0;
         
         vos_dev_write(hSPI_SLAVE_1, &report_buffer[0], 15, &num_xfer);
         spi_iocb2.ioctl_code = VOS_IOCTL_COMMON_GET_TX_QUEUE_STATUS;
            vos_dev_ioctl(hSPI_SLAVE_1, &spi_iocb2);
            dataTx = spi_iocb2.get.queue_stat; // How much data is there?
      
   }
}

===========

Logged

FTDI Community

  • Administrator
  • Hero Member
  • *****
  • Posts: 800
    • View Profile

Hi Yvonne,

The 1MHz clock should be theoretically possible. It states in section 4.2.1.1 of the VNC2 user guide that The SPI Slave and SPI Master can operate at frequencies up to one quarter of the CPU clock frequency. The SPI Master can go as low as 1/256th of the CPU clock frequency.

You should have a look at section 6 of Vinculum II User Guide, this goes over the interrupt library available on VNC2. The sample code you have modified had interrupts disabled, but you can enable them. you can try to use the function attachInterrupt() on vos_dev_write to see if this fixes your issue.

 
Logged

Yvonne

  • Newbie
  • *
  • Posts: 5
    • View Profile

Hello,

Thank you for the suggestion for the interrupt library of VNC2 in the pdf document of Vinculum II User Guide.

Afterwards, I modified the sample code by enabling the DMA mode in the VNC2 SPI slave configuration using the following code. This works on my case for 1 MHz clock frequency of  VNC2 SPI. Hope this helps others who encounter the same issue.

// enable DMA
spi_iocb.ioctl_code = VOS_IOCTL_COMMON_ENABLE_DMA;
spi_iocb.set = DMA_ACQUIRE_AS_REQUIRED;
vos_dev_ioctl(hSPI_SLAVE_1,&spi_iocb);

Thank you very much!
Yvonne

Logged