SOES/soes/hal/rt-kernel-twrk60/esc_hw.c

128 lines
3.4 KiB
C

/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
/** \file
* \brief
* ESC hardware layer functions.
*
* Function to read and write commands to the ESC. Used to read/write ESC
* registers and memory.
*/
#include "utypes.h"
#include "../../esc.h"
#include <spi/spi.h>
#include <string.h>
#include <gpio.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
static int et1100 = -1;
static uint8_t read_termination[MAX(sizeof(Wb), 128)] = { 0 };
#define GPIO_ECAT_RESET 1 /* specific function to hold ESC reset on startup
* when emulating EEPROM
*/
static void esc_address (uint16_t address, uint8_t command)
{
/* Device is selected already.
* We use 2 bytes addressing.
*/
uint8_t data[2];
/* address 12:5 */
data[0] = (address >> 5);
/* address 4:0 and cmd 2:0 */
data[1] = ((address & 0x1F) << 3) | command;
/* Write (and read AL interrupt register) */
spi_bidirectionally_transfer (et1100, (uint8_t *) &ESCvar.ALevent,
data, sizeof (data));
ESCvar.ALevent = etohs (ESCvar.ALevent);
}
/** ESC read function used by the Slave stack.
*
* @param[in] address = address of ESC register to read
* @param[out] buf = pointer to buffer to read in
* @param[in] len = number of bytes to read
*/
void ESC_read (uint16_t address, void *buf, uint16_t len)
{
ASSERT(len <= sizeof(read_termination));
/* Select device. */
spi_select (et1100);
/* Write address and command to device. */
esc_address (address, ESC_CMD_READ);
/* Here we want to read data and keep MOSI low (0x00) during
* all bytes except the last one where we want to pull it high (0xFF).
* Read (and write termination bytes).
*/
spi_bidirectionally_transfer (et1100, buf, read_termination +
(sizeof(read_termination) - len), len);
/* Un-select device. */
spi_unselect (et1100);
}
/** ESC write function used by the Slave stack.
*
* @param[in] address = address of ESC register to write
* @param[out] buf = pointer to buffer to write from
* @param[in] len = number of bytes to write
*/
void ESC_write (uint16_t address, void *buf, uint16_t len)
{
/* Select device. */
spi_select (et1100);
/* Write address and command to device. */
esc_address (address, ESC_CMD_WRITE);
/* Write data. */
write (et1100, buf, len);
/* Un-select device. */
spi_unselect (et1100);
}
void ESC_reset (void)
{
volatile int timeout;
DPRINT("esc_reset_started\n");
gpio_set (GPIO_ECAT_RESET,0); /* pin =0 */
gpio_configure_pin (GPIO_ECAT_RESET,MUX_GPIO,IRQC_DISABLED,MODE_OUTPUT);
task_delay (1000);
gpio_configure_pin (GPIO_ECAT_RESET,MUX_GPIO,IRQC_DISABLED,MODE_INPUT);
while(timeout<10000000)
{
/* ECAT releases resetpin */
if(gpio_get (GPIO_ECAT_RESET)!=0)
{
break; // OK
}
timeout++;
task_delay (30);
}
DPRINT("esc_reset_ended\n");
}
void ESC_init (const void * arg)
{
const char * spi_name = (char *)arg;
et1100 = open (spi_name, O_RDWR, 0);
read_termination[sizeof(read_termination) - 1] = 0xFF;
}