mirror of https://github.com/ARMmbed/mbed-os.git
AnalogIn, Interrupts, and I2C are added.
parent
3faaff74ee
commit
3c2258956b
|
@ -44,32 +44,15 @@ typedef enum {
|
|||
PWM_4
|
||||
} PWMName;
|
||||
|
||||
/*
|
||||
typedef enum {
|
||||
I2C_0 = (int)I2C0_BASE,
|
||||
I2C_1 = (int)I2C1_BASE,
|
||||
I2C_0 = (int)NRF_TWI0_BASE,
|
||||
I2C_1 = (int)NRF_TWI1_BASE
|
||||
} I2CName;
|
||||
|
||||
|
||||
#define CHANNELS_A_SHIFT 5
|
||||
typedef enum {
|
||||
ADC0_SE0 = 0,
|
||||
ADC0_SE3 = 3,
|
||||
ADC0_SE4a = (1 << CHANNELS_A_SHIFT) | (4),
|
||||
ADC0_SE4b = 4,
|
||||
ADC0_SE5b = 5,
|
||||
ADC0_SE6b = 6,
|
||||
ADC0_SE7a = (1 << CHANNELS_A_SHIFT) | (7),
|
||||
ADC0_SE7b = 7,
|
||||
ADC0_SE8 = 8,
|
||||
ADC0_SE9 = 9,
|
||||
ADC0_SE11 = 11,
|
||||
ADC0_SE12 = 12,
|
||||
ADC0_SE13 = 13,
|
||||
ADC0_SE14 = 14,
|
||||
ADC0_SE15 = 15,
|
||||
ADC0_SE23 = 23
|
||||
ADC0_0 = (int)NRF_ADC_BASE
|
||||
} ADCName;
|
||||
/*
|
||||
|
||||
typedef enum {
|
||||
DAC_0 = 0
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "analogin_api.h"
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "error.h"
|
||||
|
||||
#define ANALOGIN_MEDIAN_FILTER 1
|
||||
|
||||
#define ADC_10BIT_RANGE 0x3FF
|
||||
|
||||
static inline int div_round_up(int x, int y) {
|
||||
return (x + (y - 1)) / y;
|
||||
}
|
||||
|
||||
static const PinMap PinMap_ADC[] = {
|
||||
// {p26, ADC0_0, 1},
|
||||
// {p27, ADC0_0, 2},
|
||||
{p1, ADC0_0, 4},
|
||||
{p2, ADC0_0, 8},
|
||||
{p3, ADC0_0, 16},
|
||||
{p4, ADC0_0, 32},
|
||||
{p5, ADC0_0, 64},
|
||||
{p6, ADC0_0, 128},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
#define ADC_RANGE ADC_10BIT_RANGE
|
||||
|
||||
void analogin_init(analogin_t *obj, PinName pin) {
|
||||
obj->adc = (NRF_ADC_Type *) ((ADCName)pinmap_peripheral(pin, PinMap_ADC));
|
||||
if (obj->adc == (ADCName)NC) {
|
||||
error("ADC pin mapping failed");
|
||||
}
|
||||
int analogInputPin=0;
|
||||
PinMap *map = PinMap_ADC;
|
||||
while (map->pin != NC) {
|
||||
if (map->pin == pin){
|
||||
analogInputPin = map->function;
|
||||
break;
|
||||
}
|
||||
map++;
|
||||
}
|
||||
|
||||
NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
|
||||
NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
|
||||
(ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling<< ADC_CONFIG_INPSEL_Pos) |
|
||||
(ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling << ADC_CONFIG_REFSEL_Pos) |
|
||||
(analogInputPin << ADC_CONFIG_PSEL_Pos) |
|
||||
(ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
|
||||
}
|
||||
|
||||
|
||||
uint16_t analogin_read_u16(analogin_t *obj) {
|
||||
NRF_ADC->TASKS_START = 1;
|
||||
while (((NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) >> ADC_BUSY_BUSY_Pos) == ADC_BUSY_BUSY_Busy)
|
||||
{
|
||||
}
|
||||
|
||||
return (uint16_t)NRF_ADC->RESULT; // 10 bit
|
||||
}
|
||||
|
||||
float analogin_read(analogin_t *obj) {
|
||||
uint16_t value = analogin_read_u16(obj);
|
||||
return (float)value * (1.0f / (float)ADC_RANGE);
|
||||
}
|
|
@ -20,14 +20,14 @@
|
|||
#define DEVICE_PORTOUT 1
|
||||
#define DEVICE_PORTINOUT 1
|
||||
|
||||
#define DEVICE_INTERRUPTIN 0
|
||||
#define DEVICE_INTERRUPTIN 1
|
||||
|
||||
#define DEVICE_ANALOGIN 0
|
||||
#define DEVICE_ANALOGIN 1
|
||||
#define DEVICE_ANALOGOUT 0
|
||||
|
||||
#define DEVICE_SERIAL 1
|
||||
|
||||
#define DEVICE_I2C 0
|
||||
#define DEVICE_I2C 1
|
||||
#define DEVICE_I2CSLAVE 0
|
||||
|
||||
#define DEVICE_SPI 1
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include "cmsis.h"
|
||||
|
||||
#include "gpio_irq_api.h"
|
||||
#include "error.h"
|
||||
|
||||
#define CHANNEL_NUM 31
|
||||
|
||||
static uint32_t channel_ids[CHANNEL_NUM] = {0}; //each pin will be given an id, if id is 0 the pin can be ignored.
|
||||
static uint8_t channel_enabled[CHANNEL_NUM] = {0};
|
||||
static uint32_t portRISE= 0;
|
||||
static uint32_t portFALL= 0;
|
||||
static gpio_irq_handler irq_handler;
|
||||
|
||||
volatile uint32_t oldPortValue;
|
||||
static int test=0;
|
||||
|
||||
void GPIOTE_IRQHandler(void)
|
||||
{
|
||||
volatile uint32_t newVal = NRF_GPIO->IN;
|
||||
if ((NRF_GPIOTE->EVENTS_PORT != 0) && ((NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_PORT_Msk) != 0)){
|
||||
//NRF_GPIOTE->INTENSET &= ~(GPIOTE_INTENSET_PORT_Enabled<<GPIOTE_INTENSET_PORT_Pos);
|
||||
NRF_GPIOTE->EVENTS_PORT = 0;
|
||||
for(uint8_t i=0;i<31;i++)
|
||||
{
|
||||
if(channel_ids[i]>0){
|
||||
if((portRISE>>i)&1){
|
||||
if(((newVal>>i)&1) && ((oldPortValue>>i)&1)==0 ){//
|
||||
if(channel_enabled[i]){
|
||||
irq_handler(channel_ids[i], IRQ_RISE);
|
||||
}
|
||||
NRF_GPIO->PIN_CNF[i] &= ~(GPIO_PIN_CNF_SENSE_Msk);
|
||||
NRF_GPIO->PIN_CNF[i] |= (GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos) ;
|
||||
}
|
||||
else if(((newVal>>i)&1)==0 && ((NRF_GPIO->PIN_CNF[i] >>GPIO_PIN_CNF_SENSE_Pos)&GPIO_PIN_CNF_SENSE_Low) == GPIO_PIN_CNF_SENSE_Low){
|
||||
NRF_GPIO->PIN_CNF[i] &= ~(GPIO_PIN_CNF_SENSE_Msk);
|
||||
NRF_GPIO->PIN_CNF[i] |= (GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos) ;
|
||||
}
|
||||
}
|
||||
else if((portFALL>>i)&1){
|
||||
if(((oldPortValue>>i)&1) && ((newVal>>i)&1)==0 ){
|
||||
if(channel_enabled[i]){
|
||||
irq_handler(channel_ids[i], IRQ_FALL);
|
||||
}
|
||||
NRF_GPIO->PIN_CNF[i] &= ~(GPIO_PIN_CNF_SENSE_Msk);
|
||||
NRF_GPIO->PIN_CNF[i] |= (GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos) ;
|
||||
}
|
||||
else if(((newVal>>i)&1) && ((NRF_GPIO->PIN_CNF[i] >>GPIO_PIN_CNF_SENSE_Pos)&GPIO_PIN_CNF_SENSE_Low) != GPIO_PIN_CNF_SENSE_Low){
|
||||
NRF_GPIO->PIN_CNF[i] &= ~(GPIO_PIN_CNF_SENSE_Msk);
|
||||
NRF_GPIO->PIN_CNF[i] |= (GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
oldPortValue = newVal;
|
||||
//NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Enabled<<GPIOTE_INTENSET_PORT_Pos;
|
||||
}
|
||||
}
|
||||
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
|
||||
if (pin == NC) return -1;
|
||||
irq_handler = handler;
|
||||
|
||||
obj->ch = pin;
|
||||
|
||||
oldPortValue = NRF_GPIO->IN;
|
||||
|
||||
//NVIC_DisableIRQ(GPIOTE_IRQn);
|
||||
NRF_GPIOTE->EVENTS_PORT = 0;
|
||||
NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Set<<GPIOTE_INTENSET_PORT_Pos;
|
||||
NVIC_EnableIRQ(GPIOTE_IRQn);
|
||||
channel_ids[pin]=id;
|
||||
channel_enabled[pin]=1;
|
||||
}
|
||||
|
||||
void gpio_irq_free(gpio_irq_t *obj) {
|
||||
channel_ids[obj->ch] = 0;
|
||||
}
|
||||
|
||||
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
|
||||
portRISE &=~(1<<obj->ch);
|
||||
portFALL &=~(1<<obj->ch);
|
||||
if(enable){
|
||||
if(event == IRQ_RISE){
|
||||
portRISE |=(1<<obj->ch);
|
||||
NRF_GPIO->PIN_CNF[obj->ch] &= ~(GPIO_PIN_CNF_SENSE_Msk);// | GPIO_PIN_CNF_PULL_Msk);
|
||||
NRF_GPIO->PIN_CNF[obj->ch] |= (GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos) ;//| (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos);
|
||||
}
|
||||
else if(event == IRQ_FALL){
|
||||
portFALL |=(1<<obj->ch);
|
||||
NRF_GPIO->PIN_CNF[obj->ch] &= ~(GPIO_PIN_CNF_SENSE_Msk );//| GPIO_PIN_CNF_PULL_Msk);
|
||||
NRF_GPIO->PIN_CNF[obj->ch] |= (GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos);// | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos);
|
||||
}
|
||||
}
|
||||
oldPortValue = NRF_GPIO->IN;
|
||||
}
|
||||
|
||||
void gpio_irq_enable(gpio_irq_t *obj) {
|
||||
channel_enabled[obj->ch]=1;
|
||||
}
|
||||
|
||||
void gpio_irq_disable(gpio_irq_t *obj) {
|
||||
channel_enabled[obj->ch]=0;
|
||||
}
|
|
@ -0,0 +1,305 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "i2c_api.h"
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "error.h"
|
||||
|
||||
|
||||
/*
|
||||
static const PinMap PinMap_I2C_SDA[] = {
|
||||
{p9, I2C_0, 1},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_I2C_SCL[] = {
|
||||
{p8, I2C_0, 1},
|
||||
{NC , NC, 0}
|
||||
};*/
|
||||
uint8_t I2C_USED[] = {0,0};
|
||||
uint8_t addrSet=0;
|
||||
void i2c_interface_enable(i2c_t *obj)
|
||||
{
|
||||
obj->i2c->ENABLE = (TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos);
|
||||
}
|
||||
|
||||
void twi_master_init(i2c_t *obj, PinName sda, PinName scl, int frequency) {
|
||||
NRF_GPIO->PIN_CNF[scl] = ((GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) |
|
||||
(GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
|
||||
(GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
|
||||
(GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) |
|
||||
(GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos));
|
||||
|
||||
NRF_GPIO->PIN_CNF[sda] = ((GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) |
|
||||
(GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
|
||||
(GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
|
||||
(GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) |
|
||||
(GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos));
|
||||
|
||||
obj->i2c->PSELSCL = scl;
|
||||
obj->i2c->PSELSDA = sda;
|
||||
// set default frequency at 100k
|
||||
i2c_frequency(obj, frequency);
|
||||
i2c_interface_enable(obj);
|
||||
}
|
||||
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
|
||||
// determine the SPI to use
|
||||
// I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
|
||||
// I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
|
||||
if(I2C_USED[0]){
|
||||
if(I2C_USED[1]){
|
||||
error("All TWI peripherals in use.");
|
||||
}
|
||||
else
|
||||
obj->i2c = (NRF_TWI_Type *)I2C_1;
|
||||
}
|
||||
else{
|
||||
obj->i2c = (NRF_TWI_Type *)I2C_0;
|
||||
}
|
||||
|
||||
if ((int)obj->i2c == NC) {
|
||||
error("I2C pin mapping failed");
|
||||
}
|
||||
|
||||
obj->scl=scl;
|
||||
obj->sda=sda;
|
||||
obj->i2c->EVENTS_ERROR = 0;
|
||||
obj->i2c->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
|
||||
obj->i2c->POWER = 0;
|
||||
for(int i=0;i<100;i++);
|
||||
obj->i2c->POWER = 1;
|
||||
twi_master_init(obj,sda,scl,100000);
|
||||
}
|
||||
void i2c_reset(i2c_t *obj) {
|
||||
obj->i2c->EVENTS_ERROR = 0;
|
||||
obj->i2c->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
|
||||
obj->i2c->POWER = 0;
|
||||
for(int i=0;i<100;i++);
|
||||
obj->i2c->POWER = 1;
|
||||
twi_master_init(obj,obj->sda,obj->scl,obj->freq);
|
||||
}
|
||||
|
||||
inline int i2c_start(i2c_t *obj) {
|
||||
int status = 0;
|
||||
//obj->i2c->ADDRESS = 0;
|
||||
i2c_reset(obj);
|
||||
addrSet=0;
|
||||
return status;
|
||||
}
|
||||
|
||||
inline int i2c_stop(i2c_t *obj) {
|
||||
// int timeout = 0;
|
||||
obj->i2c->EVENTS_STOPPED = 0;
|
||||
// write the stop bit
|
||||
obj->i2c->TASKS_STOP=1;
|
||||
while(!obj->i2c->EVENTS_STOPPED)
|
||||
{
|
||||
}
|
||||
//obj->i2c->ADDRESS = 0;
|
||||
addrSet=0;
|
||||
i2c_reset(obj);
|
||||
//obj->i2c->EVENTS_STOPPED = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int i2c_do_write(i2c_t *obj, int value) {
|
||||
int timeOut=1000;
|
||||
obj->i2c->TXD = value;
|
||||
while(!obj->i2c->EVENTS_TXDSENT){
|
||||
timeOut--;
|
||||
if(timeOut<0)
|
||||
return 1;
|
||||
}
|
||||
obj->i2c->EVENTS_TXDSENT = 0;
|
||||
return 0;
|
||||
}
|
||||
int i2c_do_read(i2c_t *obj, char * data, int last) {
|
||||
int timeOut=1000;
|
||||
while(!obj->i2c->EVENTS_RXDREADY){
|
||||
timeOut--;
|
||||
if(timeOut<0)
|
||||
return 1;
|
||||
}
|
||||
obj->i2c->EVENTS_RXDREADY = 0;
|
||||
|
||||
if (last)
|
||||
obj->i2c->TASKS_STOP=1;
|
||||
*data = obj->i2c->RXD;
|
||||
|
||||
for(int i=0;i<320;i++);
|
||||
|
||||
obj->i2c->TASKS_RESUME = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void i2c_frequency(i2c_t *obj, int hz) {
|
||||
obj->freq=hz;
|
||||
switch(hz){
|
||||
case 100000:obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K100 << TWI_FREQUENCY_FREQUENCY_Pos);break;
|
||||
case 250000:obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K250 << TWI_FREQUENCY_FREQUENCY_Pos);break;
|
||||
case 400000:obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K400 << TWI_FREQUENCY_FREQUENCY_Pos);break;
|
||||
default:error("I2C frequency requested is not supported"); break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int checkError(i2c_t *obj)
|
||||
{
|
||||
if (obj->i2c->EVENTS_ERROR == 1)
|
||||
{
|
||||
if ((obj->i2c->ERRORSRC & TWI_ERRORSRC_ANACK_Msk) == (TWI_ERRORSRC_ANACK_Present << TWI_ERRORSRC_ANACK_Pos))
|
||||
{
|
||||
obj->i2c->EVENTS_ERROR = 0;
|
||||
obj->i2c->TASKS_STOP = 1;
|
||||
obj->i2c->ERRORSRC |= (TWI_ERRORSRC_ANACK_Present << TWI_ERRORSRC_ANACK_Pos);
|
||||
return I2C_ERROR_BUS_BUSY;
|
||||
}
|
||||
}
|
||||
if (obj->i2c->EVENTS_ERROR == 1)
|
||||
{
|
||||
obj->i2c->EVENTS_ERROR = 0;
|
||||
obj->i2c->TASKS_STOP = 1;
|
||||
|
||||
if ((obj->i2c->ERRORSRC & TWI_ERRORSRC_DNACK_Msk) == (TWI_ERRORSRC_DNACK_Present << TWI_ERRORSRC_DNACK_Pos))
|
||||
{
|
||||
obj->i2c->ERRORSRC |= (TWI_ERRORSRC_DNACK_Present << TWI_ERRORSRC_DNACK_Pos);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The I2C does a read or a write as a whole operation
|
||||
// There are two types of error conditions it can encounter
|
||||
// 1) it can not obtain the bus
|
||||
// 2) it gets error responses at part of the transmission
|
||||
//
|
||||
// We tackle them as follows:
|
||||
// 1) we retry until we get the bus. we could have a "timeout" if we can not get it
|
||||
// which basically turns it in to a 2)
|
||||
// 2) on error, we use the standard error mechanisms to report/debug
|
||||
//
|
||||
// Therefore an I2C transaction should always complete. If it doesn't it is usually
|
||||
// because something is setup wrong (e.g. wiring), and we don't need to programatically
|
||||
// check for that
|
||||
|
||||
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
|
||||
int status,count;
|
||||
obj->i2c->ADDRESS = (address>>1);
|
||||
obj->i2c->SHORTS = 0;
|
||||
obj->i2c->EVENTS_RXDREADY = 0;
|
||||
obj->i2c->TASKS_STARTRX = 1;
|
||||
// Read in all except last byte
|
||||
for (count = 0; count < (length - 1); count++) {
|
||||
status = i2c_do_read(obj,&data[count], 0);
|
||||
if (status) {
|
||||
i2c_reset(obj);
|
||||
int errorResult = checkError(obj);
|
||||
if(errorResult<0)
|
||||
return errorResult;
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
/*status = i2c_do_read(obj,&data[length-2], 1);
|
||||
if (status) {
|
||||
i2c_reset(obj);
|
||||
return length - 2;
|
||||
}*/
|
||||
// read in last byte
|
||||
status = i2c_do_read(obj,&data[length-1], 1);
|
||||
if (status) {
|
||||
i2c_reset(obj);
|
||||
return length - 1;
|
||||
}
|
||||
// If not repeated start, send stop.
|
||||
if (stop) {
|
||||
while(!obj->i2c->EVENTS_STOPPED)
|
||||
{
|
||||
}
|
||||
obj->i2c->EVENTS_STOPPED = 0;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
|
||||
int status;
|
||||
obj->i2c->ADDRESS = (address>>1);
|
||||
obj->i2c->SHORTS = 0;
|
||||
//obj->i2c->EVENTS_STOPPED = 0;
|
||||
obj->i2c->TASKS_STARTTX = 1;
|
||||
for (int i=0; i<length; i++) {
|
||||
status = i2c_do_write(obj, data[i]);
|
||||
if(status) {
|
||||
i2c_reset(obj);
|
||||
int errorResult = checkError(obj);
|
||||
if(errorResult<0)
|
||||
return errorResult;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// clearing the serial interrupt here might cause an unintended rewrite of the last byte
|
||||
// see also issue report https://mbed.org/users/mbed_official/code/mbed/issues/1
|
||||
// i2c_clear_SI(obj);
|
||||
|
||||
// If not repeated start, send stop.
|
||||
if (stop) {
|
||||
i2c_stop(obj);
|
||||
}
|
||||
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
int i2c_byte_read(i2c_t *obj, int last) {
|
||||
char data;
|
||||
int status;
|
||||
status = i2c_do_read(obj,&data, last);
|
||||
if (status) {
|
||||
i2c_reset(obj);
|
||||
}
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
int i2c_byte_write(i2c_t *obj, int data) {
|
||||
int status = 0;
|
||||
if(!addrSet)//obj->i2c->ADDRESS==0)
|
||||
{
|
||||
addrSet=1;
|
||||
obj->i2c->ADDRESS = (data>>1);
|
||||
if(data&1)
|
||||
{
|
||||
obj->i2c->EVENTS_RXDREADY = 0;
|
||||
obj->i2c->TASKS_STARTRX = 1;
|
||||
}
|
||||
else{
|
||||
obj->i2c->TASKS_STARTTX = 1;
|
||||
}
|
||||
}
|
||||
else{
|
||||
status = i2c_do_write(obj, data);
|
||||
if(status) {
|
||||
i2c_reset(obj);
|
||||
}
|
||||
}
|
||||
return (1-status);
|
||||
}
|
|
@ -48,33 +48,21 @@ struct pwmout_s {
|
|||
PinName pin;
|
||||
};
|
||||
|
||||
/*
|
||||
struct gpio_irq_s {
|
||||
uint32_t port;
|
||||
uint32_t pin;
|
||||
uint32_t ch;
|
||||
struct i2c_s {
|
||||
NRF_TWI_Type *i2c;
|
||||
PinName sda;
|
||||
PinName scl;
|
||||
int freq;
|
||||
};
|
||||
|
||||
struct pwmout_s {
|
||||
__IO uint32_t *MOD;
|
||||
__IO uint32_t *CNT;
|
||||
__IO uint32_t *CnV;
|
||||
};
|
||||
|
||||
|
||||
struct analogin_s {
|
||||
ADCName adc;
|
||||
};
|
||||
|
||||
struct dac_s {
|
||||
DACName dac;
|
||||
struct gpio_irq_s {
|
||||
uint32_t ch;
|
||||
};
|
||||
|
||||
struct i2c_s {
|
||||
I2C_Type *i2c;
|
||||
};
|
||||
|
||||
*/
|
||||
#include "gpio_object.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
Loading…
Reference in New Issue