Example #1
0
/**
 * Read \a _buf lenght \a size byte from serial flash memmory.
 *
 * For read in serial flash memory we
 * enble cs pin and send one byte of read opcode,
 * and then 3 byte of address of memory cell we
 * want to read. After the last byte of address we
 * can read data from so pin.
 *
 * \return the number of bytes read.
 */
static size_t flash25_read(struct KFile *_fd, void *buf, size_t size)
{
	uint8_t *data = (uint8_t *)buf;

	Flash25 *fd = FLASH25_CAST(_fd);

	ASSERT(fd->fd.seek_pos + (kfile_off_t)size <= fd->fd.size);
	size = MIN((kfile_off_t)size, fd->fd.size - fd->fd.seek_pos);

	//kprintf("Reading at addr[%lu], size[%d]\n", fd->seek_pos, size);
	SS_ACTIVE();

	kfile_putc(FLASH25_READ, fd->channel);


	/*
	 * Address that we want to read.
	 */
	kfile_putc((fd->fd.seek_pos >> 16) & 0xFF, fd->channel);
	kfile_putc((fd->fd.seek_pos >> 8) & 0xFF, fd->channel);
	kfile_putc(fd->fd.seek_pos & 0xFF, fd->channel);

	kfile_read(fd->channel, data, size);

	SS_INACTIVE();

	fd->fd.seek_pos += size;

	return size;
}
Example #2
0
/**
 * Send a character over pocketBus channel stream, handling escape mode.
 */
void pocketbus_putchar(struct PocketBusCtx *ctx, uint8_t c)
{
	/* Update checksum */
	rotating_update1(c, &ctx->out_cks);

	/* Escape characters with special meaning */
	if (c == POCKETBUS_ESC || c == POCKETBUS_STX || c == POCKETBUS_ETX)
		kfile_putc(POCKETBUS_ESC, ctx->fd);

	kfile_putc(c, ctx->fd);
}
Example #3
0
/**
 * flash25 init function.
 * This function init a comunication channel and
 * try to read manufacturer id of serial memory,
 * then check if is equal to selected type.
 */
static bool flash25_pin_init(Flash25 *fd)
{
	uint8_t device_id;
	uint8_t manufacturer;

	SPI_HW_INIT();

	SS_ACTIVE();
	/*
	 * Send read id productor opcode on
	 * comunication channel
	 * TODO:controllare se ha senso
	 */
	kfile_putc(FLASH25_RDID, fd->channel);

	manufacturer = kfile_getc(fd->channel);
	device_id = kfile_getc(fd->channel);

	SS_INACTIVE();

	if((FLASH25_MANUFACTURER_ID == manufacturer) &&
		(FLASH25_DEVICE_ID == device_id))
		return true;
	else
		return false;
}
Example #4
0
File: main.c Project: DINKIN/bertos
/* Process that reads from the USB port and writes to the UART port */
static void NORETURN usb_serial_process(void)
{
	iptr_t type = proc_currentUserData();

	KFile *in_fd = (type == USB_TO_SERIAL) ? &usb_port.fd : &ser_port.fd;
	KFile *out_fd = (type == USB_TO_SERIAL) ? &ser_port.fd : &usb_port.fd;

	while (1)
	{
		int c;

		c = kfile_getc(in_fd);
		if (UNLIKELY(c == EOF))
		{
			kfile_clearerr(in_fd);
			continue;
		}
		kfile_putc(c, out_fd);

		/*
		 * Toggle the STAT LED when some data passes through the
		 * usb-seral link
		 */
		LED_TOGGLE();
	}
}
Example #5
0
/**
 * Read a line long at most as size and put it
 * in buf, with optional echo.
 *
 * \return number of chars read, or EOF in case
 *         of error.
 */
