EtherCAT slave that reads 3 Xsens IMU's connected to a Xbus Master

Dependencies:   MODSERIAL mbed KL25Z_ClockControl

Fork of EtherCAT by First Last

EtherCAT/esc_hw.cpp

Committer:
vsluiter
Date:
2014-12-11
Revision:
1:5e22bf1a3817

File content as of revision 1:5e22bf1a3817:

/*
 * SOES Simple Open EtherCAT Slave
 *
 * File    : esc_hw.c
 * Version : 0.9.2
 * Date    : 22-02-2010
 * Copyright (C) 2007-2010 Arthur Ketels
 *
 * SOES is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License version 2 as published by the Free
 * Software Foundation.
 *
 * SOES is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * As a special exception, if other files instantiate templates or use macros
 * or inline functions from this file, or you compile this file and link it
 * with other works to produce a work based on this file, this file does not
 * by itself cause the resulting work to be covered by the GNU General Public
 * License. However the source code for this file must still be made available
 * in accordance with section (3) of the GNU General Public License.
 *
 * This exception does not invalidate any other reasons why a work based on
 * this file might be covered by the GNU General Public License.
 *
 * The EtherCAT Technology, the trade name and logo "EtherCAT" are the intellectual
 * property of, and protected by Beckhoff Automation GmbH.
 */
#include "cpuinit.h"
#include "utypes.h"

#define ESC_CMD_READ    0x02
#define ESC_CMD_READWS  0x03
#define ESC_CMD_WRITE   0x04
#define ESC_CMD_NOP     0x00
#define ESC_TERM        0xff
#define ESC_NEXT        0x00

#ifndef WSREAD

/** \fn uint8 ESC_read(uint16 address, void *buf, uint8 len, void *tALevent)
    \brief Read a value from the ESC.
    \param address ESC address
    \param *buf pointer to buffer of uint8s in RAM
    \param len length of buffer in RAM
    \param *tALevent pointer to Application Layer event
*/
uint8 ESC_read(uint16 address, void *buf, uint8 len, void *tALevent)
{
    uint8 pstat;
    uint8 count;
    uint8 *ptr;
    uint16union adr;
    //SPI_Cmd(SPI1, ENABLE); //pull nSS low
    //GPIO_ResetBits(GPIOA, GPIO_Pin_4);
    et1100_ss.write(0);
    adr.w = address << 3;
    pstat = !et1100_miso.read(); //last cmd result; read MISO pin state and invert
    ptr = (uint8_t *)tALevent;
    *ptr = et1100_spi.write(adr.b[1]);  //write first address byte
    ptr++;                                                        //increase write pointer
    *ptr = et1100_spi.write(adr.b[0] + ESC_CMD_READ);        //write second address byte, with read command
    count = len;                                                  //
    ptr = (uint8_t *)buf;                                                    //let ptr point to the buffer location
    while (count > 1) {                                           //while number of received bytes is smaller than len
        *ptr = et1100_spi.write(ESC_NEXT);                                 //write dummy byte to start transaction
        count--;                                                      //decrease bytecounter
        ptr++;                                                        //increase buffer pointer
    }
    *ptr = et1100_spi.write( ESC_TERM);                                //write last byte

    //SPI_Cmd(SPI1, DISABLE);                                       //set SS high
    et1100_ss.write(1);
    return pstat;      //return inverted MISO state from previous transaction
}
#endif

#ifdef WSREAD
// use read with wait state byte, needed if SPI>12Mhz or>16KB addressing
/** void ESC_read(uint16 address, void *buf, uint8 len, void *tALevent)
    \brief read function for SPI ESC interface ("PDI")
    \param address - address of register in ESC
    \param *buf pointer to read buffer in microcontroller
    \param len  length of memory section to read, from start of 'address'
    \param *tAlevent microcontroller status register to write response to
*/
uint8 ESC_read(uint16 address, void *buf, uint8 len, void *tALevent)
{
    uint8 pstat;
    uint8 count;
    uint8 *ptr;
    uint16union adr;
    //SPI_Cmd(SPI1, ENABLE); //pull nSS low
    et1100_ss.write(0);
    adr.w = address << 3;
    pstat = !et1100_miso.read();
        ptr = tALevent;
    *ptr = et1100_spi.write(adr.b[1]);                                //write first address byte
    ptr++;                                                        //increase write pointer
    *ptr = et1100_spi.write(adr.b[0] + ESC_CMD_READWS);               //write second address byte, with readws command
    et1100_spi.write( ESC_TERM);		                        //write byte to start transaction //COMMENT: Why not ESC_NEXT?
    ptr = buf;			                                        //change ptr to point to buffer
    count = len;                                                  //
    while (count > 1) {                                           //while number of received bytes is smaller than len
        *(ptr) = et1100_spi.write( ESC_NEXT);                         //write dummy byte to start transaction
        count--;                                                      //decrease bytecounter
        ptr++;                                                        //increase buffer pointer
    }
    *(ptr) = et1100_spi.write( ESC_TERM);                                //write last byte
    //SPI_Cmd(SPI1, DISABLE);                               //set SS high
    et1100_ss.write(1);
    return pstat;                                                 //return inverted MISO state from previous transaction
}
#endif

/** void ESC_write(uint16 address, void *buf, uint8 len, void *tALevent)
    \brief write function for SPI ESC interface ("PDI")
    \param address - address of register in ESC
    \param *buf pointer to data buffer in microcontroller, buffer contains 'len' bytes to write to location 'address'
    \param len  length of memory section to write, from start of 'address'
    \param *tAlevent microcontroller status register to write response to
*/
uint8 ESC_write(uint16 address, void *buf, uint8 len, void *tALevent)
{
    uint8 pstat;
    uint8 count;
    uint8 *ptr;
    uint16union adr;
    adr.w = address << 3;                                      //shift 16-bit address value 3 places, then write to adr (union of uint16 and uint8[2])
    pstat = !3;                                        //last cmd result   ///////COMMENT: Shouldn't this be  pstat = !(PINB & (1 << i_spimiso));? Otherwise just return 0
    //SPI_Cmd(SPI1, ENABLE); //pull nSS low
    et1100_ss.write(0);
    ptr = (uint8_t *)tALevent;                                            //set pointer to tAlevent
    *ptr = et1100_spi.write( adr.b[1]);                                   //write first address byte
    ptr++;                                                     //increase pointer to second byte of tAlevent
    *ptr = et1100_spi.write(adr.b[0] + ESC_CMD_WRITE);                   //write second address byte with write command
    count = len;                                               //
    ptr = (uint8_t *)buf;                                                 //set pointer to buffer location
    while (count > 0) {                                        //while number of received bytes is smaller than len
        et1100_spi.write( *(ptr));                                        //write byte from buffer
        ptr++;                                                        //increase buffer pointer
        count--;                                                      //decrease counter
    }
    //SPI_Cmd(SPI1, DISABLE);                              //set SS high
    et1100_ss.write(1);
    return pstat;
}