mbed library sources(for async_print)
Fork of mbed-src by
Revision 454:a07e52520545, committed 2015-01-27
- Comitter:
- mbed_official
- Date:
- Tue Jan 27 07:15:07 2015 +0000
- Parent:
- 453:a290c6acf95e
- Child:
- 455:8bc3a354916d
- Commit message:
- Synchronized with git revision 8c14c0600dbcc802b3320eed4291ce569e93c103
Full URL: https://github.com/mbedmicro/mbed/commit/8c14c0600dbcc802b3320eed4291ce569e93c103/
Targets - Gpio irq hal with max num of irq for Nucleo 103RB
Changed in this revision
--- a/targets/hal/TARGET_NXP/TARGET_LPC81X/i2c_api.c Mon Jan 26 17:45:07 2015 +0000 +++ b/targets/hal/TARGET_NXP/TARGET_LPC81X/i2c_api.c Tue Jan 27 07:15:07 2015 +0000 @@ -86,11 +86,16 @@ return status; } + + +//Generate Stop condition and wait until bus is Idle +//Will also send NAK for previous RD inline int i2c_stop(i2c_t *obj) { int timeout = 0; - obj->i2c->MSTCTL = (1 << 2) | (1 << 0); - while ((obj->i2c->STAT & ((1 << 0) | (7 << 1))) != ((1 << 0) | (0 << 1))) { + obj->i2c->MSTCTL = (1 << 2) | (1 << 0); // STP bit and Continue bit. Sends NAK to complete previous RD + + while ((obj->i2c->STAT & ((7 << 1) | (1 << 0))) != ((0 << 1) | (1 << 0))) { //Spin until Ready (b0 == 1)and Status is Idle (b3..b1 == 000) timeout ++; if (timeout > 100000) return 1; } @@ -98,7 +103,6 @@ return 0; } - static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) { // write the data I2C_DAT(obj) = value; @@ -145,62 +149,82 @@ // because something is setup wrong (e.g. wiring), and we don't need to programatically // check for that +//New version WH, Tested OK for Start and Repeated Start +//Old version was Wrong: Calls i2c_start without setting address, i2c_do_read continues before checking status, status check for wrong value int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { int count, status; + //Store the address+RD and then generate STA + I2C_DAT(obj) = address | 0x01; + i2c_start(obj); + + // Wait for completion of STA and Sending of SlaveAddress+RD and first Read byte + i2c_wait_SI(obj); + status = i2c_status(obj); + if (status == 0x03) { // NAK on SlaveAddress + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + // Read in all except last byte + for (count = 0; count < (length-1); count++) { + + // Wait for it to arrive, note that first byte read after address+RD is already waiting + i2c_wait_SI(obj); + status = i2c_status(obj); + if (status != 0x01) { // RX RDY + i2c_stop(obj); + return count; + } + data[count] = I2C_DAT(obj) & 0xFF; // Store read byte + + obj->i2c->MSTCTL = (1 << 0); // Send ACK and Continue to read + } + + // Read final byte + // Wait for it to arrive + i2c_wait_SI(obj); + + status = i2c_status(obj); + if (status != 0x01) { // RX RDY + i2c_stop(obj); + return count; + } + data[count] = I2C_DAT(obj) & 0xFF; // Store final read byte + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); // Also sends NAK for last read byte + } else { + repeated_start = 1; + } + + return length; +} + + + +//New version WH, Tested OK for Start and Repeated Start +//Old version was Wrong: Calls i2c_start without setting address first +int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { + int i, status; + + //Store the address+/WR and then generate STA + I2C_DAT(obj) = address & 0xFE; i2c_start(obj); - status = i2c_do_write(obj, (address | 0x01), 1); - if (status != 0x01) { + // Wait for completion of STA and Sending of SlaveAddress+/WR + i2c_wait_SI(obj); + status = i2c_status(obj); + if (status == 0x03) { // NAK SlaveAddress i2c_stop(obj); return I2C_ERROR_NO_SLAVE; } - // Read in all except last byte - for (count = 0; count < (length - 1); count++) { - int value = i2c_do_read(obj, 0); - status = i2c_status(obj); - if (status != 0x00) { - i2c_stop(obj); - return count; - } - data[count] = (char) value; - } - - // read in last byte - int value = i2c_do_read(obj, 1); - status = i2c_status(obj); - if (status != 0x01) { - i2c_stop(obj); - return length - 1; - } - - data[count] = (char) value; - - // If not repeated start, send stop. - if (stop) { - i2c_stop(obj); - } else { - repeated_start = 1; - } - - return length; -} - -int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { - int i, status; - - i2c_start(obj); - - status = i2c_do_write(obj, (address & 0xFE), 1); - if (status != 0x02) { - i2c_stop(obj); - return I2C_ERROR_NO_SLAVE; - } - + //Write all bytes for (i=0; i<length; i++) { status = i2c_do_write(obj, data[i], 0); - if (status != 0x02) { + if (status != 0x02) { // TX RDY. Handles a Slave NAK on datawrite i2c_stop(obj); return i; } @@ -216,6 +240,8 @@ return length; } + + void i2c_reset(i2c_t *obj) { i2c_stop(obj); }
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F103RB/gpio_irq_api.c Mon Jan 26 17:45:07 2015 +0000 +++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F103RB/gpio_irq_api.c Tue Jan 27 07:15:07 2015 +0000 @@ -39,62 +39,125 @@ #define EDGE_BOTH (3) #define CHANNEL_NUM (7) +// Max pins for one line (max with EXTI10_15) +#define MAX_PIN_LINE (6) -static uint32_t channel_ids[CHANNEL_NUM] = {0, 0, 0, 0, 0, 0, 0}; -static uint32_t channel_gpio[CHANNEL_NUM] = {0, 0, 0, 0, 0, 0, 0}; -static uint32_t channel_pin[CHANNEL_NUM] = {0, 0, 0, 0, 0, 0, 0}; +typedef struct gpio_channel { + uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts + uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance + uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group + uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group +} gpio_channel_t; + +static gpio_channel_t channels[CHANNEL_NUM] = { + {.pin_mask = 0}, + {.pin_mask = 0}, + {.pin_mask = 0}, + {.pin_mask = 0}, + {.pin_mask = 0}, + {.pin_mask = 0}, + {.pin_mask = 0} +}; + +// Used to return the index for channels array. +static uint32_t pin_base_nr[16] = { + // EXTI0 + 0, // pin 0 + // EXTI1 + 0, // pin 1 + // EXTI2 + 0, // pin 2 + // EXTI3 + 0, // pin 3 + // EXTI4 + 0, // pin 4 + // EXTI5_9 + 0, // pin 5 + 1, // pin 6 + 2, // pin 7 + 3, // pin 8 + 4, // pin 9 + // EXTI10_15 + 0, // pin 10 + 1, // pin 11 + 2, // pin 12 + 3, // pin 13 + 4, // pin 14 + 5 // pin 15 +}; static gpio_irq_handler irq_handler; -static void handle_interrupt_in(uint32_t irq_index) +static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) { - // Retrieve the gpio and pin that generate the irq - GPIO_TypeDef *gpio = (GPIO_TypeDef *)(channel_gpio[irq_index]); - uint32_t pin = (uint32_t)(1 << channel_pin[irq_index]); + gpio_channel_t *gpio_channel = &channels[irq_index]; + uint32_t gpio_idx; + + for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) { + uint32_t current_mask = (1 << gpio_idx); + + if (gpio_channel->pin_mask & current_mask) { + // Retrieve the gpio and pin that generate the irq + GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]); + uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx])); - // Clear interrupt flag - if (EXTI_GetITStatus(pin) != RESET) { - EXTI_ClearITPendingBit(pin); - } + // Clear interrupt flag + if (EXTI_GetITStatus(pin) != RESET) { + EXTI_ClearITPendingBit(pin); + + if (gpio_channel->channel_ids[gpio_idx] == 0) continue; - if (channel_ids[irq_index] == 0) return; - - // Check which edge has generated the irq - if ((gpio->IDR & pin) == 0) { - irq_handler(channel_ids[irq_index], IRQ_FALL); - } else { - irq_handler(channel_ids[irq_index], IRQ_RISE); + // Check which edge has generated the irq + if ((gpio->IDR & pin) == 0) { + irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL); + } else { + irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE); + } + } + } } } -// The irq_index is passed to the function +// EXTI line 0 static void gpio_irq0(void) { - handle_interrupt_in(0); // EXTI line 0 + handle_interrupt_in(0, 1); } + +// EXTI line 1 static void gpio_irq1(void) { - handle_interrupt_in(1); // EXTI line 1 + handle_interrupt_in(1, 1); } + +// EXTI line 2 static void gpio_irq2(void) { - handle_interrupt_in(2); // EXTI line 2 + handle_interrupt_in(2, 1); } + +// EXTI line 3 static void gpio_irq3(void) { - handle_interrupt_in(3); // EXTI line 3 + handle_interrupt_in(3, 1); } + +// EXTI line 4 static void gpio_irq4(void) { - handle_interrupt_in(4); // EXTI line 4 + handle_interrupt_in(4, 1); } + +// EXTI lines 5 to 9 static void gpio_irq5(void) { - handle_interrupt_in(5); // EXTI lines 5 to 9 + handle_interrupt_in(5, 5); } + +// EXTI lines 10 to 15 static void gpio_irq6(void) { - handle_interrupt_in(6); // EXTI lines 10 to 15 + handle_interrupt_in(6, 6); } extern uint32_t Set_GPIO_Clock(uint32_t port_idx); @@ -104,6 +167,8 @@ IRQn_Type irq_n = (IRQn_Type)0; uint32_t vector = 0; uint32_t irq_index; + gpio_channel_t *gpio_channel; + uint32_t gpio_idx; if (pin == NC) return -1; @@ -193,9 +258,14 @@ obj->irq_n = irq_n; obj->irq_index = irq_index; obj->event = EDGE_NONE; - channel_ids[irq_index] = id; - channel_gpio[irq_index] = gpio_add; - channel_pin[irq_index] = pin_index; + obj->pin = pin; + + gpio_channel = &channels[irq_index]; + gpio_idx = pin_base_nr[pin_index]; + gpio_channel->pin_mask |= (1 << gpio_idx); + gpio_channel->channel_ids[gpio_idx] = id; + gpio_channel->channel_gpio[gpio_idx] = gpio_add; + gpio_channel->channel_pin[gpio_idx] = pin_index; irq_handler = handler; @@ -204,21 +274,29 @@ void gpio_irq_free(gpio_irq_t *obj) { - channel_ids[obj->irq_index] = 0; - channel_gpio[obj->irq_index] = 0; - channel_pin[obj->irq_index] = 0; + gpio_channel_t *gpio_channel = &channels[obj->irq_index]; + uint32_t pin_index = STM_PIN(obj->pin); + uint32_t gpio_idx = pin_base_nr[pin_index]; + + gpio_channel->pin_mask &= ~(1 << gpio_idx); + gpio_channel->channel_ids[gpio_idx] = 0; + gpio_channel->channel_gpio[gpio_idx] = 0; + gpio_channel->channel_pin[gpio_idx] = 0; + // Disable EXTI line EXTI_InitTypeDef EXTI_InitStructure; EXTI_StructInit(&EXTI_InitStructure); EXTI_Init(&EXTI_InitStructure); + + pin_function(obj->pin, STM_PIN_DATA(GPIO_Mode_Out_PP, 0)); + pin_function(obj->pin, STM_PIN_DATA(GPIO_Mode_IN_FLOATING, 0)); obj->event = EDGE_NONE; } void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { EXTI_InitTypeDef EXTI_InitStructure; - - uint32_t pin_index = channel_pin[obj->irq_index]; + uint32_t pin_index = STM_PIN(obj->pin); EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << pin_index); EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F103RB/objects.h Mon Jan 26 17:45:07 2015 +0000 +++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F103RB/objects.h Tue Jan 27 07:15:07 2015 +0000 @@ -43,6 +43,7 @@ IRQn_Type irq_n; uint32_t irq_index; uint32_t event; + PinName pin; }; struct port_s {