For Wire Hand
Dependencies: mbed mbed-rtos EthernetInterface
main.cpp
- Committer:
- Masayoshi
- Date:
- 2020-04-24
- Revision:
- 0:88bfb16a6ad5
File content as of revision 0:88bfb16a6ad5:
/*------------------------------------------------------------------------------
* LPC1768_OC_MULTIMODAL
*
* <DEBUG PORT>
* d19 MAIL-LOOP TOGGLE
* d20 UART1
* d21 UART3
* d22 ERROR mutil-plexer etc.
* d23
* d24 UDP RECEIVE
* d25 UDP SEND
* d26 I2C
*/
#include "mbed.h"
#include "UDPSocket.h"
#include "fdc.h"
#include "EthernetInterface.h"
#define SERIAL_CH 2
#define I2C_CH 2
// Constants
static const int NUM_AXES1 = 5;
static const int NUM_AXES2 = 4;
//static const int TX_BYTE_SIZE = 3;
//static const int RX_BYTE_SIZE = 3;
//static const int RX_RETRY_MAX = 200;
static const int NUM_AXES = NUM_AXES1 + NUM_AXES2;
//static const int UDP_TX_SIZE = sizeof(float) * NUM_AXES; // send to pc
//static const int UDP_RX_SIZE = sizeof(float) * NUM_AXES; // recv from pc
//static const int USB_BAUDRATE = 9600;
static const int ICS_BAUDRATE = 1250000;
static const int POS_MID = 7500;
static const int POS_FREE = 255;
static const uint8_t POS_COMMAND = 0x80;
static const char * NETMASK = "255.255.0.0";
static const char * GATEWAY = "0.0.0.0";
static const char * PC_ADDRESS = "192.168.1.2";
static const char * MY_ADDRESS = "192.168.1.3";
static const int PC_RX_PORT = 5000; // from pc
static const int PC_TX_PORT = 5001; // to pc
//static const int MY_PORT = 6007;
static const float MAX_DIFF_DEG = 10;
RawSerial *p_serial1, *p_serial2;;
I2C *p_i2c1, *p_i2c2;
UDPSocket s_sock;
UDPSocket r_sock;
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
// finish
uint8_t g_finish = 0; // b0:uart1 b1:uart2 b2:i2c1 b3:i2c2
uint8_t g_next = 0;
// finish bit
#define BIT_SERIAL1 0x01
#define BIT_SERIAL2 0x02
#define BIT_I2C1 0x04
#define BIT_I2C2 0x08
// udp data
typedef struct {
uint16_t seq;
uint16_t dmy;
float motorData[NUM_AXES]; // 9*4=36byte
} data_t;
union RxUnion {
data_t d;
char buf[sizeof(data_t)];
};
typedef struct {
uint16_t seq;
uint16_t dmy;
float motorData[NUM_AXES]; // 9*4=36byte
float sensorData[FDC_NUM][NUM_DEN]; // 3*4*4=48byte
} data2_t;
union TxUnion {
data2_t d;
char buf[sizeof(data2_t)];
};
RxUnion g_rx = {0};
TxUnion g_tx = {0};
Endpoint ep_pc_tx, ep_pc_rx;
// for motor value
uint8_t g_res1[3], g_res2[3]; // motor response
uint8_t g_n1, g_n2; // motor response index
int g_echoCount1, g_echoCount2; // motor command echo counter
uint8_t g_id1, g_id2; // motor id
char g_cmd1[4], g_cmd2[4]; // motor command
static inline void GenCommand(uint8_t id/*1,2,...*/, float cmd_deg, char *cmd/*OUT*/){
int32_t cmd_fit = POS_MID - int(cmd_deg * 1000 / 34.0);
cmd[0] = uint8_t(POS_COMMAND | id);
cmd[1] = uint8_t(cmd_fit >> 7);
cmd[2] = uint8_t(cmd_fit & 0x7F);
cmd[3] = 0; // null
}
static inline float ParseResponse(uint8_t id/*1,2,...*/, uint8_t *p, float pre_deg){
int act_fit = ((*(p+1) & 0x7F) << 7) + (*(p+2) & 0x7F);
float act_deg = 34 * (POS_MID - act_fit) / 1000.0;
act_deg = fabs(act_deg - pre_deg) > MAX_DIFF_DEG ? pre_deg : act_deg;
return act_deg;
}
/*Ticker ticker;
int g_tmCnt = 0;
uint8_t g_tmReq = 0;
static void tick_handler(){
if(--g_tmCnt <= 0){
if(g_tmReq == 1){
g_tmReq = 0;
led4 = 1;
}
}
}*/
static inline void wait_us(uint32_t microsec){
wait(microsec * 1e-6);
}
static inline void Serial1_puts(float val){
GenCommand(g_id1+1, val, g_cmd1); // cmd is 3byte + NULL
g_echoCount1 = 0;
g_n1 = 0;
p_serial1->putc(g_cmd1[0]); // async
//p_serial1->putc(g_cmd1[1]); // async
//p_serial1->putc(g_cmd1[2]); // async
}
static inline void Serial2_puts(float val){
GenCommand(g_id2+1, val, g_cmd2); // cmd is 3byte + NULL
g_echoCount2 = 0;
g_n2 = 0;
p_serial2->putc(g_cmd2[0]); // async
//p_serial2->putc(g_cmd2[1]); // async
//p_serial2->putc(g_cmd2[2]); // async
}
static inline void Serial1_Rx(){
g_next++;
// first is echoback. second is motor response.
uint8_t c = p_serial1->getc();
if(g_echoCount1 < 3){ // echoback is 3byte
if(++g_echoCount1 < 3){
p_serial1->putc(g_cmd1[g_echoCount1]); // async
}
return;
}
/*if(g_echoCount1-- > 0){ // echoback is 3byte
return;
}*/
// motor response.
do {
g_res1[g_n1++] = c;
if(p_serial1->readable()) {
c = p_serial1->getc();
} else break;
} while(1);
if(g_n1 == 3){ // response is 3byte
// receive data set pre_deg
g_tx.d.motorData[g_id1] = ParseResponse(g_id1+1, g_res1, g_tx.d.motorData[g_id1]);
g_id1++; // 0-4
// last check
if(g_id1 == NUM_AXES1){ // motor num is 5
g_finish |= BIT_SERIAL1; // receive finished
//d20=1;d20=0;
// next uart start
g_id2 = NUM_AXES1; // 5-8
Serial2_puts(g_rx.d.motorData[g_id2]); // serial2 start
} else {
// next id send
Serial1_puts(g_rx.d.motorData[g_id1]);
}
}
}
static inline void Serial2_Rx(){
g_next++;
// first is echoback. second is motor response.
uint8_t c = p_serial2->getc();
if(g_echoCount2 < 3){ // echoback is 3byte
if(++g_echoCount2 < 3){
p_serial2->putc(g_cmd2[g_echoCount2]); // async
}
return;
}
/*if(g_echoCount2-- > 0){ // echoback is 3byte
return;
}*/
// motor response.
do {
g_res2[g_n2++] = c;
if(p_serial2->readable()) {
c = p_serial2->getc();
} else break;
} while(1);
if(g_n2 == 3){ // response is 3byte
// receive data set pre_deg
g_tx.d.motorData[g_id2] = ParseResponse(g_id2+1, g_res2, g_tx.d.motorData[g_id2]);
g_id2++; // 0-3
// last check
if(g_id2 == NUM_AXES1 + NUM_AXES2){ // motor num is 4
g_finish |= BIT_SERIAL2; // receive finished
//d20=1;d20=0;
} else {
// next id send
Serial2_puts(g_rx.d.motorData[g_id2]);
}
}
}
static inline void setupUdp(void) {
EthernetInterface eth;
//serial_usb.printf("Setup UDP\n");
eth.init(MY_ADDRESS, NETMASK, GATEWAY);
//serial_usb.printf("eth.init()\n");
int ret;
do {
ret = eth.connect(15000); // use dhcp
} while(ret < 0);
//serial_usb.printf("eth.connect()\n");
//const char *ip = eth.getIPAddress();
//printf("IP: %s\n", ip ? ip : "No IP");
r_sock.bind(PC_RX_PORT); //rx
s_sock.bind(PC_TX_PORT); //tx
//serial_usb.printf("Port: %d\n", MY_PORT);
}
static inline void UdpReceive(){
static uint16_t seq = 0;
//char buf[128];
int ret = r_sock.receiveFrom(ep_pc_rx, g_rx.buf, sizeof(g_rx.buf));
if(ret > 0){
//UDP-RECEIVE
d24=1;d24=0;
//__disable_irq();
//memcpy(g_rx.buf, buf, sizeof(g_rx.buf));
//__enable_irq();
if(g_rx.d.seq != seq){ // seq error
g_tx.d.dmy++; // seq error count
//ERROR
d22=1;d22=0;
}
if(g_rx.d.dmy == 1){ // err count clear request
g_rx.d.dmy = 0;
g_tx.d.dmy = 0; // err count clear
}
seq = g_rx.d.seq + 1; // next sequence
}
}
int main() {
float val;
int rate = 3; // Measuring rate -- 1:100S/s, 2:200S/s, 3:400S/s
int capdac[4] = {-1,-1,-1,-1}; // -1: CAPDAC disable, >=0: CAPDAC value
bool switchResult = true;
/*--- Initialize -------------------------------------------------------------*/
//ticker.attach(&tick_handler, 0.01); // 10us
#if 1
// udp initialized.
ep_pc_rx.set_address(PC_ADDRESS, PC_RX_PORT);
ep_pc_tx.set_address(PC_ADDRESS, PC_TX_PORT);
setupUdp();
r_sock.set_blocking(false, 0); // non-blocking
s_sock.set_blocking(true, 1500); // blocking
#endif
#if 1
// serial initialized
p_serial1 = new RawSerial(p13, p14); // uart1
p_serial1->baud(ICS_BAUDRATE);
p_serial1->attach(Serial1_Rx, RawSerial::RxIrq);
p_serial1->format(8, Serial::Even, 1);
p_serial2 = new RawSerial(p17, p18); // uart3
p_serial2->baud(ICS_BAUDRATE);
p_serial2->attach(Serial2_Rx, RawSerial::RxIrq);
p_serial2->format(8, Serial::Even, 1);
#endif
#if 1
// i2c initialized
p_i2c1 = new I2C(p9, p10); // i2c1 sda,scl
p_i2c1->frequency(400000);
p_i2c2 = new I2C(p28, p27); // i2c2 sda,scl
p_i2c2->frequency(400000);
#endif
#if 1
// Initialize I2C Interface
do{
for(int i=0; i < FDC_NUM; i++) {
I2C *i2c = (i == 2)? p_i2c2 : p_i2c1;
// MULTI PLEXER
if(i != 2){
switchResult = switchI2c(i2c, i); // MUXのch0にI2Cを切替
if(!switchResult) break;
}
if (initFdc(i2c)) {
config(i2c, rate, capdac);
//pc.printf("ch %d_FDC1004 is ready.\r\n", i);
} else {
//pc.printf("ch %d_FDC1004 is not ready. Please check and restart.\r\n", i);
switchResult = false;
wait(1.0);
}
} // end_for
}while(!switchResult);
#endif
// debug port
d26 = 0;
d25 = 0;
d24 = 0;
d23 = 0;
d22 = 0;
d21 = 0;
d20 = 0;
d19 = 0;
g_finish = 0;
uint16_t seq = 0;
/*--- MAIN LOOP --------------------------------------------------------------*/
while(1) {
d19=!d19; //main-loop
/*--- UDP RECEIVE (NON-BLOCKING) ---------------------------------------------*/
#if 1
d21=1;
UdpReceive();
d21=0;
#endif
/*--- SERIAL -----------------------------------------------------------------*/
#if 1
g_next = 0;
g_id1 = 0; //0-4
Serial1_puts(g_rx.d.motorData[g_id1]); // serial1 start
#endif
/*--- I2C --------------------------------------------------------------------*/
#if 1
// Acquire sensor values
do{
for (int j=0; j<FDC_NUM ;j++) {
I2C *i2c = (j == 2)? p_i2c2 : p_i2c1;
// MULTI PLEXER
if(j != 2){
switchResult = switchI2c(i2c, j);
if(!switchResult) break;
}
senseCapacitance(i2c, g_tx.d.sensorData[j], capdac);
}
}while(!switchResult);
//d20=1;d20=0;
//g_finish |= BIT_I2C1;
//g_finish |= BIT_I2C2;
#endif
/*--- UDP SEND (BLOCKING) ----------------------------------------------------*/
#if 1
if((g_finish & 0x03) == 0x03){ // all data gathered
L001:
d20=1;
g_tx.d.seq = seq++;
int ret = s_sock.sendTo(ep_pc_tx, g_tx.buf, sizeof(g_tx.buf));
d20=0;
if(ret != sizeof(g_tx.buf)){ // send error
//SEND-ERROR
d22=1;d22=0;
}
} else {
//GATHER-ERROR
led1=!led1;
//memset(&g_tx.d.motorData, 0, sizeof(g_tx.d.motorData)); // motor not needed
memset(&g_tx.d.sensorData, 0, sizeof(g_tx.d.sensorData)); // sensor is ZERO.
goto L001;
}
g_finish = 0;
#endif
} // end_while(1)
}
