示例#1
0
/* Many XMOS apps may call xmos_flash_init() without ever using the
 * XMOS flash device.  We prevent the creation of many unused large files
 * by creating the flash emulation file only once it is actually used.
 */
static void lazyInit()
{
   mos_mutex_lock (&xmos_flash_mutex);
   // check for race condition
   if (flash_file) return;
	
   // See if the flash file exists
   if (access(flash_file_name, F_OK)) {
      // write a bunch of zeros to the new file
      flash_file = fopen(flash_file_name, "w");
      fseek(flash_file, 0, SEEK_SET);
      void* buf = calloc(1, flash_size);
      fwrite(buf, 1, flash_size, flash_file);
      fflush(flash_file);
      free(buf);
      fclose(flash_file);
   }
	
   flash_file = fopen(flash_file_name, "r+");
   if (!flash_file) {
      perror("xmos_flash_init: fopen");
      mos_mutex_unlock (&xmos_flash_mutex);
      return;
   }
	
   mos_mutex_unlock (&xmos_flash_mutex);
}
示例#2
0
uint8_t dev_ioctl_DEV_ATMEL_FLASH (int8_t request, ...)
{
   if (!flash_file_name) return DEV_NOT_REGISTERED;
   if (!flash_file) lazyInit();
	
   uint32_t arg;
   va_list ap;

   mos_mutex_lock (&xmos_flash_mutex);
   
   va_start (ap, request);
   switch (request) {
   case DEV_SEEK:
      arg = va_arg (ap, uint32_t);
      xmos_flash_addr = arg;
      //printf("xmos_flash_addr = %i;\n", xmos_flash_addr);
      break;
   default:
      return DEV_BAD_IOCTL;      
   }
   va_end (ap);

   mos_mutex_unlock (&xmos_flash_mutex);
   
   return DEV_OK;
}
示例#3
0
/** @brief Set some protocol specific parameters. 
 * @param request IO request
 * @param args Arguements
 */
