Page MenuHomec4science

sbcp_host_tx.c
No OneTemporary

File Metadata

Created
Wed, Feb 19, 22:53

sbcp_host_tx.c

#include "sbcp_host.h"
#include <p33Fxxxx.h>
#include "sbcp_bus.h"
#include <sbcp-uc/register.h>
#include <sbcp-uc/packet.h>
typedef enum host_tx_state {
HOST_TX_STATE_IDLE = 0,
HOST_TX_STATE_TX,
HOST_TX_STATE_CLEAN
} host_tx_state;
typedef struct host_tx_data {
host_tx_state state;
volatile packet_mdata * cur_pck;
} host_tx_data;
volatile host_tx_data host_tx;
void init_sbcp_host_tx_data(){
host_tx.state = HOST_TX_STATE_IDLE;
}
void __attribute__((__interrupt__ , no_auto_psv)) _DMA3Interrupt(void) {
host_tx.state = HOST_TX_STATE_CLEAN;
//clear flags
IFS2bits.DMA3IF = 0;
}
void sbcp_process_host_tx() {
//avoid race condition
IEC2bits.DMA3IE= 0;
host_tx_state state = host_tx.state;
IEC2bits.DMA3IE = 1;
//simply check if in cleaning, to free the bus packet
if ( state == HOST_TX_STATE_CLEAN ) {
release_bus_packet(host_tx.cur_pck);
//can safely change state as we are not interuptible anymore
host_tx.state = HOST_TX_STATE_IDLE;
return;
}
//we do not have anything to do when transmitting
if ( state == HOST_TX_STATE_TX ) {
return;
}
host_tx.cur_pck = next_bus_packet();
if (host_tx.cur_pck == 0) { // no packet available
return ;
}
if (host_tx.cur_pck->rx_error == PCK_RX_TERR ) {
//rewrite the packet to show an error from slave.
host_tx.cur_pck->data[SBCP_HEADER_POS] = SBCP_HEADER_VALUE;
host_tx.cur_pck->data[SBCP_CLASS_POS] = SBCP_MY_CLASS;
host_tx.cur_pck->data[SBCP_ID_POS] = SBCP_MY_ID;
host_tx.cur_pck->data[SBCP_PAYLOAD_SIZE_POS] = 0;
host_tx.cur_pck->data[SBCP_INSTRUCTION_POS] = SBCP_CERR_SLAVE_TIMEOUT;
host_tx.cur_pck->data[SBCP_PAYLOAD_START_POS] = sbcp_compute_packet_cs(host_tx.cur_pck->data);
}
DMA3CONbits.CHEN = 0;
DMA3STA = host_tx.cur_pck->dma_adr;
DMA3CNT = pck_byte_size(host_tx.cur_pck) - 1;
host_tx.state = HOST_TX_STATE_TX;
DMA3CONbits.CHEN = 1;
//do this once started !
DMA3REQbits.FORCE = 1;
}

Event Timeline