kopia lustrzana https://github.com/OpenRTX/OpenRTX
rtxlink: implemented DAT endpoint
rodzic
52e66b27ac
commit
84ff4c2147
|
@ -49,6 +49,7 @@ openrtx_src = ['openrtx/src/core/state.c',
|
|||
'openrtx/src/core/rtxlink.c',
|
||||
'openrtx/src/core/rtxlink_cat.c',
|
||||
'openrtx/src/core/rtxlink_fmp.c',
|
||||
'openrtx/src/core/rtxlink_dat.c',
|
||||
'openrtx/src/core/datetime.c',
|
||||
'openrtx/src/core/openrtx.c',
|
||||
'openrtx/src/core/audio_codec.c',
|
||||
|
|
|
@ -38,7 +38,7 @@ enum ProtocolID
|
|||
RTXLINK_FRAME_STDIO = 0x00,
|
||||
RTXLINK_FRAME_CAT = 0x01,
|
||||
RTXLINK_FRAME_FMP = 0x02,
|
||||
RTXLINK_FRAME_XMODEM = 0x03,
|
||||
RTXLINK_FRAME_DAT = 0x03,
|
||||
|
||||
RTXLINK_NUM_PROTOCOLS
|
||||
};
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2023 by Federico Amedeo Izzo IU2NUO, *
|
||||
* Niccolò Izzo IU2KIN *
|
||||
* Frederik Saraci IU2NRO *
|
||||
* Silvano Seva IU2KWO *
|
||||
* *
|
||||
* 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/> *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef RTXLINK_DAT_H
|
||||
#define RTXLINK_DAT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
enum DatStatus
|
||||
{
|
||||
RTXLINK_DAT_IDLE,
|
||||
RTXLINK_DAT_START_READ,
|
||||
RTXLINK_DAT_READ,
|
||||
RTXLINK_DAT_WRITE
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Start an rtxlink data transfer from a nonvolatile memory area to the host
|
||||
* using the DAT protocol. The function returns immediately and data transfer
|
||||
* is done in background until all the content of the area is read.
|
||||
*
|
||||
* @param area: NVM area to be read.
|
||||
* @return zero on success, a negative error code otherwhise.
|
||||
*/
|
||||
int dat_readNvmArea(const struct nvmArea *area);
|
||||
|
||||
/**
|
||||
* Start an rtxlink data transfer from the host to a nonvolatile memory area
|
||||
* using the DAT protocol. The function returns immediately and data transfer
|
||||
* is done in background until all the content of the area is written.
|
||||
*
|
||||
* @param area: NVM area to be written.
|
||||
* @return zero on success, a negative error code otherwhise.
|
||||
*/
|
||||
int dat_writeNvmArea(const struct nvmArea *area);
|
||||
|
||||
/**
|
||||
* Get the current status of the DAT endpoint.
|
||||
*
|
||||
* @return DAT endpoint status.
|
||||
*/
|
||||
enum DatStatus dat_getStatus();
|
||||
|
||||
/**
|
||||
* Reset the DAT endpoint interrupting any transfer eventually ongoing.
|
||||
*/
|
||||
void dat_reset();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,151 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2023 by Federico Amedeo Izzo IU2NUO, *
|
||||
* Niccolò Izzo IU2KIN *
|
||||
* Frederik Saraci IU2NRO *
|
||||
* Silvano Seva IU2KWO *
|
||||
* *
|
||||
* 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/> *
|
||||
***************************************************************************/
|
||||
|
||||
#include <interfaces/nvmem.h>
|
||||
#include <nvmem_access.h>
|
||||
#include <rtxlink_dat.h>
|
||||
#include <rtxlink.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define DAT_PAYLOAD_SIZE 1024
|
||||
|
||||
#define ACK (0x06) // ACKnowledge, receive OK
|
||||
#define NAK (0x15) // Negative ACKnowledge, receiver ERROR, retry
|
||||
|
||||
static enum DatStatus status = RTXLINK_DAT_IDLE;
|
||||
static const struct nvmArea *memArea;
|
||||
static uint8_t blockCnt;
|
||||
static size_t curAddr;
|
||||
static size_t readSize;
|
||||
|
||||
static size_t datReadHandler(const uint8_t *rxData, size_t rxLen, uint8_t *txData,
|
||||
size_t txMaxLen)
|
||||
{
|
||||
(void) rxLen;
|
||||
|
||||
if(rxData[0] == ACK)
|
||||
{
|
||||
switch(status)
|
||||
{
|
||||
case RTXLINK_DAT_START_READ:
|
||||
status = RTXLINK_DAT_READ;
|
||||
break;
|
||||
|
||||
case RTXLINK_DAT_READ:
|
||||
blockCnt += 1;
|
||||
curAddr += readSize;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// Previous read ok, update the size for the next read
|
||||
readSize = memArea->size - (curAddr - memArea->startAddr);
|
||||
if(readSize == 0)
|
||||
{
|
||||
status = RTXLINK_DAT_IDLE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t maxSize = (txMaxLen > DAT_PAYLOAD_SIZE) ? DAT_PAYLOAD_SIZE : txMaxLen;
|
||||
if(readSize > maxSize)
|
||||
readSize = maxSize;
|
||||
}
|
||||
|
||||
// Read from memory and send
|
||||
txData[0] = blockCnt;
|
||||
txData[1] = blockCnt ^ 0xFF;
|
||||
nvmArea_read(memArea, curAddr, &txData[2], readSize);
|
||||
|
||||
return readSize + 2;
|
||||
}
|
||||
|
||||
static size_t datWriteHandler(const uint8_t *rxData, size_t rxLen, uint8_t *txData,
|
||||
size_t txMaxLen)
|
||||
{
|
||||
(void) txMaxLen;
|
||||
|
||||
// Set up a NACK response, overridden to ACK if everything goes well
|
||||
txData[0] = NAK;
|
||||
|
||||
// Check sequence numbers
|
||||
uint8_t bNum = rxData[0];
|
||||
uint8_t ibNum = rxData[1];
|
||||
|
||||
if(((bNum ^ ibNum) != 0xFF) || (bNum != blockCnt))
|
||||
return 1;
|
||||
|
||||
int ret = nvmArea_write(memArea, curAddr, &rxData[2], rxLen - 2);
|
||||
if(ret < 0)
|
||||
return 1;
|
||||
|
||||
// Success: prepare next block number, update address and send ACK
|
||||
blockCnt += 1;
|
||||
curAddr += (rxLen - 2);
|
||||
txData[0] = ACK;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int dat_readNvmArea(const struct nvmArea *area)
|
||||
{
|
||||
if(status != RTXLINK_DAT_IDLE)
|
||||
return -EBUSY;
|
||||
|
||||
status = RTXLINK_DAT_START_READ;
|
||||
memArea = area;
|
||||
curAddr = memArea->startAddr;
|
||||
blockCnt = 0;
|
||||
|
||||
rtxlink_setProtocolHandler(RTXLINK_FRAME_DAT, datReadHandler);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dat_writeNvmArea(const struct nvmArea *area)
|
||||
{
|
||||
if(status != RTXLINK_DAT_IDLE)
|
||||
return -EBUSY;
|
||||
|
||||
status = RTXLINK_DAT_WRITE;
|
||||
memArea = area;
|
||||
curAddr = memArea->startAddr;
|
||||
blockCnt = 0;
|
||||
|
||||
rtxlink_setProtocolHandler(RTXLINK_FRAME_DAT, datWriteHandler);
|
||||
|
||||
uint8_t ready = ACK;
|
||||
rtxlink_send(RTXLINK_FRAME_DAT, &ready, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum DatStatus dat_getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
void dat_reset()
|
||||
{
|
||||
rtxlink_removeProtocolHandler(RTXLINK_FRAME_DAT);
|
||||
status = RTXLINK_DAT_IDLE;
|
||||
}
|
Ładowanie…
Reference in New Issue