You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
2.8 KiB
120 lines
2.8 KiB
#include "ftdi_daemon.h"
|
|
|
|
struct ftdi_context ftdic;
|
|
|
|
uint8_t USB_GPIO_DDR;
|
|
uint8_t USB_GPIO_PORT;
|
|
uint8_t USB_GPIO_PIN;
|
|
|
|
volatile uint8_t main_loop=1;
|
|
|
|
static int vendor=0x0403, device=0x6001;
|
|
|
|
|
|
|
|
static int is_output(unsigned offset){
|
|
return !!((USB_GPIO_DDR)&(1<<offset));
|
|
}
|
|
|
|
static int is_high(unsigned offset){
|
|
return !!((USB_GPIO_PORT)&(1<<offset));
|
|
}
|
|
|
|
static int update_mode(void){
|
|
if( ftdi_set_bitmode(&ftdic, USB_GPIO_DDR, BITMODE_BITBANG)<0 ){
|
|
printf("%s: Can't enter FTDIs bitbang mode (%04x:%04x)!\n",MOD_NAME,vendor,device);
|
|
printf("%s: %s\n",MOD_NAME,ftdi_get_error_string(&ftdic));
|
|
return -EIO;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int get_value(unsigned offset){
|
|
DEBUG_OUT("%s: GET_VALUE of pin%d ",MOD_NAME,offset);
|
|
if( !is_output(offset) ){
|
|
while( ftdic.readbuffer_remaining > 0 ){
|
|
if( ftdi_read_data(&ftdic,&USB_GPIO_PIN,1) < 0){
|
|
printf("%s: Unable to read pin%d \n",MOD_NAME,offset);
|
|
}
|
|
}
|
|
return !!((USB_GPIO_PIN) & (1<<offset));
|
|
}
|
|
return 0;
|
|
}
|
|
static void set_value(unsigned offset, int value){
|
|
DEBUG_OUT("%s: SET_VALUE of pin%d to %d",MOD_NAME,offset,value);
|
|
|
|
if( !is_output(offset) ){
|
|
if(value && !is_high(offset)){
|
|
if( ftdi_write_data(&ftdic,&USB_GPIO_PORT,1) < 0){
|
|
printf("%s: Unable to set pin%d to value %d\n",MOD_NAME,offset,value);
|
|
}
|
|
}else if(!value && is_high(offset)){
|
|
if( ftdi_write_data(&ftdic,&USB_GPIO_PORT,1) < 0){
|
|
printf("%s: Unable to set pin%d to value %d\n",MOD_NAME,offset,value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static int set_in(unsigned offset){
|
|
DEBUG_OUT("%s: SET_INPUT of pin%d ",MOD_NAME,offset);
|
|
|
|
USB_GPIO_DDR &= ~(1<<offset);
|
|
return update_mode();
|
|
}
|
|
static int set_out(unsigned offset, int value){
|
|
DEBUG_OUT("%s: SET_OUTPUT of pin%d to %d",MOD_NAME,offset,value);
|
|
|
|
USB_GPIO_DDR |= (1<<offset);
|
|
return update_mode();
|
|
}
|
|
|
|
static int ftdi_chip_init(){
|
|
// Init FTDI lib
|
|
if( ftdi_init(&ftdic)<0 ){
|
|
printf("%s: Can't initialize FTDI-lib!\n",MOD_NAME);
|
|
return ENOMEM;
|
|
}
|
|
|
|
// Open device
|
|
if(ftdi_usb_open(&ftdic, vendor, device)<0) {
|
|
printf("%s: Can't open FTDI chip (%04x:%04x)!\n",MOD_NAME,vendor,device);
|
|
printf("%s: %s\n",MOD_NAME,ftdi_get_error_string(&ftdic));
|
|
return ENXIO;
|
|
}
|
|
// Put device into bitbang modes
|
|
if( ftdi_set_bitmode(&ftdic, 0x00, BITMODE_BITBANG)<0 ){
|
|
printf("%s: Can't enter FTDIs bitbang mode (%04x:%04x)!\n",MOD_NAME,vendor,device);
|
|
printf("%s: %s\n",MOD_NAME,ftdi_get_error_string(&ftdic));
|
|
return EIO;
|
|
}
|
|
|
|
//All pins input
|
|
USB_GPIO_DDR = 0x00;
|
|
//No port set
|
|
USB_GPIO_PORT = 0x00;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void ftdi_chip_exit(){
|
|
if( ftdi_disable_bitbang(&ftdic)<0 ){
|
|
printf("%s: Can't reset FTDI (%04x:%04x)!\n",MOD_NAME,vendor,device);
|
|
}
|
|
}
|
|
|
|
int main(void){
|
|
int ret=ftdi_chip_init();
|
|
if(ret!=0){
|
|
return ret;
|
|
}
|
|
|
|
for(;main_loop;){
|
|
//Sleep mostly
|
|
}
|
|
|
|
ftdi_chip_exit();
|
|
return 0;
|
|
}
|
|
|
|
|