int kfile_gets_echo(struct KFile *fd, char *buf, int size, bool echo)
{
	int i = 0;
	int c;

	for (;;)
	{
		if ((c = kfile_getc(fd)) == EOF)
		{
			buf[i] = '\0';
			return -1;
		}

		/* FIXME */
		if (c == '\r' || c == '\n' || i >= size-1)
		{
			buf[i] = '\0';
			if (echo)
				kfile_print(fd, "\r\n");
			break;
		}
		buf[i++] = c;
		if (echo)
			kfile_putc(c, fd);
	}

	return i;
}
Example #6
0
void
print_graph (KFile *stream, uint8_t type, uint8_t style)
{
	MEDIAN *mArray;
	uint8_t i, j, index;
	int16_t highest, lowest, scale, value;
	static uint8_t last_type = 99, last_style = 99;
	char buf[21];

	switch(type)
	{
	case MINGRAPH:
		mArray = &PowerMins;
		strncpy(buf, "Hourly", 7);
		break;
	case HOURGRAPH:
		mArray = &PowerHours;
		strncpy(buf, "Daily", 6);
		break;
	case DAYGRAPH:
		mArray = &PowerDays;
		strncpy(buf, "Monthly", 8);
		break;
	default:
		mArray = &PowerMins;
		break;
	}

	median_getHighest(mArray, &highest);
	median_getLowest(mArray, &lowest);
	scale = MAX(abs(highest), abs(lowest));

	if ((last_type != type) || (last_style != style))
	{
		kfile_putc(TERM_CLR, stream);
		last_type = type;
		last_style = style;
	}

	if ((style == GRAPHSTYLE) && scale)
	{
		for (i = 0; i < 4; i++)          // for each line to be displayed
		{
			index = median_getStart(mArray);
			for (j = 0; j < median_getCount(mArray); j++)
			{
				median_getNext(mArray, &index, &value);
				buf[j] = graphmap[i][(int32_t)(value + scale) * 8 / scale];
			}
			buf[j] = 0;
			kfile_printf(stream, "%c%c%c%s", TERM_CPC, TERM_ROW + i, TERM_COL, buf);
		}
	}
	else
	{
		kfile_printf(stream, "\r\n%s Range:\r\n    %d to %d", buf, lowest, highest);
	}

}
Example #7
0
/**
 * Send a single command to serial flash memory.
 */
static void flash25_sendCmd(Flash25 *fd, Flash25Opcode cmd)
{
	SS_ACTIVE();

	kfile_putc(cmd, fd->channel);

	SS_INACTIVE();
}
Example #8
0
static void tlv5618_write(Tlv5618 *ctx, uint16_t val)
{
	TLV5618_CSLOW(ctx->cs_pin);
	kfile_putc(val >> 8, ctx->ch);
	kfile_putc(val & 0xFF, ctx->ch);
	kfile_flush(ctx->ch);
	TLV5618_CSHIGH(ctx->cs_pin);
}
Example #9
0
/**
 * Send pocketBus packet tail.
 */
void pocketbus_end(struct PocketBusCtx *ctx)
{
	/* Send checksum */
	rotating_t cks = cpu_to_be16(ctx->out_cks);
	pocketbus_write(ctx, &cks, sizeof(cks));

	/* Send ETX */
	kfile_putc(POCKETBUS_ETX, ctx->fd);
}
Example #10
0
// This is a callback we register with the protocol,
// so we can process each packet as they are decoded.
// Right now it just prints the packet to the serial port.
static void mp1Callback(struct MP1Packet *packet) {
    if (SERIAL_DEBUG) {
        kfile_printf(&ser.fd, "%.*s\n", packet->dataLength, packet->data);
    } else {
        for (unsigned long i = 0; i < packet->dataLength; i++) {
            kfile_putc(packet->data[i], &ser.fd);
        }
    }
}
Example #11
0
/**
 * Write a string to kfile \a fd.
 * \return 0 if OK, EOF in case of error.
 */
int kfile_print(struct KFile *fd, const char *s)
{
	while (*s)
	{
		if (kfile_putc(*s++, fd) == EOF)
			return EOF;
	}
	return 0;
}
Example #12
0
/**
 * Sector erase function.
 *
 * Erase a select \p sector of serial flash memory.
 *
 * \note A sector size is FLASH25_SECTOR_SIZE.
 * This operation could take a while.
 */
