u2f-zero/firmware/src/i2c.c

110 wiersze
3.2 KiB
C
Czysty Zwykły widok Historia

2016-03-29 04:35:26 +00:00
/*
2016-06-18 14:40:01 +00:00
* Copyright (c) 2016, Conor Patrick
* All rights reserved.
2016-03-29 04:35:26 +00:00
*
2016-06-18 14:40:01 +00:00
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2016-03-29 04:35:26 +00:00
*/
#include <SI_EFM8UB1_Register_Enums.h>
#include <string.h>
#include <stdint.h>
#include "i2c.h"
#include "bsp.h"
#include "app.h"
uint8_t smb_read (uint8_t addr, uint8_t* dest, uint8_t count)
{
while(SMB_IS_BUSY()){}
2016-03-29 04:35:26 +00:00
2016-03-31 01:48:01 +00:00
SMB_crc = 0;
SMB_crc_offset = 0;
SMB_FLAGS = SMB_READ | SMB_BUSY | SMB_preflags;
2016-03-31 00:35:25 +00:00
SMB_preflags = 0;
2016-03-29 04:35:26 +00:00
2016-03-31 00:35:25 +00:00
SMB_read_offset = 0;
SMB_addr = addr;
SMB_read_len = count;
SMB_read_buf = dest;
2016-03-29 04:35:26 +00:00
SMB0CN0_STA = 1;
while(SMB_IS_BUSY()){}
2016-03-31 00:35:25 +00:00
return SMB_read_len;
2016-03-29 04:35:26 +00:00
}
void smb_write (uint8_t addr, uint8_t* buf, uint8_t len)
{
while(SMB_IS_BUSY()){}
2016-03-29 04:35:26 +00:00
2016-03-31 01:48:01 +00:00
SMB_crc = 0;
SMB_crc_offset = 0;
SMB_FLAGS = SMB_WRITE | SMB_BUSY | SMB_preflags;
SMB_preflags = 0;
2016-03-29 04:35:26 +00:00
2016-03-31 01:48:01 +00:00
SMB_write_len = len;
SMB_write_buf = buf;
SMB_write_offset = 0;
SMB_addr = addr;
2016-03-29 04:35:26 +00:00
2016-03-31 01:48:01 +00:00
SMB0CN0_STA = 1;
while(SMB_IS_BUSY()){}
2016-03-29 04:35:26 +00:00
}
void smb_set_ext_write( uint8_t* extbuf, uint8_t extlen)
{
while(SMB_IS_BUSY()){}
2016-03-31 00:35:25 +00:00
SMB_write_ext_len = extlen;
SMB_write_ext_buf = extbuf;
SMB_write_ext_offset = 0;
SMB_preflags |= SMB_WRITE_EXT;
2016-03-29 04:35:26 +00:00
}
2016-06-18 15:21:48 +00:00
// CRC-16 appropriate for a byte model interrupt routine.
2016-03-29 04:35:26 +00:00
uint16_t feed_crc(uint16_t crc, uint8_t b)
{
crc ^= b;
crc = crc & 1 ? (crc >> 1) ^ 0xa001 : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ 0xa001 : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ 0xa001 : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ 0xa001 : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ 0xa001 : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ 0xa001 : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ 0xa001 : crc >> 1;
return crc & 1 ? (crc >> 1) ^ 0xa001 : crc >> 1;
}
2016-06-18 15:21:48 +00:00
// Resulting CRC should be reversed to be correct CRC-16
2016-03-29 04:35:26 +00:00
uint16_t reverse_bits(uint16_t crc)
{
// efficient bit reversal for 16 bit int
crc = (((crc & 0xaaaa) >> 1) | ((crc & 0x5555) << 1));
crc = (((crc & 0xcccc) >> 2) | ((crc & 0x3333) << 2));
crc = (((crc & 0xf0f0) >> 4) | ((crc & 0x0f0f) << 4));
return (((crc & 0xff00) >> 8) | ((crc & 0x00ff) << 8));
}
void smb_init()
{
SMB_FLAGS = 0;
}