int8_t dvdrp_ioctl(uint8_t request, va_list args)
{
    uint8_t ret = TRUE;
    dvdrp_route *route;
    dvdrp_filter_list *pred;

    switch(request) { 
    case DVDRP_IOCTL_SETPRED: // Change subscription predicate
       //printf("dvdrp_ioctl(): setpred\n");
       pred = va_arg(args, dvdrp_filter_list *);
       node_delay = va_arg(args, uint32_t);
       
       mos_mutex_lock(&route_lock);
       route = dvdrp_route_find(node_id);
       if(!route) {
	  ret = dvdrp_route_local_update(NULL, pred);
       } else {
	  ret = dvdrp_route_local_update(route, pred);
       }
       mos_mutex_unlock(&route_lock);
       
       break;
    case DVDRP_IOCTL_SETFAILURE_LIMIT:   
    case DVDRP_IOCTL_RESET_PROTO:        
    default:
	break;
    } 
   
    return ret;
}
示例#4
0
uint8_t com_send_IFACE_SERIAL (comBuf *buf)
{
   uint8_t byte = PREAMBLE;
   uint8_t i;
   int retval;

   mos_mutex_lock (&if_send_mutexes[IFACE_SERIAL]);
   
   // Send the preamble then the size and packet
   for(i = 0; i < PREAMBLE_SIZE; i++) {
      retval = write (serialfd, &byte, 1);
      if (retval == -1)
	 goto serial_send_error;
   }
   retval = write (serialfd, &buf->size, 1);
   if (retval == -1)
      goto serial_send_error;
   retval = write (serialfd, &buf->data, buf->size);
   if (retval == -1)
      goto serial_send_error;
   retval = tcdrain (serialfd);

serial_send_error:
   if (retval == -1)
      perror("com_send_IFACE_SERIAL");
			
   mos_mutex_unlock (&if_send_mutexes[IFACE_SERIAL]);
   
   return 0;
}
示例#5
0
uint16_t dev_write_DEV_AVR_I2C (const void *buf, uint16_t count)
{
   uint8_t int_handle;
   mos_mutex_lock (&i2c_mutex);

   //initialize counting vars
   write_count = 0;
   write_max = count;
   write_buf = (uint8_t *)buf;

   
   if(mode == DEV_MODE_OFF)
      avr_i2c_enable();

   state = START;
   reading = false;

   uint8_t polling = true;

   if(polling) {
      TWCR |= (1 << TWINT) | (1<<TWSTA);

      avr_i2c_wait_status_write(START);
      avr_i2c_put_byte(SLA_W);

      TWCR = (1 << TWINT) | (1 << TWEN);

      avr_i2c_wait_status_write(MT_SLA_ACK);

      while(write_count < write_max) {
	 TWDR = write_buf[write_count++];
	 TWCR = (1 << TWINT) | (1 << TWEN);

	 avr_i2c_wait_status_write(MT_DATA_ACK);
      }

      TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
   } else {
      int_handle = mos_disable_ints();
      avr_i2c_interrupt_enable(); //enable interrupt mode
      avr_i2c_clear_int_flag(); //clear old flag
      avr_i2c_start_condition(); //initiate start condition
      
      mos_led_display(5);
      mos_enable_ints(int_handle);
      mos_led_display(4);
      mos_sem_wait(&i2c_sem_write);
   }
   
   if(mode == DEV_MODE_OFF)
      avr_i2c_disable();
   
   mos_mutex_unlock(&i2c_mutex);
   return write_count;
}
示例#6
0
void send_packet(uint8_t packet_id)
{
   static uint8_t inited = 0;
   uint16_t temp;
   uint16_t hum;
   
   if (!inited)
   {
      inited = 1;
      dev_open(DEV_MSP_HUMIDITY);
      if (dev_mode(DEV_MSP_HUMIDITY, DEV_MODE_ON) == DEV_FAILURE)
      {
	 no_sensor = 1;
      }
      
   }
   
   mos_mutex_lock(&send_mutex);

   if (no_sensor)
   {
      temp = rand();
      hum = rand();
   }
   else
   {
      
      dev_read(DEV_MSP_TEMPERATURE, &temp, sizeof(temp));
      dev_read(DEV_MSP_HUMIDITY, &hum, sizeof(hum));
   }
   

   buf.size = 13;
   buf.data[0] = packet_id;
   
   buf_insert_WORD(buf.data, 1, mos_node_id_get());
   buf_insert_WORD(buf.data, 3, temp);
   buf_insert_WORD(buf.data, 5, hum);
   if (no_sensor)
   {
      buf_insert_WORD(buf.data, 7, rand());
      buf_insert_WORD(buf.data, 9, rand());
   }
   else
   {
      buf_insert_WORD(buf.data, 7, adc_get_conversion16(4));
      buf_insert_WORD(buf.data, 9, adc_get_conversion16(5));
   }
   
   buf_insert_WORD(buf.data, 11, crc_compute(buf.data, 11));

   com_send(IFACE_RADIO, &buf);

   mos_mutex_unlock(&send_mutex);
}
示例#7
0
static void checkNeighbor(uint16_t id)
{
	uint8_t i;
	mos_mutex_lock(&send_lock);
	for (i = 0; i<neighbor_count && i<28; i++) {
		if (id == out->neighbors[i]) {
			mos_mutex_unlock(&send_lock);
			return;
		}
	}
	if (i==neighbor_count && i<28) {
		mos_remove_alarm(&send_alarm);
		out->neighbors[neighbor_count++] = id;
		mos_led_display(neighbor_count);
		rseed = rand();
        send_alarm.msecs = 500 + rseed % 500;
		mos_alarm(&send_alarm);
	}
	mos_mutex_unlock(&send_lock);
}
示例#8
0
/** @brief Receive a packet that came using the dvdrping protocol. 
 *
 * NOTE: Must subtract the sizeof route header from pkt->size so
 *       the net layer can determine whether any more data is available.
 * @param pkt Packet received
 * @param footer Location
 * @return FALSE if failure, else return TRUE
 */
boolean dvdrp_recv(comBuf *pkt, uint8_t **footer, uint8_t port)
{
    uint8_t hdr_size = pkt->data[pkt->size-1];
    uint8_t matches_local = FALSE;
    dvdrp_pkt *hdr = (dvdrp_pkt*)&pkt->data[pkt->size - hdr_size - 1];

    hdr->htl--;
    if(hdr->pkt_type == DVDRP_ADVERT_PKT) {
	printf(".ad");
	mos_led_toggle(2);
	mos_mutex_lock(&route_lock);
	dvdrp_route_update(dvdrp_route_find(((dvdrp_advert_pkt *)hdr)->receiver_id),
			   (dvdrp_advert_pkt *)hdr);
	mos_mutex_unlock(&route_lock);
    } else if(hdr->pkt_type == DVDRP_MESG_PKT) {
	printf(".msg");
	//note, we do not match the message again, but just match bv_id's
	if(((dvdrp_mesg_pkt *)hdr)->immed_dest == node_id) {
	    mos_mutex_lock(&route_lock);
	    matches_local = dvdrp_mesg_send((dvdrp_mesg_pkt *)hdr, pkt);
	    mos_mutex_unlock(&route_lock);
	} //else we drop the mo'fo
    } else if(hdr->pkt_type == DVDRP_REPAIR_PKT) {
	printf(".rep");
    }
    
    // Pull our header off. 
    pkt->size -= hdr_size + 1;  // +1 for size at eop

    //Set the footer if we need to deliver info to the application
    *footer = (uint8_t *)hdr;

    //Should the higher layer give a shit?
    if(matches_local) {
	printf(".ml\n");
	return TRUE;
    } else {
	printf("\n");
	return FALSE;
    }
}
//TODO: send more meaningful instructions to ultrasound, like beep duration
uint16_t dev_write_DEV_MICA2_ULTRASOUND(const void *buf, uint16_t count)
{
   mos_mutex_lock(&ultrasound_mutex);
   
   if(((uint8_t *)buf)[0] == 0)
      mica2_ultrasound_off();
   else
      mica2_ultrasound_on();

   mos_mutex_unlock(&ultrasound_mutex);
   
   return count;
}
示例#10
0
/* HACK to let us optimize, define our own version of putchar()
   the assembler "optimizes" calls to printf() with a single char
   argument by converting it to a putchar() */