void flash25_sectorErase(Flash25 *fd, Flash25Sector sector)
{

	/*
	 * Erase a sector could take a while,
	 * for debug we measure that time
	 * see datasheet to compare this time.
	 */
	DB(ticks_t start_time = timer_clock());

	SS_ACTIVE();

	/*
	 * To erase a sector of serial flash memory we must first
	 * enable write with a WREN opcode command, before
	 * the SECTOR_ERASE opcode. Sector is automatically
	 * determinate if any address within the sector
	 * is selected.
	 */
	kfile_putc(FLASH25_WREN, fd->channel);
	kfile_putc(FLASH25_SECTORE_ERASE,fd-> channel);

	/*
	 * Address inside the sector that we want to
	 * erase.
	 */
	kfile_putc(sector, fd->channel);

	SS_INACTIVE();

	/*
	 * We check serial flash memory state, and wait until ready-flag
	 * is hight.
	 */
	flash25_waitReady(fd);

	DB(kprintf("Erased sector [%ld] in %ld ms\n", (unsigned long)sector, (unsigned long)ticks_to_ms(timer_clock() - start_time)));
}
Example #13
0
/**
 * Send pocketBus packet header.
 */
void pocketbus_begin(struct PocketBusCtx *ctx, pocketbus_addr_t addr)
{
	PocketBusHdr hdr;

	hdr.ver = POCKETBUS_VER;
	hdr.addr = cpu_to_be16(addr);
	rotating_init(&ctx->out_cks);

	/* Send STX */
	kfile_putc(POCKETBUS_STX, ctx->fd);

	/* Send header */
	pocketbus_write(ctx, &hdr, sizeof(hdr));
}
Example #14
0
/**
 * Wait until flash memory is ready.
 */
static void flash25_waitReady(Flash25 *fd)
{
	uint8_t stat;

	while (1)
	{
		SS_ACTIVE();

		kfile_putc(FLASH25_RDSR, fd->channel);
		stat = kfile_getc(fd->channel);

		SS_INACTIVE();

		if (!(stat & RDY_BIT))
			break;

		cpu_relax();
	}
}
Example #15
0
static int8_t _gsmWrite(const char *cmd, size_t count)
{
	size_t i;

	// NOTE: debugging should no be mixed to modem command and response to
	// avoid timeing issues and discrepancy between debug and release
	// versions
	gsmDebug("TX [%s]\n", cmd);

	// Purge any buffered data before sending a new command
	ser_purge(gsm);
	// Clear error flags
	ser_setstatus(gsm, 0);

	// Sending the AT command
	WATCHDOG_RESET();
	for (i=0; cmd[i]!='\0' && count; i++, count--) {
		kfile_putc(cmd[i], &(gsm->fd));
		WATCHDOG_RESET();
	}
	return i;
}
Example #16
0
static void NORETURN hadarp_process(void)
{
	char buf[16];

	while (1)
	{
		if (sig_check(SIG_POLIFEMO))
			kfile_putc('@', &ser.fd);

		if (kfile_gets(&ser.fd, buf, sizeof(buf)) == EOF)
		{
			hadarp_cnt = -1;
			kfile_clearerr(&ser.fd);
			continue;
		}

		if (buf[0] == '\0')
		{
			/* Discard empty strings */
			continue;
		}


		char *endptr = buf;
		int hadarp_raw = strtol(buf, &endptr, 10);

		if (*endptr != '\0' || hadarp_raw > 10000 || hadarp_raw < 0)
			hadarp_cnt = -1;
		else
		{
			/* Compensate for geiger tube dead time */
			float cps = hadarp_raw / 60.0;
			hadarp_cnt = ABS(cps / (1.0 - (cps * 1.9e-4)) * 60.0 + 0.5);
		}
		LOG_INFO("HADARP cnt:%d\n", hadarp_cnt);
	}
}
Example #17
0
/**
 * Write \a _buf in serial flash memory
 *
 * Before to write data into flash we must enable
 * memory writing. To do this we send a WRE command opcode.
 * After this command the flash is ready to be write, and so
 * we send a PROGRAM opcode followed to 3 byte of
 * address memory, at the end of last address byte
 * we can send the data.
 * When we finish to send all data, we disable cs
 * and flash write received data bytes on its memory.
 *
 * \note: WARNING: you could write only on erased memory section!
 * Each write time you could write max a memory page size,
 * because if you write more than memory page size the
 * address roll over to first byte of page.
 *
 * \return the number of bytes write.
 */
