100 lines
2.3 KiB
C
100 lines
2.3 KiB
C
#include "data_channel.h"
|
|
|
|
#include <system.h>
|
|
#include <stdio.h>
|
|
#include <io.h>
|
|
|
|
const uint32_t DATA_CHANNEL_DEPTH = 1024;
|
|
const uint32_t DATA_CHANNEL_COUNT = 7;
|
|
|
|
const uint32_t DATA_CHANNEL_BASE_LIST[] = {
|
|
DATA_CHANNEL_0_BASE,
|
|
DATA_CHANNEL_1_BASE,
|
|
DATA_CHANNEL_2_BASE,
|
|
DATA_CHANNEL_3_BASE,
|
|
DATA_CHANNEL_4_BASE,
|
|
DATA_CHANNEL_5_BASE,
|
|
DATA_CHANNEL_6_BASE
|
|
};
|
|
|
|
#define REG_BINDING_OFFSET 0
|
|
#define BINDING_SINK_POS 0
|
|
#define BINDING_SOURCE_POS 1
|
|
|
|
#define REG_EMPTY_OFFSET 1
|
|
#define REG_FULL_OFFSET 2
|
|
#define REG_LEVEL_OFFSET 3
|
|
#define REG_SINK_OFFSET 4
|
|
#define REG_SOURCE_OFFSET 5
|
|
#define REG_CLEAR_OFFSET 6
|
|
|
|
void data_channel_bind( uint32_t base, const DataChannelBinding * binding ) {
|
|
|
|
uint32_t value = binding->sink << BINDING_SINK_POS |
|
|
binding->source << BINDING_SOURCE_POS;
|
|
|
|
IOWR( base, REG_BINDING_OFFSET, value );
|
|
}
|
|
|
|
uint32_t data_channel_get_binding( uint32_t base ) {
|
|
return IORD( base, REG_BINDING_OFFSET );
|
|
}
|
|
|
|
uint32_t data_channel_is_empty( uint32_t base ) {
|
|
return IORD( base, REG_EMPTY_OFFSET );
|
|
}
|
|
|
|
uint32_t data_channel_is_full( uint32_t base ) {
|
|
return IORD( base, REG_FULL_OFFSET );
|
|
}
|
|
|
|
uint32_t data_channel_level( uint32_t base ) {
|
|
return IORD( base, REG_LEVEL_OFFSET );
|
|
}
|
|
|
|
void data_channel_clear( uint32_t base ) {
|
|
IOWR( base, REG_CLEAR_OFFSET, 1 );
|
|
}
|
|
|
|
int data_channel_write( uint32_t base, uint32_t value ) {
|
|
if ( data_channel_is_full( base ) ) {
|
|
return 1;
|
|
}
|
|
IOWR( base, REG_SINK_OFFSET, value );
|
|
return 0;
|
|
}
|
|
|
|
int data_channel_write_all( uint32_t base, const uint32_t * data, uint32_t len ) {
|
|
for ( uint32_t i = 0; i < len; ++i ) {
|
|
int ret = data_channel_write( base, data[ i ] );
|
|
if ( ret ) return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int data_channel_read( uint32_t base, uint32_t * value ) {
|
|
if ( data_channel_is_empty( base ) ) {
|
|
return 1;
|
|
}
|
|
* value = IORD( base, REG_SOURCE_OFFSET );
|
|
return 0;
|
|
}
|
|
|
|
int data_channel_read_all( uint32_t base, void * buffer ) {
|
|
int i;
|
|
for ( i = 0; i < DATA_CHANNEL_DEPTH; ++i ) {
|
|
int ret = data_channel_read( base, buffer + i );
|
|
if ( ret ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
uint32_t data_channel_base_from_number( uint32_t channel ) {
|
|
return DATA_CHANNEL_BASE_LIST[ channel ];
|
|
}
|
|
|