int putchar(int character)
{
   mos_mutex_lock(&printf_lock);
   
   printf_packet.size = 2;
   printf_packet.data[0] = character;
   printf_packet.data[1] = '\0';
   //com_send(IFACE_SERIAL, &printf_packet);
   com_send_packet(&printf_packet);
   printf_packet.size = 0;
   
   mos_mutex_unlock(&printf_lock);
   return 0;
}
示例#11
0
void sendThread()
{
	while (1)
	{
		mos_sem_wait(&send_sem);
		mos_mutex_lock(&send_lock);
		out->origin = out->route = mos_node_id_get();
		out->type = TOPO_REPLY;
		out->seqNo = seqNo;
		npkt.size = 6 + 2*neighbor_count;
		net_send(&npkt, 77, 0);
		mos_mutex_unlock(&send_lock);
	}
}
示例#12
0
void mos_cond_wait(mos_cond_t *cond, mos_mutex_t *mt)
{
   // Get the current thread ID
   mos_thread_t *id = mos_thread_current();
   // Disable interrupts so we can unlock and wait atomically
   handle_t int_handle = mos_disable_ints();
   // Unlock the mutex
   mos_mutex_unlock(mt);
   // Put us on the list for the condition variable
   mos_tlist_add(&cond->q, id);
   // Suspend us with interrupts already disabled
   mos_thread_suspend_noints(int_handle);
   // Lock the mutex again before returning
   mos_mutex_lock(mt);
}
示例#13
0
static void reinit()
{
	uint8_t i;
	mos_mutex_lock(&send_lock);
	for (i = 0; i<28; i++) {
		out->neighbors[i] = -1;
	}
	neighbor_count = 0;
	mos_led_display(neighbor_count);
	for (i = 0; i<10; i++) {
		reply_cache[i] = -1;
	}
	reply_ndx = 0;
	mos_mutex_unlock(&send_lock);
}
示例#14
0
/** @brief Read from the current flash address into p, for count bytes
 */
uint16_t dev_read_DEV_ATMEL_FLASH (void *p, uint16_t count)
{
   if (!flash_file_name) return DEV_NOT_REGISTERED;
   if (xmos_flash_addr+count > flash_size) return DEV_OUT_OF_RANGE;
   if (!flash_file) lazyInit();

   mos_mutex_lock (&xmos_flash_mutex);
	
   fseek(flash_file, xmos_flash_addr, SEEK_SET);
   uint16_t len = fread(p, 1, count, flash_file);
   xmos_flash_addr += len;
	
   mos_mutex_unlock (&xmos_flash_mutex);
   
   return len;
}
示例#15
0
/** @brief Send a packet using the DV/DRP protocol. 
 * @param pkt Packet to send
 * @param args 
 */
int8_t dvdrp_send(comBuf *pkt, va_list args)
{
    uint8_t i, orig_size;
    uint8_t num_attribs = va_arg(args, int);
    dvdrp_mesg_pkt *dvdrp_ptr = (dvdrp_mesg_pkt*)&(pkt->data[pkt->size]);
    dvdrp_attrib *attribs = va_arg(args, dvdrp_attrib *);

//    printf("dvdrp_send(%x): orig_size %C\n", attribs, pkt->size);

    orig_size = pkt->size;
    
    if(pkt->size + sizeof(dvdrp_mesg_pkt) + (num_attribs << 2) > COM_DATA_SIZE)
	return NET_BUF_FULL;

    dvdrp_ptr->header.pkt_type = DVDRP_MESG_PKT;
    dvdrp_ptr->header.htl = DVDRP_MAX_HTL;
    dvdrp_ptr->is_secondary = FALSE;
    dvdrp_ptr->num_attribs = num_attribs;

    pkt->size += 10;
    
    for(i = 0; i < num_attribs; ++i) {
//	printf("%x = %d\n", attribs[i].name, attribs[i].value);
	dvdrp_ptr->attributes[i].name = attribs[i].name;
	dvdrp_ptr->attributes[i].value = attribs[i].value;
	pkt->size += sizeof(dvdrp_attrib);
    }

//    printf("new size: %C\n", pkt->size);
    pkt->data[pkt->size++] = pkt->size - orig_size;

    mos_mutex_lock(&route_lock);
    dvdrp_get_splitbv(dvdrp_ptr, &dvdrp_ptr->split_bv);
    if(dvdrp_ptr->split_bv != 0) {
	dvdrp_mesg_send(dvdrp_ptr, pkt);
	i = pkt->size;
	//!!!!need to check for local delivery here - maybe we should
	//do such in dvdrp_mesg_send and return bytes instead
    } else {
	//no valid destinations, drop packet, don't do work
	printf(".NR");
	i = 0;
    }
    mos_mutex_unlock(&route_lock);

    return i;
}
示例#16
0
/* HACK to let us optimize, define our own version of puts()
   the assembler "optimizes" calls to printf() with no args by
   converting it to a puts () */