static size_t flash25_write(struct KFile *_fd, const void *_buf, size_t size)
{
	flash25Offset_t offset;
	flash25Size_t total_write = 0;
	flash25Size_t wr_len;
	const uint8_t *data = (const uint8_t *) _buf;

	Flash25 *fd = FLASH25_CAST(_fd);

	ASSERT(fd->fd.seek_pos + (kfile_off_t)size <= fd->fd.size);

	size = MIN((kfile_off_t)size, fd->fd.size - fd->fd.seek_pos);

	while (size)
	{
		offset = fd->fd.seek_pos % (flash25Size_t)FLASH25_PAGE_SIZE;
		wr_len = MIN((flash25Size_t)size, FLASH25_PAGE_SIZE - (flash25Size_t)offset);

		kprintf("[seek_pos-<%lu>, offset-<%d>]\n", fd->fd.seek_pos, offset);

		/*
		 * We check serial flash memory state, and wait until ready-flag
		 * is high.
		 */
		flash25_waitReady(fd);

		/*
		 * Start write cycle.
		 * We could write only data not more long than one
		 * page size.
		 *
		 * To write on serial flash memory we must first
		 * enable write with a WREN opcode command, before
		 * the PROGRAM opcode.
		 *
		 * \note: the same byte cannot be reprogrammed without
		 * erasing the whole sector first.
		 */
		flash25_sendCmd(fd, FLASH25_WREN);

		SS_ACTIVE();
		kfile_putc(FLASH25_PROGRAM, fd->channel);

		/*
		 * Address that we want to write.
		 */
		kfile_putc((fd->fd.seek_pos >> 16) & 0xFF, fd->channel);
		kfile_putc((fd->fd.seek_pos >> 8) & 0xFF, fd->channel);
		kfile_putc(fd->fd.seek_pos & 0xFF, fd->channel);

		kfile_write(fd->channel, data, wr_len);

		SS_INACTIVE();

		data += wr_len;
		fd->fd.seek_pos += wr_len;
		size -= wr_len;
		total_write += wr_len;
	}

	kprintf("written %lu bytes\n", total_write);
	return total_write;
}
Example #18
0
int main(void){
	init();

	while (1){
		/*
		 * This function will look for new messages from the AFSK channel.
		 * It will call the message_callback() function when a new message is received.
		 * If there's nothing to do, this function will call cpu_relax()
		 */
		ax25_poll(&g_ax25);

		check_run_mode();

		switch(currentMode){
			case MODE_CFG:
#if MOD_CONSOLE
				console_poll();
#endif
#if MOD_BEACON
				beacon_broadcast_poll();
#endif
				break;
#if MOD_TRACKER
			case MODE_TRACKER:
				tracker_poll();
				break;
#endif

#if MOD_KISS
			case MODE_KISS:{
				kiss_poll();
				break;
			}
#endif

#if MOD_DIGI
			case MODE_DIGI:{
				console_poll();
				beacon_broadcast_poll();
				break;
			}
#endif

			default:
				break;
		}// end of switch(runMode)

#if DEBUG_FREE_RAM
		{
			static ticks_t ts = 0;

			if(timer_clock_unlocked() -  ts > ms_to_ticks(5000)){
				ts = timer_clock_unlocked();
				uint16_t ram = freeRam();
				SERIAL_PRINTF((&g_serial),"%u\r\n",ram);
			}
		}
#endif
#if DEBUG_SOFT_SER
		// Dump the isr changes
		{
			SoftSerial *softSer = radioPort;
			static uint32_t i = 0;
			//static uint32_t j = 0;
			if(i++ == 30000){
				i = 0;

				char c;
				while(softser_avail(softSer)){
					c = softser_read(softSer);
					kfile_putc(c,&(g_serial.fd));
				}
				char buf[8];
				sprintf_P(buf,PSTR("0K\n\r"));
				softser_print(softSer,buf);
			}
		}
#endif

	} // end of while(1)
	return 0;
}
Example #19
0
/**
 * \brief Receive a file using the XModem protocol.
 *
 * \param ch Channel to use for transfer
 * \param fd Destination file
 *
 * \note This function allocates a large amount of stack (\see XM_BUFSIZE).
 */
