cleaning up code within Nordic's mbed HAL using astyle

pull/464/merge
Rohit Grover 2014-08-12 14:53:35 +01:00
parent d20ce63487
commit 90467175c0
12 changed files with 690 additions and 634 deletions

View File

@ -29,45 +29,47 @@ static const PinMap PinMap_ADC[] = {
{p4, ADC0_0, 32},
{p5, ADC0_0, 64},
{p6, ADC0_0, 128},
{NC , NC , 0}
{NC, NC, 0}
};
void analogin_init(analogin_t *obj, PinName pin) {
int analogInputPin=0;
const PinMap *map = PinMap_ADC;
void analogin_init(analogin_t *obj, PinName pin)
{
int analogInputPin = 0;
const PinMap *map = PinMap_ADC;
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); //(NRF_ADC_Type *)
MBED_ASSERT(obj->adc != (ADCName)NC);
while (map->pin != NC) {
if (map->pin == pin){
if (map->pin == pin) {
analogInputPin = map->function;
break;
}
map++;
}
obj->adc_pin = (uint8_t)analogInputPin;
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_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->CONFIG &= ~ADC_CONFIG_PSEL_Msk;
NRF_ADC->CONFIG |= obj->adc_pin << ADC_CONFIG_PSEL_Pos;
uint16_t analogin_read_u16(analogin_t *obj)
{
NRF_ADC->CONFIG &= ~ADC_CONFIG_PSEL_Msk;
NRF_ADC->CONFIG |= obj->adc_pin << ADC_CONFIG_PSEL_Pos;
NRF_ADC->TASKS_START = 1;
while ( ( (NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) >> ADC_BUSY_BUSY_Pos) == ADC_BUSY_BUSY_Busy)
{
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) {
float analogin_read(analogin_t *obj)
{
uint16_t value = analogin_read_u16(obj);
return (float)value * (1.0f / (float)ADC_RANGE);
}

View File

@ -17,10 +17,12 @@
#include "gpio_api.h"
#include "pinmap.h"
void gpio_init(gpio_t *obj, PinName pin) {
void gpio_init(gpio_t *obj, PinName pin)
{
obj->pin = pin;
if (pin == (PinName)NC)
if (pin == (PinName)NC) {
return;
}
obj->mask = (1ul << pin);
@ -30,14 +32,16 @@ void gpio_init(gpio_t *obj, PinName pin) {
obj->reg_dir = &NRF_GPIO->DIR;
}
void gpio_mode(gpio_t *obj, PinMode mode) {
void gpio_mode(gpio_t *obj, PinMode mode)
{
pin_mode(obj->pin, mode);
}
void gpio_dir(gpio_t *obj, PinDirection direction) {
void gpio_dir(gpio_t *obj, PinDirection direction)
{
MBED_ASSERT(obj->pin != (PinName)NC);
switch (direction) {
case PIN_INPUT :
case PIN_INPUT:
NRF_GPIO->PIN_CNF[obj->pin] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
| (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
| (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
@ -52,4 +56,3 @@ void gpio_dir(gpio_t *obj, PinDirection direction) {
break;
}
}

View File

@ -23,103 +23,105 @@
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 uint32_t portRISE = 0;
static uint32_t portFALL = 0;
static gpio_irq_handler irq_handler;
#ifdef __cplusplus
extern "C" {
#endif
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->EVENTS_PORT = 0;
for(uint8_t i=0;i<31;i++){
if(channel_ids[i]>0){
if(channel_enabled[i]){
#endif
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->EVENTS_PORT = 0;
for (uint8_t i = 0; i<31; i++) {
if (channel_ids[i]>0) {
if (channel_enabled[i]) {
if( ((newVal>>i)&1) && ( ( (NRF_GPIO->PIN_CNF[i] >>GPIO_PIN_CNF_SENSE_Pos) & GPIO_PIN_CNF_SENSE_Low) != GPIO_PIN_CNF_SENSE_Low) && ( (portRISE>>i)&1) ){
irq_handler(channel_ids[i], IRQ_RISE);
}
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) && ( (portFALL>>i)&1) ){
irq_handler(channel_ids[i], IRQ_FALL);
}
}
if(NRF_GPIO->PIN_CNF[i] &GPIO_PIN_CNF_SENSE_Msk){
NRF_GPIO->PIN_CNF[i] &= ~(GPIO_PIN_CNF_SENSE_Msk);
if(newVal>>i &1){
NRF_GPIO->PIN_CNF[i] |= (GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos) ;
irq_handler(channel_ids[i], IRQ_RISE);
} 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) &&
((portFALL >> i) & 1)) {
irq_handler(channel_ids[i], IRQ_FALL);
}
else{
NRF_GPIO->PIN_CNF[i] |= (GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos) ;
}
if (NRF_GPIO->PIN_CNF[i] & GPIO_PIN_CNF_SENSE_Msk) {
NRF_GPIO->PIN_CNF[i] &= ~(GPIO_PIN_CNF_SENSE_Msk);
if (newVal >> i & 1) {
NRF_GPIO->PIN_CNF[i] |= (GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos);
} else {
NRF_GPIO->PIN_CNF[i] |= (GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos);
}
}
}
}
}
}
}
#ifdef __cplusplus
}
#endif
#endif
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
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;
NRF_GPIOTE->EVENTS_PORT = 0;
channel_ids[pin] = id;
channel_enabled[pin] = 1;
NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Set<<GPIOTE_INTENSET_PORT_Pos;
irq_handler = handler;
obj->ch = pin;
NRF_GPIOTE->EVENTS_PORT = 0;
channel_ids[pin] = id;
channel_enabled[pin] = 1;
NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Set << GPIOTE_INTENSET_PORT_Pos;
NVIC_SetPriority(GPIOTE_IRQn, 3);
NVIC_EnableIRQ (GPIOTE_IRQn);
NVIC_EnableIRQ (GPIOTE_IRQn);
return 0;
}
void gpio_irq_free(gpio_irq_t *obj) {
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) {
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
{
NRF_GPIO->PIN_CNF[obj->ch] &= ~(GPIO_PIN_CNF_SENSE_Msk);
if(enable){
if(event == IRQ_RISE){
portRISE |= (1<<obj->ch);
if (enable) {
if (event == IRQ_RISE) {
portRISE |= (1 << obj->ch);
} else if (event == IRQ_FALL) {
portFALL |= (1 << obj->ch);
}
} else {
if (event == IRQ_RISE) {
portRISE &= ~(1 << obj->ch);
} else if (event == IRQ_FALL) {
portFALL &= ~(1 << obj->ch);
}
else if(event == IRQ_FALL){
portFALL |= (1<<obj->ch);
}
}
else{
if(event == IRQ_RISE){
portRISE &= ~(1<<obj->ch);
}
else if(event == IRQ_FALL){
portFALL &= ~(1<<obj->ch);
}
}
if( ( (portRISE>>obj->ch) & 1) || ( (portFALL>>obj->ch) & 1) ){
if((NRF_GPIO->IN>>obj->ch)&1){
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);
}
else{
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);
if (((portRISE >> obj->ch) & 1) || ((portFALL >> obj->ch) & 1)) {
if ((NRF_GPIO->IN >> obj->ch) & 1) {
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);
} else {
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);
}
}
}
void gpio_irq_enable(gpio_irq_t *obj) {
void gpio_irq_enable(gpio_irq_t *obj)
{
channel_enabled[obj->ch] = 1;
}
void gpio_irq_disable(gpio_irq_t *obj) {
void gpio_irq_disable(gpio_irq_t *obj)
{
channel_enabled[obj->ch] = 0;
}

View File

@ -21,175 +21,187 @@
static const PinMap PinMap_I2C_SDA[] = {
{p22, I2C_0, 1},
{p13, I2C_1, 2},
{NC , NC , 0}
{NC, NC, 0}
};
static const PinMap PinMap_I2C_SCL[] = {
{p20, I2C_0, 1},
{p15, I2C_1, 2},
{NC , NC, 0}
{NC, NC, 0}
};
uint8_t addrSet=0;
uint8_t addrSet = 0;
void i2c_interface_enable(i2c_t *obj){
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));
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));
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;
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) {
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);
I2CName i2c = (I2CName)pinmap_merge(i2c_sda,i2c_scl);
obj->i2c = (NRF_TWI_Type *)i2c;
I2CName i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
obj->i2c = (NRF_TWI_Type *)i2c;
MBED_ASSERT((int)obj->i2c != NC);
obj->scl=scl;
obj->sda=sda;
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++){
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);
obj->i2c->POWER = 1;
twi_master_init(obj, sda, scl, 100000);
}
int i2c_start(i2c_t *obj) {
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);
}
int i2c_start(i2c_t *obj)
{
int status = 0;
i2c_reset(obj);
addrSet=0;
addrSet = 0;
return status;
}
int i2c_stop(i2c_t *obj) {
int i2c_stop(i2c_t *obj)
{
int timeOut = 100000;
obj->i2c->EVENTS_STOPPED = 0;
// write the stop bit
obj->i2c->TASKS_STOP = 1;
while(!obj->i2c->EVENTS_STOPPED){
while (!obj->i2c->EVENTS_STOPPED) {
timeOut--;
if(timeOut<0)
if (timeOut<0) {
return 1;
}
}
addrSet = 0;
i2c_reset(obj);
return 0;
}
int i2c_do_write(i2c_t *obj, int value) {
int i2c_do_write(i2c_t *obj, int value)
{
int timeOut = 100000;
obj->i2c->TXD = value;
while(!obj->i2c->EVENTS_TXDSENT){
while (!obj->i2c->EVENTS_TXDSENT) {
timeOut--;
if(timeOut<0)
if (timeOut<0) {
return 1;
}
}
obj->i2c->EVENTS_TXDSENT = 0;
return 0;
}
int i2c_do_read(i2c_t *obj, char * data, int last) {
int i2c_do_read(i2c_t *obj, char *data, int last)
{
int timeOut = 100000;
if (last){
if (last) {
obj->i2c->TASKS_STOP = 1;
}
while(!obj->i2c->EVENTS_RXDREADY){
while (!obj->i2c->EVENTS_RXDREADY) {
timeOut--;
if(timeOut<0)
if (timeOut<0) {
return 1;
}
}
obj->i2c->EVENTS_RXDREADY = 0;
obj->i2c->EVENTS_RXDREADY = 0;
*data = obj->i2c->RXD;
for(int i=0;i<320;i++){
for (int i = 0; i<320; i++) {
}
obj->i2c->TASKS_RESUME = 1;
return 0;
}
void i2c_frequency(i2c_t *obj, int hz) {
if(hz<250000){
void i2c_frequency(i2c_t *obj, int hz)
{
if (hz<250000) {
obj->freq = 100000;
obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K100 << TWI_FREQUENCY_FREQUENCY_Pos);
}
else if(hz<400000){
} else if (hz<400000) {
obj->freq = 250000;
obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K250 << TWI_FREQUENCY_FREQUENCY_Pos);
}
else{
} else {
obj->freq = 400000;
obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K400 << TWI_FREQUENCY_FREQUENCY_Pos);
}
}
int checkError(i2c_t *obj){
if (obj->i2c->EVENTS_ERROR == 1){
if (obj->i2c->ERRORSRC & TWI_ERRORSRC_ANACK_Msk){
obj->i2c->EVENTS_ERROR = 0;
obj->i2c->TASKS_STOP = 1;
int checkError(i2c_t *obj)
{
if (obj->i2c->EVENTS_ERROR == 1) {
if (obj->i2c->ERRORSRC & TWI_ERRORSRC_ANACK_Msk) {
obj->i2c->EVENTS_ERROR = 0;
obj->i2c->TASKS_STOP = 1;
return I2C_ERROR_BUS_BUSY;
}
obj->i2c->EVENTS_ERROR = 0;
obj->i2c->TASKS_STOP = 1;
obj->i2c->EVENTS_ERROR = 0;
obj->i2c->TASKS_STOP = 1;
return I2C_ERROR_NO_SLAVE;
}
return 0;
}
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
int status,count,errorResult;
obj->i2c->ADDRESS = (address>>1);
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
{
int status, count, errorResult;
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);
status = i2c_do_read(obj, &data[count], 0);
if (status) {
errorResult = checkError(obj);
i2c_reset(obj);
if(errorResult<0){
if (errorResult<0) {
return errorResult;
}
return count;
@ -197,77 +209,78 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
}
// read in last byte
status = i2c_do_read(obj,&data[length-1], 1);
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){
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 i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
{
int status, errorResult;
obj->i2c->ADDRESS = (address>>1);
obj->i2c->ADDRESS = (address >> 1);
obj->i2c->SHORTS = 0;
obj->i2c->TASKS_STARTTX = 1;
for (int i=0; i<length; i++) {
for (int i = 0; i<length; i++) {
status = i2c_do_write(obj, data[i]);
if(status) {
if (status) {
i2c_reset(obj);
errorResult = checkError(obj);
if(errorResult<0){
if (errorResult<0) {
return errorResult;
}
return i;
}
}
// If not repeated start, send stop.
if (stop) {
if(i2c_stop(obj)){
if (i2c_stop(obj)) {
return I2C_ERROR_NO_SLAVE;
}
}
return length;
}
int i2c_byte_read(i2c_t *obj, int last) {
int i2c_byte_read(i2c_t *obj, int last)
{
char data;
int status;
status = i2c_do_read(obj,&data, last);
status = i2c_do_read(obj, &data, last);
if (status) {
i2c_reset(obj);
}
return data;
}
int i2c_byte_write(i2c_t *obj, int data) {
int i2c_byte_write(i2c_t *obj, int data)
{
int status = 0;
if(!addrSet){
addrSet = 1;
obj->i2c->ADDRESS = (data>>1);
if(data&1){
if (!addrSet) {
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{
obj->i2c->TASKS_STARTTX = 1;
}
}
else{
} else {
status = i2c_do_write(obj, data);
if(status) {
if (status) {
i2c_reset(obj);
}
}
return (1-status);
return (1 - status);
}

View File

@ -17,14 +17,16 @@
#include "pinmap.h"
#include "mbed_error.h"
void pin_function(PinName pin, int function) {
void pin_function(PinName pin, int function)
{
}
void pin_mode(PinName pin, PinMode mode) {
void pin_mode(PinName pin, PinMode mode)
{
MBED_ASSERT(pin != (PinName)NC);
uint32_t pin_number = (uint32_t)pin;
NRF_GPIO->PIN_CNF[pin_number] &= ~GPIO_PIN_CNF_PULL_Msk;
NRF_GPIO->PIN_CNF[pin_number] |= (mode << GPIO_PIN_CNF_PULL_Pos);
}

View File

@ -17,37 +17,41 @@
#include "pinmap.h"
#include "gpio_api.h"
PinName port_pin(PortName port, int pin_n) {
PinName port_pin(PortName port, int pin_n)
{
return (PinName)(pin_n);
}
void port_init(port_t *obj, PortName port, int mask, PinDirection dir) {
void port_init(port_t *obj, PortName port, int mask, PinDirection dir)
{
obj->port = port;
obj->mask = mask;
obj->mask = mask;
obj->reg_out = &NRF_GPIO->OUT;
obj->reg_in = &NRF_GPIO->IN;
obj->reg_cnf = NRF_GPIO->PIN_CNF;
port_dir(obj, dir);
}
void port_mode(port_t *obj, PinMode mode) {
void port_mode(port_t *obj, PinMode mode)
{
uint32_t i;
// The mode is set per pin: reuse pinmap logic
for (i=0; i<31; i++) {
if (obj->mask & (1<<i)) {
for (i = 0; i<31; i++) {
if (obj->mask & (1 << i)) {
pin_mode(port_pin(obj->port, i), mode);
}
}
}
void port_dir(port_t *obj, PinDirection dir) {
void port_dir(port_t *obj, PinDirection dir)
{
int i;
switch (dir) {
case PIN_INPUT :
for (i=0; i<31; i++) {
if (obj->mask & (1<<i)) {
case PIN_INPUT:
for (i = 0; i<31; i++) {
if (obj->mask & (1 << i)) {
obj->reg_cnf[i] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
| (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
| (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
@ -55,9 +59,9 @@ void port_dir(port_t *obj, PinDirection dir) {
}
}
break;
case PIN_OUTPUT:
for (i=0; i<31; i++) {
if (obj->mask & (1<<i)) {
case PIN_OUTPUT:
for (i = 0; i<31; i++) {
if (obj->mask & (1 << i)) {
obj->reg_cnf[i] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
| (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
| (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
@ -69,10 +73,12 @@ void port_dir(port_t *obj, PinDirection dir) {
}
}
void port_write(port_t *obj, int value) {
void port_write(port_t *obj, int value)
{
*obj->reg_out = value;
}
int port_read(port_t *obj) {
int port_read(port_t *obj)
{
return (*obj->reg_in);
}

View File

@ -20,7 +20,7 @@
#include "mbed_error.h"
#define NO_PWMS 3
#define TIMER_PRECISION 4 //4us ticks
#define TIMER_PRECISION 4 //4us ticks
#define TIMER_PRESCALER 6 //4us ticks = 16Mhz/(2**6)
static const PinMap PinMap_PWM[] = {
{p0, PWM_1, 1},
@ -59,65 +59,66 @@ static NRF_TIMER_Type *Timers[1] = {
NRF_TIMER2
};
uint16_t PERIOD = 20000/TIMER_PRECISION;//20ms
uint8_t PWM_taken[NO_PWMS] = {0,0,0};
uint16_t PULSE_WIDTH[NO_PWMS] = {1,1,1};//set to 1 instead of 0
uint16_t ACTUAL_PULSE[NO_PWMS] = {0,0,0};
uint16_t PERIOD = 20000 / TIMER_PRECISION; //20ms
uint8_t PWM_taken[NO_PWMS] = {0, 0, 0};
uint16_t PULSE_WIDTH[NO_PWMS] = {1, 1, 1}; //set to 1 instead of 0
uint16_t ACTUAL_PULSE[NO_PWMS] = {0, 0, 0};
/** @brief Function for handling timer 2 peripheral interrupts.
*/
#ifdef __cplusplus
#ifdef __cplusplus
extern "C" {
#endif
#endif
void TIMER2_IRQHandler(void)
{
NRF_TIMER2->EVENTS_COMPARE[3] = 0;
NRF_TIMER2->CC[3] = PERIOD;
if(PWM_taken[0]){
NRF_TIMER2->CC[0] = PULSE_WIDTH[0];
}
if(PWM_taken[1]){
NRF_TIMER2->CC[1] = PULSE_WIDTH[1];
}
if(PWM_taken[2]){
NRF_TIMER2->CC[2] = PULSE_WIDTH[2];
}
NRF_TIMER2->TASKS_START = 1;
NRF_TIMER2->CC[3] = PERIOD;
if (PWM_taken[0]) {
NRF_TIMER2->CC[0] = PULSE_WIDTH[0];
}
if (PWM_taken[1]) {
NRF_TIMER2->CC[1] = PULSE_WIDTH[1];
}
if (PWM_taken[2]) {
NRF_TIMER2->CC[2] = PULSE_WIDTH[2];
}
NRF_TIMER2->TASKS_START = 1;
}
#ifdef __cplusplus
}
#endif
#endif
/** @brief Function for initializing the Timer peripherals.
*/
void timer_init(uint8_t pwmChoice)
{
NRF_TIMER_Type *timer = Timers[0];
timer->TASKS_STOP = 0;
if(pwmChoice == 0){
if (pwmChoice == 0) {
timer->POWER = 0;
timer->POWER = 1;
timer->MODE = TIMER_MODE_MODE_Timer;
timer->POWER = 1;
timer->MODE = TIMER_MODE_MODE_Timer;
timer->BITMODE = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
timer->PRESCALER = TIMER_PRESCALER;
timer->PRESCALER = TIMER_PRESCALER;
timer->CC[3] = PERIOD;
}
timer->CC[pwmChoice] = PULSE_WIDTH[pwmChoice];
//high priority application interrupt
NVIC_SetPriority(TIMER2_IRQn, 1);
NVIC_EnableIRQ(TIMER2_IRQn);
timer->TASKS_START = 0x01;
}
/** @brief Function for initializing the GPIO Tasks/Events peripheral.
*/
void gpiote_init(PinName pin,uint8_t channel_number)
void gpiote_init(PinName pin, uint8_t channel_number)
{
// Connect GPIO input buffers and configure PWM_OUTPUT_PIN_NUMBER as an output.
NRF_GPIO->PIN_CNF[pin] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
@ -129,215 +130,216 @@ void gpiote_init(PinName pin,uint8_t channel_number)
// Configure GPIOTE channel 0 to toggle the PWM pin state
// @note Only one GPIOTE task can be connected to an output pin.
/* Configure channel to Pin31, not connected to the pin, and configure as a tasks that will set it to proper level */
NRF_GPIOTE->CONFIG[channel_number] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
(31UL << GPIOTE_CONFIG_PSEL_Pos) |
NRF_GPIOTE->CONFIG[channel_number] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
(31UL << GPIOTE_CONFIG_PSEL_Pos) |
(GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos);
/* Three NOPs are required to make sure configuration is written before setting tasks or getting events */
/* Three NOPs are required to make sure configuration is written before setting tasks or getting events */
__NOP();
__NOP();
__NOP();
__NOP();
/* Launch the task to take the GPIOTE channel output to the desired level */
NRF_GPIOTE->TASKS_OUT[channel_number] = 1;
/* Finally configure the channel as the caller expects. If OUTINIT works, the channel is configured properly.
/* Finally configure the channel as the caller expects. If OUTINIT works, the channel is configured properly.
If it does not, the channel output inheritance sets the proper level. */
NRF_GPIOTE->CONFIG[channel_number] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
((uint32_t)pin << GPIOTE_CONFIG_PSEL_Pos) |
((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) |
((uint32_t)GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos);// ((uint32_t)GPIOTE_CONFIG_OUTINIT_High << GPIOTE_CONFIG_OUTINIT_Pos);//
NRF_GPIOTE->CONFIG[channel_number] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
((uint32_t)pin << GPIOTE_CONFIG_PSEL_Pos) |
((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) |
((uint32_t)GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos); // ((uint32_t)GPIOTE_CONFIG_OUTINIT_High <<
// GPIOTE_CONFIG_OUTINIT_Pos);//
/* Three NOPs are required to make sure configuration is written before setting tasks or getting events */
__NOP();
__NOP();
__NOP();
__NOP();
}
/** @brief Function for initializing the Programmable Peripheral Interconnect peripheral.
*/
static void ppi_init(uint8_t pwm)
{
//using ppi channels 0-7 (only 0-7 are available)
uint8_t channel_number = 2*pwm;
NRF_TIMER_Type *timer = Timers[0];
//using ppi channels 0-7 (only 0-7 are available)
uint8_t channel_number = 2 * pwm;
NRF_TIMER_Type *timer = Timers[0];
// Configure PPI channel 0 to toggle ADVERTISING_LED_PIN_NO on every TIMER1 COMPARE[0] match
NRF_PPI->CH[channel_number].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pwm];
NRF_PPI->CH[channel_number+1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pwm];
NRF_PPI->CH[channel_number].EEP = (uint32_t)&timer->EVENTS_COMPARE[pwm];
NRF_PPI->CH[channel_number+1].EEP = (uint32_t)&timer->EVENTS_COMPARE[3];
NRF_PPI->CH[channel_number + 1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pwm];
NRF_PPI->CH[channel_number].EEP = (uint32_t)&timer->EVENTS_COMPARE[pwm];
NRF_PPI->CH[channel_number + 1].EEP = (uint32_t)&timer->EVENTS_COMPARE[3];
// Enable PPI channels.
NRF_PPI->CHEN |= (1 << channel_number)
| (1 << (channel_number+1));
NRF_PPI->CHEN |= (1 << channel_number) |
(1 << (channel_number + 1));
}
void setModulation(pwmout_t* obj,uint8_t toggle,uint8_t high)
void setModulation(pwmout_t *obj, uint8_t toggle, uint8_t high)
{
if(high){
if (high) {
NRF_GPIOTE->CONFIG[obj->pwm] |= ((uint32_t)GPIOTE_CONFIG_OUTINIT_High << GPIOTE_CONFIG_OUTINIT_Pos);
if(toggle){
NRF_GPIOTE->CONFIG[obj->pwm] |= (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
if (toggle) {
NRF_GPIOTE->CONFIG[obj->pwm] |= (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
} else {
NRF_GPIOTE->CONFIG[obj->pwm] &= ~((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
NRF_GPIOTE->CONFIG[obj->pwm] |= ((uint32_t)GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos);
}
else{
NRF_GPIOTE->CONFIG[obj->pwm] &= ~((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
NRF_GPIOTE->CONFIG[obj->pwm] |= ((uint32_t)GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos);
}
}
else{
} else {
NRF_GPIOTE->CONFIG[obj->pwm] &= ~((uint32_t)GPIOTE_CONFIG_OUTINIT_High << GPIOTE_CONFIG_OUTINIT_Pos);
if(toggle){
NRF_GPIOTE->CONFIG[obj->pwm] |= (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
}
else{
NRF_GPIOTE->CONFIG[obj->pwm] &= ~((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
NRF_GPIOTE->CONFIG[obj->pwm] |= ((uint32_t)GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos);
if (toggle) {
NRF_GPIOTE->CONFIG[obj->pwm] |= (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
} else {
NRF_GPIOTE->CONFIG[obj->pwm] &= ~((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
NRF_GPIOTE->CONFIG[obj->pwm] |= ((uint32_t)GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos);
}
}
}
void pwmout_init(pwmout_t* obj, PinName pin) {
void pwmout_init(pwmout_t *obj, PinName pin)
{
// determine the channel
uint8_t pwmOutSuccess = 0;
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
MBED_ASSERT(pwm != (PWMName)NC);
if(PWM_taken[(uint8_t)pwm]){
for(uint8_t i = 1; !pwmOutSuccess && (i<NO_PWMS) ;i++){
if(!PWM_taken[i]){
if (PWM_taken[(uint8_t)pwm]) {
for (uint8_t i = 1; !pwmOutSuccess && (i<NO_PWMS); i++) {
if (!PWM_taken[i]) {
pwm = (PWMName)i;
PWM_taken[i] = 1;
pwmOutSuccess = 1;
}
}
}
else{
} else {
pwmOutSuccess = 1;
PWM_taken[(uint8_t)pwm] = 1;
}
if(!pwmOutSuccess){
if (!pwmOutSuccess) {
error("PwmOut pin mapping failed. All available PWM channels are in use.");
}
obj->pwm = pwm;
obj->pin = pin;
gpiote_init(pin,(uint8_t)pwm);
gpiote_init(pin, (uint8_t)pwm);
ppi_init((uint8_t)pwm);
if(pwm == 0){
if (pwm == 0) {
NRF_POWER->TASKS_CONSTLAT = 1;
}
timer_init((uint8_t)pwm);
//default to 20ms: standard for servos, and fine for e.g. brightness control
pwmout_period_ms(obj, 20);
pwmout_write (obj, 0);
}
void pwmout_free(pwmout_t* obj) {
void pwmout_free(pwmout_t *obj)
{
// [TODO]
}
void pwmout_write(pwmout_t* obj, float value) {
void pwmout_write(pwmout_t *obj, float value)
{
uint16_t oldPulseWidth;
NRF_TIMER2->EVENTS_COMPARE[3] = 0;
NRF_TIMER2->TASKS_STOP = 1;
NRF_TIMER2->TASKS_STOP = 1;
if (value < 0.0f) {
value = 0.0;
} else if (value > 1.0f) {
value = 1.0;
}
oldPulseWidth = ACTUAL_PULSE[obj->pwm];
ACTUAL_PULSE[obj->pwm] = PULSE_WIDTH[obj->pwm] = value* PERIOD;
if(PULSE_WIDTH[obj->pwm] == 0){
}
oldPulseWidth = ACTUAL_PULSE[obj->pwm];
ACTUAL_PULSE[obj->pwm] = PULSE_WIDTH[obj->pwm] = value * PERIOD;
if (PULSE_WIDTH[obj->pwm] == 0) {
PULSE_WIDTH[obj->pwm] = 1;
setModulation(obj,0,0);
setModulation(obj, 0, 0);
} else if (PULSE_WIDTH[obj->pwm] == PERIOD) {
PULSE_WIDTH[obj->pwm] = PERIOD - 1;
setModulation(obj, 0, 1);
} else if ((oldPulseWidth == 0) || (oldPulseWidth == PERIOD)) {
setModulation(obj, 1, oldPulseWidth == PERIOD);
}
else if(PULSE_WIDTH[obj->pwm] == PERIOD){
PULSE_WIDTH[obj->pwm] = PERIOD-1;
setModulation(obj,0,1);
}
else if( (oldPulseWidth == 0) || (oldPulseWidth == PERIOD) ){
setModulation(obj,1,oldPulseWidth == PERIOD);
}
NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE3_Msk;
NRF_TIMER2->SHORTS = TIMER_SHORTS_COMPARE3_CLEAR_Msk | TIMER_SHORTS_COMPARE3_STOP_Msk;
NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE3_Msk;
NRF_TIMER2->SHORTS = TIMER_SHORTS_COMPARE3_CLEAR_Msk | TIMER_SHORTS_COMPARE3_STOP_Msk;
NRF_TIMER2->TASKS_START = 1;
}
float pwmout_read(pwmout_t* obj) {
return ((float)PULSE_WIDTH[obj->pwm]/(float)PERIOD);
float pwmout_read(pwmout_t *obj)
{
return ((float)PULSE_WIDTH[obj->pwm] / (float)PERIOD);
}
void pwmout_period(pwmout_t* obj, float seconds) {
void pwmout_period(pwmout_t *obj, float seconds)
{
pwmout_period_us(obj, seconds * 1000000.0f);
}
void pwmout_period_ms(pwmout_t* obj, int ms) {
void pwmout_period_ms(pwmout_t *obj, int ms)
{
pwmout_period_us(obj, ms * 1000);
}
// Set the PWM period, keeping the duty cycle the same.
void pwmout_period_us(pwmout_t* obj, int us) {
uint32_t periodInTicks = us/TIMER_PRECISION;
void pwmout_period_us(pwmout_t *obj, int us)
{
uint32_t periodInTicks = us / TIMER_PRECISION;
NRF_TIMER2->EVENTS_COMPARE[3] = 0;
NRF_TIMER2->TASKS_STOP = 1;
if(periodInTicks>((1<<16) -1))
{
PERIOD = (1<<16 )-1;//131ms
}
else if(periodInTicks<5){
NRF_TIMER2->TASKS_STOP = 1;
if (periodInTicks>((1 << 16) - 1)) {
PERIOD = (1 << 16) - 1; //131ms
} else if (periodInTicks<5) {
PERIOD = 5;
} else {
PERIOD = periodInTicks;
}
else{
PERIOD =periodInTicks;
}
NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE3_Msk;
NRF_TIMER2->SHORTS = TIMER_SHORTS_COMPARE3_CLEAR_Msk | TIMER_SHORTS_COMPARE3_STOP_Msk;
NRF_TIMER2->TASKS_START = 1;
NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE3_Msk;
NRF_TIMER2->SHORTS = TIMER_SHORTS_COMPARE3_CLEAR_Msk | TIMER_SHORTS_COMPARE3_STOP_Msk;
NRF_TIMER2->TASKS_START = 1;
}
void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
{
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
}
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
{
pwmout_pulsewidth_us(obj, ms * 1000);
}
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
uint32_t pulseInTicks = us/TIMER_PRECISION;
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
{
uint32_t pulseInTicks = us / TIMER_PRECISION;
uint16_t oldPulseWidth = ACTUAL_PULSE[obj->pwm];
NRF_TIMER2->EVENTS_COMPARE[3] = 0;
NRF_TIMER2->TASKS_STOP = 1;
NRF_TIMER2->TASKS_STOP = 1;
ACTUAL_PULSE[obj->pwm] = PULSE_WIDTH[obj->pwm] = pulseInTicks;
if(PULSE_WIDTH[obj->pwm] == 0){
if (PULSE_WIDTH[obj->pwm] == 0) {
PULSE_WIDTH[obj->pwm] = 1;
setModulation(obj,0,0);
setModulation(obj, 0, 0);
} else if (PULSE_WIDTH[obj->pwm] == PERIOD) {
PULSE_WIDTH[obj->pwm] = PERIOD - 1;
setModulation(obj, 0, 1);
} else if ((oldPulseWidth == 0) || (oldPulseWidth == PERIOD)) {
setModulation(obj, 1, oldPulseWidth == PERIOD);
}
else if(PULSE_WIDTH[obj->pwm] == PERIOD){
PULSE_WIDTH[obj->pwm] = PERIOD-1;
setModulation(obj,0,1);
}
else if( (oldPulseWidth == 0) || (oldPulseWidth == PERIOD) ){
setModulation(obj,1,oldPulseWidth == PERIOD);
}
NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE3_Msk;
NRF_TIMER2->SHORTS = TIMER_SHORTS_COMPARE3_CLEAR_Msk | TIMER_SHORTS_COMPARE3_STOP_Msk;
NRF_TIMER2->TASKS_START = 1;
NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE3_Msk;
NRF_TIMER2->SHORTS = TIMER_SHORTS_COMPARE3_CLEAR_Msk | TIMER_SHORTS_COMPARE3_STOP_Msk;
NRF_TIMER2->TASKS_START = 1;
}

View File

@ -29,22 +29,22 @@
static uint32_t serial_irq_ids[UART_NUM] = {0};
static uart_irq_handler irq_handler;
static uint32_t acceptedSpeeds[16][2] = {{1200,UART_BAUDRATE_BAUDRATE_Baud1200},
{2400,UART_BAUDRATE_BAUDRATE_Baud2400},
{4800,UART_BAUDRATE_BAUDRATE_Baud4800},
{9600,UART_BAUDRATE_BAUDRATE_Baud9600},
{14400,UART_BAUDRATE_BAUDRATE_Baud14400},
{19200,UART_BAUDRATE_BAUDRATE_Baud19200},
{28800,UART_BAUDRATE_BAUDRATE_Baud28800},
{38400,UART_BAUDRATE_BAUDRATE_Baud38400},
{57600,UART_BAUDRATE_BAUDRATE_Baud57600},
{76800,UART_BAUDRATE_BAUDRATE_Baud76800},
{115200,UART_BAUDRATE_BAUDRATE_Baud115200},
{230400,UART_BAUDRATE_BAUDRATE_Baud230400},
{250000,UART_BAUDRATE_BAUDRATE_Baud250000},
{460800,UART_BAUDRATE_BAUDRATE_Baud460800},
{921600,UART_BAUDRATE_BAUDRATE_Baud921600},
{1000000,UART_BAUDRATE_BAUDRATE_Baud1M}};
static uint32_t acceptedSpeeds[16][2] = {{1200, UART_BAUDRATE_BAUDRATE_Baud1200},
{2400, UART_BAUDRATE_BAUDRATE_Baud2400},
{4800, UART_BAUDRATE_BAUDRATE_Baud4800},
{9600, UART_BAUDRATE_BAUDRATE_Baud9600},
{14400, UART_BAUDRATE_BAUDRATE_Baud14400},
{19200, UART_BAUDRATE_BAUDRATE_Baud19200},
{28800, UART_BAUDRATE_BAUDRATE_Baud28800},
{38400, UART_BAUDRATE_BAUDRATE_Baud38400},
{57600, UART_BAUDRATE_BAUDRATE_Baud57600},
{76800, UART_BAUDRATE_BAUDRATE_Baud76800},
{115200, UART_BAUDRATE_BAUDRATE_Baud115200},
{230400, UART_BAUDRATE_BAUDRATE_Baud230400},
{250000, UART_BAUDRATE_BAUDRATE_Baud250000},
{460800, UART_BAUDRATE_BAUDRATE_Baud460800},
{921600, UART_BAUDRATE_BAUDRATE_Baud921600},
{1000000, UART_BAUDRATE_BAUDRATE_Baud1M}};
int stdio_uart_inited = 0;
serial_t stdio_uart;
@ -52,78 +52,81 @@ serial_t stdio_uart;
void serial_init(serial_t *obj, PinName tx, PinName rx) {
UARTName uart = UART_0;
MBED_ASSERT((int)uart != NC);
obj->uart = (NRF_UART_Type *)uart;
//pin configurations --
//outputs
NRF_GPIO->DIR |= (1<<tx);//TX_PIN_NUMBER);
NRF_GPIO->DIR |= (1<<RTS_PIN_NUMBER);
NRF_GPIO->DIR |= (1 << tx); //TX_PIN_NUMBER);
NRF_GPIO->DIR |= (1 << RTS_PIN_NUMBER);
NRF_GPIO->DIR &= ~(1 << rx); //RX_PIN_NUMBER);
NRF_GPIO->DIR &= ~(1 << CTS_PIN_NUMBER);
NRF_GPIO->DIR &= ~(1<<rx);//RX_PIN_NUMBER);
NRF_GPIO->DIR &= ~(1<<CTS_PIN_NUMBER);
obj->uart->PSELRTS = RTS_PIN_NUMBER;
obj->uart->PSELTXD = tx;//TX_PIN_NUMBER;
obj->uart->PSELTXD = tx; //TX_PIN_NUMBER;
//inputs
obj->uart->PSELCTS = CTS_PIN_NUMBER;
obj->uart->PSELRXD = rx;//RX_PIN_NUMBER;
obj->uart->PSELRXD = rx; //RX_PIN_NUMBER;
// set default baud rate and format
serial_baud (obj, 9600);
serial_format(obj, 8, ParityNone, 1);
obj->uart->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos);;
obj->uart->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos);
obj->uart->TASKS_STARTTX = 1;
obj->uart->TASKS_STARTRX = 1;
obj->uart->EVENTS_RXDRDY =0;
obj->uart->EVENTS_RXDRDY = 0;
obj->index = 0;
// set rx/tx pins in PullUp mode
pin_mode(tx, PullUp);
pin_mode(rx, PullUp);
if (uart == STDIO_UART) {
stdio_uart_inited = 1;
memcpy(&stdio_uart, obj, sizeof(serial_t));
}
}
void serial_free(serial_t *obj) {
void serial_free(serial_t *obj)
{
serial_irq_ids[obj->index] = 0;
}
// serial_baud
// set the baud rate, taking in to account the current SystemFrequency
void serial_baud(serial_t *obj, int baudrate) {
if(baudrate<=1200){
void serial_baud(serial_t *obj, int baudrate)
{
if (baudrate<=1200) {
obj->uart->BAUDRATE = UART_BAUDRATE_BAUDRATE_Baud1200;
return;
}
for(int i=1;i<16;i++){
if(baudrate<acceptedSpeeds[i][0]){
obj->uart->BAUDRATE = acceptedSpeeds[i-1][1];
for (int i = 1; i<16; i++) {
if (baudrate<acceptedSpeeds[i][0]) {
obj->uart->BAUDRATE = acceptedSpeeds[i - 1][1];
return;
}
}
obj->uart->BAUDRATE = UART_BAUDRATE_BAUDRATE_Baud1M;
}
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
{
// 0: 1 stop bits, 1: 2 stop bits
// int parity_enable, parity_select;
// int parity_enable, parity_select;
switch (parity) {
case ParityNone:
obj->uart->CONFIG = 0;
break;
obj->uart->CONFIG = 0;
break;
default:
obj->uart->CONFIG = (UART_CONFIG_PARITY_Included<<UART_CONFIG_PARITY_Pos);
obj->uart->CONFIG = (UART_CONFIG_PARITY_Included << UART_CONFIG_PARITY_Pos);
return;
}
//no Flow Control
@ -132,74 +135,85 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
//******************************************************************************
// * INTERRUPT HANDLING
//******************************************************************************
static inline void uart_irq(uint32_t iir, uint32_t index) {
static inline void uart_irq(uint32_t iir, uint32_t index)
{
SerialIrq irq_type;
switch (iir) {
case 1:
irq_type = TxIrq;
break;
break;
case 2:
irq_type = RxIrq;
break;
default: return;
break;
default:
return;
}
if (serial_irq_ids[index] != 0){
if (serial_irq_ids[index] != 0) {
irq_handler(serial_irq_ids[index], irq_type);
}
}
#ifdef __cplusplus
extern "C" {
#endif
void UART0_IRQHandler()
{
uint32_t irtype =0;
if(NRF_UART0->EVENTS_TXDRDY){
irtype =1;
}
else if(NRF_UART0->EVENTS_RXDRDY){
irtype =2;
uint32_t irtype = 0;
if (NRF_UART0->EVENTS_TXDRDY) {
irtype = 1;
} else if (NRF_UART0->EVENTS_RXDRDY) {
irtype = 2;
}
uart_irq(irtype, 0);
}
#ifdef __cplusplus
}
#endif
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
irq_handler = handler;
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
{
irq_handler = handler;
serial_irq_ids[obj->index] = id;
}
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
{
IRQn_Type irq_n = (IRQn_Type)0;
switch ((int)obj->uart) {
case UART_0: irq_n=UART0_IRQn ;
case UART_0:
irq_n = UART0_IRQn;
break;
}
if (enable) {
switch (irq) {
case RxIrq: obj->uart->INTENSET |= (UART_INTENSET_RXDRDY_Msk);break;
case TxIrq: obj->uart->INTENSET |= (UART_INTENSET_TXDRDY_Msk);break;
case RxIrq:
obj->uart->INTENSET |= (UART_INTENSET_RXDRDY_Msk);
break;
case TxIrq:
obj->uart->INTENSET |= (UART_INTENSET_TXDRDY_Msk);
break;
}
NVIC_SetPriority(irq_n, 3);
NVIC_EnableIRQ(irq_n);
}
else { // disable
} else { // disable
int all_disabled = 0;
switch (irq) {
case RxIrq: obj->uart->INTENSET &= ~(UART_INTENSET_RXDRDY_Msk);
all_disabled = (obj->uart->INTENSET& (UART_INTENSET_TXDRDY_Msk))==0;
break;
case TxIrq: obj->uart->INTENSET &= ~(UART_INTENSET_TXDRDY_Msk);
all_disabled = (obj->uart->INTENSET& (UART_INTENSET_RXDRDY_Msk))==0;
break;
case RxIrq:
obj->uart->INTENSET &= ~(UART_INTENSET_RXDRDY_Msk);
all_disabled = (obj->uart->INTENSET & (UART_INTENSET_TXDRDY_Msk))==0;
break;
case TxIrq:
obj->uart->INTENSET &= ~(UART_INTENSET_TXDRDY_Msk);
all_disabled = (obj->uart->INTENSET & (UART_INTENSET_RXDRDY_Msk))==0;
break;
}
if (all_disabled){
if (all_disabled) {
NVIC_DisableIRQ(irq_n);
}
}
@ -208,35 +222,43 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
//******************************************************************************
//* READ/WRITE
//******************************************************************************
int serial_getc(serial_t *obj) {
while (!serial_readable(obj));
int serial_getc(serial_t *obj)
{
while (!serial_readable(obj)) {
}
obj->uart->EVENTS_RXDRDY = 0;
return (uint8_t)obj->uart->RXD;
}
void serial_putc(serial_t *obj, int c) {
void serial_putc(serial_t *obj, int c)
{
obj->uart->TXD = (uint8_t)c;
while (!serial_writable(obj));
obj->uart->EVENTS_TXDRDY =0;
while (!serial_writable(obj)) {
}
obj->uart->EVENTS_TXDRDY = 0;
}
int serial_readable(serial_t *obj) {
int serial_readable(serial_t *obj)
{
return (obj->uart->EVENTS_RXDRDY == 1);
}
int serial_writable(serial_t *obj) {
int serial_writable(serial_t *obj)
{
return (obj->uart->EVENTS_TXDRDY ==1);
}
void serial_break_set(serial_t *obj) {
void serial_break_set(serial_t *obj)
{
obj->uart->TASKS_SUSPEND = 1;
}
void serial_break_clear(serial_t *obj) {
void serial_break_clear(serial_t *obj)
{
obj->uart->TASKS_STARTTX = 1;
obj->uart->TASKS_STARTRX = 1;
}

View File

@ -17,14 +17,16 @@
#include "cmsis.h"
#include "mbed_interface.h"
void sleep(void) {
void sleep(void)
{
// ensure debug is disconnected if semihost is enabled....
NRF_POWER->TASKS_LOWPWR=1;
NRF_POWER->TASKS_LOWPWR = 1;
// wait for interrupt
__WFE();
}
void deepsleep(void) {
void deepsleep(void)
{
sleep();
// NRF_POWER->SYSTEMOFF=1;
// NRF_POWER->SYSTEMOFF=1;
}

View File

@ -21,29 +21,29 @@
#include "mbed_error.h"
static const PinMap PinMap_SPI_SCLK[] = {
{SPI_PSELSCK0 , SPI_0, 0x01},
{SPI_PSELSCK0, SPI_0, 0x01},
{SPI_PSELSCK1, SPI_1, 0x02},
{SPIS_PSELSCK, SPIS, 0x03},
{NC , NC , 0}
{NC, NC, 0}
};
static const PinMap PinMap_SPI_MOSI[] = {
{SPI_PSELMOSI0 , SPI_0, 0x01},
{SPI_PSELMOSI0, SPI_0, 0x01},
{SPI_PSELMOSI1, SPI_1, 0x02},
{SPIS_PSELMOSI, SPIS, 0x03},
{NC , NC , 0}
{NC, NC, 0}
};
static const PinMap PinMap_SPI_MISO[] = {
{SPI_PSELMISO0 , SPI_0, 0x01},
{SPI_PSELMISO0, SPI_0, 0x01},
{SPI_PSELMISO1, SPI_1, 0x02},
{SPIS_PSELMISO, SPIS, 0x03},
{NC , NC , 0}
{NC, NC, 0}
};
static const PinMap PinMap_SPI_SSEL[] = {
{SPIS_PSELSS, SPIS, 0x03},
{NC , NC , 0}
{NC, NC, 0}
};
// {SPI_PSELSS0 , SPI_0, 0x01},
#define SPIS_MESSAGE_SIZE 1
@ -51,7 +51,8 @@ volatile uint8_t m_tx_buf[SPIS_MESSAGE_SIZE] = {0};
volatile uint8_t m_rx_buf[SPIS_MESSAGE_SIZE] = {0};
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
{
// determine the SPI to use
SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
@ -59,22 +60,21 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
SPIName spi = (SPIName)pinmap_merge(spi_data, spi_cntl);
SPIName spi = (SPIName)pinmap_merge(spi_data, spi_cntl);
//SPIName
if(ssel==NC){
obj->spi = (NRF_SPI_Type*)spi;
obj->spis = (NRF_SPIS_Type*)NC;
}
else{
obj->spi = (NRF_SPI_Type*)NC;
obj->spis = (NRF_SPIS_Type*)spi;
if (ssel==NC) {
obj->spi = (NRF_SPI_Type *)spi;
obj->spis = (NRF_SPIS_Type *)NC;
} else {
obj->spi = (NRF_SPI_Type *)NC;
obj->spis = (NRF_SPIS_Type *)spi;
}
MBED_ASSERT((int)obj->spi != NC || (int)obj->spis != NC);
// pin out the spi pins
if (ssel != NC) {//slave
obj->spis->POWER=0;
obj->spis->POWER=1;
// pin out the spi pins
if (ssel != NC) { //slave
obj->spis->POWER = 0;
obj->spis->POWER = 1;
NRF_GPIO->PIN_CNF[mosi] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
| (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
@ -96,26 +96,25 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
| (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
| (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
| (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
obj->spis->PSELMOSI = mosi;
obj->spis->PSELMISO = miso;
obj->spis->PSELSCK = sclk;
obj->spis->PSELCSN = ssel;
obj->spis->EVENTS_END=0;
obj->spis->EVENTS_ACQUIRED=0;
obj->spis->MAXRX=SPIS_MESSAGE_SIZE;
obj->spis->MAXTX=SPIS_MESSAGE_SIZE;
obj->spis->TXDPTR = (uint32_t)&m_tx_buf[0];
obj->spis->RXDPTR = (uint32_t)&m_rx_buf[0];
obj->spis->SHORTS = (SPIS_SHORTS_END_ACQUIRE_Enabled<<SPIS_SHORTS_END_ACQUIRE_Pos);
obj->spis->PSELSCK = sclk;
obj->spis->PSELCSN = ssel;
obj->spis->EVENTS_END = 0;
obj->spis->EVENTS_ACQUIRED = 0;
obj->spis->MAXRX = SPIS_MESSAGE_SIZE;
obj->spis->MAXTX = SPIS_MESSAGE_SIZE;
obj->spis->TXDPTR = (uint32_t)&m_tx_buf[0];
obj->spis->RXDPTR = (uint32_t)&m_rx_buf[0];
obj->spis->SHORTS = (SPIS_SHORTS_END_ACQUIRE_Enabled << SPIS_SHORTS_END_ACQUIRE_Pos);
spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave
}
else{//master
obj->spi->POWER=0;
obj->spi->POWER=1;
} else { //master
obj->spi->POWER = 0;
obj->spi->POWER = 1;
//NRF_GPIO->DIR |= (1<<mosi);
NRF_GPIO->PIN_CNF[mosi] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
| (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
@ -123,14 +122,14 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
| (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
| (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
obj->spi->PSELMOSI = mosi;
NRF_GPIO->PIN_CNF[sclk] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
| (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
| (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
| (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
| (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
obj->spi->PSELSCK = sclk;
//NRF_GPIO->DIR &= ~(1<<miso);
NRF_GPIO->PIN_CNF[miso] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
| (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
@ -139,53 +138,53 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
| (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
obj->spi->PSELMISO = miso;
obj->spi->EVENTS_READY = 0U;
spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master
spi_frequency(obj, 1000000);
}
}
void spi_free(spi_t *obj) {}
void spi_free(spi_t *obj) {
}
static inline void spi_disable(spi_t *obj, int slave) {
if(slave){
static inline void spi_disable(spi_t *obj, int slave)
{
if (slave) {
obj->spis->ENABLE = (SPIS_ENABLE_ENABLE_Disabled << SPIS_ENABLE_ENABLE_Pos);
}
else{
} else {
obj->spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
}
}
static inline void spi_enable(spi_t *obj, int slave) {
if(slave){
static inline void spi_enable(spi_t *obj, int slave)
{
if (slave) {
obj->spis->ENABLE = (SPIS_ENABLE_ENABLE_Enabled << SPIS_ENABLE_ENABLE_Pos);
}
else{
} else {
obj->spi->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos);
}
}
void spi_format(spi_t *obj, int bits, int mode, int slave) {
void spi_format(spi_t *obj, int bits, int mode, int slave)
{
uint32_t config_mode = 0;
spi_disable(obj,slave);
spi_disable(obj, slave);
if (bits != 8) {
error("Only 8bits SPI supported");
}
switch (mode)
{
switch (mode) {
case 0:
config_mode = (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos) | (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
config_mode = (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos) | (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
break;
case 1:
config_mode = (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos) | (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
break;
case 2:
config_mode = (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos) | (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
config_mode = (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos) | (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
break;
case 3:
config_mode = (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos) | (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
@ -195,65 +194,63 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) {
break;
}
//default to msb first
if(slave){
obj->spis->CONFIG = (config_mode | (SPI_CONFIG_ORDER_MsbFirst << SPI_CONFIG_ORDER_Pos) );
if (slave) {
obj->spis->CONFIG = (config_mode | (SPI_CONFIG_ORDER_MsbFirst << SPI_CONFIG_ORDER_Pos));
} else {
obj->spi->CONFIG = (config_mode | (SPI_CONFIG_ORDER_MsbFirst << SPI_CONFIG_ORDER_Pos));
}
else{
obj->spi->CONFIG = (config_mode | (SPI_CONFIG_ORDER_MsbFirst << SPI_CONFIG_ORDER_Pos) );
}
spi_enable(obj,slave);
spi_enable(obj, slave);
}
void spi_frequency(spi_t *obj, int hz) {
if((int)obj->spi==NC)
void spi_frequency(spi_t *obj, int hz)
{
if ((int)obj->spi==NC) {
return;
spi_disable(obj,0);
if(hz<250000) { //125Kbps
}
spi_disable(obj, 0);
if (hz<250000) { //125Kbps
obj->spi->FREQUENCY = (uint32_t) SPI_FREQUENCY_FREQUENCY_K125;
}
else if(hz<500000){//250Kbps
} else if (hz<500000) { //250Kbps
obj->spi->FREQUENCY = (uint32_t) SPI_FREQUENCY_FREQUENCY_K250;
}
else if(hz<1000000){//500Kbps
} else if (hz<1000000) { //500Kbps
obj->spi->FREQUENCY = (uint32_t) SPI_FREQUENCY_FREQUENCY_K500;
}
else if(hz<2000000){//1Mbps
} else if (hz<2000000) { //1Mbps
obj->spi->FREQUENCY = (uint32_t) SPI_FREQUENCY_FREQUENCY_M1;
}
else if(hz<4000000){//2Mbps
} else if (hz<4000000) { //2Mbps
obj->spi->FREQUENCY = (uint32_t) SPI_FREQUENCY_FREQUENCY_M2;
}
else if(hz<8000000){//4Mbps
} else if (hz<8000000) { //4Mbps
obj->spi->FREQUENCY = (uint32_t) SPI_FREQUENCY_FREQUENCY_M4;
}
else{//8Mbps
} else { //8Mbps
obj->spi->FREQUENCY = (uint32_t) SPI_FREQUENCY_FREQUENCY_M8;
}
spi_enable(obj,0);
spi_enable(obj, 0);
}
static inline int spi_readable(spi_t *obj) {
static inline int spi_readable(spi_t *obj)
{
return (obj->spi->EVENTS_READY == 1);
}
static inline int spi_writeable(spi_t *obj) {
static inline int spi_writeable(spi_t *obj)
{
return (obj->spi->EVENTS_READY == 0);
}
static inline int spi_read(spi_t *obj) {
while (!spi_readable(obj)){
static inline int spi_read(spi_t *obj)
{
while (!spi_readable(obj)) {
}
obj->spi->EVENTS_READY =0;
obj->spi->EVENTS_READY = 0;
return (int)obj->spi->RXD;
}
int spi_master_write(spi_t *obj, int value) {
while (!spi_writeable(obj)){
int spi_master_write(spi_t *obj, int value)
{
while (!spi_writeable(obj)) {
}
obj->spi->TXD = (uint32_t)value;
return spi_read(obj);
@ -263,17 +260,20 @@ int spi_master_write(spi_t *obj, int value) {
// return (obj->spis->EVENTS_ACQUIRED==1);
//}
int spi_slave_receive(spi_t *obj) {
int spi_slave_receive(spi_t *obj)
{
return obj->spis->EVENTS_END;
};
}
int spi_slave_read(spi_t *obj) {
int spi_slave_read(spi_t *obj)
{
return m_rx_buf[0];
}
void spi_slave_write(spi_t *obj, int value) {
m_tx_buf[0]= value & 0xFF;
obj->spis->TASKS_RELEASE=1;
obj->spis->EVENTS_ACQUIRED=0;
obj->spis->EVENTS_END=0;
void spi_slave_write(spi_t *obj, int value)
{
m_tx_buf[0] = value & 0xFF;
obj->spis->TASKS_RELEASE = 1;
obj->spis->EVENTS_ACQUIRED = 0;
obj->spis->EVENTS_END = 0;
}

View File

@ -21,107 +21,109 @@
#define US_TICKER_TIMER NRF_TIMER1
#define US_TICKER_TIMER_IRQn TIMER1_IRQn
int us_ticker_inited = 0;
volatile uint16_t overflow=0; //overflow value that forms the upper 16 bits of the counter
volatile uint16_t timeStamp=0;
int us_ticker_inited = 0;
volatile uint16_t overflow = 0; //overflow value that forms the upper 16 bits of the counter
volatile uint16_t timeStamp = 0;
#ifdef __cplusplus
extern "C" {
#endif
void TIMER1_IRQHandler(void){
#endif
if ((US_TICKER_TIMER->EVENTS_COMPARE[1] != 0) &&
((US_TICKER_TIMER->INTENSET & TIMER_INTENSET_COMPARE1_Msk) != 0))
{
US_TICKER_TIMER->EVENTS_COMPARE[1] = 0;
overflow++;
US_TICKER_TIMER->CC[1] =0xFFFF;
if(timeStamp>0)
{
timeStamp--;
if(timeStamp==0)
{
us_ticker_clear_interrupt();
us_ticker_disable_interrupt();
us_ticker_irq_handler();
return;
}
}
void TIMER1_IRQHandler(void)
{
if ((US_TICKER_TIMER->EVENTS_COMPARE[1] != 0) &&
((US_TICKER_TIMER->INTENSET & TIMER_INTENSET_COMPARE1_Msk) != 0)) {
US_TICKER_TIMER->EVENTS_COMPARE[1] = 0;
overflow++;
US_TICKER_TIMER->CC[1] = 0xFFFF;
if (timeStamp>0) {
timeStamp--;
if (timeStamp==0) {
us_ticker_clear_interrupt();
us_ticker_disable_interrupt();
us_ticker_irq_handler();
return;
}
}
}
if ((US_TICKER_TIMER->EVENTS_COMPARE[0] != 0) &&
((US_TICKER_TIMER->INTENSET & TIMER_INTENSET_COMPARE0_Msk) != 0))
{
us_ticker_clear_interrupt();
us_ticker_disable_interrupt();
if(timeStamp==0)
us_ticker_irq_handler();
if ((US_TICKER_TIMER->EVENTS_COMPARE[0] != 0) &&
((US_TICKER_TIMER->INTENSET & TIMER_INTENSET_COMPARE0_Msk) != 0)) {
us_ticker_clear_interrupt();
us_ticker_disable_interrupt();
if (timeStamp==0) {
us_ticker_irq_handler();
}
}
}
#ifdef __cplusplus
}
#endif
void us_ticker_init(void){
if (us_ticker_inited && US_TICKER_TIMER->POWER){
#endif
void us_ticker_init(void)
{
if (us_ticker_inited && US_TICKER_TIMER->POWER) {
return;
}
us_ticker_inited = 1;
US_TICKER_TIMER->POWER = 0;
US_TICKER_TIMER->POWER = 1;
US_TICKER_TIMER->MODE = TIMER_MODE_MODE_Timer;
US_TICKER_TIMER->PRESCALER = 4;
US_TICKER_TIMER->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
US_TICKER_TIMER->TASKS_CLEAR =1;
US_TICKER_TIMER->CC[1] = 0xFFFF;
US_TICKER_TIMER->INTENSET = TIMER_INTENSET_COMPARE1_Set << TIMER_INTENSET_COMPARE1_Pos;
US_TICKER_TIMER->PRESCALER = 4;
US_TICKER_TIMER->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
US_TICKER_TIMER->TASKS_CLEAR = 1;
US_TICKER_TIMER->CC[1] = 0xFFFF;
US_TICKER_TIMER->INTENSET = TIMER_INTENSET_COMPARE1_Set << TIMER_INTENSET_COMPARE1_Pos;
NVIC_SetPriority(US_TICKER_TIMER_IRQn, 3);
NVIC_EnableIRQ(US_TICKER_TIMER_IRQn);
US_TICKER_TIMER->TASKS_START = 0x01;
}
uint32_t us_ticker_read(){
if (!us_ticker_inited || US_TICKER_TIMER->POWER==0){
uint32_t us_ticker_read()
{
if (!us_ticker_inited || (US_TICKER_TIMER->POWER==0)) {
us_ticker_init();
}
uint16_t bufferedOverFlow = overflow;
US_TICKER_TIMER->TASKS_CAPTURE[2] = 1;
if(overflow!=bufferedOverFlow){
bufferedOverFlow = overflow;
US_TICKER_TIMER->TASKS_CAPTURE[2] = 1;
}
return (((uint32_t)bufferedOverFlow<<16) | US_TICKER_TIMER->CC[2]);
uint16_t bufferedOverFlow = overflow;
US_TICKER_TIMER->TASKS_CAPTURE[2] = 1;
if (overflow!=bufferedOverFlow) {
bufferedOverFlow = overflow;
US_TICKER_TIMER->TASKS_CAPTURE[2] = 1;
}
return (((uint32_t)bufferedOverFlow << 16) | US_TICKER_TIMER->CC[2]);
}
void us_ticker_set_interrupt(unsigned int timestamp){
if (!us_ticker_inited || US_TICKER_TIMER->POWER==0)
{
void us_ticker_set_interrupt(unsigned int timestamp)
{
if (!us_ticker_inited || (US_TICKER_TIMER->POWER == 0)) {
us_ticker_init();
}
US_TICKER_TIMER->TASKS_CAPTURE[0] = 1;
uint16_t tsUpper16 = (uint16_t)((timestamp-us_ticker_read())>>16);
if(tsUpper16>0){
if(timeStamp ==0 || timeStamp> tsUpper16){
timeStamp = tsUpper16;
}
}
else{
US_TICKER_TIMER->INTENSET |= TIMER_INTENSET_COMPARE0_Set << TIMER_INTENSET_COMPARE0_Pos;
US_TICKER_TIMER->CC[0] += timestamp-us_ticker_read();
}
}
US_TICKER_TIMER->TASKS_CAPTURE[0] = 1;
uint16_t tsUpper16 = (uint16_t)((timestamp - us_ticker_read()) >> 16);
if (tsUpper16>0) {
if ((timeStamp ==0) || (timeStamp> tsUpper16)) {
timeStamp = tsUpper16;
}
} else {
US_TICKER_TIMER->INTENSET |= TIMER_INTENSET_COMPARE0_Set << TIMER_INTENSET_COMPARE0_Pos;
US_TICKER_TIMER->CC[0] += timestamp - us_ticker_read();
}
}
void us_ticker_disable_interrupt(void){
void us_ticker_disable_interrupt(void)
{
US_TICKER_TIMER->INTENCLR = TIMER_INTENCLR_COMPARE0_Clear << TIMER_INTENCLR_COMPARE0_Pos;
}
void us_ticker_clear_interrupt(void){
void us_ticker_clear_interrupt(void)
{
US_TICKER_TIMER->EVENTS_COMPARE[0] = 0;
}

View File

@ -27,16 +27,16 @@ int us_ticker_inited = 0;
void us_ticker_init(void) {
if (us_ticker_inited) return;
us_ticker_inited = 1;
US_TICKER_TIMER->CTCR = 0x0; // timer mode
uint32_t PCLK = SystemCoreClock;
US_TICKER_TIMER->TCR = 0x2; // reset
uint32_t prescale = PCLK / 1000000; // default to 1MHz (1 us ticks)
US_TICKER_TIMER->PR = prescale - 1;
US_TICKER_TIMER->TCR = 1; // enable = 1, reset = 0
NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler);
NVIC_EnableIRQ(US_TICKER_TIMER_IRQn);
}
@ -44,7 +44,7 @@ void us_ticker_init(void) {
uint32_t us_ticker_read() {
if (!us_ticker_inited)
us_ticker_init();
return US_TICKER_TIMER->TC;
}