int puts(const char *msg)
{
   //printf("%s\n\0", msg);

   mos_mutex_lock(&printf_lock);

   send_string(msg);
   printf_packet.data[printf_packet.size++] = '\n';
   printf_packet.data[printf_packet.size++] = '\0';
   //com_send(IFACE_SERIAL, &printf_packet);
   com_send_packet(&printf_packet);
   printf_packet.size = 0;

   mos_mutex_unlock(&printf_lock);

   return 0;
}
示例#17
0
文件: block.c 项目: atiselsts/osw
/* Allocate a handle */
static struct fsBlockHandle *allocHandle(struct fsFileControlBlock *fcb)
{
    struct fsBlockHandle *res = NULL;
    size_t                i;

    mos_mutex_lock(&fsBlkHandleMutex);
    for (i = 0; i < FS_MAX_OPEN_FILES; i++)
    {
        if (!blkHandles[i].fcb)
        {
            res = blkHandles + i;
            res->fcb = fcb;
            break;
        }
    }
    mos_mutex_unlock(&fsBlkHandleMutex);

    return res;
}
示例#18
0
文件: block.c 项目: atiselsts/osw
static void *blkOpen(const char *path, fsMode_t mode)
{
    struct fsFileControlBlock *fcb;

    if (mode & FS_RDWR || !(mode & (FS_READ | FS_APPEND)) ||
        (mode & FS_READ && mode & FS_APPEND))
    {
        fsSetError(FS_ERR_INVAL);
        return NULL;
    }

    fcb = fsBlockOpenFile(path, mode & FS_APPEND);
    if (fcb)
    {
        struct fsBlockHandle *handle = allocHandle(fcb);
        if (handle)
        {
            handle->mode = mode;

            mos_mutex_lock(&fcb->mutex);
            if (mode & FS_READ) /* Read mode */
            {
                handle->pos     = 0;
                handle->curr    = fcb->first;
                handle->readEnd = 0;
            }
            else /* Write mode */
            {
                /* Traverse blocks until the last one */
                seekBlock(handle, fcb->size);

                handle->pos = fcb->size;
            }
            mos_mutex_unlock(&fcb->mutex);
        }
        else
            fsBlockCloseFile(fcb);
        return handle;
    }
    else
        return NULL;
}
示例#19
0
void xmos_flash_init (void)
{
   flash_file = NULL;
   flash_file_name = NULL;
   flash_size = DEFAULT_FLASH_SIZE;
   mos_mutex_init (&xmos_flash_mutex);

   mos_mutex_lock (&xmos_flash_mutex);
	
   if (!mos_arg_check("-flashfile", &flash_file_name)) {
      // default name is hex of node id
      sprintf(namebuf, "%04hx.flash", mos_node_id_get());
      flash_file_name = namebuf;
   }
	
   char* fsize;
   if (mos_arg_check("-flashsize", &fsize)) {
      flash_size = atol(fsize);
   }
	
   mos_mutex_unlock (&xmos_flash_mutex);
}
示例#20
0
uint8_t com_send_IFACE_LOOPBACK(comBuf *buf)
{
  uint8_t i;

  mos_mutex_lock(&if_send_mutexes[IFACE_LOOPBACK]);

  if(managed_buf != NULL) {
     for(i = 0; i < buf->size; i++)
	managed_buf->data[i] = buf->data[i];
     
     managed_buf->size = buf->size;
  }

  com_swap_bufs(IFACE_LOOPBACK, managed_buf, &managed_buf);
  
  mos_sem_post(&send_sem);
  mos_sem_wait(&send_sem);

  mos_mutex_unlock(&if_send_mutexes[IFACE_LOOPBACK]);

  return 0;
}
示例#21
0
文件: core.c 项目: atiselsts/osw
/* Allocate a new file handle */
static int8_t fsAllocHandle(const struct fsOperations *ops)
{
    int8_t i;

    mos_mutex_lock(&openFilesMutex);
    for (i = 0; i < FS_MAX_OPEN_FILES; i++)
    {
        if (!openFiles[i].ops)
        {
            openFiles[i].ops = ops;
            break;
        }
    }
    mos_mutex_unlock(&openFilesMutex);

    if (i == FS_MAX_OPEN_FILES)
    {
        fsSetError(FS_ERR_NOMEM);
        return -1;
    }

    return i;
}
示例#22
0
文件: core.c 项目: atiselsts/osw
/* Free file handle */
static inline void fsFreeHandle(int8_t fd)
{
    mos_mutex_lock(&openFilesMutex);
    openFiles[fd].ops = NULL;
    mos_mutex_unlock(&openFilesMutex);
}
示例#23
0
文件: block.c 项目: atiselsts/osw
/* Free a handle */
static void freeHandle(struct fsBlockHandle *handle)
{
    mos_mutex_lock(&fsBlkHandleMutex);
    handle->fcb = NULL;
    mos_mutex_unlock(&fsBlkHandleMutex);
}
示例#24
0
int16_t printf(const char *format, ...)
{
   va_list arg;
   const char *p = format;

   if(format == NULL)
      return -1;

   mos_mutex_lock(&printf_lock);
   va_start(arg, format);

   printf_packet.size = 0;
   memset(printf_packet.data, 0, COM_DATA_SIZE);
   
   while(*p) {
      // If its not a conversion specifier we just send it
      if(*p != '%') {
	 printf_packet.data[printf_packet.size++] = *p++;
	 check_size();
      } else {
	 // Otherwise we need to substitute in a variable
	 *p++;
	 
	 // TODO the padding options are not implemented for non-numeric stuff
	 // Pad with zeros or spaces?
	 if (*p == '0') {
	    padchar = '0';
	    p++;
	 } else
	    padchar = ' ';
	 
	 // Width of field
	 fieldwidth = 0;
	 while(*p >= '0' && *p <= '9') {
	    fieldwidth = fieldwidth * 10 + *p - '0';
	    p++;
	 }
	 
	 switch(*p++) {
	 case 's': {
	    char *s;
	    s = va_arg(arg, char *);
	    send_string(s);
	    break;
	 }
#ifdef ARCH_AVR
	 case 'P': {
	    PGM_P s;
	    s = va_arg(arg, PGM_P);
	    send_prog_string(s);
	 }
#endif
	 case 'd': {
	    uint16_t num16;
	    num16 = va_arg(arg, uint16_t);
	    norecurse_16(num16, 10);
	    break;
	 }
	 case 'l': {
	    num32 = va_arg(arg, uint32_t);
	    norecurse_32(num32, 10);
	    break;
	 }
	 case 'c': {
	    uint16_t num8 = 0;
	    num8 = (uint8_t)va_arg(arg, uint16_t);
	    printf_packet.data[printf_packet.size++] = num8;
	    check_size();
	    break;
	 }
	 case 'C': {
	    uint16_t num8 = 0;
	    num8 = (uint8_t) va_arg(arg, uint16_t);
	    norecurse_16((uint16_t)num8, 10);
	    break;
	 }
	 case 'x': 
	    printf_packet.data[printf_packet.size++] = '0';
	    check_size();
	    printf_packet.data[printf_packet.size++] = 'x';
	    check_size();
	 case 'h': {
	    uint16_t num16;
	    num16 = va_arg(arg, uint16_t);
	    norecurse_16(num16, 16);
	    break;
	 }
	 case 'o': {
	    uint16_t num16;
	    num16 = va_arg(arg, uint16_t);
	    norecurse_16(num16, 8);
	    break;
	 }
	 case '%':
	    printf_packet.data[printf_packet.size++] = '%';
	    check_size();
	    break;
	 case 'b': {
	    uint16_t num16;
	    num16 = va_arg(arg, uint16_t);
	    norecurse_16(num16, 2);
	    break;
	 }
	 default:
	    printf_packet.data[printf_packet.size++] = '?';
	    check_size();
	    printf_packet.data[printf_packet.size++] = '?';
	    check_size();
	    printf_packet.data[printf_packet.size++] = '?';
	    check_size();
	    break;
	 }
      }
   }
   va_end(arg);

   printf_packet.data[printf_packet.size++] = '\0';
   //com_send(IFACE_SERIAL, &printf_packet);
   com_send_packet(&printf_packet);
   printf_packet.size = 0;

   mos_mutex_unlock(&printf_lock);

   return 0;
}
示例#25
0
/** @brief printf_P Same as printf, except that the format string must be stored
 * int program memory.
 * @param format Format to print
 */
