/** ****************************************************************************** * * @file ahrs_spi_program_master.c * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief AHRS programming over SPI link - master(OpenPilot) end. * * @see The GNU Public License (GPL) Version 3 * *****************************************************************************/ /* * 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, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "openpilot.h" #include "ahrs_spi_program_master.h" #include "ahrs_spi_program.h" #include "pios_spi.h" PROGERR TransferPacket(uint32_t spi_id, AhrsProgramPacket *txBuf, AhrsProgramPacket *rxBuf); #define MAX_CONNECT_TRIES 500 //half a second bool AhrsProgramConnect(uint32_t spi_id) { AhrsProgramPacket rxBuf; AhrsProgramPacket txBuf; memset(&rxBuf, 0, sizeof(AhrsProgramPacket)); memcpy(&txBuf,SPI_PROGRAM_REQUEST,SPI_PROGRAM_REQUEST_LENGTH); for(int ct = 0; ct < MAX_CONNECT_TRIES; ct++) { PIOS_SPI_RC_PinSet(spi_id, 0); uint32_t res = PIOS_SPI_TransferBlock(spi_id, (uint8_t *) &txBuf, (uint8_t *) & rxBuf, SPI_PROGRAM_REQUEST_LENGTH +1, NULL); PIOS_SPI_RC_PinSet(spi_id, 1); if(res == 0 && memcmp(&rxBuf, SPI_PROGRAM_ACK, SPI_PROGRAM_REQUEST_LENGTH) == 0) { return (true); } vTaskDelay(1 / portTICK_RATE_MS); } return (false); } PROGERR AhrsProgramWrite(uint32_t spi_id, uint32_t address, void * data, uint32_t size) { AhrsProgramPacket rxBuf; AhrsProgramPacket txBuf; memset(&rxBuf, 0, sizeof(AhrsProgramPacket)); memcpy(txBuf.data,data,size); txBuf.size = size; txBuf.type = PROGRAM_WRITE; txBuf.address = address; PROGERR ret = TransferPacket(spi_id, &txBuf, &rxBuf); if(ret != PROGRAM_ERR_OK) { return(ret); } return(PROGRAM_ERR_OK); } PROGERR AhrsProgramRead(uint32_t spi_id, uint32_t address, void * data, uint32_t size) { AhrsProgramPacket rxBuf; AhrsProgramPacket txBuf; memset(&rxBuf, 0, sizeof(AhrsProgramPacket)); txBuf.size = size; txBuf.type = PROGRAM_READ; txBuf.address = address; PROGERR ret = TransferPacket(spi_id, &txBuf, &rxBuf); if(ret != PROGRAM_ERR_OK) { return(ret); } memcpy(data, rxBuf.data, size); return(PROGRAM_ERR_OK); } PROGERR AhrsProgramReboot(uint32_t spi_id) { AhrsProgramPacket rxBuf; AhrsProgramPacket txBuf; memset(&rxBuf, 0, sizeof(AhrsProgramPacket)); txBuf.type = PROGRAM_REBOOT; memcpy(txBuf.data,REBOOT_CONFIRMATION,REBOOT_CONFIRMATION_LENGTH); PROGERR ret = TransferPacket(spi_id, &txBuf, &rxBuf); //If AHRS has rebooted we will get comms errors if(ret == PROGRAM_ERR_LINK) { return(PROGRAM_ERR_OK); } return(PROGRAM_ERR_FUNCTION); } PROGERR TransferPacket(uint32_t spi_id, AhrsProgramPacket *txBuf, AhrsProgramPacket *rxBuf) { static uint32_t pktId = 0; pktId++; txBuf->packetId = pktId; txBuf->crc = GenerateCRC(txBuf); int ct = 0; for(; ct < MAX_CONNECT_TRIES; ct++) { PIOS_SPI_RC_PinSet(spi_id, 0); uint32_t res = PIOS_SPI_TransferBlock(spi_id, (uint8_t *) txBuf, (uint8_t *) rxBuf, sizeof(AhrsProgramPacket), NULL); PIOS_SPI_RC_PinSet(spi_id, 1); if(res == 0) { if(rxBuf->type != PROGRAM_NULL && rxBuf->crc == GenerateCRC(rxBuf) && rxBuf->packetId == pktId) { break; } } vTaskDelay(1 / portTICK_RATE_MS); } if(ct == MAX_CONNECT_TRIES) { return (PROGRAM_ERR_LINK); } if(rxBuf->type != PROGRAM_ACK) { return(PROGRAM_ERR_FUNCTION); } return(PROGRAM_ERR_OK); }