bool xmodem_recv(KFile *ch, KFile *fd)
{
    char block_buffer[XM_BUFSIZE]; /* Buffer to hold a block of data */
    int c, i, blocksize;
    int blocknr = 0, last_block_done = 0, retries = 0;
    char *buf;
    uint8_t checksum;
    uint16_t crc;
    bool purge = false;
    bool usecrc = true;


    LOG_INFO("Starting Transfer...\n");
    purge = true;
    kfile_clearerr(ch);

    /* Send initial NAK to start transmission */
    for(;;)
    {
        if (XMODEM_CHECK_ABORT)
        {
            kfile_putc(XM_CAN, ch);
            kfile_putc(XM_CAN, ch);
            LOG_INFO("Transfer aborted\n");
            return false;
        }

        /*
         * Discard incoming input until a timeout occurs, then send
         * a NAK to the transmitter.
         */
        if (purge)
        {
            purge = false;

            if (kfile_error(ch))
            {
                LOG_ERR("Retries %d\n", retries);
            }

            kfile_resync(ch, 200);
            retries++;

            if (retries >= CONFIG_XMODEM_MAXRETRIES)
            {
                kfile_putc(XM_CAN, ch);
                kfile_putc(XM_CAN, ch);
                LOG_INFO("Transfer aborted\n");
                return false;
            }

            /* Transmission start? */
            if (blocknr == 0)
            {
                if (retries < CONFIG_XMODEM_MAXCRCRETRIES)
                {
                    LOG_INFO("Request Tx (CRC)\n");
                    kfile_putc(XM_C, ch);
                }
                else
                {
                    /* Give up with CRC and fall back to checksum */
                    usecrc = false;
                    LOG_INFO("Request Tx (BCC)\n");
                    kfile_putc(XM_NAK, ch);
                }
            }
            else
                kfile_putc(XM_NAK, ch);
        }

        switch (kfile_getc(ch))
        {
#if XM_BUFSIZE >= 1024
        case XM_STX:  /* Start of header (1024-byte block) */
            blocksize = 1024;
            goto getblock;
#endif

        case XM_SOH:  /* Start of header (128-byte block) */
            blocksize = 128;
            /* Needed to avoid warning if XM_BUFSIZE < 1024 */

getblock:
            /* Get block number */
            c = kfile_getc(ch);

            /* Check complemented block number */
            if ((~c & 0xff) != kfile_getc(ch))
            {
                LOG_WARN("Bad blk (%d)\n", c);
                purge = true;
                break;
            }

            /* Determine which block is being sent */
            if (c == (blocknr & 0xff))
            {
                /* Last block repeated */
                LOG_INFO("Repeat blk %d\n", blocknr);
            }
            else if (c == ((blocknr + 1) & 0xff))
            {
                /* Next block */
                LOG_INFO("Recv blk %d\n", ++blocknr);
            }
            else
            {
                /* Sync lost */
                LOG_WARN("Sync lost (%d/%d)\n", c, blocknr);
                purge = true;
                break;
            }

            buf = block_buffer;	/* Reset pointer to start of buffer */
            checksum = 0;
            crc = 0;
            for (i = 0; i < blocksize; i++)
            {
                if ((c = kfile_getc(ch)) == EOF)
                {
                    purge = true;
                    break;
                }

                /* Store in buffer */
                *buf++ = (char)c;

                /* Calculate block checksum or CRC */
                if (usecrc)
                    crc = UPDCRC16(c, crc);
                else
                    checksum += (char)c;
            }

            if (purge)
                break;

            /* Get the checksum byte or the CRC-16 MSB */
            if ((c = kfile_getc(ch)) == EOF)
            {
                purge = true;
                break;
            }

            if (usecrc)
            {
                crc = UPDCRC16(c, crc);

                /* Get CRC-16 LSB */
                if ((c = kfile_getc(ch)) == EOF)
                {
                    purge = true;
                    break;
                }

                crc = UPDCRC16(c, crc);

                if (crc)
                {
                    LOG_ERR("Bad CRC: %04x\n", crc);
                    purge = true;
                    break;
                }
            }
            /* Compare the checksum */
            else if (c != checksum)
            {
                LOG_ERR("Bad sum: %04x/%04x\n", checksum, c);
                purge = true;
                break;
            }

            /*
             * Avoid flushing the same block twice.
             * This could happen when the sender does not receive our
             * acknowledge and resends the same block.
             */
            if (last_block_done < blocknr)
            {
                /* Call user function to flush the buffer */
                if (kfile_write(fd, block_buffer, blocksize))
                {
                    /* Acknowledge block and clear error counter */
                    kfile_putc(XM_ACK, ch);
                    retries = 0;
                    last_block_done = blocknr;
                }
                else
                {
                    /* User callback failed: abort transfer immediately */
                    retries = CONFIG_XMODEM_MAXRETRIES;
                    purge = true;
                }
            }
            break;

        case XM_EOT:	/* End of transmission */
            kfile_putc(XM_ACK, ch);
            LOG_INFO("Transfer completed\n");
            return true;

        case EOF: /* Timeout or serial error */
            purge = true;
            break;

        default:
            LOG_INFO("Skipping garbage\n");
            purge = true;
            break;
        }
    } /* End forever */
}
Example #20
0
/**
 * \brief Transmit some data using the XModem protocol.
 *
 * \param ch Channel to use for transfer
 * \param fd Source file
 *
 * \note This function allocates a large amount of stack for
 *       the XModem transfer buffer (\see XM_BUFSIZE).
 */