int16_t printf_P(const ARCH_PROGMEM char *format, ...)
{
   va_list arg;
   const prog_char *p = format;

   if(format == NULL)
      return -1;

   mos_mutex_lock(&printf_lock);
   va_start(arg, format);

   printf_packet.size = 0;
   
   char c = pgm_read_byte(p);
   while(c) {
      // If its not a conversion specifier we just send it
      if(c != '%') {
	 printf_packet.data[printf_packet.size++] = c;
	 c = pgm_read_byte(++p);
	 check_size();
      } else {
	 // Otherwise we need to substitute in a variable
	 c = pgm_read_byte(++p);
	 
	 // TODO the padding options are not implemented for non-numeric stuff
	 // Pad with zeros or spaces?
	 if (c == '0') {
	 	padchar = '0';
	 	c = pgm_read_byte(++p);
	 } else
	 	padchar = ' ';
	 
	 // Width of field
	 fieldwidth = 0;
	 while(c >= '0' && c <= '9') {
	 	fieldwidth = fieldwidth * 10 + c - '0';
	 	c = pgm_read_byte(++p);
	 }
	 
	 switch(c) {
	 case 's': {
	    char *s;
	    s = va_arg(arg, char *);
	    send_string(s);
	    break;
	 }
	 case 'P': {
	    PGM_P s;
	    s = va_arg(arg, PGM_P);
	    send_prog_string(s);
	 }
	 case 'd': {
	    uint16_t num16;
	    num16 = va_arg(arg, uint16_t);
	    norecurse_16(num16,10);
	    break;
	 }
	 case 'l': {
//	    uint32_t num32;
	    num32 = va_arg(arg, uint32_t);
	    norecurse_32(num32, 10);
	    break;
	 }
	 case 'c': {
	    uint16_t num8 = 0;
	    num8 = (uint8_t)va_arg(arg, uint16_t);
	    printf_packet.data[printf_packet.size++] = num8;
	    check_size();
	    break;
	 }
	 case 'C': {
	    uint16_t num8 = 0;
	    num8 = (uint8_t) va_arg(arg, uint16_t);
	    norecurse_16((uint16_t)num8, 10);
	    break;
	 }
	 case 'x': 
	    printf_packet.data[printf_packet.size++] = '0';
	    check_size();
	    printf_packet.data[printf_packet.size++] = 'x';
	    check_size();
	 case 'h': {
	    uint16_t num16;
	    num16 = va_arg(arg, uint16_t);
	    norecurse_16(num16, 16);
	    break;
	 }
	 case 'o': {
	    uint16_t num16;
	    num16 = va_arg(arg, uint16_t);
	    norecurse_16(num16, 8);
	    break;
	 }
	 case '%':
	    printf_packet.data[printf_packet.size++] = '%';
	    check_size();
	    break;
	 case 'b': {
	    uint16_t num16;
	    num16 = va_arg(arg, uint16_t);
	    norecurse_16(num16, 2);
	    break;
	 }
	 default:
	    printf_packet.data[printf_packet.size++] = '?';
	    check_size();
	    printf_packet.data[printf_packet.size++] = '?';
	    check_size();
	    printf_packet.data[printf_packet.size++] = '?';
	    check_size();
	    break;
	 }
	c = pgm_read_byte(++p);
      }
   }
   va_end(arg);

   printf_packet.data[printf_packet.size++] = '\0';
   com_send(IFACE_SERIAL, &printf_packet);
   printf_packet.size = 0;

   mos_mutex_unlock(&printf_lock);

   return 0;
}
示例#26
0
uint16_t dev_read_DEV_AVR_I2C(void *buf, uint16_t count)
{
   if(count == 0)
      return 0;
   
   if(mode == DEV_MODE_OFF)
      avr_i2c_enable();
   
   read_max = count;
   read_count = 0;
   read_buf = (uint8_t *)buf;
   reading = true;

   uint8_t polling = true;

   if(polling)
   {
      //transmit a start condition
      TWCR |= (1 << TWINT) | (1<<TWSTA);

      //wait for response
      avr_i2c_wait_status_read(START);

      //transmit SLA+R
      avr_i2c_put_byte(SLA_W | 0x01); //lsb = 1 for read


      //wait for response
      TWCR = (1 << TWINT) | (1 << TWEN);
      avr_i2c_wait_status_read(MR_SLA_ACK);

      //get count -1 bytes and return ACK
      while(read_count < read_max - 1){
	 TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA);

	 //wait for response
	 avr_i2c_wait_status_read(MR_DATA_ACK);

	 read_buf[read_count++] = avr_i2c_get_byte();
      }

      //get last byte, return NACK
      TWCR = (1 << TWINT) | (1 << TWEN);
      
      //wait for response
      avr_i2c_wait_status_read(MR_DATA_NACK);

      read_buf[read_count++] = avr_i2c_get_byte();

      //issue a stop condition
      TWCR = (1 << TWSTO) | (1 << TWINT);
      
   } else {
      mos_sem_wait (&i2c_sem_read);
   }

   if(mode == DEV_MODE_OFF)
      avr_i2c_disable();
   
   mos_mutex_unlock(&i2c_mutex);
   return read_count;
}
示例#27
0
void handleCommand(deluge_app* app, comBuf* pkt, uint8_t port)
{
	deluge_foot_command* command = (deluge_foot_command*)
		&pkt->data[pkt->size - sizeof(deluge_foot_command)];
	#ifdef DELUGE_PRINT_PACKETS
	printf_P(sRecvComm, command->seq, command->command, command->to);
	#endif
	if (checkCache(command->id, command->seq)) return;
	
	// Temporarily switch to max power to make sure the command gets through
	/*uint8_t oldPower;
	com_ioctl(IFACE_RADIO, CC1000_GET_TX_POWER, &oldPower);
	com_ioctl(IFACE_RADIO, CC1000_TX_POWER, 0xFF);*/
	
	// If the command is not specifically addessed to us, forward it now
	/*if (command->to != mos_node_id_get())
		net_send(pkt, DELUGE_PROTO_ID, port, port);*/
	if (command->to != -1 && command->to != mos_node_id_get()) {
		//com_ioctl(IFACE_RADIO, CC1000_TX_POWER, oldPower);
		return;
	}
	
	//extern mutex epromLock;
	
	switch(command->command) {
		case DELUGE_COMMAND_HELLO: 
			printf_P(sHello);
			logHeader(&spkt, DELUGE_COMMAND_HELLO);
			com_send(IFACE_SERIAL, &spkt);
			break;
		//case DELUGE_COMMAND_SEQNO: seqNo = 0; break;
		/*case DELUGE_COMMAND_STOPALL: 
			//app->dcb.codeSize;
			//app->dcb.programcrc;
			memset(app->dcb.pagesNeeded, 0, sizeof(app->dcb.pagesNeeded));
			//app->dcb.version;
			app->dcb.incomingPage = app->dcb.highPage = app->dcb.goalPage;
			deluge_saveState(app);
			deluge_app_init(app, app->index);
			break;*/
		#ifdef DELUGE_KEEP_STATS
		case DELUGE_COMMAND_CLEARSTATS:
			#ifdef DELUGE_PRINT_EVENT
			printf_P(sClearStats);
			//printf_P(sClearTimer);		// reset timer
			#endif	
			memset(packet_counts, 0, sizeof(packet_counts));
			logHeader(&spkt, DELUGE_COMMAND_CLEARSTATS);
			com_send(IFACE_SERIAL, &spkt);
			break;
		case DELUGE_COMMAND_STARTRECORD:
			#ifdef DELUGE_PRINT_EVENT
			printf_P(sStartRec);
			//printf_P(sClearTimer);		// reset timer
			#endif
			logHeader(&spkt, DELUGE_COMMAND_STARTRECORD);
			com_send(IFACE_SERIAL, &spkt);
			deluge_recordstats = 1;
			break;
		case DELUGE_COMMAND_ENDRECORD: 
			#ifdef DELUGE_PRINT_EVENT
			//printf_P(sDisplayTime);		// display timer
			printf_P(sStopRec);
			#endif
			deluge_recordstats = 0;
			/*mos_mutex_lock(&epromLock);
			dev_ioctl(DEV_AVR_EEPROM, DEV_SEEK, DELUGE_STATS_ADDR);
			dev_write(DEV_AVR_EEPROM, (uint8_t*)packet_counts, sizeof(packet_counts));
			mos_mutex_unlock(&epromLock);*/
			logHeader(&spkt, DELUGE_COMMAND_ENDRECORD);
			com_send(IFACE_SERIAL, &spkt);
			break;
		case DELUGE_COMMAND_SENDSTATS:
			if (-1 != command->to && !sendingStats) {	// it's addressed to us
				sendingStats = 1;
				statsPort = port;
				// This is a slow procedure that requires multiple packets to
				// reply, so run it in another thread.
				//mos_thread_new(statsThread, 256, PRIORITY_NORMAL);

				uint8_t r = 0;
				uint8_t i = 0;
				
				for (r=0; r<DELUGE_STATS_COUNT;)
				{
					logHeader(&spkt, DELUGE_COMMAND_SENDSTATS_REPLY);
					spkt.data[spkt.size++] = r;
					
					for (i=0; i<4 && r+i<DELUGE_STATS_COUNT; i++)
					{
						uint8_t j;
						for (j=0; j<4; j++)
						{
							uint16_t stat = packet_counts[r+i][j];
							spkt.data[spkt.size++] = (uint8_t)(stat >> 8);
							spkt.data[spkt.size++] = (uint8_t)(stat);
						}
					}
					r += i;
					com_send(IFACE_SERIAL, &spkt);
				}
				sendingStats = 0;
			}
			break;
		#endif
		case DELUGE_COMMAND_VERSION:
			#ifdef DELUGE_PRINT_EVENT
			printf_P(sChangeVer, pkt->data[0]);
			printf_P(sClearTimer);		// clear timer
			#endif
			mos_mutex_lock(&app->delugeLock);	
			app->dcb.version = pkt->data[0];
			deluge_saveState(app);
			app->detectedInconsistency = 1;
			stateTransition(app, DELUGE_STATE_MAINTAIN);
			mos_mutex_unlock(&app->delugeLock);	
			if (command->to != -1) {
				/*command->seq = ++seqNo;
				command->command = DELUGE_COMMAND_VERSION_REPLY;
				command->to = command->id;
				command->id = mos_node_id_get();
				command->type = DELUGE_PACKET_COMMAND;
				mos_thread_sleep(1000);
				net_send(pkt, DELUGE_PROTO_ID, port, port);*/
				logHeader(&spkt, DELUGE_COMMAND_VERSION_REPLY);
				com_send(IFACE_SERIAL, &spkt);
			}
			break;
		#ifdef DELUGE_SYMMETRIC_LINKS
		/*case DELUGE_COMMAND_NEIGHBORS:
			if (-1 != command->to) {	// it's addressed to us
				memcpy(pkt->data, app->neighbors, sizeof(app->neighbors));
				pkt->size = sizeof(app->neighbors);
				//memcpy(&pkt->data[pkt->size], app->symdtbs, sizeof(app->symdtbs));
				//pkt->size += sizeof(app->symdtbs);

				command = (deluge_foot_command*)&pkt->data[pkt->size];
				command->seq = ++seqNo;
				command->command = DELUGE_COMMAND_NEIGHBORS_REPLY;
				command->to = -1;
				command->id = mos_node_id_get();
				command->type = DELUGE_PACKET_COMMAND;
				pkt->size += sizeof(deluge_foot_command);
				mos_thread_sleep(1000);
				net_send(pkt, DELUGE_PROTO_ID, port, port);
			}
			break;*/
		#endif
		/*case DELUGE_COMMAND_WIPE: {
			com_mode(IFACE_RADIO, IF_OFF);
			deluge_suspend();
			
			#ifdef DELUGE_PRINT_EVENT
			printf_P(sWipe);
			#endif
			uint16_t zero = 0;
			uint16_t addr;
			mos_mutex_lock(&epromLock);
			for (addr = DELUGE_CONTROL_BLOCK_ADDR; addr < SIMPLE_FS_ADDR; addr += 2)
			{
				dev_ioctl(DEV_AVR_EEPROM, DEV_SEEK, addr);
				dev_write(DEV_AVR_EEPROM, (uint8_t*)&zero, 2);
			}
			simple_fs_format();
			
			uint8_t default_portmap[DELUGE_INSTANCE_COUNT];
			uint8_t i;
			for (i=0; i<DELUGE_INSTANCE_COUNT; i++)
				default_portmap[i] = i+1;
			dev_ioctl(DEV_AVR_EEPROM, DEV_SEEK, DELUGE_DIRECTORY_ADDR);
			dev_write(DEV_AVR_EEPROM, default_portmap, sizeof (default_portmap));
			mos_mutex_unlock(&epromLock);
			#ifdef DELUGE_PRINT_EVENT
			printf_P(sDone);
			#endif
			
			deluge_init();
			
			com_mode(IFACE_RADIO, IF_LISTEN);
			break;
		}*/
		case DELUGE_COMMAND_BOOT: {
			mos_mutex_lock(&app->delugeLock);
			com_mode(IFACE_RADIO, IF_OFF);
			deluge_suspend();
			
			if (pkt->data[0]==0) {
				// Just reboot
				reboot();
				break;
			}
			
			// Open the requested backup image
			char name[4] = { 'b', 'k', '0'+pkt->data[0], 0 };
			mos_file* file = mos_file_open(name);
			if (!file) {
				printf_P(sFileErr, name);
				
				deluge_resume();
				com_mode(IFACE_RADIO, IF_LISTEN);
				break;
			}
			
			// We keep our current state, but we boot the backup image
			deluge_saveState(app);
			
			// Reboot.  This function will copy the file location into the 
			// boot control block for reprogramming
			app->image_file = file;
			runReprogram(app);
			// We shouldn't return from runReprogram
			mos_mutex_unlock(&app->delugeLock);
			break;
		}
		#if DELUGE_CACHE_PAGES > 1
		case DELUGE_COMMAND_CACHESIZE: {
			if (pkt->data[0] >= DELUGE_CACHE_PAGES) break;
			#ifdef DELUGE_PRINT_EVENT
			printf_P(sChangeCache, pkt->data[0]);
			#endif
			mos_mutex_lock(&app->delugeLock);
			app->cacheSize = pkt->data[0];
			int8_t i;
			for (i=0; i<DELUGE_CACHE_PAGES; i++)
				app->cache_map[i] = -1;
			app->outgoingCachePage = 0;
			app->incomingCachePage = 0;
			stateTransition(app, DELUGE_STATE_MAINTAIN);
			mos_mutex_unlock(&app->delugeLock);
			break;
		}
		#endif
		case DELUGE_COMMAND_POWER: {
			#ifdef DELUGE_PRINT_EVENT
			printf_P(sChangeTx, pkt->data[0]);
			#endif
			//oldPower = pkt->data[0];	// Will get changed at the end
			com_ioctl(IFACE_RADIO, CC1000_TX_POWER, pkt->data[0]);
			break;
		}
		default:
			break;
	}