Page MenuHomec4science

dma_spi.h
No OneTemporary

File Metadata

Created
Wed, Jun 26, 20:00

dma_spi.h

/*
* dma_spi.h
*
* Copyright (c) Alexandre Tuleu
* EPFL Biorobotics Laboratory (http://biorob.epfl.ch)
* EPFL Ecole Polytechnique Federale de Lausanne (http://www.epfl.ch)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* \file dma_sbcp.h
* DMA management for spi communications. This module uses the following DMA
* channels :
* - Channel 2 for SPI 1 Communications
* \author Alexandre Tuleu
*
*/
#ifndef DMA_SPI_H_
#define DMA_SPI_H_
#include "pindefs.h"
/*******************************************************************************
*
* Defines
*
******************************************************************************/
/**
* Latency to put before actually reading the devices. AS5045 specify a minimal
* latency of 500 ns, let put it 1us, so a frequency of 1Mhz
*/
#define FSPI_ME_READING_LATENCY 1000000
/*******************************************************************************
*
* Type definitions
*
******************************************************************************/
/**
* Th state machine states for Magnetic encoders reception
*/
typedef enum DMA_SPI_ME_rx_state {
DMA_SPI_ME_IDLE, ///< No reading is beeing performed.
DMA_SPI_ME_WAITING_FOR_DEVICES, ///< Reading is started, we send the start order to device, we putting a latency for them to read their data.
DMA_SPI_ME_READING_DEVICES, ///< We are actually reading the data from teh devices
DMA_SPI_ME_DATA_READY_TO_BE_PROCESSED ///< We have finish to read the data, and we need to process it to extract atual data in the spi_main function
}DMA_SPI_ME_rx_state;
typedef struct DMA_SPI_data {
DMA_SPI_ME_rx_state ME_rx_state;
}DMA_SPI_data;
/**
* A structire describing the bit representation of the data getted by the
* sensors. Like this we let the compiler optimize how to access it.
*/
typedef union DMA_SPI_ME_rx_buffer{
struct{
//First word definition little endian representation
unsigned Q1_LIN : 1; ///< their is a linearity read alarm, data invalid
unsigned Q1_COF : 1; ///< their is CORDIC Overflow, data invalid
unsigned Q1_OCF : 1; ///< Algorithm is finished. If zero, data invalid
unsigned Q1_ENC_DATA_LOW : 8; ///< first 8 bits of data
unsigned Q1_ENC_DATA_HIGH : 4; ///< last 4 bits of data
unsigned Q1_DUMMY_BIT : 1; ///< unimplemented
//------ 1 word size
//second word definition, little endian representation
unsigned Q2_ENC_DATA_LOW : 8; ///< first 8 bits of data
unsigned Q2_ENC_DATA_HIGH : 4; ///< last 4 bits of data
unsigned Q2_DUMMY_BIT : 1; ///< unimplemented
unsigned Q1_EVEN_PAR : 1; ///< even parity bit
unsigned Q1_MAG_DEC : 1; ///< Maginute amplitude decreased.
unsigned Q1_MAG_INC : 1; ///< Maginute amplitude increased.
//------ 1 word size
//third word little endian representation
unsigned Q3_ENC_DATA_MID : 5; ///<central 5 bits of data
unsigned Q3_ENC_DATA_HIGH : 4; ///< last 4 bits of data
unsigned Q3_DUMMY_BIT : 1; ///< unimplemented
//19 bits for the first knee encoder.
unsigned Q2_EVEN_PAR : 1; ///< even parity bit
unsigned Q2_MAG_DEC : 1; ///< Maginute amplitude decreased.
unsigned Q2_MAG_INC : 1; ///< Maginute amplitude increased.
unsigned Q2_LIN : 1; ///< their is a linearity read alarm, data invalid
unsigned Q2_COF : 1; ///< their is CORDIC Overflow, data invalid
unsigned Q2_OCF : 1; ///< Algorithm is finished. If zero, data invalid
//------ 1word size
// 4th and last word, little endian representation
//trailing 7 bits that should be ignored
unsigned DUMMY_BITS : 7; ///< unimplemented
//19 bits for the 2nd knee encoder.
unsigned Q3_EVEN_PAR : 1; ///< even parity bit
unsigned Q3_MAG_DEC : 1; ///< Maginute amplitude decreased.
unsigned Q3_MAG_INC : 1; ///< Maginute amplitude increased.
unsigned Q3_LIN : 1; ///< their is a linearity read alarm, data invalid
unsigned Q3_COF : 1; ///< their is CORDIC Overflow, data invalid
unsigned Q3_OCF : 1; ///< Algorithm is finished. If zero, data invalid
unsigned Q3_ENC_DATA_LOW : 3; ///< first 3 bits of data
//------ 1word size
} b; ///< bits representation
unsigned char B[8];///<byte representation
unsigned int w[4];///<word representation
} DMA_SPI_ME_rx_buffer;
/*******************************************************************************
*
* Memory public mapping
*
******************************************************************************/
/**
* A buffer for reciving Magnetic encoders data.(57 bytes, so we need a 64 byte
* storage)
*/
extern DMA_SPI_ME_rx_buffer dma_spi_me_rx_buffer __attribute__((space(dma)));
extern DMA_SPI_data dma_spi;
/*******************************************************************************
*
* Inlined macros, for interuption use.
*
******************************************************************************/
/**
* Ask Magnetic Encoders to prepare themself to send data. Note that we have to
* wait at least 500 ns before actually reading data. This is done with the help
* of timer 2.
*/
#define SPI_ME_START_TRANSFER do{ \
SPI1_CS = 0;\
}while(0)
/**
* Ask Magnetic Encoders to prepare themself to send data.
*/
#define SPI_ME_STOP_TRANSFER do{\
SPI1_CS = 1;\
}while(0)
/**
* Starts the reading from the SPI 1 bus wioth DMA 2 channel
*/
#define DMA_SPI_ME_START_ACTUAL_READING do{\
SPI1BUF = 0x0000; /*this will start a transfer of 4 word thanks to DMA.*/ \
dma_spi.ME_rx_state = DMA_SPI_ME_READING_DEVICES;\
}while(0)
/*******************************************************************************
*
* Public functions
*
******************************************************************************/
void spi_init();
void spi_start_reading();
void spi_main();
#endif //DMA_SPI_H_

Event Timeline