bool xmodem_send(KFile *ch, KFile *fd)
{
    char block_buffer[XM_BUFSIZE]; /* Buffer to hold a block of data */
    size_t size = -1;
    int blocknr = 1, retries = 0, c, i;
    bool proceed, usecrc = false;
    uint16_t crc;
    uint8_t sum;

    /*
     * Reading a block can be very slow, so we read the first block early
     * to avoid receiving double XM_C char.
     * This could happen if we check for XM_C and then read the block, giving
     * the receiving device time to send another XM_C char misinterpretating
     * the blocks sent.
     */
    size = kfile_read(fd, block_buffer, XM_BUFSIZE);

    kfile_clearerr(ch);
    LOG_INFO("Wait remote host\n");

    for(;;)
    {
        proceed = false;
        do
        {
            if (XMODEM_CHECK_ABORT)
                return false;

            switch (c = kfile_getc(ch))
            {
            case XM_NAK:
                LOG_INFO("Resend blk %d\n", blocknr);
                proceed = true;
                break;

            case XM_C:
                if (c == XM_C)
                {
                    LOG_INFO("Tx start (CRC)\n");
                    usecrc = true;
                }
                else
                {
                    LOG_INFO("Tx start (BCC)\n");
                }

                proceed = true;
                break;

            case XM_ACK:
                /* End of transfer? */
                if (!size)
                    return true;

                /* Call user function to read in one block */
                size = kfile_read(fd, block_buffer, XM_BUFSIZE);
                LOG_INFO("Send blk %d\n", blocknr);
                blocknr++;
                retries = 0;
                proceed = true;
                break;

            case EOF:
                kfile_clearerr(ch);
                retries++;
                LOG_INFO("Retries %d\n", retries);
                if (retries <= CONFIG_XMODEM_MAXRETRIES)
                    break;
            /* falling through! */

            case XM_CAN:
                LOG_INFO("Transfer aborted\n");
                return false;

            default:
                LOG_INFO("Skipping garbage\n");
                break;
            }
        }
        while (!proceed);

        if (!size)
        {
            kfile_putc(XM_EOT, ch);
            continue;
        }

        /* Pad block with 0xFF if it's partially full */
        memset(block_buffer + size, 0xFF, XM_BUFSIZE - size);

        /* Send block header (STX, blocknr, ~blocknr) */
#if XM_BUFSIZE == 128
        kfile_putc(XM_SOH, ch);
#else
        kfile_putc(XM_STX, ch);
#endif
        kfile_putc(blocknr & 0xFF, ch);
        kfile_putc(~blocknr & 0xFF, ch);

        /* Send block and compute its CRC/checksum */
        sum = 0;
        crc = 0;
        for (i = 0; i < XM_BUFSIZE; i++)
        {
            kfile_putc(block_buffer[i], ch);
            crc = UPDCRC16(block_buffer[i], crc);
            sum += block_buffer[i];
        }

        /* Send CRC/Checksum */
        if (usecrc)
        {
            kfile_putc(crc >> 8, ch);
            kfile_putc(crc & 0xFF, ch);
        }
        else
            kfile_putc(sum, ch);
    }