EtherCAT slave that reads 3 Xsens IMU's connected to a Xbus Master
Dependencies: MODSERIAL mbed KL25Z_ClockControl
Fork of EtherCAT by
EtherCAT/esc_hw.cpp@1:5e22bf1a3817, 2014-12-11 (annotated)
- Committer:
- vsluiter
- Date:
- Thu Dec 11 21:16:00 2014 +0000
- Revision:
- 1:5e22bf1a3817
Working slave;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
vsluiter | 1:5e22bf1a3817 | 1 | /* |
vsluiter | 1:5e22bf1a3817 | 2 | * SOES Simple Open EtherCAT Slave |
vsluiter | 1:5e22bf1a3817 | 3 | * |
vsluiter | 1:5e22bf1a3817 | 4 | * File : esc_hw.c |
vsluiter | 1:5e22bf1a3817 | 5 | * Version : 0.9.2 |
vsluiter | 1:5e22bf1a3817 | 6 | * Date : 22-02-2010 |
vsluiter | 1:5e22bf1a3817 | 7 | * Copyright (C) 2007-2010 Arthur Ketels |
vsluiter | 1:5e22bf1a3817 | 8 | * |
vsluiter | 1:5e22bf1a3817 | 9 | * SOES is free software; you can redistribute it and/or modify it under |
vsluiter | 1:5e22bf1a3817 | 10 | * the terms of the GNU General Public License version 2 as published by the Free |
vsluiter | 1:5e22bf1a3817 | 11 | * Software Foundation. |
vsluiter | 1:5e22bf1a3817 | 12 | * |
vsluiter | 1:5e22bf1a3817 | 13 | * SOES is distributed in the hope that it will be useful, but WITHOUT ANY |
vsluiter | 1:5e22bf1a3817 | 14 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or |
vsluiter | 1:5e22bf1a3817 | 15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
vsluiter | 1:5e22bf1a3817 | 16 | * for more details. |
vsluiter | 1:5e22bf1a3817 | 17 | * |
vsluiter | 1:5e22bf1a3817 | 18 | * As a special exception, if other files instantiate templates or use macros |
vsluiter | 1:5e22bf1a3817 | 19 | * or inline functions from this file, or you compile this file and link it |
vsluiter | 1:5e22bf1a3817 | 20 | * with other works to produce a work based on this file, this file does not |
vsluiter | 1:5e22bf1a3817 | 21 | * by itself cause the resulting work to be covered by the GNU General Public |
vsluiter | 1:5e22bf1a3817 | 22 | * License. However the source code for this file must still be made available |
vsluiter | 1:5e22bf1a3817 | 23 | * in accordance with section (3) of the GNU General Public License. |
vsluiter | 1:5e22bf1a3817 | 24 | * |
vsluiter | 1:5e22bf1a3817 | 25 | * This exception does not invalidate any other reasons why a work based on |
vsluiter | 1:5e22bf1a3817 | 26 | * this file might be covered by the GNU General Public License. |
vsluiter | 1:5e22bf1a3817 | 27 | * |
vsluiter | 1:5e22bf1a3817 | 28 | * The EtherCAT Technology, the trade name and logo "EtherCAT" are the intellectual |
vsluiter | 1:5e22bf1a3817 | 29 | * property of, and protected by Beckhoff Automation GmbH. |
vsluiter | 1:5e22bf1a3817 | 30 | */ |
vsluiter | 1:5e22bf1a3817 | 31 | #include "cpuinit.h" |
vsluiter | 1:5e22bf1a3817 | 32 | #include "utypes.h" |
vsluiter | 1:5e22bf1a3817 | 33 | |
vsluiter | 1:5e22bf1a3817 | 34 | #define ESC_CMD_READ 0x02 |
vsluiter | 1:5e22bf1a3817 | 35 | #define ESC_CMD_READWS 0x03 |
vsluiter | 1:5e22bf1a3817 | 36 | #define ESC_CMD_WRITE 0x04 |
vsluiter | 1:5e22bf1a3817 | 37 | #define ESC_CMD_NOP 0x00 |
vsluiter | 1:5e22bf1a3817 | 38 | #define ESC_TERM 0xff |
vsluiter | 1:5e22bf1a3817 | 39 | #define ESC_NEXT 0x00 |
vsluiter | 1:5e22bf1a3817 | 40 | |
vsluiter | 1:5e22bf1a3817 | 41 | #ifndef WSREAD |
vsluiter | 1:5e22bf1a3817 | 42 | |
vsluiter | 1:5e22bf1a3817 | 43 | /** \fn uint8 ESC_read(uint16 address, void *buf, uint8 len, void *tALevent) |
vsluiter | 1:5e22bf1a3817 | 44 | \brief Read a value from the ESC. |
vsluiter | 1:5e22bf1a3817 | 45 | \param address ESC address |
vsluiter | 1:5e22bf1a3817 | 46 | \param *buf pointer to buffer of uint8s in RAM |
vsluiter | 1:5e22bf1a3817 | 47 | \param len length of buffer in RAM |
vsluiter | 1:5e22bf1a3817 | 48 | \param *tALevent pointer to Application Layer event |
vsluiter | 1:5e22bf1a3817 | 49 | */ |
vsluiter | 1:5e22bf1a3817 | 50 | uint8 ESC_read(uint16 address, void *buf, uint8 len, void *tALevent) |
vsluiter | 1:5e22bf1a3817 | 51 | { |
vsluiter | 1:5e22bf1a3817 | 52 | uint8 pstat; |
vsluiter | 1:5e22bf1a3817 | 53 | uint8 count; |
vsluiter | 1:5e22bf1a3817 | 54 | uint8 *ptr; |
vsluiter | 1:5e22bf1a3817 | 55 | uint16union adr; |
vsluiter | 1:5e22bf1a3817 | 56 | //SPI_Cmd(SPI1, ENABLE); //pull nSS low |
vsluiter | 1:5e22bf1a3817 | 57 | //GPIO_ResetBits(GPIOA, GPIO_Pin_4); |
vsluiter | 1:5e22bf1a3817 | 58 | et1100_ss.write(0); |
vsluiter | 1:5e22bf1a3817 | 59 | adr.w = address << 3; |
vsluiter | 1:5e22bf1a3817 | 60 | pstat = !et1100_miso.read(); //last cmd result; read MISO pin state and invert |
vsluiter | 1:5e22bf1a3817 | 61 | ptr = (uint8_t *)tALevent; |
vsluiter | 1:5e22bf1a3817 | 62 | *ptr = et1100_spi.write(adr.b[1]); //write first address byte |
vsluiter | 1:5e22bf1a3817 | 63 | ptr++; //increase write pointer |
vsluiter | 1:5e22bf1a3817 | 64 | *ptr = et1100_spi.write(adr.b[0] + ESC_CMD_READ); //write second address byte, with read command |
vsluiter | 1:5e22bf1a3817 | 65 | count = len; // |
vsluiter | 1:5e22bf1a3817 | 66 | ptr = (uint8_t *)buf; //let ptr point to the buffer location |
vsluiter | 1:5e22bf1a3817 | 67 | while (count > 1) { //while number of received bytes is smaller than len |
vsluiter | 1:5e22bf1a3817 | 68 | *ptr = et1100_spi.write(ESC_NEXT); //write dummy byte to start transaction |
vsluiter | 1:5e22bf1a3817 | 69 | count--; //decrease bytecounter |
vsluiter | 1:5e22bf1a3817 | 70 | ptr++; //increase buffer pointer |
vsluiter | 1:5e22bf1a3817 | 71 | } |
vsluiter | 1:5e22bf1a3817 | 72 | *ptr = et1100_spi.write( ESC_TERM); //write last byte |
vsluiter | 1:5e22bf1a3817 | 73 | |
vsluiter | 1:5e22bf1a3817 | 74 | //SPI_Cmd(SPI1, DISABLE); //set SS high |
vsluiter | 1:5e22bf1a3817 | 75 | et1100_ss.write(1); |
vsluiter | 1:5e22bf1a3817 | 76 | return pstat; //return inverted MISO state from previous transaction |
vsluiter | 1:5e22bf1a3817 | 77 | } |
vsluiter | 1:5e22bf1a3817 | 78 | #endif |
vsluiter | 1:5e22bf1a3817 | 79 | |
vsluiter | 1:5e22bf1a3817 | 80 | #ifdef WSREAD |
vsluiter | 1:5e22bf1a3817 | 81 | // use read with wait state byte, needed if SPI>12Mhz or>16KB addressing |
vsluiter | 1:5e22bf1a3817 | 82 | /** void ESC_read(uint16 address, void *buf, uint8 len, void *tALevent) |
vsluiter | 1:5e22bf1a3817 | 83 | \brief read function for SPI ESC interface ("PDI") |
vsluiter | 1:5e22bf1a3817 | 84 | \param address - address of register in ESC |
vsluiter | 1:5e22bf1a3817 | 85 | \param *buf pointer to read buffer in microcontroller |
vsluiter | 1:5e22bf1a3817 | 86 | \param len length of memory section to read, from start of 'address' |
vsluiter | 1:5e22bf1a3817 | 87 | \param *tAlevent microcontroller status register to write response to |
vsluiter | 1:5e22bf1a3817 | 88 | */ |
vsluiter | 1:5e22bf1a3817 | 89 | uint8 ESC_read(uint16 address, void *buf, uint8 len, void *tALevent) |
vsluiter | 1:5e22bf1a3817 | 90 | { |
vsluiter | 1:5e22bf1a3817 | 91 | uint8 pstat; |
vsluiter | 1:5e22bf1a3817 | 92 | uint8 count; |
vsluiter | 1:5e22bf1a3817 | 93 | uint8 *ptr; |
vsluiter | 1:5e22bf1a3817 | 94 | uint16union adr; |
vsluiter | 1:5e22bf1a3817 | 95 | //SPI_Cmd(SPI1, ENABLE); //pull nSS low |
vsluiter | 1:5e22bf1a3817 | 96 | et1100_ss.write(0); |
vsluiter | 1:5e22bf1a3817 | 97 | adr.w = address << 3; |
vsluiter | 1:5e22bf1a3817 | 98 | pstat = !et1100_miso.read(); |
vsluiter | 1:5e22bf1a3817 | 99 | ptr = tALevent; |
vsluiter | 1:5e22bf1a3817 | 100 | *ptr = et1100_spi.write(adr.b[1]); //write first address byte |
vsluiter | 1:5e22bf1a3817 | 101 | ptr++; //increase write pointer |
vsluiter | 1:5e22bf1a3817 | 102 | *ptr = et1100_spi.write(adr.b[0] + ESC_CMD_READWS); //write second address byte, with readws command |
vsluiter | 1:5e22bf1a3817 | 103 | et1100_spi.write( ESC_TERM); //write byte to start transaction //COMMENT: Why not ESC_NEXT? |
vsluiter | 1:5e22bf1a3817 | 104 | ptr = buf; //change ptr to point to buffer |
vsluiter | 1:5e22bf1a3817 | 105 | count = len; // |
vsluiter | 1:5e22bf1a3817 | 106 | while (count > 1) { //while number of received bytes is smaller than len |
vsluiter | 1:5e22bf1a3817 | 107 | *(ptr) = et1100_spi.write( ESC_NEXT); //write dummy byte to start transaction |
vsluiter | 1:5e22bf1a3817 | 108 | count--; //decrease bytecounter |
vsluiter | 1:5e22bf1a3817 | 109 | ptr++; //increase buffer pointer |
vsluiter | 1:5e22bf1a3817 | 110 | } |
vsluiter | 1:5e22bf1a3817 | 111 | *(ptr) = et1100_spi.write( ESC_TERM); //write last byte |
vsluiter | 1:5e22bf1a3817 | 112 | //SPI_Cmd(SPI1, DISABLE); //set SS high |
vsluiter | 1:5e22bf1a3817 | 113 | et1100_ss.write(1); |
vsluiter | 1:5e22bf1a3817 | 114 | return pstat; //return inverted MISO state from previous transaction |
vsluiter | 1:5e22bf1a3817 | 115 | } |
vsluiter | 1:5e22bf1a3817 | 116 | #endif |
vsluiter | 1:5e22bf1a3817 | 117 | |
vsluiter | 1:5e22bf1a3817 | 118 | /** void ESC_write(uint16 address, void *buf, uint8 len, void *tALevent) |
vsluiter | 1:5e22bf1a3817 | 119 | \brief write function for SPI ESC interface ("PDI") |
vsluiter | 1:5e22bf1a3817 | 120 | \param address - address of register in ESC |
vsluiter | 1:5e22bf1a3817 | 121 | \param *buf pointer to data buffer in microcontroller, buffer contains 'len' bytes to write to location 'address' |
vsluiter | 1:5e22bf1a3817 | 122 | \param len length of memory section to write, from start of 'address' |
vsluiter | 1:5e22bf1a3817 | 123 | \param *tAlevent microcontroller status register to write response to |
vsluiter | 1:5e22bf1a3817 | 124 | */ |
vsluiter | 1:5e22bf1a3817 | 125 | uint8 ESC_write(uint16 address, void *buf, uint8 len, void *tALevent) |
vsluiter | 1:5e22bf1a3817 | 126 | { |
vsluiter | 1:5e22bf1a3817 | 127 | uint8 pstat; |
vsluiter | 1:5e22bf1a3817 | 128 | uint8 count; |
vsluiter | 1:5e22bf1a3817 | 129 | uint8 *ptr; |
vsluiter | 1:5e22bf1a3817 | 130 | uint16union adr; |
vsluiter | 1:5e22bf1a3817 | 131 | adr.w = address << 3; //shift 16-bit address value 3 places, then write to adr (union of uint16 and uint8[2]) |
vsluiter | 1:5e22bf1a3817 | 132 | pstat = !3; //last cmd result ///////COMMENT: Shouldn't this be pstat = !(PINB & (1 << i_spimiso));? Otherwise just return 0 |
vsluiter | 1:5e22bf1a3817 | 133 | //SPI_Cmd(SPI1, ENABLE); //pull nSS low |
vsluiter | 1:5e22bf1a3817 | 134 | et1100_ss.write(0); |
vsluiter | 1:5e22bf1a3817 | 135 | ptr = (uint8_t *)tALevent; //set pointer to tAlevent |
vsluiter | 1:5e22bf1a3817 | 136 | *ptr = et1100_spi.write( adr.b[1]); //write first address byte |
vsluiter | 1:5e22bf1a3817 | 137 | ptr++; //increase pointer to second byte of tAlevent |
vsluiter | 1:5e22bf1a3817 | 138 | *ptr = et1100_spi.write(adr.b[0] + ESC_CMD_WRITE); //write second address byte with write command |
vsluiter | 1:5e22bf1a3817 | 139 | count = len; // |
vsluiter | 1:5e22bf1a3817 | 140 | ptr = (uint8_t *)buf; //set pointer to buffer location |
vsluiter | 1:5e22bf1a3817 | 141 | while (count > 0) { //while number of received bytes is smaller than len |
vsluiter | 1:5e22bf1a3817 | 142 | et1100_spi.write( *(ptr)); //write byte from buffer |
vsluiter | 1:5e22bf1a3817 | 143 | ptr++; //increase buffer pointer |
vsluiter | 1:5e22bf1a3817 | 144 | count--; //decrease counter |
vsluiter | 1:5e22bf1a3817 | 145 | } |
vsluiter | 1:5e22bf1a3817 | 146 | //SPI_Cmd(SPI1, DISABLE); //set SS high |
vsluiter | 1:5e22bf1a3817 | 147 | et1100_ss.write(1); |
vsluiter | 1:5e22bf1a3817 | 148 | return pstat; |
vsluiter | 1:5e22bf1a3817 | 149 | } |
vsluiter | 1:5e22bf1a3817 | 150 | |
vsluiter | 1:5e22bf1a3817 | 151 |